From 01d5fbac96328c596bd39cddc14a3d759609277a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=BE=E6=B5=A6=20=E7=9F=A5=E4=B9=9F=20Matsuura=20Tomoy?= =?UTF-8?q?a?= Date: Tue, 1 Jul 2025 23:06:05 +0900 Subject: [PATCH] [obsidian] vault backup: 2025-07-01 23:06:05[ --- content/mimium.md | 1 + content/mimiumでのIOパラメーター.md | 128 ++++++++++++++++++++++++++++ content/mimiumのREPLをVMで実装.md | 126 +-------------------------- 3 files changed, 130 insertions(+), 125 deletions(-) create mode 100644 content/mimiumでのIOパラメーター.md diff --git a/content/mimium.md b/content/mimium.md index d1489106..77f10d9c 100644 --- a/content/mimium.md +++ b/content/mimium.md @@ -21,6 +21,7 @@ https://github.com/mimium-org/mimium-rs ### 理論 - [[mimiumの部分的DSP更新とFaustのondemand]] +- [[mimiumでのIOパラメーター]] ### 中間表現について diff --git a/content/mimiumでのIOパラメーター.md b/content/mimiumでのIOパラメーター.md new file mode 100644 index 00000000..61a79183 --- /dev/null +++ b/content/mimiumでのIOパラメーター.md @@ -0,0 +1,128 @@ +--- +date: 2025-07-01 18:43 +--- +#mimium + +マルチスレッド前提の場合、Shared State全般がRwLockとかで包まれることになってしまう + +しかし、大概の場合グローバルな状態共有はAtomicな単一パラメーターで済む + +あくまで、普通のグローバル変数宣言はスレッドローカルな扱いにして、メインスレッドと協調しないといけない場合は"shared"みたいなキーワードをつけるようにするとか(構文増やしたくないけど) + +だし、これだと結局OSC送るサーバークライアント構成と実質的に変わらないかも + +```rust +let hoge = 100; +``` + +みたいなのの代わりに、別のキーワードを持たせる + +```rust +global hoge = 100 +``` + +プリミティブな型であれば、Atomicな書き換えでOK。hogeへの書き込みをオーディオコンテキストの中でやると毎サンプル実行される保証がない、みたいな仕様? + +タプルとか合成型だと、マルチスレッドで書き換えたときに片方のパラメーターが更新されてない時に読み取られる可能性が厳密にはある + +グローバルに宣言された配列型とか、合成型をどうやって扱う? + +単に、グローバルな値への書き込みがいつ行われるか保証はされませんよ、という仕様にするならそれでも十分か + +もしくは、 + +```rust +let hoge = param(100) +``` + +みたいなラップの仕方を考える。hogeは`Param`型をもち、Number型に自動キャストできる。 + +パラメトリックフィルタ複製で、個々の周波数を外側からコントロールしたいとするとどうなるか + +```rust +fn replicate(n,gen){ + let g = gen(n, n*100) + if (n>0.0){ + let c = replicate(n - 1.0,gen) + | | g() + c() + }else{ + | | g() + } +} +fn mygen(freq){ + osc(freq) +} +fn gen(n,init_f){ + let channel = param("freq_%n",init_f); + | | mygen(channel) +} +let myfilter = replicate(5,gen) +fn dsp(){ + myfilter() +} +``` + +まあこうなるか 自動グループ化みたいなのできるか?実行してる関数の深さ的に`global::replicate::gen::(args)`で自動ネーミング自体は不可能ではなさそうだが/自動グループをやりたければ、`Param`の中身をレコード型にすればいいのか + +paramがジェネリックな関数`T->Param`であることが重要になってくる。範囲の制限とかはRanged型みたいなのをmimium側で定義すればよくなる・・・はずまあIO周りは結局命令型になるのかなあ + + + +```rust +let channel = param("freq_%n",init_f); +set_param("freq_%n",1000.0) +channel = 1000;// +``` + +最後の行のように、普通にAssign書き込むのもできるようにしておきたい。これできるようにするには、Assignをオーバーロードできるような型システムが必要なのかな`param(コンストラクタ)`と`get_param_name`、`get_param`、`set_param`の4種類があれば十分か + + + +[[mimiumのレコード型]]のデフォルト実装、関数のデフォルト引数の組み合わせに対して自動でパラメーターが作られるようにしたい + +```rust +fn gen_synthesizer(){ + let s = |gate = 0,freq=1000,gain = 1.0|{ + ... + } + s({..}) +} +let mysynth = gen_synthesizer(); + +fn dsp(){ + mysynth() +} + +``` + +これを実行すると、隠れレコード構造体定義とグローバルなデフォルト引数が作られる + +```rust +... +type defaultarg = { + "gate":number = 0, + "freq":number = 1000, + "gain":number = 1.0 +} +let default_arg_for_mysynth = param("mysynth",defaultarg::default()); +fn dsp(){ + mysynth() +} +``` + +dsp内で`mysynth({..})`と実行してしまうと、これがグローバルなコンテキストで作られない可能性がある・・のか?いや、でも基本的に書き換えられる心配はないからいいのかな + +デフォルト引数構造体のインスタンスは必ずグローバル評価で行う、だとパラメトリックな生成はできないし問題起きそう + +```rust +//自動キャストとジェネリクスの組み合わせさえうまくいけばこのくらいのことはできそう +let p = param({..}); +fn dsp(){ + p |> + |gate = 0,freq = 1000,gain = 1.0|{ + ...//do something + } +} +``` + +ということは、とりあえず雑にParamを実装して diff --git a/content/mimiumのREPLをVMで実装.md b/content/mimiumのREPLをVMで実装.md index 16016c30..98630d11 100644 --- a/content/mimiumのREPLをVMで実装.md +++ b/content/mimiumのREPLをVMで実装.md @@ -60,128 +60,4 @@ fn repl_001(){ シングルスレッドの場合、REPLで実行されたものは必ずオーディオドライバのブロック頭で消化 -マルチスレッド前提の場合、Shared State全般がRwLockとかで包まれることになってしまう - -しかし、大概の場合グローバルな状態共有はAtomicな単一パラメーターで済む - -あくまで、普通のグローバル変数宣言はスレッドローカルな扱いにして、メインスレッドと協調しないといけない場合は"shared"みたいなキーワードをつけるようにするとか(構文増やしたくないけど) - -だし、これだと結局OSC送るサーバークライアント構成と実質的に変わらないかも - -```rust -let hoge = 100; -``` - -みたいなのの代わりに、別のキーワードを持たせる - -```rust -global hoge = 100 -``` - -プリミティブな型であれば、Atomicな書き換えでOK。hogeへの書き込みをオーディオコンテキストの中でやると毎サンプル実行される保証がない、みたいな仕様? - -タプルとか合成型だと、マルチスレッドで書き換えたときに片方のパラメーターが更新されてない時に読み取られる可能性が厳密にはある - -グローバルに宣言された配列型とか、合成型をどうやって扱う? - -単に、グローバルな値への書き込みがいつ行われるか保証はされませんよ、という仕様にするならそれでも十分か - -もしくは、 - -```rust -let hoge = param(100) -``` - -みたいなラップの仕方を考える。hogeは`Param`型をもち、Number型に自動キャストできる。 - -パラメトリックフィルタ複製で、個々の周波数を外側からコントロールしたいとするとどうなるか - -```rust -fn replicate(n,gen){ - let g = gen(n, n*100) - if (n>0.0){ - let c = replicate(n - 1.0,gen) - | | g() + c() - }else{ - | | g() - } -} -fn mygen(freq){ - osc(freq) -} -fn gen(n,init_f){ - let channel = param("freq_%n",init_f); - | | mygen(channel) -} -let myfilter = replicate(5,gen) -fn dsp(){ - myfilter() -} -``` - -まあこうなるか 自動グループ化みたいなのできるか?実行してる関数の深さ的に`global::replicate::gen::(args)`で自動ネーミング自体は不可能ではなさそうだが/自動グループをやりたければ、`Param`の中身をレコード型にすればいいのか - -paramがジェネリックな関数`T->Param`であることが重要になってくる。範囲の制限とかはRanged型みたいなのをmimium側で定義すればよくなる・・・はずまあIO周りは結局命令型になるのかなあ - - - -```rust -let channel = param("freq_%n",init_f); -set_param("freq_%n",1000.0) -channel = 1000;// -``` - -最後の行のように、普通にAssign書き込むのもできるようにしておきたい。これできるようにするには、Assignをオーバーロードできるような型システムが必要なのかな`param(コンストラクタ)`と`get_param_name`、`get_param`、`set_param`の4種類があれば十分か - - - -[[mimiumのレコード型]]のデフォルト実装、関数のデフォルト引数の組み合わせに対して自動でパラメーターが作られるようにしたい - -```rust -fn gen_synthesizer(){ - let s = |gate = 0,freq=1000,gain = 1.0|{ - ... - } - s({..}) -} -let mysynth = gen_synthesizer(); - -fn dsp(){ - mysynth() -} - -``` - -これを実行すると、隠れレコード構造体定義とグローバルなデフォルト引数が作られる - -```rust -... -type defaultarg = { - "gate":number = 0, - "freq":number = 1000, - "gain":number = 1.0 -} -let default_arg_for_mysynth = param("mysynth",defaultarg::default()); -fn dsp(){ - mysynth() -} -``` - -dsp内で`mysynth({..})`と実行してしまうと、これがグローバルなコンテキストで作られない可能性がある・・のか?いや、でも基本的に書き換えられる心配はないからいいのかな - -デフォルト引数構造体のインスタンスは必ずグローバル評価で行う、だとパラメトリックな生成はできないし問題起きそう - -```rust -//自動キャストとジェネリクスの組み合わせさえうまくいけばこのくらいのことはできそう -let p = param({..}); -fn dsp(){ - p |> - |gate = 0,freq = 1000,gain = 1.0|{ - ...//do something - } -} -``` - - - -ということは、とりあえず雑にParamを実装して \ No newline at end of file +[[mimiumでのIOパラメーター]] \ No newline at end of file