[obsidian] vault backup: 2026-06-08 11:28:55[
All checks were successful
Build / build (push) Successful in 10m42s

This commit is contained in:
2026-06-08 11:28:55 +09:00
parent 449dcddb98
commit 289d3bbe23
2 changed files with 18 additions and 8 deletions

View File

@@ -122,20 +122,26 @@ MIDIのバイトストリームをフィルターして、ートオンオフ
最終的にはそれをHoldしてセルにして、セルをsampleして値にすれば良い
ジェネリックなholdの実装をどうするかがキモ
最終的にはMIDI inにコールバックを登録する形になるから、依存性が逆転する
なんかJSには[[midiguchi]]というライブラリがあるらしい
[[Haskell]]には[[Reactive-Banana]]使った[[ReactiveBalsa]]もある
```rust
fn voice_mono(notes:Stream<Note>){
let cell = notes |> hold({pitch:60,velocity:0})
let hold = |i|{
let cell = i
|input| {cell =input, cell}
}
let midiinput = midi_open_port("from Max 1");
let notes = midiinput |> filter_map(_,is_byte_note)
let notes_cell = notes |> voice_mono //ここまでが今のbind_midi_note_monoに相当
let notes_cell = midiinput
~> |x|filter_map(x,is_byte_note)
||> hold(_,{pitch:60,velocity:0}) //ここまでが今のbind_midi_note_monoに相当
fn dsp(){
let {pitch,velocity} = notes_cell |> sample
@@ -144,9 +150,13 @@ fn dsp(){
```
~>はHaskellの$のような、 a(b(c))を a ~> b~> cで結合弱く描けるようにする
[[Computation Expression]]使ってIOの値を`let!`でバインドしていく、とかの方がわかりやすいかも?
MIDI入力がトリガーになってクロージャのupvalueを書き換えることでCellの中身を書き換えるとなると、現実的にはオーディオスレッドとMIDIイベントスレッドを跨いでupvalueを操作することになる。`get_closure_mut`でクロージャをゲットして実行することはできるけど、その時には結局VMがオーディオスレッドにいるから、VMがクロージャ実行予約の命令を受け取るmpscチャネルを持っておいて、予約されたらオーディオブロックの頭で実行する、みたいな感じにする
Holdは組み込みの関数で、ArcSwapで包まれた値のセルを保持する
Arcでupvalueを全部包んで、closed upvalueの中身をAtomicU64にする、みたいな方法もあるにはあるが、そうするとClosureのストレージはVMそのものというよりもVMインスタンス間で共有される感じになるのかな
グローバル関数はメインスレッドで実行されて、クロージャIDを渡す
とはいえVMインスタンスがオーディオスレッドに渡ってしまうとなるとな