[obsidian] vault backup: 2025-11-05 15:39:21[
Some checks failed
Build / build (push) Failing after 6m18s

This commit is contained in:
2025-11-05 15:39:21 -05:00
parent 6d3faef015
commit ddbc8b6e41
2 changed files with 81 additions and 14 deletions

View File

@@ -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はヒントとして関数のラベルを受け取るような変更が考えられる。無名関数はヒントなしで頑張る
## 将来的な展望