├── rustfmt.toml ├── web ├── plugin │ ├── .gitignore │ ├── tsconfig.json │ ├── CHANGELOG.md │ ├── src │ │ ├── transport.ts │ │ ├── IgnoreErrorBoundary.tsx │ │ ├── protocol │ │ │ ├── param_info.ts │ │ │ └── index.ts │ │ ├── stores_provider.tsx │ │ ├── index.ts │ │ ├── msgpack_transport.ts │ │ ├── ui_state_provider.tsx │ │ ├── DevModeTools.tsx │ │ ├── ui_state.ts │ │ ├── ui_state_test.tsx │ │ ├── wry_transport.ts │ │ ├── stores_react.ts │ │ ├── params.ts │ │ └── mock_store.ts │ ├── README.md │ ├── eslint.config.mjs │ ├── LICENSE │ └── package.json ├── scripts │ ├── src │ │ ├── repoRoot.ts │ │ ├── util.ts │ │ ├── index.ts │ │ ├── configArg.ts │ │ ├── format.ts │ │ ├── checkFormat.ts │ │ ├── bundleData.ts │ │ ├── create-plugin.ts │ │ ├── cargo.ts │ │ ├── checkLicenses.ts │ │ ├── workspaceRoot.ts │ │ ├── webScript.ts │ │ ├── selfDoc.ts │ │ ├── cli.ts │ │ ├── validate.ts │ │ ├── runShell.ts │ │ ├── ci.ts │ │ ├── checkTodo.ts │ │ ├── package.ts │ │ └── checkLfs.ts │ ├── tsconfig.json │ ├── README.md │ ├── eslint.config.mjs │ ├── LICENSE │ ├── package.json │ └── CHANGELOG.md ├── create │ ├── template │ │ ├── rustfmt.toml │ │ ├── prettier.config.mjs │ │ ├── web │ │ │ ├── tsconfig │ │ │ │ ├── package.json │ │ │ │ └── tsconfig.json │ │ │ └── eslint-config-custom │ │ │ │ ├── eslint.config.mjs │ │ │ │ ├── package.json │ │ │ │ └── index.mjs │ │ ├── .gitattributes │ │ ├── {{gitignore}} │ │ ├── .github │ │ │ ├── workflows │ │ │ │ ├── ci.yml │ │ │ │ └── release.yml │ │ │ └── actions │ │ │ │ └── bootstrap │ │ │ │ └── action.yml │ │ ├── {{cargo_toml}} │ │ └── package.json │ ├── .prettierignore │ ├── tsconfig.json │ ├── eslint.config.mjs │ ├── src │ │ ├── index.ts │ │ └── config.ts │ ├── LICENSE │ ├── package.json │ └── CHANGELOG.md ├── create-plugin │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── template-effect │ │ ├── rust │ │ │ └── {{plug_slug}} │ │ │ │ ├── vst │ │ │ │ ├── .prettierignore │ │ │ │ ├── about.toml │ │ │ │ ├── {{cargo_toml}} │ │ │ │ ├── src │ │ │ │ │ └── lib.rs │ │ │ │ └── about.hbs │ │ │ │ └── component │ │ │ │ ├── {{cargo_toml}} │ │ │ │ └── src │ │ │ │ └── lib.rs │ │ └── web │ │ │ └── {{plug_slug}} │ │ │ ├── {{gitignore}} │ │ │ ├── src │ │ │ ├── index.css │ │ │ ├── App.{{test_marker}}.tsx │ │ │ ├── App.tsx │ │ │ ├── mock_infos.ts │ │ │ ├── Layout.tsx │ │ │ └── main.tsx │ │ │ ├── tsconfig.json │ │ │ ├── bundle.json │ │ │ ├── index.html │ │ │ ├── eslint.config.mjs │ │ │ ├── package.json │ │ │ └── vite.config.ts │ ├── template-synth │ │ ├── rust │ │ │ └── {{plug_slug}} │ │ │ │ ├── vst │ │ │ │ ├── .prettierignore │ │ │ │ ├── about.toml │ │ │ │ ├── {{cargo_toml}} │ │ │ │ ├── src │ │ │ │ │ └── lib.rs │ │ │ │ └── about.hbs │ │ │ │ └── component │ │ │ │ └── {{cargo_toml}} │ │ └── web │ │ │ └── {{plug_slug}} │ │ │ ├── {{gitignore}} │ │ │ ├── src │ │ │ ├── index.css │ │ │ ├── App.{{test_marker}}.tsx │ │ │ ├── App.tsx │ │ │ ├── mock_infos.ts │ │ │ ├── Layout.tsx │ │ │ └── main.tsx │ │ │ ├── tsconfig.json │ │ │ ├── bundle.json │ │ │ ├── index.html │ │ │ ├── eslint.config.mjs │ │ │ ├── package.json │ │ │ └── vite.config.ts │ ├── tsconfig.json │ ├── src │ │ ├── uuid.ts │ │ ├── index.ts │ │ └── config.ts │ ├── scripts │ │ ├── cleanup.ts │ │ └── gather_rust_versions.ts │ ├── eslint.config.mjs │ ├── LICENSE │ ├── package.json │ └── CHANGELOG.md ├── tsconfig │ ├── package.json │ └── tsconfig.json ├── docs │ ├── pages │ │ ├── index.mdx │ │ ├── docs │ │ │ ├── tutorials │ │ │ │ └── _meta.ts │ │ │ ├── concepts │ │ │ │ ├── _meta.ts │ │ │ │ └── what.mdx │ │ │ ├── guides │ │ │ │ ├── _meta.ts │ │ │ │ └── quickstart.mdx │ │ │ ├── _meta.ts │ │ │ ├── reference │ │ │ │ ├── _meta.ts │ │ │ │ └── ts.mdx │ │ │ └── index.mdx │ │ ├── _app.tsx │ │ ├── _meta.ts │ │ └── app_notes │ │ │ ├── _meta.ts │ │ │ └── index.mdx │ ├── .gitignore │ ├── src │ │ ├── images │ │ │ ├── app-notes │ │ │ │ ├── 1 │ │ │ │ │ ├── varp.gif │ │ │ │ │ ├── changingc.gif │ │ │ │ │ └── fixedp.gif │ │ │ │ ├── 2 │ │ │ │ │ ├── smoothed.wav │ │ │ │ │ ├── smoothing.png │ │ │ │ │ ├── smoothing2.png │ │ │ │ │ └── unsmoothed.wav │ │ │ │ ├── 3 │ │ │ │ │ ├── polyblep-0.png │ │ │ │ │ ├── polyblep-1.png │ │ │ │ │ ├── polyblep-2.png │ │ │ │ │ ├── polyblit-0.png │ │ │ │ │ ├── polyblit-1.png │ │ │ │ │ ├── polyblamp-1.png │ │ │ │ │ ├── polyblamp-2.png │ │ │ │ │ ├── polyblamp-3.png │ │ │ │ │ ├── polyblamp-2-residual.png │ │ │ │ │ ├── polyblamp-3-residual.png │ │ │ │ │ ├── polyblep-1-residual.png │ │ │ │ │ └── polyblep-2-residual.png │ │ │ │ ├── 4 │ │ │ │ │ ├── circuit.png │ │ │ │ │ ├── simplified.asc │ │ │ │ │ ├── simplified.png │ │ │ │ │ ├── spice_vca.png │ │ │ │ │ ├── spice-circuit.png │ │ │ │ │ ├── spice_ie_vs_vin.png │ │ │ │ │ ├── spice_vbc_vs_vin.png │ │ │ │ │ ├── spice_ie_vs_vcontrol.png │ │ │ │ │ └── spice_vbc_vs_vcontrol.png │ │ │ │ └── 5 │ │ │ │ │ ├── u.png │ │ │ │ │ ├── v.png │ │ │ │ │ ├── x.png │ │ │ │ │ ├── y.png │ │ │ │ │ ├── box_kernel.png │ │ │ │ │ ├── clipper.png │ │ │ │ │ ├── lin_kernel.png │ │ │ │ │ ├── naive_y.png │ │ │ │ │ ├── u_ring.png │ │ │ │ │ ├── v_ring.png │ │ │ │ │ ├── y_calc.png │ │ │ │ │ ├── y_ring.png │ │ │ │ │ ├── spectrum_comparison.png │ │ │ │ │ └── clipper_antiderivative.png │ │ │ └── first-plug-in-imgs │ │ │ │ ├── 00-ableton.png │ │ │ │ ├── 01-stub-ui.png │ │ │ │ └── 02-animation.gif │ │ ├── app_notes │ │ │ └── 2 │ │ │ │ ├── Controls.ts │ │ │ │ ├── ControlsStore.tsx │ │ │ │ ├── NumBucketControl.tsx │ │ │ │ └── ClockRateControl.tsx │ │ ├── DocsRedirect.tsx │ │ ├── OptimizedImage.tsx │ │ ├── build.test.ts │ │ └── head │ │ │ └── index.tsx │ ├── next-env.d.ts │ ├── tsconfig.json │ ├── theme.config.tsx │ ├── next.config.js │ ├── eslint.config.mjs │ └── package.json ├── stamp │ ├── tsconfig.json │ ├── eslint.config.mjs │ ├── LICENSE │ └── package.json ├── internal-scripts │ ├── tsconfig.json │ ├── src │ │ ├── index.ts │ │ ├── postpack.ts │ │ ├── cli.ts │ │ ├── deployDocs.ts │ │ ├── prepack.ts │ │ ├── rustChange.ts │ │ ├── cleanWorkspace.ts │ │ └── release.ts │ ├── eslint.config.mjs │ └── package.json └── eslint-config-custom │ ├── eslint.config.mjs │ ├── package.json │ └── index.mjs ├── prettier.config.mjs ├── rust ├── core │ ├── docs_boilerplate.md │ ├── README.md │ ├── src │ │ ├── lib.rs │ │ ├── parameters.rs │ │ └── parameters │ │ │ └── store.rs │ ├── CHANGELOG.md │ └── Cargo.toml ├── poly │ ├── docs_boilerplate.md │ ├── CHANGELOG.md │ ├── Cargo.toml │ └── README.md ├── ui │ ├── docs_boilerplate.md │ ├── README.md │ ├── CHANGELOG.md │ ├── src │ │ ├── preferences_convert.rs │ │ └── lib.rs │ └── Cargo.toml ├── component │ ├── docs_boilerplate.md │ ├── CHANGELOG.md │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── effect.rs │ │ ├── audio │ │ └── compare.rs │ │ └── lib.rs ├── preferences │ ├── docs_boilerplate.md │ ├── CHANGELOG.md │ ├── README.md │ ├── src │ │ ├── fake_os.rs │ │ └── macos.rs │ └── Cargo.toml ├── vst-wrapper │ ├── docs_boilerplate.md │ ├── src │ │ ├── processor │ │ │ └── state.rs │ │ ├── host_info.rs │ │ ├── dummy_host.rs │ │ ├── parameters.rs │ │ └── io.rs │ ├── README.md │ ├── CHANGELOG.md │ └── Cargo.toml ├── macos-bundle │ ├── docs_boilerplate.md │ ├── README.md │ ├── CHANGELOG.md │ ├── Cargo.toml │ └── src │ │ └── lib.rs └── docs_boilerplate.md ├── .gitignore ├── happydom.ts ├── bunfig.toml ├── .gitattributes ├── .changeset └── config.json ├── .github ├── actions │ └── bootstrap │ │ └── action.yml └── workflows │ ├── ci.yml │ ├── docs.yml │ ├── prepare-release.yml │ └── release.yml ├── README.md ├── COPYING ├── Cargo.toml ├── knope.toml └── package.json /rustfmt.toml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/plugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist -------------------------------------------------------------------------------- /web/scripts/src/repoRoot.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/create/template/rustfmt.toml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export default {}; 2 | -------------------------------------------------------------------------------- /web/create/.prettierignore: -------------------------------------------------------------------------------- 1 | template/.github -------------------------------------------------------------------------------- /rust/core/docs_boilerplate.md: -------------------------------------------------------------------------------- 1 | ../docs_boilerplate.md -------------------------------------------------------------------------------- /rust/poly/docs_boilerplate.md: -------------------------------------------------------------------------------- 1 | ../docs_boilerplate.md -------------------------------------------------------------------------------- /rust/ui/docs_boilerplate.md: -------------------------------------------------------------------------------- 1 | ../docs_boilerplate.md -------------------------------------------------------------------------------- /web/create-plugin/.gitignore: -------------------------------------------------------------------------------- 1 | rust_versions.toml 2 | -------------------------------------------------------------------------------- /rust/component/docs_boilerplate.md: -------------------------------------------------------------------------------- 1 | ../docs_boilerplate.md -------------------------------------------------------------------------------- /rust/preferences/docs_boilerplate.md: -------------------------------------------------------------------------------- 1 | ../docs_boilerplate.md -------------------------------------------------------------------------------- /rust/vst-wrapper/docs_boilerplate.md: -------------------------------------------------------------------------------- 1 | ../docs_boilerplate.md -------------------------------------------------------------------------------- /web/create-plugin/.npmignore: -------------------------------------------------------------------------------- 1 | /scripts 2 | /tsconfig.json -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .DS_Store 3 | node_modules 4 | /.env 5 | -------------------------------------------------------------------------------- /rust/macos-bundle/docs_boilerplate.md: -------------------------------------------------------------------------------- 1 | ../docs_boilerplate.md -------------------------------------------------------------------------------- /web/create/template/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export default {}; 2 | -------------------------------------------------------------------------------- /web/create-plugin/.prettierignore: -------------------------------------------------------------------------------- 1 | template-*/rust/**/vst/about.hbs -------------------------------------------------------------------------------- /web/create-plugin/template-effect/rust/{{plug_slug}}/vst/.prettierignore: -------------------------------------------------------------------------------- 1 | about.hbs -------------------------------------------------------------------------------- /web/create-plugin/template-synth/rust/{{plug_slug}}/vst/.prettierignore: -------------------------------------------------------------------------------- 1 | about.hbs -------------------------------------------------------------------------------- /web/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tsconfig", 3 | "private": true 4 | } 5 | -------------------------------------------------------------------------------- /rust/macos-bundle/README.md: -------------------------------------------------------------------------------- 1 | This crate contains operations for working with macOS bundles. 2 | -------------------------------------------------------------------------------- /rust/core/README.md: -------------------------------------------------------------------------------- 1 | This crate contains code shared between wrappers for the conformal framework. 2 | -------------------------------------------------------------------------------- /web/docs/pages/index.mdx: -------------------------------------------------------------------------------- 1 | import DocsRedirect from "../src/DocsRedirect"; 2 | 3 | ; 4 | -------------------------------------------------------------------------------- /web/stamp/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/tsconfig.json", 3 | "include": ["src"] 4 | } 5 | -------------------------------------------------------------------------------- /web/create/template/web/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tsconfig", 3 | "private": true 4 | } 5 | -------------------------------------------------------------------------------- /web/create/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/tsconfig.json", 3 | "include": ["src"] 4 | } 5 | -------------------------------------------------------------------------------- /web/plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/tsconfig.json", 3 | "include": ["src"] 4 | } 5 | -------------------------------------------------------------------------------- /web/scripts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/tsconfig.json", 3 | "include": ["src"] 4 | } 5 | -------------------------------------------------------------------------------- /web/internal-scripts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/tsconfig.json", 3 | "include": ["src"] 4 | } 5 | -------------------------------------------------------------------------------- /happydom.ts: -------------------------------------------------------------------------------- 1 | import { GlobalRegistrator } from "@happy-dom/global-registrator"; 2 | 3 | GlobalRegistrator.register(); 4 | -------------------------------------------------------------------------------- /rust/ui/README.md: -------------------------------------------------------------------------------- 1 | This crate contains code to connect a web user interface to a [`conformal_component::Component`]. 2 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/web/{{plug_slug}}/{{gitignore}}: -------------------------------------------------------------------------------- 1 | /dist/ 2 | tsconfig.tsbuildinfo 3 | /node_modules/ 4 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/web/{{plug_slug}}/{{gitignore}}: -------------------------------------------------------------------------------- 1 | /dist/ 2 | tsconfig.tsbuildinfo 3 | /node_modules/ 4 | -------------------------------------------------------------------------------- /web/docs/pages/docs/tutorials/_meta.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | "first-plug-in": "Building your First Plug-in", 3 | }; 4 | -------------------------------------------------------------------------------- /web/create/template/.gitattributes: -------------------------------------------------------------------------------- 1 | *.wav filter=lfs diff=lfs merge=lfs -text 2 | *.woff2 filter=lfs diff=lfs merge=lfs -text 3 | -------------------------------------------------------------------------------- /web/docs/pages/docs/concepts/_meta.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | what: "What is Conformal?", 3 | why: "Why Conformal?", 4 | }; 5 | -------------------------------------------------------------------------------- /web/create/template/{{gitignore}}: -------------------------------------------------------------------------------- 1 | /target 2 | .DS_Store 3 | /node_modules/ 4 | /.env 5 | /web/**/installer_resources/license.txt 6 | -------------------------------------------------------------------------------- /rust/component/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.3.6 (2025-09-23) 2 | 3 | ### Features 4 | 5 | - Minimum support rust version (MSRV) is now 1.90 6 | -------------------------------------------------------------------------------- /rust/macos-bundle/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.3.6 (2025-09-23) 2 | 3 | ### Features 4 | 5 | - Minimum support rust version (MSRV) is now 1.90 6 | -------------------------------------------------------------------------------- /rust/preferences/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.3.6 (2025-09-23) 2 | 3 | ### Features 4 | 5 | - Minimum support rust version (MSRV) is now 1.90 6 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/web/{{plug_slug}}/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | user-select: none; 3 | -webkit-user-select: none; 4 | } 5 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/web/{{plug_slug}}/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | user-select: none; 3 | -webkit-user-select: none; 4 | } 5 | -------------------------------------------------------------------------------- /web/scripts/src/util.ts: -------------------------------------------------------------------------------- 1 | export const failUnless = (condition: boolean) => { 2 | if (!condition) { 3 | process.exit(1); 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /bunfig.toml: -------------------------------------------------------------------------------- 1 | [install] 2 | registry = { url = "https://registry.npmjs.org", token = "$NPM_TOKEN" } 3 | 4 | [test] 5 | preload = "./happydom.ts" 6 | -------------------------------------------------------------------------------- /web/docs/pages/docs/guides/_meta.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | quickstart: "Quick Start", 3 | "macos-installers": "Build macOS Installers", 4 | }; 5 | -------------------------------------------------------------------------------- /web/create-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/tsconfig.json", 3 | "include": ["src", "scripts", "../scripts/src/workspaceRoot.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /web/scripts/src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bun 2 | 3 | import { command } from "./cli"; 4 | 5 | const program = command(); 6 | await program.parseAsync(); 7 | -------------------------------------------------------------------------------- /web/internal-scripts/src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bun 2 | 3 | import { command } from "./cli"; 4 | 5 | const program = command(); 6 | await program.parseAsync(); 7 | -------------------------------------------------------------------------------- /rust/core/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(missing_docs)] 2 | #![doc = include_str!("../docs_boilerplate.md")] 3 | #![doc = include_str!("../README.md")] 4 | 5 | pub mod parameters; 6 | -------------------------------------------------------------------------------- /web/create-plugin/src/uuid.ts: -------------------------------------------------------------------------------- 1 | const uuidHex = () => 2 | crypto.randomUUID().replace(/-/g, "").replace(/../g, "0x$&, ").slice(0, -1); 3 | 4 | export default uuidHex; 5 | -------------------------------------------------------------------------------- /web/docs/.gitignore: -------------------------------------------------------------------------------- 1 | /.next/ 2 | /out/ 3 | /pages/docs/reference/scripts.md 4 | /public/nextImageExportOptimizer/ 5 | /public/images/next-image-export-optimizer-hashes.json 6 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/1/varp.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:14bb52b05f61f4ec18cb64eee841571c204c2a3a3a314d9a4fe514383ed43638 3 | size 366409 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/u.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:80a2396bcd65cba9f923c71383173cb26593db49410b1e0c4cfc97c759e0d3be 3 | size 27015 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/v.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:447d70587e8d540f7c7d1e811a47bc70f2e9a9c76872938f9580b8a4fd5f1091 3 | size 29061 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/x.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:448f061611f424eeef396f152f8395c391f7f92189ad0da7021a902c5e9ed202 3 | size 14146 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/y.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d15709305e4761d3e302dc871e8310264443b4287729025e0e95bdebf5ce8077 3 | size 36546 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/1/changingc.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f457fe64a98d4683524ced06d8c27f1019eeae6ec95382c3e624a7d029910f2f 3 | size 635385 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/1/fixedp.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b7365d09f40bc954944883f12592a42a9d6998691bbf3d490cfbba98b4b2440c 3 | size 674985 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/2/smoothed.wav: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e25f564cc209e094932956ee642767cca274d7125135678f328d6966be5ab9e5 3 | size 192044 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/2/smoothing.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4f21633c42829bc69598498a387a226bbe978fcaa21a91765924afaf29d0fdf5 3 | size 29040 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/2/smoothing2.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3dfb07c6d9e74ec7bcba263896f99caf053aebf1fa1f7bfb5f3c1c8c2f736349 3 | size 35080 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/3/polyblep-0.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5069140483d4c91e435289c91c3a767a8df9e30bfee8af801853f2f34920f531 3 | size 6868 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/3/polyblep-1.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ecc69422e5ae719c74cd56cf70df77e79d1818e247b34e131fd5b62aeda43886 3 | size 10058 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/3/polyblep-2.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fc8d23da50513a29a3d73184b9c150858e5553fd0fbaf1e3ca719ffd420485a8 3 | size 11117 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/3/polyblit-0.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b12224b823cd61a479b05b49182d2e522c472a24663729f24606d4440a882f14 3 | size 7224 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/3/polyblit-1.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6c9bd848b9d26198cdb35817a18bbc6e06a613570a309022b7d56f7a25a106ad 3 | size 12998 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/4/circuit.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:809a3abf11042393ccb4e89254051452b9aa89caeb11a97f4aee2f47af6b2186 3 | size 105756 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/4/simplified.asc: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1254f36b14c8b5a42a3b6548d3b8efa4e375e07e592846058feedc6fe8b3d942 3 | size 1702 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/4/simplified.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4ee8bfbe91e48891efd64ee6e4fea696a2a19fb78c37ca1b116f80a9b3a2d793 3 | size 69640 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/4/spice_vca.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:903e9f5cca78075e4d6db65b1d8daa0a6fb8094be9583e500b07041cb9d0063e 3 | size 614871 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/box_kernel.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:70babdebd662c2e95f10922aa6af8422083b048d02b645c615136ca9ec3b2b0a 3 | size 8307 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/clipper.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0dc9122680ea1751dc01885f9534821568da3ebccece80bae8b126645f3b7441 3 | size 9037 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/lin_kernel.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1cf30db4f139bd3264bc8ac8214ffc1fc557c3a2a30be9d2e69da4f4104ebadc 3 | size 14746 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/naive_y.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:535174002975d6bcf0eb6f5602673a4041eb35b7ba5bd4ffeb15da01e857a5b5 3 | size 18378 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/u_ring.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ec3d5f79e80517001da193ab96fe6820fdc848a8a59bb01c9fcdd90284233845 3 | size 42503 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/v_ring.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6624f915a8fa630502e3273b741b5e618c31dad8a742fd5bdd82b7ea3bd5b536 3 | size 43120 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/y_calc.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:bf02b3653a0bcbacb5efc75d6dc732bfa3f1444c6260fcc6ccb873cc06276ec5 3 | size 40846 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/y_ring.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0dc7f9fef11ab75278b415d9fc39f5759c6808131c75f80076f2fc408c11bc44 3 | size 35540 4 | -------------------------------------------------------------------------------- /web/eslint-config-custom/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import config from "eslint-config-custom"; 3 | 4 | export default defineConfig([config]); 5 | -------------------------------------------------------------------------------- /web/create-plugin/scripts/cleanup.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | import { unlink } from "node:fs/promises"; 3 | 4 | await unlink(path.join(__dirname, "..", "rust_versions.toml")); 5 | -------------------------------------------------------------------------------- /web/docs/pages/docs/_meta.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | index: "Welcome!", 3 | tutorials: "Tutorials", 4 | concepts: "Concepts", 5 | guides: "Guides", 6 | reference: "Reference", 7 | }; 8 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/2/unsmoothed.wav: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:15d39aec52e6dfc82dc77a71db214a795132587a353aafab35e15fa76ae3a631 3 | size 192044 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/3/polyblamp-1.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d55513a8c477a0fa6ae4dbe02e34472e2eb1340d9262d1e0f654bdb54d66c739 3 | size 15749 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/3/polyblamp-2.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6eb4591d5aab99b3966f58ef61a90e97fbca5cbdeb999368cfde6ca4b4f06ced 3 | size 17837 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/3/polyblamp-3.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:faa1e27031e40b803d542c27c0d14c89f7fad1b8ea7be83745b1555b69b62874 3 | size 17777 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/4/spice-circuit.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d6913dfe6b78031132e4fb68a91c503b84a7f8867dc1518702a5a4277744c6c3 3 | size 133520 4 | -------------------------------------------------------------------------------- /web/plugin/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @conformal/plugin 2 | 3 | ## 0.4.0 4 | 5 | ### Minor Changes 6 | 7 | - f82ceaa: Support saving ui-specific state 8 | - f82ceaa: Support new ui server protocol 9 | -------------------------------------------------------------------------------- /web/docs/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import { AppProps } from "next/app"; 2 | 3 | const App = ({ Component, pageProps }: AppProps) => ( 4 | 5 | ); 6 | 7 | export default App; 8 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/3/polyblamp-2-residual.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8466fb6139bb8fb6d976e37b15ed3fc242cd5f8463f6ea879b9a469a1c0b80cd 3 | size 14192 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/3/polyblamp-3-residual.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a7a3a8f12377cb809f777f348d0a74c6342351287968fc36b6e0fdce9702247e 3 | size 12814 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/3/polyblep-1-residual.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3b05ee693765a9a98699c3a8cea4cba4b795bfcf31d4c38dd3fb565331e04113 3 | size 10424 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/3/polyblep-2-residual.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e39ab104363581961bf47166ef5dc50b25a4cf86f1acdfd6f4bc5b304bfda746 3 | size 11528 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/4/spice_ie_vs_vin.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:82089203cfd3f05bb00c4dc86f453df882f6c89e32f115a38adc665c902dd0d7 3 | size 399399 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/4/spice_vbc_vs_vin.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f86cac99e38377a2cafb6db1dc0c0de97615f4d209a2367f8b49bc958ea04029 3 | size 403842 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/spectrum_comparison.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:869be47e848c2f8ef1a2c464759b115798c76d9e8928e901f906dede7ac57e96 3 | size 36258 4 | -------------------------------------------------------------------------------- /web/docs/src/images/first-plug-in-imgs/00-ableton.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9830af578f8d1ae3fef35f61e47dfbcfc478b84e3af424657f63dfaf5d2f5a52 3 | size 12128 4 | -------------------------------------------------------------------------------- /web/docs/src/images/first-plug-in-imgs/01-stub-ui.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fd088bdde7990afef786885109c536371d7e88434a5871ddf8d063a7b3418c03 3 | size 103414 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/4/spice_ie_vs_vcontrol.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9482eea8e5fc5e0f5170d41949fbf6771fd6e75dd3350a830b631b320a0b48ce 3 | size 404085 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/4/spice_vbc_vs_vcontrol.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b78fc3be7e695ff758db98d8c8fa572900845712059b101e326f56be13e11370 3 | size 403411 4 | -------------------------------------------------------------------------------- /web/docs/src/images/app-notes/5/clipper_antiderivative.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:883eb85b46ae46f59c553c3def8b1764b3e41d56302219ff9b319ff6d8dd5af0 3 | size 17766 4 | -------------------------------------------------------------------------------- /web/docs/src/images/first-plug-in-imgs/02-animation.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2e1dd6fa82ff40ef95c74a53997fa5d92aefdf7c4e15c7474a02a555428fa02a 3 | size 2617711 4 | -------------------------------------------------------------------------------- /web/plugin/src/transport.ts: -------------------------------------------------------------------------------- 1 | type Transport = { 2 | request: (m: Request) => void; 3 | setOnResponse: (recv: (m: Response) => void) => void; 4 | }; 5 | export default Transport; 6 | -------------------------------------------------------------------------------- /web/create/template/web/eslint-config-custom/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import config from "eslint-config-custom"; 3 | 4 | export default defineConfig([config]); 5 | -------------------------------------------------------------------------------- /rust/docs_boilerplate.md: -------------------------------------------------------------------------------- 1 | This crate is part of the Conformal Framework! For high-level documentation and tutorials, please see [the main documentation website](https://russellmcc.github.io/conformal)! 2 | 3 | --- 4 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/web/{{plug_slug}}/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/tsconfig.json", 3 | "include": ["src", "vite.config.ts"], 4 | "compilerOptions": { 5 | "types": ["vite/client", "bun"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /rust/core/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.3.7 (2025-09-23) 2 | 3 | ### Features 4 | 5 | - Minimum support rust version (MSRV) is now 1.90 6 | 7 | ## 0.3.6 (2025-02-23) 8 | 9 | ### Features 10 | 11 | - Add support for persistant UI state 12 | -------------------------------------------------------------------------------- /rust/preferences/README.md: -------------------------------------------------------------------------------- 1 | This crate contains operations for working with persistant preferences systems. 2 | 3 | Currently we support the macOS `defaults` system, but we aspire to add support for more preference platforms over time. 4 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/web/{{plug_slug}}/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/tsconfig.json", 3 | "include": ["src", "vite.config.ts"], 4 | "compilerOptions": { 5 | "types": ["vite/client", "bun"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /web/docs/src/app_notes/2/Controls.ts: -------------------------------------------------------------------------------- 1 | import { atom } from "jotai"; 2 | 3 | // Define atoms for our controls 4 | export const numBucketsAtom = atom(4); // Default to 4 buckets 5 | export const clockRateAtom = atom(1.0); // Default to 1 Hz 6 | -------------------------------------------------------------------------------- /web/docs/pages/docs/reference/_meta.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | rust: { 3 | title: "Rust API", 4 | href: "/rust-doc/conformal_component", 5 | }, 6 | ts: "TypeScript APIs (coming soon!)", 7 | scripts: "@conformal/scripts", 8 | }; 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.wav filter=lfs diff=lfs merge=lfs -text 2 | *.woff2 filter=lfs diff=lfs merge=lfs -text 3 | *.png filter=lfs diff=lfs merge=lfs -text 4 | *.gif filter=lfs diff=lfs merge=lfs -text 5 | *.asc filter=lfs diff=lfs merge=lfs -text 6 | 7 | -------------------------------------------------------------------------------- /rust/vst-wrapper/src/processor/state.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | use conformal_core::parameters::serialization; 4 | 5 | #[derive(Serialize, Deserialize)] 6 | pub struct State { 7 | pub params: serialization::Snapshot, 8 | } 9 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/web/{{plug_slug}}/bundle.json: -------------------------------------------------------------------------------- 1 | { 2 | "rustPackage": "{{plug_slug}}_vst", 3 | "name": "{{plug_name}}", 4 | "id": "com.{{task_marker}}.{{plug_slug}}", 5 | "sig": "{{task_marker}}", 6 | "version": "0.0.0" 7 | } 8 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/web/{{plug_slug}}/bundle.json: -------------------------------------------------------------------------------- 1 | { 2 | "rustPackage": "{{plug_slug}}_vst", 3 | "name": "{{plug_name}}", 4 | "id": "com.{{task_marker}}.{{plug_slug}}", 5 | "sig": "{{task_marker}}", 6 | "version": "0.0.0" 7 | } 8 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/web/{{plug_slug}}/src/App.{{test_marker}}.tsx: -------------------------------------------------------------------------------- 1 | import { describe, expect, test } from "bun:test"; 2 | 3 | describe("App", () => { 4 | test("Write tests here", () => { 5 | expect(true).toBe(true); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/web/{{plug_slug}}/src/App.{{test_marker}}.tsx: -------------------------------------------------------------------------------- 1 | import { describe, expect, test } from "bun:test"; 2 | 3 | describe("App", () => { 4 | test("Write tests here", () => { 5 | expect(true).toBe(true); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /web/docs/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/pages/api-reference/config/typescript for more information. 6 | -------------------------------------------------------------------------------- /rust/poly/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.3.7 (2025-09-23) 2 | 3 | ### Features 4 | 5 | - Minimum support rust version (MSRV) is now 1.90 6 | 7 | ## 0.3.6 (2025-02-17) 8 | 9 | ### Fixes 10 | 11 | - please ignore this release, it's a test of the new publishing system. 12 | -------------------------------------------------------------------------------- /web/scripts/src/configArg.ts: -------------------------------------------------------------------------------- 1 | export type Config = "release" | "debug"; 2 | 3 | export const configArgs = (config: Config): string[] => 4 | config === "release" ? ["--release"] : []; 5 | 6 | export const parseConfigArg = (isRelease: boolean): Config => 7 | isRelease ? "release" : "debug"; 8 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/rust/{{plug_slug}}/vst/about.toml: -------------------------------------------------------------------------------- 1 | accepted = [ 2 | "MIT", 3 | "ISC", 4 | "MPL-2.0", 5 | "Apache-2.0 WITH LLVM-exception", 6 | "Apache-2.0", 7 | "Unicode-DFS-2016", 8 | "Unicode-3.0", 9 | ] 10 | ignore-dev-dependencies = true 11 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/web/{{plug_slug}}/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/web/{{plug_slug}}/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { DevModeTools } from "@conformal/plugin"; 2 | import Layout from "./Layout.tsx"; 3 | 4 | const App = () => ( 5 |
6 | 7 | 8 |
9 | ); 10 | 11 | export default App; 12 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/rust/{{plug_slug}}/vst/about.toml: -------------------------------------------------------------------------------- 1 | accepted = [ 2 | "MIT", 3 | "ISC", 4 | "MPL-2.0", 5 | "Apache-2.0 WITH LLVM-exception", 6 | "Apache-2.0", 7 | "Unicode-DFS-2016", 8 | "Unicode-3.0", 9 | ] 10 | ignore-dev-dependencies = true 11 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/web/{{plug_slug}}/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/web/{{plug_slug}}/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { DevModeTools } from "@conformal/plugin"; 2 | import Layout from "./Layout.tsx"; 3 | 4 | const App = () => ( 5 |
6 | 7 | 8 |
9 | ); 10 | 11 | export default App; 12 | -------------------------------------------------------------------------------- /web/plugin/README.md: -------------------------------------------------------------------------------- 1 | This package is part of the Conformal Framework! For high-level documentation and tutorials, please see [the main documentation website](https://russellmcc.github.io/conformal)! 2 | 3 | This package contains React hooks to connect your UIs to the parameters of the plug-in. 4 | -------------------------------------------------------------------------------- /web/docs/pages/docs/reference/ts.mdx: -------------------------------------------------------------------------------- 1 | import { Callout } from "nextra/components"; 2 | 3 | 4 | Typescript API documentation is not available yet. We're tracking the work 5 | [here](https://github.com/russellmcc/conformal/issues/16), and we'd love your 6 | help! 7 | 8 | -------------------------------------------------------------------------------- /web/docs/src/DocsRedirect.tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | import { useEffect } from "react"; 3 | 4 | const Page = () => { 5 | const router = useRouter(); 6 | useEffect(() => { 7 | void router.push("/docs"); 8 | }); 9 | return <>; 10 | }; 11 | 12 | export default Page; 13 | -------------------------------------------------------------------------------- /rust/vst-wrapper/README.md: -------------------------------------------------------------------------------- 1 | This crate contains code to wrap a [`conformal_component::Component`] in a [VST3](https://steinbergmedia.github.io/vst3_dev_portal/pages/index.html)-compatible plug-in. 2 | 3 | The main entry point is the [`wrap_factory`] macro, which should be invoked exactly once for each plug-in binary. 4 | -------------------------------------------------------------------------------- /web/docs/src/OptimizedImage.tsx: -------------------------------------------------------------------------------- 1 | import ExportedImage, { ExportedImageProps } from "next-image-export-optimizer"; 2 | 3 | export type ImageProps = Omit; 4 | 5 | const Image = (props: ImageProps) => ( 6 | 7 | ); 8 | 9 | export default Image; 10 | -------------------------------------------------------------------------------- /web/docs/src/app_notes/2/ControlsStore.tsx: -------------------------------------------------------------------------------- 1 | import { Provider } from "jotai"; 2 | 3 | type ControlsStoreProps = { 4 | children: React.ReactNode; 5 | }; 6 | 7 | export const ControlsStore = ({ children }: ControlsStoreProps) => ( 8 | {children} 9 | ); 10 | 11 | export default ControlsStore; 12 | -------------------------------------------------------------------------------- /rust/ui/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.3.7 (2025-09-23) 2 | 3 | ### Features 4 | 5 | - Minimum support rust version (MSRV) is now 1.90 6 | 7 | ## 0.3.6 (2025-02-23) 8 | 9 | ### Features 10 | 11 | - Add support for persistant UI state 12 | - Workaround https://github.com/3Hren/msgpack-rust/issues/363 by changing UI server protocol 13 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/rust/{{plug_slug}}/component/{{cargo_toml}}: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "{{plug_slug}}_component" 3 | edition.workspace = true 4 | rust-version.workspace = true 5 | publish = false 6 | 7 | [lints] 8 | workspace = true 9 | 10 | [dependencies] 11 | conformal_component = "{{{conformal_component_version}}}" 12 | -------------------------------------------------------------------------------- /web/docs/src/build.test.ts: -------------------------------------------------------------------------------- 1 | import { $ } from "bun"; 2 | import { describe, test } from "bun:test"; 3 | 4 | const MINUTE = 60_000; 5 | 6 | describe("conformal documentation", () => { 7 | test( 8 | "can build", 9 | async () => { 10 | await $`bun run web-build docs`; 11 | }, 12 | 5 * MINUTE, 13 | ); 14 | }); 15 | -------------------------------------------------------------------------------- /web/scripts/README.md: -------------------------------------------------------------------------------- 1 | This package is part of the Conformal Framework! For high-level documentation and tutorials, please see [the main documentation website](https://russellmcc.github.io/conformal)! 2 | 3 | This package contains build scripts for various common tasks for Conformal projects, including building audio plug-ins and installers. 4 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.1.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "restricted", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /.github/actions/bootstrap/action.yml: -------------------------------------------------------------------------------- 1 | name: "Bootstrap" 2 | description: "Get ready to run ci or release" 3 | runs: 4 | using: "composite" 5 | steps: 6 | - run: brew install oven-sh/bun/bun 7 | shell: bash 8 | - run: bun install --frozen-lockfile 9 | shell: bash 10 | - run: bun run bootstrap 11 | shell: bash 12 | -------------------------------------------------------------------------------- /rust/core/src/parameters.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use conformal_component::parameters::Value; 4 | 5 | pub mod serialization; 6 | 7 | pub mod store; 8 | 9 | /// This represents the current state of all parameters. 10 | #[derive(Debug, Clone, PartialEq)] 11 | pub struct Snapshot { 12 | pub values: HashMap, 13 | } 14 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | run-name: CI 3 | 4 | on: 5 | push: 6 | branches-ignore: 7 | - "next-release" 8 | 9 | jobs: 10 | ci: 11 | runs-on: macos-14 12 | steps: 13 | - uses: actions/checkout@v4 14 | with: 15 | lfs: "true" 16 | - uses: ./.github/actions/bootstrap 17 | - run: bun run ci 18 | -------------------------------------------------------------------------------- /web/create/template/.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | run-name: CI 3 | 4 | on: 5 | push: 6 | branches: 7 | - "*" 8 | 9 | jobs: 10 | ci: 11 | runs-on: macos-14 12 | steps: 13 | - uses: actions/checkout@v4 14 | with: 15 | lfs: "true" 16 | - uses: ./.github/actions/bootstrap 17 | - run: bun run ci 18 | -------------------------------------------------------------------------------- /web/docs/pages/_meta.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | index: { 3 | title: "Home", 4 | type: "page", 5 | display: "hidden", 6 | theme: { 7 | layout: "raw", 8 | }, 9 | }, 10 | docs: { 11 | title: "Documentation", 12 | type: "page", 13 | }, 14 | app_notes: { 15 | title: "App Notes", 16 | type: "page", 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /web/docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/tsconfig.json", 3 | "include": ["theme.config.tsx", "pages", "src", "next-env.d.ts"], 4 | "compilerOptions": { 5 | "allowJs": false, 6 | "incremental": false, 7 | "esModuleInterop": true, 8 | "resolveJsonModule": true, 9 | "jsx": "preserve" 10 | }, 11 | "exclude": ["node_modules"] 12 | } 13 | -------------------------------------------------------------------------------- /web/create/template/.github/actions/bootstrap/action.yml: -------------------------------------------------------------------------------- 1 | name: "Bootstrap" 2 | description: "Get ready to run ci or release" 3 | runs: 4 | using: "composite" 5 | steps: 6 | - run: brew install oven-sh/bun/bun 7 | shell: bash 8 | - run: bun install --frozen-lockfile 9 | shell: bash 10 | - run: bun run bootstrap --rust-version 1.90.0 11 | shell: bash 12 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/rust/{{plug_slug}}/component/{{cargo_toml}}: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "{{plug_slug}}_component" 3 | edition.workspace = true 4 | rust-version.workspace = true 5 | publish = false 6 | 7 | [lints] 8 | workspace = true 9 | 10 | [dependencies] 11 | itertools = "0.13.0" 12 | conformal_component = "{{{conformal_component_version}}}" 13 | conformal_poly = "{{{conformal_poly_version}}}" 14 | -------------------------------------------------------------------------------- /web/stamp/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import config from "eslint-config-custom"; 3 | 4 | export default defineConfig([ 5 | config, 6 | { 7 | files: ["**/*.ts", "**/*.tsx"], 8 | languageOptions: { 9 | parserOptions: { 10 | project: ["./tsconfig.json"], 11 | tsconfigRootDir: import.meta.dirname, 12 | }, 13 | }, 14 | }, 15 | ]); 16 | -------------------------------------------------------------------------------- /web/plugin/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import config from "eslint-config-custom"; 3 | 4 | export default defineConfig([ 5 | config, 6 | { 7 | files: ["**/*.ts", "**/*.tsx"], 8 | languageOptions: { 9 | parserOptions: { 10 | project: ["./tsconfig.json"], 11 | tsconfigRootDir: import.meta.dirname, 12 | }, 13 | }, 14 | }, 15 | ]); 16 | -------------------------------------------------------------------------------- /web/scripts/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import config from "eslint-config-custom"; 3 | 4 | export default defineConfig([ 5 | config, 6 | { 7 | files: ["**/*.ts", "**/*.tsx"], 8 | languageOptions: { 9 | parserOptions: { 10 | project: ["./tsconfig.json"], 11 | tsconfigRootDir: import.meta.dirname, 12 | }, 13 | }, 14 | }, 15 | ]); 16 | -------------------------------------------------------------------------------- /web/internal-scripts/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import config from "eslint-config-custom"; 3 | 4 | export default defineConfig([ 5 | config, 6 | { 7 | files: ["**/*.ts", "**/*.tsx"], 8 | languageOptions: { 9 | parserOptions: { 10 | project: ["./tsconfig.json"], 11 | tsconfigRootDir: import.meta.dirname, 12 | }, 13 | }, 14 | }, 15 | ]); 16 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/web/{{plug_slug}}/src/mock_infos.ts: -------------------------------------------------------------------------------- 1 | import { Info } from "@conformal/plugin"; 2 | 3 | const infos = new Map( 4 | Object.entries({ 5 | gain: { 6 | title: "Gain", 7 | type_specific: { 8 | t: "numeric", 9 | default: 100, 10 | valid_range: [0, 100], 11 | units: "%", 12 | }, 13 | }, 14 | }), 15 | ); 16 | 17 | export default infos; 18 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/rust/{{plug_slug}}/vst/{{cargo_toml}}: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "{{plug_slug}}_vst" 3 | edition.workspace = true 4 | rust-version.workspace = true 5 | publish = false 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | 10 | [lints] 11 | workspace = true 12 | 13 | [dependencies] 14 | conformal_vst_wrapper = "{{{conformal_vst_wrapper_version}}}" 15 | vst3 = "0.2.0" 16 | {{plug_slug}}_component = { path = "../component" } -------------------------------------------------------------------------------- /web/create-plugin/template-synth/rust/{{plug_slug}}/vst/{{cargo_toml}}: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "{{plug_slug}}_vst" 3 | edition.workspace = true 4 | rust-version.workspace = true 5 | publish = false 6 | 7 | [lints] 8 | workspace = true 9 | 10 | [lib] 11 | crate-type = ["cdylib"] 12 | 13 | [dependencies] 14 | conformal_vst_wrapper = "{{{conformal_vst_wrapper_version}}}" 15 | vst3 = "0.2.0" 16 | {{plug_slug}}_component = { path = "../component" } -------------------------------------------------------------------------------- /web/create-plugin/template-effect/web/{{plug_slug}}/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import config from "eslint-config-custom"; 3 | 4 | export default defineConfig([ 5 | config, 6 | { 7 | files: ["**/*.ts", "**/*.tsx"], 8 | languageOptions: { 9 | parserOptions: { 10 | project: ["./tsconfig.json"], 11 | tsconfigRootDir: import.meta.dirname, 12 | }, 13 | }, 14 | }, 15 | ]); 16 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/web/{{plug_slug}}/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import config from "eslint-config-custom"; 3 | 4 | export default defineConfig([ 5 | config, 6 | { 7 | files: ["**/*.ts", "**/*.tsx"], 8 | languageOptions: { 9 | parserOptions: { 10 | project: ["./tsconfig.json"], 11 | tsconfigRootDir: import.meta.dirname, 12 | }, 13 | }, 14 | }, 15 | ]); 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Build audio plug-ins with Rust and TypeScript! 2 | 3 | This repo contains a nascent framework for building audio plug-ins in Rust and TypeScript! The working title of this framework is "Conformal". 4 | 5 | See our [documentation website](https://russellmcc.github.io/conformal) for information about how to use thie framework. 6 | 7 | Right now this project is just in the beginning stages, so there's plenty of limitations. Feedback and contributions are welcome! 8 | -------------------------------------------------------------------------------- /web/create/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import config from "eslint-config-custom"; 3 | 4 | export default defineConfig([ 5 | config, 6 | { 7 | ignores: ["template/**"], 8 | }, 9 | { 10 | files: ["**/*.ts", "**/*.tsx"], 11 | languageOptions: { 12 | parserOptions: { 13 | project: ["./tsconfig.json"], 14 | tsconfigRootDir: import.meta.dirname, 15 | }, 16 | }, 17 | }, 18 | ]); 19 | -------------------------------------------------------------------------------- /web/create-plugin/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import config from "eslint-config-custom"; 3 | 4 | export default defineConfig([ 5 | config, 6 | { 7 | ignores: ["template-effect/**", "template-synth/**"], 8 | }, 9 | { 10 | files: ["**/*.ts", "**/*.tsx"], 11 | languageOptions: { 12 | parserOptions: { 13 | project: ["./tsconfig.json"], 14 | tsconfigRootDir: import.meta.dirname, 15 | }, 16 | }, 17 | }, 18 | ]); 19 | -------------------------------------------------------------------------------- /web/docs/pages/app_notes/_meta.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | index: "Intro", 3 | "1-exponential-scale": "1: Parameterized Exponential Scaling Functions", 4 | "2-bbd-lfo": "2: Modeling LFOs for BBD Chorus", 5 | "3-derivation-blep-blamp": 6 | "3: Quick Derivation of BLIT, BLEP, BLAMP polynomials", 7 | "4-roland-single-transistor-vca": 8 | "4: Analysis of Roland single-transistor VCA", 9 | "5-adaa-for-ring-mod": 10 | "5: Continuous-time Convolution Anti-aliasing for Ring Modulation", 11 | }; 12 | -------------------------------------------------------------------------------- /rust/macos-bundle/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "conformal_macos_bundle" 3 | version = "0.3.6" 4 | edition.workspace = true 5 | rust-version.workspace = true 6 | license = "ISC" 7 | description = "Utilities for macOS bundle directories used by the conformal audio plug-in framework." 8 | repository = "https://github.com/russellmcc/conformal" 9 | homepage = "https://russellmcc.github.io/conformal" 10 | 11 | [lints] 12 | workspace = true 13 | 14 | [dependencies] 15 | process_path = "0.1.4" 16 | objc = "0.2.7" 17 | -------------------------------------------------------------------------------- /rust/poly/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "conformal_poly" 3 | version = "0.3.7" 4 | edition.workspace = true 5 | rust-version.workspace = true 6 | license = "ISC" 7 | description = "Helper utilities for polyphonic synthesizers in the conformal framework." 8 | repository = "https://github.com/russellmcc/conformal" 9 | homepage = "https://russellmcc.github.io/conformal" 10 | 11 | [lints] 12 | workspace = true 13 | 14 | [dependencies] 15 | conformal_component = { version = "0.3.6", path = "../component" } 16 | arrayvec = "0.7.6" 17 | -------------------------------------------------------------------------------- /rust/core/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "conformal_core" 3 | version = "0.3.7" 4 | edition.workspace = true 5 | rust-version.workspace = true 6 | license = "ISC" 7 | description = "Code shared between wrappers in conformal framework." 8 | repository = "https://github.com/russellmcc/conformal" 9 | homepage = "https://russellmcc.github.io/conformal" 10 | 11 | [lints] 12 | workspace = true 13 | 14 | [dependencies] 15 | conformal_component = { version = "0.3.6", path = "../component" } 16 | serde = { version = "1.0.193", features = ["derive"] } 17 | -------------------------------------------------------------------------------- /web/docs/pages/app_notes/index.mdx: -------------------------------------------------------------------------------- 1 | # Application Notes 2 | 3 | This section of the site contains "notes" on specific techniques in plug-in development to help you get the most out of Conformal. Think of this as a technical blog focused on plug-in development in Conformal. Each note varies in length and depth, and may require some prerequisite knowledge. 4 | 5 | Like the rest of the site, we encourage contributions and corrections! 6 | 7 | We also encourage discussion on the [GitHub Discussions](https://github.com/russellmcc/conformal/discussions) page. 8 | -------------------------------------------------------------------------------- /web/scripts/src/format.ts: -------------------------------------------------------------------------------- 1 | import { $ } from "bun"; 2 | import { Command } from "@commander-js/extra-typings"; 3 | 4 | export const format = async (): Promise => 5 | (await $`cargo fmt && bun run --filter '*' format`.nothrow()).exitCode == 0; 6 | 7 | export const execute = async () => { 8 | await format(); 9 | }; 10 | 11 | export const addFormatCommand = (command: Command) => 12 | command 13 | .command("format") 14 | .description("Auto-format code") 15 | .action(async () => { 16 | await execute(); 17 | }); 18 | -------------------------------------------------------------------------------- /web/internal-scripts/src/postpack.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "@commander-js/extra-typings"; 2 | import * as fs from "node:fs/promises"; 3 | 4 | export const postpack = async () => { 5 | // Restore from backup 6 | await fs.rename("./package.json.bak", "./package.json"); 7 | }; 8 | 9 | export const addPostpackCommand = (command: Command) => { 10 | command 11 | .command("ts-browser-postpack") 12 | .description("standard postpack script for ts browser libs") 13 | .action(async () => { 14 | await postpack(); 15 | }); 16 | }; 17 | -------------------------------------------------------------------------------- /rust/vst-wrapper/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.3.8 (2025-11-02) 2 | 3 | ### Features 4 | 5 | - bumping vst3-rs 6 | 7 | ## 0.3.7 (2025-09-23) 8 | 9 | ### Features 10 | 11 | - Minimum support rust version (MSRV) is now 1.90 12 | 13 | #### Fix for VST3 format violation 14 | 15 | Fixes a subtle issue where we did not allow activating a processor unless the audio busses had been activated. It turns out compliant plug-ins must support being activated with no audio present. 16 | 17 | ## 0.3.6 (2025-02-23) 18 | 19 | ### Features 20 | 21 | - Add support for persistant UI state 22 | -------------------------------------------------------------------------------- /rust/component/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "conformal_component" 3 | version = "0.3.6" 4 | edition.workspace = true 5 | rust-version.workspace = true 6 | license = "ISC" 7 | description = "Defines basic audio component abstraction for conformal audio plug-in framework." 8 | repository = "https://github.com/russellmcc/conformal" 9 | documentation = "https://russellmcc.github.io/conformal/rust-doc/conformal_component" 10 | homepage = "https://russellmcc.github.io/conformal" 11 | 12 | [lints] 13 | workspace = true 14 | 15 | [dependencies] 16 | itertools = "0.13.0" 17 | fxhash = "0.2.1" 18 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/web/{{plug_slug}}/src/mock_infos.ts: -------------------------------------------------------------------------------- 1 | import { Info } from "@conformal/plugin"; 2 | 3 | const infos = new Map( 4 | Object.entries({ 5 | bypass: { 6 | title: "Bypass", 7 | type_specific: { 8 | t: "switch", 9 | default: false, 10 | }, 11 | }, 12 | gain: { 13 | title: "Gain", 14 | type_specific: { 15 | t: "numeric", 16 | default: 100, 17 | valid_range: [0, 100], 18 | units: "%", 19 | }, 20 | }, 21 | }), 22 | ); 23 | 24 | export default infos; 25 | -------------------------------------------------------------------------------- /rust/preferences/src/fake_os.rs: -------------------------------------------------------------------------------- 1 | use super::{OSStore, Value}; 2 | use std::collections::HashMap; 3 | 4 | #[derive(Default, Debug)] 5 | pub struct Store { 6 | pub values: HashMap, 7 | } 8 | 9 | impl OSStore for Store { 10 | #[cfg(all(test, not(miri)))] 11 | fn reset(&mut self) { 12 | self.values.clear(); 13 | } 14 | 15 | fn get(&self, unique_id: &str) -> Option { 16 | self.values.get(unique_id).cloned() 17 | } 18 | 19 | fn set(&mut self, unique_id: &str, value: Value) { 20 | self.values.insert(unique_id.to_string(), value); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /web/create/template/{{cargo_toml}}: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = [] 4 | 5 | [workspace.package] 6 | rust-version = "1.90.0" 7 | edition = "2024" 8 | 9 | [workspace.lints.rust] 10 | nonstandard_style = "warn" 11 | rust_2018_idioms = "warn" 12 | future_incompatible = "warn" 13 | 14 | [workspace.lints.rustdoc] 15 | private_doc_tests = "warn" 16 | unescaped_backticks = "warn" 17 | 18 | [workspace.lints.clippy] 19 | pedantic = { level = "warn", priority = -1 } 20 | todo = "warn" 21 | type_complexity = "allow" 22 | cast_sign_loss = "allow" 23 | cast_possible_wrap = "allow" 24 | default_trait_access = "allow" 25 | -------------------------------------------------------------------------------- /rust/preferences/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "conformal_preferences" 3 | version = "0.3.6" 4 | edition.workspace = true 5 | license = "ISC" 6 | description = "Utilities for persistent user preferences used by the conformal audio plug-in framework." 7 | repository = "https://github.com/russellmcc/conformal" 8 | homepage = "https://russellmcc.github.io/conformal" 9 | 10 | [dependencies] 11 | serde = { version = "1.0.193", features = ["derive"] } 12 | serde_json = "1.0.117" 13 | 14 | [lints] 15 | workspace = true 16 | 17 | [features] 18 | test-utils = [] 19 | 20 | [target.'cfg(target_os = "macos")'.dependencies] 21 | objc = "0.2.7" 22 | -------------------------------------------------------------------------------- /web/eslint-config-custom/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-custom", 3 | "exports": { 4 | ".": { 5 | "default": "./index.mjs" 6 | } 7 | }, 8 | "type": "module", 9 | "private": true, 10 | "scripts": { 11 | "lint": "eslint . --max-warnings 0" 12 | }, 13 | "dependencies": { 14 | "globals": "catalog:", 15 | "@eslint/js": "catalog:", 16 | "eslint-plugin-react": "catalog:", 17 | "eslint-plugin-react-hooks": "catalog:", 18 | "eslint-plugin-react-refresh": "catalog:", 19 | "eslint-plugin-prefer-arrow-functions": "catalog:", 20 | "typescript-eslint": "catalog:" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /web/create/template/web/eslint-config-custom/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-custom", 3 | "exports": { 4 | ".": { 5 | "default": "./index.mjs" 6 | } 7 | }, 8 | "type": "module", 9 | "private": true, 10 | "scripts": { 11 | "lint": "eslint . --max-warnings 0" 12 | }, 13 | "dependencies": { 14 | "globals": "catalog:", 15 | "@eslint/js": "catalog:", 16 | "eslint-plugin-react": "catalog:", 17 | "eslint-plugin-react-hooks": "catalog:", 18 | "eslint-plugin-react-refresh": "catalog:", 19 | "eslint-plugin-prefer-arrow-functions": "catalog:", 20 | "typescript-eslint": "catalog:" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /web/create/template/web/tsconfig/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["es2020", "dom", "dom.iterable"], 6 | "module": "esnext", 7 | "skipLibCheck": true, 8 | /* Bundler mode */ 9 | "moduleResolution": "bundler", 10 | "allowImportingTsExtensions": true, 11 | "isolatedModules": true, 12 | "noEmit": true, 13 | "jsx": "react-jsx", 14 | /* Linting */ 15 | "strict": true, 16 | "noUnusedLocals": true, 17 | "noUnusedParameters": true, 18 | "noFallthroughCasesInSwitch": true, 19 | "noUncheckedIndexedAccess": true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /web/plugin/src/IgnoreErrorBoundary.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactNode } from "react"; 2 | 3 | export type Props = { 4 | children?: ReactNode; 5 | }; 6 | 7 | type State = { 8 | hasError: boolean; 9 | }; 10 | 11 | class IgnoreErrorBoundary extends React.Component { 12 | constructor(props: Props) { 13 | super(props); 14 | this.state = { hasError: false }; 15 | } 16 | 17 | static getDerivedStateFromError() { 18 | return { hasError: true }; 19 | } 20 | 21 | render() { 22 | if (this.state.hasError) { 23 | return <>; 24 | } 25 | 26 | return this.props.children; 27 | } 28 | } 29 | export default IgnoreErrorBoundary; 30 | -------------------------------------------------------------------------------- /web/scripts/src/checkFormat.ts: -------------------------------------------------------------------------------- 1 | import { $ } from "bun"; 2 | import { failUnless } from "./util"; 3 | import { Command } from "@commander-js/extra-typings"; 4 | 5 | export const checkFormat = async (): Promise => 6 | (await $`cargo fmt --check && bun run --filter '*' check-format`.nothrow()) 7 | .exitCode == 0; 8 | 9 | export const execute = async () => { 10 | failUnless(await checkFormat()); 11 | }; 12 | 13 | export const addCheckFormatCommand = (command: Command): void => { 14 | command 15 | .command("check-format") 16 | .description("Check if the code is formatted correctly") 17 | .action(async () => { 18 | await execute(); 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /web/create/src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bun 2 | 3 | import { Command } from "@commander-js/extra-typings"; 4 | import { Config, metadatas, postBuild } from "./config"; 5 | import { toEnv } from "@conformal/create-plugin"; 6 | import { buildStampCommand } from "@conformal/stamp"; 7 | import path from "node:path"; 8 | 9 | const command = buildStampCommand({ 10 | command: new Command(), 11 | metadatas, 12 | toEnv, 13 | toDest: (config) => Promise.resolve(config.proj_slug), 14 | toTemplate: () => 15 | Promise.resolve( 16 | path.join(path.dirname(import.meta.path), "..", "template"), 17 | ), 18 | postBuild, 19 | }); 20 | 21 | await command.parseAsync(); 22 | -------------------------------------------------------------------------------- /rust/ui/src/preferences_convert.rs: -------------------------------------------------------------------------------- 1 | use super::protocol; 2 | use conformal_preferences::Value; 3 | 4 | impl From for protocol::Value { 5 | fn from(value: Value) -> Self { 6 | match value { 7 | Value::Switch(b) => protocol::Value::Bool(b), 8 | } 9 | } 10 | } 11 | 12 | pub enum ValueError { 13 | InvalidValue, 14 | } 15 | 16 | impl TryFrom for Value { 17 | type Error = ValueError; 18 | 19 | fn try_from(value: protocol::Value) -> Result { 20 | match value { 21 | protocol::Value::Bool(b) => Ok(Value::Switch(b)), 22 | _ => Err(ValueError::InvalidValue), 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /web/docs/src/head/index.tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | import { useConfig } from "nextra-theme-docs"; 3 | const Head = () => { 4 | const config = useConfig(); 5 | const { route } = useRouter(); 6 | 7 | const title = config.title + (route === "/" ? "" : " - Conformal"); 8 | 9 | return ( 10 | <> 11 | {title} 12 | {typeof config.frontMatter.description === "string" ? ( 13 | 14 | ) : null} 15 | 16 | 17 | 18 | ); 19 | }; 20 | 21 | export default Head; 22 | -------------------------------------------------------------------------------- /rust/vst-wrapper/src/host_info.rs: -------------------------------------------------------------------------------- 1 | use crate::HostInfo; 2 | use vst3::Steinberg::Vst::IHostApplicationTrait; 3 | 4 | use super::from_utf16_buffer; 5 | 6 | fn get_name(host: &dyn IHostApplicationTrait) -> Option { 7 | let mut name_buffer = [0u16; 128]; 8 | let res = unsafe { host.getName(&raw mut name_buffer) }; 9 | if res != vst3::Steinberg::kResultOk { 10 | return None; 11 | } 12 | 13 | from_utf16_buffer(&name_buffer) 14 | } 15 | 16 | /// Extract the host info from `IHostApplication`. Note that this is 17 | /// potentially re-entrant! 18 | pub fn get(host: &dyn IHostApplicationTrait) -> Option { 19 | let name = get_name(host)?; 20 | Some(HostInfo { name }) 21 | } 22 | -------------------------------------------------------------------------------- /web/plugin/src/protocol/param_info.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const TypeSpecific = z.union([ 4 | z.object({ 5 | t: z.literal("numeric"), 6 | default: z.number(), 7 | valid_range: z.tuple([z.number(), z.number()]), 8 | units: z.string(), 9 | }), 10 | z.object({ 11 | t: z.literal("enum"), 12 | default: z.string(), 13 | values: z.array(z.string()), 14 | }), 15 | z.object({ 16 | t: z.literal("switch"), 17 | default: z.boolean(), 18 | }), 19 | ]); 20 | export type TypeSpecific = z.infer; 21 | 22 | export const Info = z.object({ 23 | title: z.string(), 24 | type_specific: TypeSpecific, 25 | }); 26 | export type Info = z.infer; 27 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/web/{{plug_slug}}/src/Layout.tsx: -------------------------------------------------------------------------------- 1 | import { useNumericParam } from "@conformal/plugin"; 2 | 3 | const Layout = () => { 4 | const { value: gain, set: setGain } = useNumericParam("gain"); 5 | 6 | return ( 7 |
8 |

Current gain: {gain}%

9 |

10 | { 12 | setGain(Math.max(0, gain - 10)); 13 | }} 14 | > 15 | - 16 | 17 | { 19 | setGain(Math.min(100, gain + 10)); 20 | }} 21 | > 22 | + 23 | 24 |

25 |
26 | ); 27 | }; 28 | 29 | export default Layout; 30 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/web/{{plug_slug}}/src/Layout.tsx: -------------------------------------------------------------------------------- 1 | import { useNumericParam } from "@conformal/plugin"; 2 | 3 | const Layout = () => { 4 | const { value: gain, set: setGain } = useNumericParam("gain"); 5 | 6 | return ( 7 |
8 |

Current gain: {gain}%

9 |

10 | { 12 | setGain(Math.max(0, gain - 10)); 13 | }} 14 | > 15 | - 16 | 17 | { 19 | setGain(Math.min(100, gain + 10)); 20 | }} 21 | > 22 | + 23 | 24 |

25 |
26 | ); 27 | }; 28 | 29 | export default Layout; 30 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 by Conformal Authors 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /web/create/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 by Conformal Authors 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /web/plugin/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 by Conformal Authors 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /web/plugin/src/stores_provider.tsx: -------------------------------------------------------------------------------- 1 | import msgpackTransport from "./msgpack_transport"; 2 | import storesWithTransport from "./stores"; 3 | import wryTransport from "./wry_transport"; 4 | import { Info } from "./protocol/param_info"; 5 | import mockStore from "./mock_store"; 6 | import { Context } from "./stores_react"; 7 | 8 | const stores = wryTransport 9 | ? storesWithTransport(msgpackTransport(wryTransport)) 10 | : undefined; 11 | 12 | export const Provider = ({ 13 | mockInfos, 14 | children, 15 | }: { 16 | mockInfos: Map; 17 | children: React.ReactNode; 18 | }) => ( 19 | 20 | {children} 21 | 22 | ); 23 | 24 | export default Provider; 25 | -------------------------------------------------------------------------------- /web/scripts/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 by Conformal Authors 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /web/stamp/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 by Conformal Authors 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /rust/poly/README.md: -------------------------------------------------------------------------------- 1 | This crate provides helpful utilities for writing polyphonic synthesizers in the [Conformal Framework](https://russellmcc.github.io/conformal). 2 | 3 | The main entry point for this crate is the [`Poly`] struct, which can be used to implement the [`handle_events`](`conformal_component::synth::Synth::handle_events`), [`process`](`conformal_component::synth::Synth::process`), and [`set_processing`](`conformal_component::Processor::set_processing`) methods on [`Synth`](`conformal_component::synth::Synth`). To use [`Poly`], a component must implement the [`Voice`] trait, which defines how to render a single voice. Common tasks such as routing events and note expression changes to voices, and mixing the output of voices are handled by the [`Poly`] struct. 4 | -------------------------------------------------------------------------------- /web/create-plugin/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 by Conformal Authors 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /web/docs/theme.config.tsx: -------------------------------------------------------------------------------- 1 | import { DocsThemeConfig, useConfig } from "nextra-theme-docs"; 2 | import Head from "./src/head"; 3 | const themeConfig: DocsThemeConfig = { 4 | project: { 5 | link: "https://github.com/russellmcc/conformal", 6 | }, 7 | docsRepositoryBase: 8 | "https://github.com/russellmcc/conformal/tree/main/web/docs", 9 | logo: Conformal, 10 | feedback: { 11 | useLink: () => { 12 | const config = useConfig(); 13 | const title = config.title; 14 | 15 | return `https://github.com/russellmcc/conformal/discussions/new?category=q-a&title=Feedback regarding ${title}`; 16 | }, 17 | }, 18 | head: Head, 19 | footer: { 20 | component: <>, 21 | }, 22 | }; 23 | 24 | export default themeConfig; 25 | -------------------------------------------------------------------------------- /web/scripts/src/bundleData.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import * as path from "path"; 3 | 4 | const BundleDataParser = z.object({ 5 | rustPackage: z.string(), 6 | name: z.string(), 7 | id: z.string(), 8 | sig: z.string(), 9 | version: z.string(), 10 | }); 11 | 12 | export type BundleData = z.infer; 13 | 14 | export const getBundleData = async ( 15 | packageRoot: string, 16 | ): Promise => { 17 | const result = await BundleDataParser.safeParseAsync( 18 | (await Bun.file(path.join(packageRoot, "bundle.json")).json()) as unknown, 19 | ); 20 | if (result.success) { 21 | return result.data; 22 | } else { 23 | throw new Error(result.error.message); 24 | } 25 | }; 26 | 27 | export default getBundleData; 28 | -------------------------------------------------------------------------------- /web/tsconfig/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "useDefineForClassFields": true, 5 | "lib": [ 6 | "es2020", 7 | "dom", 8 | "dom.iterable" 9 | ], 10 | "module": "esnext", 11 | "skipLibCheck": true, 12 | /* Bundler mode */ 13 | "moduleResolution": "bundler", 14 | "allowImportingTsExtensions": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx", 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedIndexedAccess": true, 24 | }, 25 | } -------------------------------------------------------------------------------- /web/docs/src/app_notes/2/NumBucketControl.tsx: -------------------------------------------------------------------------------- 1 | import { useAtom } from "jotai"; 2 | import { numBucketsAtom } from "./Controls"; 3 | 4 | export const NumBucketControl = () => { 5 | const [numBuckets, setNumBuckets] = useAtom(numBucketsAtom); 6 | 7 | return ( 8 |
9 | 22 |
23 | ); 24 | }; 25 | export default NumBucketControl; 26 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = [ 4 | "rust/vst-wrapper", 5 | "rust/macos-bundle", 6 | "rust/preferences", 7 | "rust/component", 8 | "rust/ui", 9 | "rust/core", 10 | "rust/poly", 11 | ] 12 | 13 | [workspace.package] 14 | rust-version = "1.90.0" 15 | edition = "2024" 16 | 17 | [workspace.lints.rust] 18 | nonstandard_style = "warn" 19 | rust_2018_idioms = "warn" 20 | future_incompatible = "warn" 21 | missing_docs = "warn" 22 | 23 | [workspace.lints.rustdoc] 24 | private_doc_tests = "warn" 25 | unescaped_backticks = "warn" 26 | 27 | [workspace.lints.clippy] 28 | pedantic = { level = "warn", priority = -1 } 29 | todo = "warn" 30 | type_complexity = "allow" 31 | cast_sign_loss = "allow" 32 | cast_possible_wrap = "allow" 33 | default_trait_access = "allow" 34 | large_enum_variant = "allow" 35 | -------------------------------------------------------------------------------- /web/docs/src/app_notes/2/ClockRateControl.tsx: -------------------------------------------------------------------------------- 1 | import { useAtom } from "jotai"; 2 | import { clockRateAtom } from "./Controls"; 3 | 4 | export const ClockRateControl = () => { 5 | const [clockRate, setClockRate] = useAtom(clockRateAtom); 6 | 7 | return ( 8 |
9 | 23 |
24 | ); 25 | }; 26 | 27 | export default ClockRateControl; 28 | -------------------------------------------------------------------------------- /web/scripts/src/create-plugin.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Config, 3 | metadatas, 4 | postBuild, 5 | toEnv, 6 | toTemplate, 7 | } from "@conformal/create-plugin"; 8 | import { buildStampCommand } from "@conformal/stamp"; 9 | import { findWorkspaceRoot } from "./workspaceRoot"; 10 | import { Command } from "@commander-js/extra-typings"; 11 | 12 | export const addCreatePlugCommand = (command: Command) => { 13 | buildStampCommand({ 14 | command: command.command("create-plugin"), 15 | metadatas, 16 | toEnv: toEnv, 17 | toDest: () => findWorkspaceRoot(process.cwd()), 18 | toTemplate, 19 | postBuild: async (config) => 20 | postBuild(await findWorkspaceRoot(process.cwd()), config), 21 | options: { 22 | merge: true, 23 | }, 24 | }).description("Create a new plug-in from a template"); 25 | }; 26 | -------------------------------------------------------------------------------- /rust/vst-wrapper/src/dummy_host.rs: -------------------------------------------------------------------------------- 1 | use vst3::{ 2 | Class, 3 | Steinberg::Vst::{IHostApplication, IHostApplicationTrait}, 4 | }; 5 | 6 | #[derive(Default)] 7 | pub struct Host {} 8 | 9 | impl IHostApplicationTrait for Host { 10 | unsafe fn getName( 11 | &self, 12 | name: *mut vst3::Steinberg::Vst::String128, 13 | ) -> vst3::Steinberg::tresult { 14 | unsafe { super::to_utf16("Dummy Host", &mut (*name)) }; 15 | vst3::Steinberg::kResultOk 16 | } 17 | 18 | unsafe fn createInstance( 19 | &self, 20 | _cid: *mut vst3::Steinberg::TUID, 21 | _iid: *mut vst3::Steinberg::TUID, 22 | _obj: *mut *mut std::ffi::c_void, 23 | ) -> vst3::Steinberg::tresult { 24 | unimplemented!() 25 | } 26 | } 27 | 28 | impl Class for Host { 29 | type Interfaces = (IHostApplication,); 30 | } 31 | -------------------------------------------------------------------------------- /web/internal-scripts/src/cli.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "@commander-js/extra-typings"; 2 | import { addReleaseCommand } from "./release"; 3 | import { addPostpackCommand } from "./postpack"; 4 | import { addPrepackCommand } from "./prepack"; 5 | import { addDeployDocsCommand } from "./deployDocs"; 6 | import { 7 | addRustChangeCommand, 8 | addRustPrepareReleaseCommand, 9 | } from "./rustChange"; 10 | 11 | export const command = () => { 12 | const command = new Command("conformal-internal-scripts").description( 13 | "This is a CLI entry point for various scripts needed to build the conformal audio framework.", 14 | ); 15 | 16 | addReleaseCommand(command); 17 | addPrepackCommand(command); 18 | addPostpackCommand(command); 19 | addDeployDocsCommand(command); 20 | addRustChangeCommand(command); 21 | addRustPrepareReleaseCommand(command); 22 | 23 | return command; 24 | }; 25 | -------------------------------------------------------------------------------- /web/docs/next.config.js: -------------------------------------------------------------------------------- 1 | import nextra from "nextra"; 2 | 3 | const withNextra = nextra({ 4 | theme: "nextra-theme-docs", 5 | themeConfig: "./theme.config.tsx", 6 | latex: true, 7 | }); 8 | 9 | export default withNextra({ 10 | output: "export", 11 | images: { 12 | loader: "custom", 13 | imageSizes: [16, 128, 384], 14 | deviceSizes: [1280, 3840], 15 | }, 16 | transpilePackages: ["next-image-export-optimizer"], 17 | env: { 18 | nextImageExportOptimizer_exportFolderPath: "out", 19 | nextImageExportOptimizer_quality: "75", 20 | nextImageExportOptimizer_storePicturesInWEBP: "true", 21 | nextImageExportOptimizer_exportFolderName: "nextImageExportOptimizer", 22 | nextImageExportOptimizer_generateAndUseBlurImages: "true", 23 | nextImageExportOptimizer_remoteImageCacheTTL: "0", 24 | }, 25 | 26 | trailingSlash: true, 27 | basePath: "/conformal", 28 | }); 29 | -------------------------------------------------------------------------------- /web/docs/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import config from "eslint-config-custom"; 3 | import { FlatCompat } from "@eslint/eslintrc"; 4 | 5 | const compat = new FlatCompat({ 6 | baseDirectory: import.meta.dirname, 7 | }); 8 | 9 | export default defineConfig([ 10 | config, 11 | compat.extends("plugin:@next/next/recommended"), 12 | { 13 | ignores: ["out", ".next"], 14 | }, 15 | { 16 | files: ["**/*.ts", "**/*.tsx"], 17 | languageOptions: { 18 | parserOptions: { 19 | project: ["./tsconfig.json"], 20 | tsconfigRootDir: import.meta.dirname, 21 | }, 22 | }, 23 | rules: { 24 | "react-refresh/only-export-components": "off", 25 | // Some of the blog posts do ref crimes, disable for now. 26 | "react-hooks/refs": "off", 27 | "@typescript-eslint/triple-slash-reference": "off", 28 | }, 29 | }, 30 | ]); 31 | -------------------------------------------------------------------------------- /web/plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | export { Info } from "./protocol/param_info"; 2 | export type { default as Transport } from "./transport"; 3 | export { storesFromGenericStore } from "./stores"; 4 | export type { Family } from "./stores"; 5 | export { 6 | useStores, 7 | useBooleanAtom, 8 | useBooleanValue, 9 | useBytesAtom, 10 | useBytesValue, 11 | useExtended, 12 | useGenericAtom, 13 | useGenericValue, 14 | useGrab, 15 | useNumericAtom, 16 | useNumericValue, 17 | useStringAtom, 18 | useStringValue, 19 | } from "./stores_react"; 20 | export { default as Provider } from "./stores_provider"; 21 | export { useEnumParam, useNumericParam, useSwitchParam } from "./params"; 22 | export { default as DevModeTools } from "./DevModeTools"; 23 | export { useUiStateAtom, codecFromZod } from "./ui_state"; 24 | export type { Codec } from "./ui_state"; 25 | export { UiStateProvider } from "./ui_state_provider"; 26 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Release Docs 2 | run-name: Release Docs 3 | 4 | on: 5 | workflow_dispatch: 6 | 7 | permissions: 8 | contents: read 9 | pages: write 10 | id-token: write 11 | 12 | jobs: 13 | release-docs: 14 | runs-on: macos-14 15 | steps: 16 | - uses: actions/checkout@v4 17 | with: 18 | lfs: "true" 19 | fetch-depth: 0 20 | - uses: ./.github/actions/bootstrap 21 | - run: bun run deploy-docs 22 | - name: Upload pages artifact 23 | uses: actions/upload-pages-artifact@v3 24 | with: 25 | path: ./_site 26 | deploy: 27 | environment: 28 | name: github-pages 29 | url: ${{ steps.deployment.outputs.page_url }} 30 | runs-on: ubuntu-latest 31 | needs: release-docs 32 | steps: 33 | - name: Deploy to GitHub Pages 34 | id: deployment 35 | uses: actions/deploy-pages@v4 36 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/web/{{plug_slug}}/src/main.tsx: -------------------------------------------------------------------------------- 1 | // Temporary workaround for https://github.com/oven-sh/bun/issues/4890 2 | /// 3 | /// 4 | 5 | import App from "./App.tsx"; 6 | import * as Jotai from "jotai"; 7 | import { StrictMode, Suspense } from "react"; 8 | import * as Client from "react-dom/client"; 9 | import { Provider } from "@conformal/plugin"; 10 | import "./index.css"; 11 | import infos from "./mock_infos.ts"; 12 | 13 | const domElement = document.querySelector("#root"); 14 | 15 | if (!(domElement == null)) { 16 | Client.createRoot(domElement).render( 17 | 18 | 19 | 20 | }> 21 | 22 | 23 | 24 | 25 | , 26 | ); 27 | } 28 | 29 | export {}; 30 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/web/{{plug_slug}}/src/main.tsx: -------------------------------------------------------------------------------- 1 | // Temporary workaround for https://github.com/oven-sh/bun/issues/4890 2 | /// 3 | /// 4 | 5 | import App from "./App.tsx"; 6 | import * as Jotai from "jotai"; 7 | import { StrictMode, Suspense } from "react"; 8 | import * as Client from "react-dom/client"; 9 | import { Provider } from "@conformal/plugin"; 10 | import "./index.css"; 11 | import infos from "./mock_infos.ts"; 12 | 13 | const domElement = document.querySelector("#root"); 14 | 15 | if (!(domElement == null)) { 16 | Client.createRoot(domElement).render( 17 | 18 | 19 | 20 | }> 21 | 22 | 23 | 24 | 25 | , 26 | ); 27 | } 28 | 29 | export {}; 30 | -------------------------------------------------------------------------------- /web/create/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-conformal", 3 | "version": "0.8.0", 4 | "description": "Project generator script for conformal projects", 5 | "homepage": "https://russellmcc.github.io/conformal", 6 | "bugs": "https://github.com/russellmcc/conformal/issues", 7 | "repository": "github:russellmcc/conformal", 8 | "license": "ISC", 9 | "scripts": { 10 | "lint": "tsc && eslint . --max-warnings 0", 11 | "check-format": "prettier -c .", 12 | "format": "prettier --write ." 13 | }, 14 | "bin": "./src/index.ts", 15 | "type": "module", 16 | "dependencies": { 17 | "@conformal/stamp": "workspace:^0.3.5", 18 | "@conformal/create-plugin": "workspace:^0.8.0", 19 | "@commander-js/extra-typings": "catalog:", 20 | "commander": "catalog:" 21 | }, 22 | "devDependencies": { 23 | "tmp-promise": "catalog:", 24 | "eslint-config-custom": "workspace:*", 25 | "zod": "catalog:" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /web/stamp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@conformal/stamp", 3 | "version": "0.3.5", 4 | "description": "Utility functions for project generator scripts", 5 | "homepage": "https://russellmcc.github.io/conformal", 6 | "bugs": "https://github.com/russellmcc/conformal/issues", 7 | "repository": "github:russellmcc/conformal", 8 | "license": "ISC", 9 | "scripts": { 10 | "lint": "tsc && eslint . --max-warnings 0", 11 | "check-format": "prettier -c .", 12 | "format": "prettier --write ." 13 | }, 14 | "exports": { 15 | ".": { 16 | "import": "./src/index.ts", 17 | "bun": "./src/index.ts" 18 | } 19 | }, 20 | "type": "module", 21 | "dependencies": { 22 | "handlebars": "catalog:", 23 | "@commander-js/extra-typings": "catalog:", 24 | "@inquirer/prompts": "catalog:", 25 | "commander": "catalog:" 26 | }, 27 | "devDependencies": { 28 | "eslint-config-custom": "workspace:" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /web/scripts/src/cargo.ts: -------------------------------------------------------------------------------- 1 | import runShell from "./runShell"; 2 | import { Command } from "@commander-js/extra-typings"; 3 | 4 | export const execute = async (args: readonly string[]) => { 5 | const cargoArgs: string[] = ["cargo", ...args]; 6 | // Disallow warnings if the CI environment variable is set. 7 | // exception - never disallow warnings when building on nightly, 8 | // because the set of available warnings changes every night! 9 | if (process.env.CI && !args.includes("+nightly")) { 10 | cargoArgs.push( 11 | '--config=target.\'cfg(all())\'.rustflags = ["-D", "warnings"]', 12 | ); 13 | } 14 | await runShell(cargoArgs); 15 | }; 16 | 17 | export const addCargoCommand = (command: Command): void => { 18 | command 19 | .command("cargo") 20 | .description("Runs cargo") 21 | .arguments("[args...]") 22 | .allowUnknownOption() 23 | .action(async (args) => { 24 | await execute(args); 25 | }); 26 | }; 27 | -------------------------------------------------------------------------------- /rust/component/README.md: -------------------------------------------------------------------------------- 1 | This crate defines abstractions for audio processing components. 2 | 3 | Users of this crate will generally implement a [`Component`] that can create either an [`effect::Effect`] or a [`synth::Synth`] and then use a Conformal wrapper crate (currently `conformal_vst_wrapper`) to wrap the component in a standard audio Plug-in format. 4 | 5 | This crate contains: 6 | 7 | - Definitions for the traits [`Component`]s must implement 8 | - Definitions for traits that Conformal wrappers will implement to provide data for the [`Component`] to consume. (e.g., [`parameters::BufferStates`], [`audio::Buffer`]) 9 | - Simple implementatations of traits normally implemented by Conformal wrappers, to make testing easier and to provide a simple way to use [`Component`]s outside of a Conformal wrapper. (e.g., [`audio::BufferData`], [`parameters::ConstantBufferStates`]) 10 | - Utilities to make some of these traits either to work with (e.g., [`pzip`]). 11 | -------------------------------------------------------------------------------- /web/scripts/src/checkLicenses.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "@commander-js/extra-typings"; 2 | import { join, dirname } from "node:path"; 3 | 4 | import { $, Glob } from "bun"; 5 | 6 | const checkLicensesForCrate = async (crate: string): Promise => { 7 | const aboutPath = join(crate, "about.hbs"); 8 | const cargoTomlPath = join(crate, "Cargo.toml"); 9 | console.log(`Checking licenses for ${crate}`); 10 | await $`cargo about generate -m ${cargoTomlPath} ${aboutPath}`.quiet(); 11 | }; 12 | 13 | export const checkLicenses = async (): Promise => { 14 | for await (const aboutFile of new Glob("rust/**/about.hbs").scan()) { 15 | await checkLicensesForCrate(dirname(aboutFile.trim())); 16 | } 17 | }; 18 | 19 | export const addCheckLicensesCommand = (command: Command) => 20 | command 21 | .command("check-licenses") 22 | .description("Check if all rust dependency licenses are valid") 23 | .action(async () => { 24 | await checkLicenses(); 25 | }); 26 | -------------------------------------------------------------------------------- /web/plugin/src/msgpack_transport.ts: -------------------------------------------------------------------------------- 1 | import { decode, encode } from "@msgpack/msgpack"; 2 | import { Transport as ProtocolTransport, Request, Response } from "./protocol"; 3 | import Transport from "./transport"; 4 | 5 | const transport = ( 6 | transport: Transport, 7 | ): ProtocolTransport => { 8 | const request = (request: Request) => { 9 | transport.request( 10 | encode(request, { forceFloat32: true, forceIntegerToFloat: true }), 11 | ); 12 | }; 13 | const setOnResponse = (onResponse: (response: Response) => void) => { 14 | transport.setOnResponse((bytes: Uint8Array) => { 15 | try { 16 | onResponse(Response.parse(decode(bytes))); 17 | } catch { 18 | // If we couldn't decode the response, it could be from a new server version - 19 | // so we silently ignore it! 20 | } 21 | }); 22 | }; 23 | return { 24 | request, 25 | setOnResponse, 26 | }; 27 | }; 28 | 29 | export default transport; 30 | -------------------------------------------------------------------------------- /web/internal-scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "conformal-internal-scripts", 3 | "description": "Build scripts for building the conformal audio framework itself", 4 | "private": true, 5 | "homepage": "https://github.com/russellmcc/conformal", 6 | "bugs": "https://github.com/russellmcc/conformal/issues", 7 | "license": "ISC", 8 | "scripts": { 9 | "lint": "tsc && eslint . --max-warnings 0", 10 | "check-format": "prettier --ignore-path .gitignore -c .", 11 | "format": "prettier --ignore-path .gitignore --write .", 12 | "validate": "echo 'dummy validation'" 13 | }, 14 | "bin": "./src/index.ts", 15 | "type": "module", 16 | "dependencies": { 17 | "@commander-js/extra-typings": "catalog:", 18 | "commander": "catalog:", 19 | "tmp-promise": "catalog:", 20 | "zod": "catalog:", 21 | "bun-plugin-dts": "catalog:" 22 | }, 23 | "devDependencies": { 24 | "@morlay/bunpublish": "catalog:", 25 | "eslint-config-custom": "workspace:*" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /web/create-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@conformal/create-plugin", 3 | "version": "0.8.0", 4 | "description": "Utility functions for adding a plugin to a conformal project", 5 | "homepage": "https://russellmcc.github.io/conformal", 6 | "bugs": "https://github.com/russellmcc/conformal/issues", 7 | "repository": "github:russellmcc/conformal", 8 | "license": "ISC", 9 | "scripts": { 10 | "lint": "tsc && eslint . --max-warnings 0", 11 | "check-format": "prettier -c .", 12 | "format": "prettier --write .", 13 | "prepack": "bun run scripts/gather_rust_versions.ts", 14 | "postpack": "bun run scripts/cleanup.ts" 15 | }, 16 | "bin": "./src/cli.ts", 17 | "exports": { 18 | ".": { 19 | "import": "./src/index.ts", 20 | "bun": "./src/index.ts" 21 | } 22 | }, 23 | "type": "module", 24 | "dependencies": { 25 | "smol-toml": "catalog:", 26 | "zod": "catalog:" 27 | }, 28 | "devDependencies": { 29 | "eslint-config-custom": "workspace:*" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/web/{{plug_slug}}/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{plug_slug}}", 3 | "private": true, 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "tsc && vite build", 7 | "lint": "tsc && eslint . --max-warnings 0", 8 | "preview": "vite preview", 9 | "check-format": "prettier --ignore-path .gitignore -c .", 10 | "format": "prettier --ignore-path .gitignore --write .", 11 | "package": "conformal-scripts package", 12 | "validate": "conformal-scripts validate" 13 | }, 14 | "type": "module", 15 | "dependencies": { 16 | "@conformal/plugin": "catalog:", 17 | "react": "catalog:", 18 | "react-dom": "catalog:", 19 | "jotai": "catalog:" 20 | }, 21 | "devDependencies": { 22 | "rollup-plugin-license": "catalog:", 23 | "@types/react": "catalog:", 24 | "@types/react-dom": "catalog:", 25 | "@vitejs/plugin-react": "catalog:", 26 | "babel-plugin-react-compiler": "catalog:", 27 | "vite": "catalog:", 28 | "eslint-config-custom": "workspace:*" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/web/{{plug_slug}}/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{plug_slug}}", 3 | "private": true, 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "tsc && vite build", 7 | "lint": "tsc && eslint . --max-warnings 0", 8 | "preview": "vite preview", 9 | "check-format": "prettier --ignore-path .gitignore -c .", 10 | "format": "prettier --ignore-path .gitignore --write .", 11 | "package": "conformal-scripts package", 12 | "validate": "conformal-scripts validate" 13 | }, 14 | "type": "module", 15 | "dependencies": { 16 | "@conformal/plugin": "catalog:", 17 | "react": "catalog:", 18 | "react-dom": "catalog:", 19 | "jotai": "catalog:" 20 | }, 21 | "devDependencies": { 22 | "rollup-plugin-license": "catalog:", 23 | "@types/react": "catalog:", 24 | "@types/react-dom": "catalog:", 25 | "@vitejs/plugin-react": "catalog:", 26 | "babel-plugin-react-compiler": "catalog:", 27 | "vite": "catalog:", 28 | "eslint-config-custom": "workspace:*" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /web/docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "description": "Documentation site", 4 | "private": true, 5 | "homepage": "https://github.com/russellmcc/conformal", 6 | "bugs": "https://github.com/russellmcc/conformal/issues", 7 | "license": "ISC", 8 | "scripts": { 9 | "lint": "tsc && eslint . --max-warnings 0", 10 | "check-format": "prettier -c .", 11 | "format": "prettier --write .", 12 | "gen-scripts": "bun ../scripts/src/selfDoc.ts > pages/docs/reference/scripts.md", 13 | "dev": "bun run gen-scripts && bun x --bun next dev", 14 | "build": "bun run gen-scripts && bun x --bun next build && bun x next-image-export-optimizer" 15 | }, 16 | "type": "module", 17 | "dependencies": { 18 | "next": "catalog:", 19 | "next-image-export-optimizer": "catalog:", 20 | "nextra": "catalog:", 21 | "nextra-theme-docs": "catalog:" 22 | }, 23 | "devDependencies": { 24 | "eslint-config-custom": "workspace:*", 25 | "@next/eslint-plugin-next": "catalog:", 26 | "@eslint/eslintrc": "catalog:" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /web/create-plugin/template-synth/rust/{{plug_slug}}/vst/src/lib.rs: -------------------------------------------------------------------------------- 1 | use {{plug_slug}}_component::Component; 2 | 3 | use conformal_vst_wrapper::{ClassID, ClassInfo, HostInfo, Info, SynthClass}; 4 | 5 | const CID: ClassID = [ 6 | {{class_id}} 7 | ]; 8 | const EDIT_CONTROLLER_CID: ClassID = [ 9 | {{edit_class_id}} 10 | ]; 11 | 12 | conformal_vst_wrapper::wrap_factory!( 13 | &const { 14 | [&SynthClass { 15 | info: ClassInfo { 16 | name: "{{plug_name}}", 17 | cid: CID, 18 | edit_controller_cid: EDIT_CONTROLLER_CID, 19 | ui_initial_size: conformal_vst_wrapper::UiSize { 20 | width: 400, 21 | height: 400, 22 | }, 23 | }, 24 | factory: |_: &HostInfo| -> Component { Default::default() }, 25 | }] 26 | }, 27 | Info { 28 | vendor: "{{vendor_name}}", 29 | url: "{{task_marker}} add URL", 30 | email: "test@example.com", 31 | version: "1.0.0", 32 | } 33 | ); 34 | -------------------------------------------------------------------------------- /rust/vst-wrapper/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "conformal_vst_wrapper" 3 | version = "0.3.8" 4 | edition.workspace = true 5 | rust-version.workspace = true 6 | license = "ISC" 7 | description = "Implements a VST3-compatible plug-in for audio processors implemented with the conformal audio plug-in framework." 8 | repository = "https://github.com/russellmcc/conformal" 9 | documentation = "https://russellmcc.github.io/conformal/rust-doc/conformal_vst_wrapper" 10 | homepage = "https://russellmcc.github.io/conformal" 11 | 12 | [lints] 13 | workspace = true 14 | 15 | [target.'cfg(target_os = "macos")'.dependencies] 16 | conformal_macos_bundle = { version = "0.3.5", path = "../macos-bundle" } 17 | 18 | [dependencies] 19 | vst3 = "0.2.0" 20 | serde = { version = "1.0.193", features = ["derive"] } 21 | conformal_component = { version = "0.3.6", path = "../component" } 22 | conformal_ui = { version = "0.3.7", path = "../ui" } 23 | conformal_core = { version = "0.3.7", path = "../core" } 24 | rmp-serde = "1.1.2" 25 | itertools = "0.13.0" 26 | 27 | [dev-dependencies] 28 | assert_approx_eq = "1.1.0" 29 | -------------------------------------------------------------------------------- /web/scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@conformal/scripts", 3 | "version": "0.8.1", 4 | "description": "Build scripts for the conformal audio plug-in framework", 5 | "homepage": "https://russellmcc.github.io/conformal", 6 | "bugs": "https://github.com/russellmcc/conformal/issues", 7 | "repository": "github:russellmcc/conformal", 8 | "license": "ISC", 9 | "scripts": { 10 | "lint": "tsc && eslint . --max-warnings 0", 11 | "check-format": "prettier --ignore-path .gitignore -c .", 12 | "format": "prettier --ignore-path .gitignore --write .", 13 | "validate": "echo 'dummy validation'" 14 | }, 15 | "bin": { 16 | "conformal-scripts": "./src/index.ts" 17 | }, 18 | "type": "module", 19 | "dependencies": { 20 | "@conformal/create-plugin": "workspace:^0.8.0", 21 | "@conformal/stamp": "workspace:^0.3.5", 22 | "@commander-js/extra-typings": "catalog:", 23 | "commander": "catalog:", 24 | "tmp-promise": "catalog:", 25 | "zod": "catalog:" 26 | }, 27 | "devDependencies": { 28 | "eslint-config-custom": "workspace:" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /.github/workflows/prepare-release.yml: -------------------------------------------------------------------------------- 1 | name: Prepare Release 2 | run-name: Prepare Release 3 | 4 | permissions: 5 | contents: write 6 | id-token: write 7 | pull-requests: write 8 | repository-projects: write 9 | 10 | on: 11 | push: 12 | branches: 13 | - main 14 | 15 | jobs: 16 | prepare: 17 | runs-on: macos-14 18 | steps: 19 | - uses: actions/checkout@v4 20 | with: 21 | lfs: "true" 22 | - run: brew install oven-sh/bun/bun 23 | shell: bash 24 | - run: bun install --frozen-lockfile 25 | shell: bash 26 | - run: brew install knope-dev/tap/knope 27 | shell: bash 28 | - run: bun run prepare-release 29 | shell: bash 30 | - name: Create Pull Request 31 | uses: peter-evans/create-pull-request@v7 32 | with: 33 | branch: next-release 34 | title: "Release recent changes" 35 | body: "Merging this PR will create new releases for changed packages. Note that CI will not run on this branch, please bypass rules when merging" 36 | sign-commits: true 37 | -------------------------------------------------------------------------------- /web/create-plugin/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @conformal/create-plugin 2 | 3 | ## 0.8.0 4 | 5 | ### Minor Changes 6 | 7 | - 739063e: use isolated installs 8 | - bf6b0e1: update template to eslint 9 9 | - 34ed385: support react compiler and bump to react 19 10 | 11 | ## 0.7.0 12 | 13 | ### Minor Changes 14 | 15 | - 2b139f7: allow unicode 3.0 license 16 | 17 | ## 0.6.0 18 | 19 | ### Minor Changes 20 | 21 | - 657e18a: Bump vst3 wrapper version 22 | 23 | ### Patch Changes 24 | 25 | - 74e0f8a: Redact cargo.toml filenames in templates 26 | 27 | ## 0.5.0 28 | 29 | ### Minor Changes 30 | 31 | - 0d15265: Upgrade rust to 1.90 32 | 33 | ## 0.4.1 34 | 35 | ### Patch Changes 36 | 37 | - ddc3214: fix gitignore in web folder 38 | 39 | ## 0.4.0 40 | 41 | ### Minor Changes 42 | 43 | - 07e7800: Default to Rust 2024 edition 44 | - 07e7800: Use workspace to control edition 45 | 46 | ## 0.3.7 47 | 48 | ### Patch Changes 49 | 50 | - da9a572: Please ignore this change, it's a test of the new deployment system. 51 | 52 | ## 0.3.6 53 | 54 | ### Patch Changes 55 | 56 | - 818320c: Support differing rust crate versions 57 | -------------------------------------------------------------------------------- /web/create-plugin/template-effect/rust/{{plug_slug}}/vst/src/lib.rs: -------------------------------------------------------------------------------- 1 | use {{plug_slug}}_component::Component; 2 | 3 | use conformal_vst_wrapper::{ClassID, ClassInfo, EffectClass, HostInfo, Info}; 4 | 5 | const CID: ClassID = [ 6 | {{class_id}} 7 | ]; 8 | const EDIT_CONTROLLER_CID: ClassID = [ 9 | {{edit_class_id}} 10 | ]; 11 | 12 | conformal_vst_wrapper::wrap_factory!( 13 | &const { 14 | [&EffectClass { 15 | info: ClassInfo { 16 | name: "{{plug_name}}", 17 | cid: CID, 18 | edit_controller_cid: EDIT_CONTROLLER_CID, 19 | ui_initial_size: conformal_vst_wrapper::UiSize { 20 | width: 400, 21 | height: 400, 22 | }, 23 | }, 24 | factory: |_: &HostInfo| -> Component { Default::default() }, 25 | category: "Fx", 26 | bypass_id: "bypass", 27 | }] 28 | }, 29 | Info { 30 | vendor: "{{vendor_name}}", 31 | url: "{{task_marker}} add URL", 32 | email: "test@example.com", 33 | version: "1.0.0", 34 | } 35 | ); 36 | -------------------------------------------------------------------------------- /rust/ui/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "conformal_ui" 3 | version = "0.3.7" 4 | edition.workspace = true 5 | rust-version.workspace = true 6 | license = "ISC" 7 | description = "Implements a wry-based UI for audio processors. Part of the conformal audio plug-in framework." 8 | repository = "https://github.com/russellmcc/conformal" 9 | homepage = "https://russellmcc.github.io/conformal" 10 | 11 | [lints] 12 | workspace = true 13 | 14 | [dependencies] 15 | base64 = "0.22.1" 16 | conformal_component = { version = "0.3.6", path = "../component" } 17 | conformal_core = { version = "0.3.7", path = "../core" } 18 | wry = { version = "0.40.0", features = ["devtools"] } 19 | conformal_preferences = { version = "0.3.6", path = "../preferences" } 20 | serde = { version = "1.0.193", features = ["derive"] } 21 | serde_bytes = "0.11.14" 22 | rmp-serde = "1.1.2" 23 | mime_guess = "2.0.4" 24 | 25 | [target.'cfg(target_os = "macos")'.dependencies] 26 | conformal_macos_bundle = { version = "0.3.5", path = "../macos-bundle" } 27 | 28 | [dev-dependencies] 29 | conformal_preferences = { version = "0.3.6", path = "../preferences", features = [ 30 | "test-utils" 31 | ] } 32 | -------------------------------------------------------------------------------- /web/plugin/src/protocol/index.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { default as GenericTransport } from "../transport"; 3 | 4 | export const Value = z.union([ 5 | z.object({ numeric: z.number() }), 6 | z.object({ string: z.string() }), 7 | z.object({ bool: z.boolean() }), 8 | z.object({ bytes: z.instanceof(Uint8Array) }), 9 | ]); 10 | export type Value = z.infer; 11 | 12 | export const Request = z.union([ 13 | z.object({ 14 | m: z.literal("subscribe"), 15 | path: z.string(), 16 | }), 17 | z.object({ 18 | m: z.literal("unsubscribe"), 19 | path: z.string(), 20 | }), 21 | z.object({ 22 | m: z.literal("set"), 23 | path: z.string(), 24 | value: Value, 25 | }), 26 | ]); 27 | 28 | export type Request = z.infer; 29 | 30 | export const Response = z.union([ 31 | z.object({ 32 | m: z.literal("values"), 33 | values: z.record(Value), 34 | }), 35 | z.object({ 36 | m: z.literal("subscribe_error"), 37 | path: z.string(), 38 | }), 39 | ]); 40 | 41 | export type Response = z.infer; 42 | export type Transport = GenericTransport; 43 | -------------------------------------------------------------------------------- /rust/vst-wrapper/src/parameters.rs: -------------------------------------------------------------------------------- 1 | // Generally we _expect_ truncation here, so allow it. 2 | #[allow(clippy::cast_possible_truncation)] 3 | pub fn convert_numeric(value: f64, valid_range: &std::ops::RangeInclusive) -> f32 { 4 | (value as f32).clamp(0.0, 1.0) * (valid_range.end() - valid_range.start()) + valid_range.start() 5 | } 6 | 7 | pub fn normalize_numeric(value: f32, valid_range: &std::ops::RangeInclusive) -> f64 { 8 | ((value.clamp(*valid_range.start(), *valid_range.end()) - valid_range.start()) 9 | / (valid_range.end() - valid_range.start())) 10 | .into() 11 | } 12 | 13 | // Generally we _expect_ truncation here, so allow it. 14 | #[allow(clippy::cast_possible_truncation)] 15 | pub fn convert_enum(value: f64, count: u32) -> u32 { 16 | ((value.clamp(0.0, 1.0) * (f64::from(count))).floor() as u32).min(count - 1) 17 | } 18 | 19 | pub fn normalize_enum(value: u32, count: u32) -> f64 { 20 | (f64::from(value.clamp(0, count - 1))) / (f64::from(count - 1)) 21 | } 22 | 23 | pub fn convert_switch(value: f64) -> bool { 24 | value > 0.5 25 | } 26 | 27 | pub fn normalize_switch(value: bool) -> f64 { 28 | if value { 1.0 } else { 0.0 } 29 | } 30 | -------------------------------------------------------------------------------- /web/plugin/src/ui_state_provider.tsx: -------------------------------------------------------------------------------- 1 | import { Codec, context, UiStateData } from "./ui_state"; 2 | import { atom } from "jotai"; 3 | import { useStores } from "./stores_react"; 4 | 5 | /** 6 | * Provides the ui state to the component tree. 7 | * 8 | * Use the `useUiStateAtom` hook to get the atom for the ui state. 9 | * 10 | * Note that this requires a `Provider` to be present to use the store. 11 | */ 12 | export const UiStateProvider = ({ 13 | codec, 14 | children, 15 | }: { 16 | codec: Codec; 17 | children: React.ReactNode; 18 | }) => { 19 | const rawState = useStores().bytes("ui-state"); 20 | const stateAtom = atom( 21 | (get) => { 22 | const raw = get(rawState); 23 | if (raw instanceof Promise) { 24 | return undefined; 25 | } 26 | try { 27 | return codec.decode(raw); 28 | } catch { 29 | return undefined; 30 | } 31 | }, 32 | (_get, set, update: T) => { 33 | const raw = codec.encode(update); 34 | set(rawState, raw); 35 | }, 36 | ); 37 | const state: UiStateData = { atom: stateAtom }; 38 | return {children}; 39 | }; 40 | -------------------------------------------------------------------------------- /web/create/src/config.ts: -------------------------------------------------------------------------------- 1 | import { ConfigMetadata, stampTemplate } from "@conformal/stamp"; 2 | import { 3 | Config as PlugConfig, 4 | metadatas as plugMetadatas, 5 | toTemplate, 6 | postBuild as plugPostBuild, 7 | } from "@conformal/create-plugin"; 8 | import { $ } from "bun"; 9 | import path from "node:path"; 10 | 11 | export type Config = { 12 | proj_slug: string; 13 | } & PlugConfig; 14 | 15 | export const metadatas: Record = { 16 | ...plugMetadatas, 17 | proj_slug: { 18 | prompt: "Project slug (lower snake_case, e.g. `my_project`)", 19 | description: "Slug for the project in lower snake_case, e.g. `my_project`", 20 | default: "my_project", 21 | positional: true, 22 | }, 23 | }; 24 | 25 | export const postBuild = async ( 26 | config: Config, 27 | env: Record, 28 | root?: string, 29 | ) => { 30 | const template = await toTemplate(config); 31 | const dest = 32 | root === undefined ? config.proj_slug : path.join(root, config.proj_slug); 33 | 34 | await stampTemplate(dest, template, env, { merge: true }); 35 | 36 | await plugPostBuild(dest, config); 37 | 38 | await $`git init`.cwd(dest); 39 | }; 40 | -------------------------------------------------------------------------------- /web/scripts/src/workspaceRoot.ts: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | import { access } from "node:fs/promises"; 3 | 4 | const directoryExists = async (dir: string) => { 5 | try { 6 | await access(dir); 7 | return true; 8 | } catch { 9 | return false; 10 | } 11 | }; 12 | 13 | export const findWorkspaceRoot = async (dir: string) => { 14 | // Since we don't have an api to actually get the workspace root, we 15 | // rather crawl up trying to find a file named `bun.lockb`. 16 | let last = null; 17 | while (dir !== last) { 18 | last = dir; 19 | if ( 20 | (await Bun.file(path.join(dir, "bun.lockb")).exists()) || 21 | (await Bun.file(path.join(dir, "bun.lock")).exists()) 22 | ) { 23 | return dir; 24 | } 25 | dir = path.dirname(dir); 26 | } 27 | 28 | // If that didn't work, assume _this file_ is installed in the workspace. 29 | last = null; 30 | dir = import.meta.dir; 31 | while (dir !== last) { 32 | last = dir; 33 | if (await directoryExists(path.join(dir, "node_modules"))) { 34 | return dir; 35 | } 36 | dir = path.dirname(dir); 37 | } 38 | 39 | throw new Error("Could not find workspace root!"); 40 | }; 41 | -------------------------------------------------------------------------------- /web/scripts/src/webScript.ts: -------------------------------------------------------------------------------- 1 | // This command is not used directly, but rather is used to create the `web-*` actions that run on a specific sub-library. 2 | 3 | import runShell from "./runShell"; 4 | import { Command } from "@commander-js/extra-typings"; 5 | 6 | export const execute = async ( 7 | whichPackage: string | undefined, 8 | script: string, 9 | args: string[], 10 | ) => { 11 | whichPackage ??= "*"; 12 | if (whichPackage.includes("*")) { 13 | await runShell(["bun", "run", "--filter", whichPackage, script, ...args]); 14 | } else { 15 | await runShell(["bun", "run", script, ...args], { 16 | cwd: `web/${whichPackage}`, 17 | }); 18 | } 19 | }; 20 | 21 | export const addWebScriptCommand = (command: Command): void => { 22 | command 23 | .command("web-script") 24 | .description( 25 | "Run a script defined in a specific web-package. If no package is provided, it will run on all packages that define the script.", 26 | ) 27 | .requiredOption("-s, --script