マルチスレッド前提の場合、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種類があれば十分か
mimiumのレコード型のデフォルト実装、関数のデフォルト引数の組み合わせに対して自動でパラメーターが作られるようにしたい
fn gen_synthesizer(){
let s = |gate = 0,freq=1000,gain = 1.0|{
...
}
s({..})
}
let mysynth = gen_synthesizer();
fn dsp(){
mysynth()
}
これを実行すると、隠れレコード構造体定義とグローバルなデフォルト引数が作られる
...
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({..})
と実行してしまうと、これがグローバルなコンテキストで作られない可能性がある・・のか?いや、でも基本的に書き換えられる心配はないからいいのかな
デフォルト引数構造体のインスタンスは必ずグローバル評価で行う、だとパラメトリックな生成はできないし問題起きそう
//自動キャストとジェネリクスの組み合わせさえうまくいけばこのくらいのことはできそう
let p = param({..});
fn dsp(){
p |>
|gate = 0,freq = 1000,gain = 1.0|{
...//do something
}
}
ということは、とりあえず雑にParamを実装して