aboutsummaryrefslogtreecommitdiffstats
path: root/lib/midi
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-03-01 17:44:56 +0000
committers-ol <s-ol@users.noreply.github.com>2020-03-01 17:46:04 +0000
commita1312100fad100190e20b1b3443b5cd962dc8999 (patch)
tree8fc6194fc4b326ee39a9ca6d798cd208664f5fc3 /lib/midi
parentadd type-pattern matching language (diff)
downloadalive-a1312100fad100190e20b1b3443b5cd962dc8999.tar.gz
alive-a1312100fad100190e20b1b3443b5cd962dc8999.zip
new op interface part one
Diffstat (limited to 'lib/midi')
-rw-r--r--lib/midi/core.moon66
-rw-r--r--lib/midi/init.moon50
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