From b61976c14cc5ed805fb283eea31378323fc6fc84 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: Wed, 5 Nov 2025 15:39:21 -0500 Subject: [PATCH] [obsidian] vault backup: 2025-11-05 15:39:21[ --- ...ィブプログラミングのによる信号処理のライブコーディング.md | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/content/多段階計算と増分関数型リアクティブプログラミングのによる信号処理のライブコーディング.md b/content/多段階計算と増分関数型リアクティブプログラミングのによる信号処理のライブコーディング.md index 039903c0..1b8a86f4 100644 --- a/content/多段階計算と増分関数型リアクティブプログラミングのによる信号処理のライブコーディング.md +++ b/content/多段階計算と増分関数型リアクティブプログラミングのによる信号処理のライブコーディング.md @@ -120,37 +120,47 @@ fn osc(freq){ 構造が大きくなった時にドロップアウトしないか。木のサイズでざっくりベンチを取りたい。バッファサイズの参考にできるはず -たまたま入れ替えた時に、引き継いではいけないはずのデータを引き継ぐ可能性がある。 +最長共通部分列の仕様上、`osc1()+osc2()`から`osc2()+osc1()`への変更のような、明らかに問題のない入れ替えでもどちらか片方しか引き継がれない。また、どちらが引き継がれるかはLCSのバックトラックの戦略に依存する。ツリーのノードの子の種類として、順序の関係ない集合、ある集合とを区別するようにすれば実現できるかも。 +関連して、引き継いではいけないはずのデータを引き継ぐ可能性がある。 ```rust -fn osc(freq){ - let phase = samplerate/freq - (self+phase)%1.0 |> sin +fn phasor1(freq){ //0 ~ samplerate/freq + (self+1.0)% (samplerate/freq) +} +fn osc1(freq){ + phasor1(freq)*freq/samplerate |> sin } fn myfreq(){ - 1000 + osc(1.0)*100 //oscは1Feedを持つ + 1000 + osc1(1.0)*100 //myfreqはFncall[FnCall[Feed]]を持つ +} +fn phasor2(freq){ //0 ~ 1 + (self+freq/samplerate)% 1.0 +} +fn osc2(freq){ + phasor2(freq) |> sin } fn myamp(){ - (osc(1.0)+1.0) / 2 + (osc2(1.0)+1.0) / 2 //myampもFncall[FnCall[Feed]] } + //変更前 -fn dsp(){ - osc(myfreq()) +fn dsp(){ //dspはFncall[Fncall[FnCall[Feed]],Fncall[Feed]] + let f = myfreq() + osc2(f) } //変更後 -fn dsp(){ - osc(1000)*myamp() +fn dsp(){//dspはFncall[Fncall[FnCall[Feed]],Fncall[Feed]]で変化なし + myamp() * osc2(1000) } ``` 上のサンプルでは、はじめlfoを使って周波数をモジュレーションしている状態から、周波数は固定にして音量をモジュレーションする処理へと切り替えた例である。myfreq()とmyamp()はそれぞれどちらもosc関数を1度だけ呼び出すため、dsp関数の内部状態ツリーの構成は共通しており、再コンパイル時にデータが引き継がれる。 -この時、myampにはmyfreqの最後の位相が引き継がれることになるが、これは特に望ましいというわけではない(どうでもよさそうではあるけど) +この時、myampにはmyfreqの最後の位相が引き継がれることになるが、今回実装しているphasor1はselfに保存される値が0~samplerate/freq、例えば1000Hzなら0~48の値のレンジを取り、これがmyampの中で使われているphasor2のselfのその値の本来のレンジは0~1であるべきにも関わらず引き継がれてしまう。 -myfreqとmyampをそれぞれselfを使って個別に実装していた場合、値の範囲がおかしくなる可能性がある。 -ツリー構築の際に、関数ラベルをつけるようにすればいいが、ラベルのネーミング方法に一貫性がないとダメ -親の関数名+child1,2,3...みたいにすれば多分大丈夫。 +ツリー構築の際に、FnCallはヒントとして関数のラベルを受け取るような変更が考えられる。無名関数はヒントなしで頑張る。 + ## 将来的な展望