2.3 KiB
2.3 KiB
date |
---|
2024-10-30 15:42 |
#mimium
要件
どこまでMIDIインプットをmimiumの世界の外側として捉えるか
先行例
SuperColliderやChucKはコールバックを登録するようなイメージ
[Using MIDI | SuperCollider 3.12.2 Help](https://doc.sccode.org/Guides/UsingMIDI.html
s.boot;
(
var notes, on, off;
MIDIClient.init;
MIDIIn.connectAll;
notes = Array.newClear(128); // array has one slot per possible MIDI note
on = MIDIFunc.noteOn({ |veloc, num, chan, src|
notes[num] = Synth(\default, [\freq, num.midicps,
\amp, veloc * 0.00315]);
});
off = MIDIFunc.noteOff({ |veloc, num, chan, src|
notes[num].release;
});
q = { on.free; off.free; };
)
// when done:
q.value;
まあこれはDSPアウトプットの合成が.playで暗黙的に行える(加算で合成されるという想定)だからできることかな、、、
ChuckもボイスごとにShredを生やす方向で対応してるからちょっと微妙だ
現実的には、Faustのように、ボイスアロケーターは外側で実装してしまい、非同期に更新されうるAtomicな値のセルをノートやccのデータとして受け取れるようにすれば当面は十分
が、最終的にはMIDIエフェクト(MIDI信号自体のディレイやクォンタイズ、スロットリングとか)をFUnctional Reactive Programmingっぽく書けると嬉しい
Noteのバインドの記法
let channel:()->float = bind_midi_note_mono(channel)
channel() //値の取り出し
//rust
fn bind_midi_note_mono(vm:&mut Machine)->ReturnCode{
let ch = vm.get_stack(0)
}
IOの順序保証とか考える
正格評価だとIOモナドとかはそもそも考える必要がない
type 'a io = unit -> 'a
純粋な値は以下のようなIOモナドにリフトできる。let return x = fun () -> x
計算はバインド演算子によってつなげることができる。let (>>=) c1 c2 = fun () -> c2 (c1 ())
mimiumだとバインド演算子ってこうか(ジェネリクスが必要だけども)
fn bind(f1,f2){
| | f1() |> f2
}