diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-03-01 17:44:56 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-03-01 17:46:04 +0000 |
| commit | a1312100fad100190e20b1b3443b5cd962dc8999 (patch) | |
| tree | 8fc6194fc4b326ee39a9ca6d798cd208664f5fc3 /lib/midi | |
| parent | add type-pattern matching language (diff) | |
| download | alive-a1312100fad100190e20b1b3443b5cd962dc8999.tar.gz alive-a1312100fad100190e20b1b3443b5cd962dc8999.zip | |
new op interface part one
Diffstat (limited to 'lib/midi')
| -rw-r--r-- | lib/midi/core.moon | 66 | ||||
| -rw-r--r-- | lib/midi/init.moon | 50 |
2 files changed, 59 insertions, 57 deletions
diff --git a/lib/midi/core.moon b/lib/midi/core.moon index 7f661ed..3bf47a9 100644 --- a/lib/midi/core.moon +++ b/lib/midi/core.moon @@ -1,6 +1,8 @@ import RtMidiIn, RtMidiOut, RtMidi from require 'luartmidi' import band, bor, lshift, rshift from require 'bit32' import Op, Registry from require 'core' +import ValueInput, EventInput from require 'core.base' +import match from require 'core.pattern' MIDI = { [0x9]: 'note-on' @@ -62,58 +64,58 @@ class MidiPort class input extends Op @doc: "(midi/input name) - create a MIDI input port" - new: => - super 'midi/port' - @impulses = { Registry.active!.kr } + new: => super 'midi/port' - setup: (params) => - super params - @assert_types 'str' + setup: (inputs) => + { name } = match 'str', inputs + super + name: ValueInput name + root: EventInput Registry.active!.kr - tick: (first) => - { name } = @inputs - if first or name\dirty! - @out\set MidiPort find_port RtMidiIn, name\unwrap! + tick: => + if @inputs.name\dirty! + @out\set MidiPort find_port RtMidiIn, @inputs.name! @out\unwrap!\tick! class output extends Op @doc: "(midi/output name) - create a MIDI output port" - new: => - super 'midi/port' + new: => super 'midi/port' + + setup: (inputs) => + { name } = match 'str', inputs + super + name: ValueInput name + root: EventInput Registry.active!.kr - setup: (params) => - super params - @assert_types 'str' + tick: => + if @inputs.name\dirty! + @out\set MidiPort nil, find_port RtMidiOut, @inputs.name! - tick: (first) => - { name } = @inputs - if first or name\dirty! - @out\set MidiPort nil, find_port RtMidiOut, name\unwrap! + @out\unwrap!\tick! class inout extends Op @doc: "(midi/inout inname outname) - create a bidirectional MIDI port" - new: => - super 'midi/port' - @impulses = { Registry.active!.kr } - - setup: (params) => - super params - @assert_types 'str', 'str' + new: => super 'midi/port' - tick: (first) => - { inp, out } = @inputs + setup: (inputs) => + { inp, out } = match 'str, str', inputs + super + inp: ValueInput inp + out: ValueInput out + root: EventInput Registry.active!.kr - if first or inp\dirty! or out\dirty! - inp, out = inp\unwrap!, out\unwrap! - @out\set MidiPort (find_port RtMidiIn, inp), (find_port RtMidiOut, out) + tick: => + { :inp, :out } = @inputs + if inp\dirty! or out\dirty! + @out\set MidiPort (find_port RtMidiIn, inp!), (find_port RtMidiOut, out!) @out\unwrap!\tick! apply_range = (range, val) -> - if range.type == 'str' + if range\type! == 'str' switch range\unwrap! when 'raw' then val when 'uni' then val / 128 diff --git a/lib/midi/init.moon b/lib/midi/init.moon index b0f2f6a..0cbe5e0 100644 --- a/lib/midi/init.moon +++ b/lib/midi/init.moon @@ -1,5 +1,7 @@ import Value, Op from require 'core' import input, output, inout, apply_range from require 'lib.midi.core' +import ValueInput, EventInput from require 'core.base' +import match from require 'core.pattern' class gate extends Op @doc: "(midi/gate port note [chan]) - gate from note-on and note-off messages" @@ -7,18 +9,21 @@ class gate extends Op new: => super 'bool', false - setup: (params) => - super params - @inputs[3] or= Value.num -1 - @assert_types 'midi/port', 'num', 'num' - @impulses = { @inputs[1]\unwrap! } + setup: (inputs) => + { port, note, chan } = match '=midi/port num num?', inputs + super + port: EventInput port.value! + note: ValueInput note + chan: ValueInput chan or Value.num -1 tick: => - local port, note, chan - { port, note, chan } = [i\unwrap! for i in *@inputs] + { port, note, chan } = @inputs + + if note\dirty! or chan\dirty! + @out\set false for msg in port\receive! - if msg.a == note and (chan == -1 or msg.chan == chan) + if msg.a == note! and (chan == -1 or msg.chan == chan!) if msg.status == 'note-on' @out\set true elseif msg.status == 'note-off' @@ -37,30 +42,25 @@ range can be one of: new: => super 'num' - destroy: => - dispatch\detach @mask if @mask - setup: (params) => - super params - @inputs[3] or= Value.num -1 - @inputs[4] or= Value.str 'uni' - assert #@inputs == 4 - assert @inputs[4].type == 'num' or @inputs[4].type == 'str' - @assert_types 'midi/port', 'num', 'num' - @impulses = { @inputs[1]\unwrap! } + setup: (inputs) => + { port, cc, chan, range } = match '=midi/port num num? any?', inputs + super + port: EventInput port.value! + cc: ValueInput cc + chan: ValueInput chan or Value.num -1 + range: ValueInput range or Value.str 'uni' if not @out\unwrap! - @out\set apply_range @inputs[4], 0 + @out\set apply_range @inputs.range, 0 tick: => - local port, cc, chan - { port, cc, chan } = [i\unwrap! for i in *@inputs] - + { port, cc, chan, range } = @inputs for msg in port\receive! if msg.status == 'control-change' and - (chan == -1 or msg.chan == chan) and - msg.a == cc - @out\set apply_range @inputs[4], msg.b + (chan == -1 or msg.chan == chan!) and + msg.a == cc! + @out\set apply_range range, msg.b { :input |
