3.5 KiB
date
date |
---|
2025-06-27 16:54 |
#mimium #livecoding
mimiumでもライブコーディングがやりたいよね
一般化するとこういうモデルにならんだろうか
Tracksの部分の抜き差しだけできるのがChucKのShredシステム。
とりあえずはこれをRust実装してもいいけど、最終的にはこのモデル自体をmimium上で実装することもできそう
(不要なトラックの削除と空きスロット再利用を実現するためには、普通の配列とは別に単方向リストかSlotmap的なものを作る必要がありそう)
Reducerは基本的には全てのチャンネルの加算だけでいいので滅多にいじる必要ないけど、いじりたいケースが出てくるかも
ChucKではエフェクトのテールが更新時にぶちぎれる問題があったので、それを防ぐためのPostFX Chain
各トラックごとのエフェクトのライブ切り替えとかも実現しようと思えばできるかな
...これ、結局SuperColliderのJITLibと同じことかもな
jitlib_basic_concepts_01 | SuperCollider 3.14.0-dev Help
信号処理の状態持ち越し
Incremental Functional Reactive Programmingの仕組みを用いることはできるだろうか
//これが
fn dsp(){
delay(100,100,input)+ delay(200,200,input)
}
//こう更新されるとする
fn dsp(){
delay(300,300,input) + delay(100,100,input)+ delay(200,200,input)
}
delay(100)
にはID(delay_1)が、delay(200)
にはID(delay_2)がそれぞれつけられる
(どう増分検出してID割り振るかの仕組みは置いといて)、再コンパイル時に100と200はそのまま、新しく増えたdelay(300)にID(delay_3)
を挿入する
そうすると、StateStackのためのメモリは完全にリニアにはしないほうが良くて、ツリー状のデータ構造に戻した方が良さそう
Red Green Syntax TreeのGreen Node→状態メモリのマップだと考えるとわかりやすいのか?
dsp
| \
delay(1) delay(2)
から
dsp
/ | \
delay(3)delay(1) delay(2)
に更新される
//PartialEqで中身ではなくサイズを比較するようにする
struct MemoryChunk(Vec<u64>>);
enum StateNode{
FnCall(Symbol,StateTree),
Delay(MemoryChunk),
FeedBack(MemoryChunk),
}
struct StateTree{
children: SlotMap<Box<StateNode>>
}
途中でchildrenの一部が削除される可能性がある(1,2,3,4の中から2だけが削除されるケースとか)
このchildren同士の構造比較はどうするべきか?Delay、Feedbackは
かつiterateも行うのでSlotmapで良さそう Delay、feedback、Externalを区別する意味はあるのか?→たまたまサイズが同じなDelayとExternalとかはあり得るので区別必要
クロージャの呼び出しの時は?→コンパイル時ではなく、Closure命令でクロージャが作られる際にアロケートとIDの振り分けが起きる これは諦めて良さそう(適切にやりたければ多段階計算でコンパイル時に頑張れ)
あとはIDの振り方問題。dspから順番にnon-closure-callをトレースするのは同じとして
fn update_state_tree(oldtree:StateTree,newtree)->StateTree{
let state_changed = oldtree.children.iter().zip(newtree.children.iter()).all(|oldc,newc|newc == oldc)
}