diff --git a/content/関数型信号処理プログラミング言語のソース変更時に内部状態を差分保持するシステム.md b/content/関数型信号処理プログラミング言語のソース変更時に内部状態を差分保持するシステム.md index 462cbd40..510c6988 100644 --- a/content/関数型信号処理プログラミング言語のソース変更時に内部状態を差分保持するシステム.md +++ b/content/関数型信号処理プログラミング言語のソース変更時に内部状態を差分保持するシステム.md @@ -68,16 +68,45 @@ Memは1サンプルのみのディレイであるため、最終的な計算結 その後、木構造の比較を行い、必要な差分変更処理のパッチを作成する。 +(ここまではオーディオスレッドをブロックせずに実行可能) 古い内部メモリと木構造にパッチを適用し、新しいメモリへ必要なデータをコピーする。 信号処理インスタンスを、新たに確保したメモリと共にオーディオバッファ処理の間に入れ替える。 ## 問題点 -差分処理を実行している間に内部状態が更新されてはいけない。なので、新しいソースコードのパースや内部状態構造導出、VMコード生成までは非同期で行えるが、木の比較にはじまる状態更新処理中はオーディオ処理全てを一度中断しなくてはならない。 +差分処理を実行している間に内部状態が更新されてはいけない。なので、新しいソースコードのパースや内部状態構造導出、VMコード生成、木の比較までは非同期で行えるが、コピー中はオーディオ処理全てを一度中断しなくてはならない。 構造が大きくなった時にドロップアウトしないか。木のサイズでざっくりベンチを取りたい。バッファサイズの参考にできるはず +たまたま入れ替えた時に、引き継いではいけないはずのデータを引き継ぐ可能性がある。 + +```rust +fn osc(freq){ + let phase = samplerate/freq + (self+phase)%1.0 |> sin +} +fn myfreq(){ + 1000 + osc(1.0)*100 //oscは1Feedを持つ +} +fn myamp(){ + (osc(1.0)+1.0) / 2 +} +//変更前 +fn dsp(){ + osc(myfreq()) +} +//変更後 +fn dsp(){ + osc(1000)*myamp() +} +``` + +上のサンプルでは、はじめlfoを使って周波数をモジュレーションしている状態から、周波数は固定にして音量をモジュレーションする処理へと切り替えた例である。myfreq()とmyamp()はそれぞれどちらもosc関数を1度だけ呼び出すため、dsp関数の内部状態ツリーの構成は共通しており、再コンパイル時にデータが引き継がれる。 +この時、myampにはmyfreqの最後の位相が引き継がれることになるが、これは特に望ましいというわけではない(どうでもよさそうではあるけど) + +myfreqとmyampをそれぞれselfを使って個別に実装していた場合、値の範囲がおかしくなるkのう + ## 将来的な展望