5.0 KiB
date
date |
---|
2025-07-01 18:43 |
#mimium
マルチスレッド前提の場合、Shared State全般がRwLockとかで包まれることになってしまう
しかし、大概の場合グローバルな状態共有はAtomicな単一パラメーターで済む
あくまで、普通のグローバル変数宣言はスレッドローカルな扱いにして、メインスレッドと協調しないといけない場合は"shared"みたいなキーワードをつけるようにするとか(構文増やしたくないけど)
だし、これだと結局OSC送るサーバークライアント構成と実質的に変わらないかも
let hoge = 100;
みたいなのの代わりに、別のキーワードを持たせる
global hoge = 100
プリミティブな型であれば、Atomicな書き換えでOK。hogeへの書き込みをオーディオコンテキストの中でやると毎サンプル実行される保証がない、みたいな仕様?
タプルとか合成型だと、マルチスレッドで書き換えたときに片方のパラメーターが更新されてない時に読み取られる可能性が厳密にはある
グローバルに宣言された配列型とか、合成型をどうやって扱う?
単に、グローバルな値への書き込みがいつ行われるか保証はされませんよ、という仕様にするならそれでも十分か
もしくは、
let hoge = param(100)
みたいなラップの仕方を考える。hogeはParam<Number>
型をもち、Number型に自動キャストできる。
パラメトリックフィルタ複製で、個々の周波数を外側からコントロールしたいとするとどうなるか
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<T>
の中身をレコード型にすればいいのか
paramがジェネリックな関数T->Param<T>
であることが重要になってくる。範囲の制限とかはRanged型みたいなのをmimium側で定義すればよくなる・・・はずまあIO周りは結局命令型になるのかなあ
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種類があれば十分か
ParamよりControllerの方が良くないか
Parameterは単に関数の引数という意味合いにもとれてしまう
Inputだとプログラムの入力という意味は伝わりやすいが、オーディオインプットとの区別がつきづらくなってしまう
ので、Controllerがわかりやすいかもしれない
mimiumのレコード型の実装と組み合わせる
デフォルト実装、関数のデフォルト引数の組み合わせに対して自動でパラメーターが作られるようにしたい
//自動キャストとジェネリクスの組み合わせさえうまくいけばこのくらいのことはできそう
let p = controller({..});
fn dsp(){
p |>
|gate = 0,freq = 1000,gain = 1.0|{
...//do something
}
}
これを実行すると、隠れレコード構造体定義とグローバルなデフォルト引数が作られる
...
type defaultarg = {
gate:number = 0,
freq:number = 1000,
gain:number = 1.0
}
let p = param(defaultarg::default());//p is higher order function
fn dsp(){
mysynth(p())
}
dsp内でmysynth({..})
と実行してしまうと、これがグローバルなコンテキストで作られない可能性がある・・のか?いや、でも基本的に書き換えられる心配はないからいいのかな
デフォルト引数構造体のインスタンスは必ずグローバル評価で行う、だとパラメトリックな生成はできないし問題起きそう
mimiumの多段階計算と組み合わせる
controller
関数がジェネリックなCode
型を返す関数であれば、関数内に直接埋め込むこともできそう
//これが
fn dsp(){
controller!({..})
|> |gate = 0,freq = 1000,gain = 1.0|{
...//do something
}
}
//こう展開される(本当にジェネリックにできるかは要検討)
fn dsp(){
__get_generated_controller_value(uuid)
|> |gate = 0,freq = 1000,gain = 1.0|{
...//do something
}
}