diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-03-25 10:43:29 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-03-25 11:25:05 +0000 |
| commit | 7cb862f6f6079509dafd466fff83c719cb2fd89e (patch) | |
| tree | 843f92c4d4b2507e88a525b7c56c29d343958e5b /lib/midi/launchctl.moon | |
| parent | Value -> Value/Event/IO-Stream (diff) | |
| download | alive-7cb862f6f6079509dafd466fff83c719cb2fd89e.tar.gz alive-7cb862f6f6079509dafd466fff83c719cb2fd89e.zip | |
new core.base.match, update lib
Diffstat (limited to 'lib/midi/launchctl.moon')
| -rw-r--r-- | lib/midi/launchctl.moon | 133 |
1 files changed, 98 insertions, 35 deletions
diff --git a/lib/midi/launchctl.moon b/lib/midi/launchctl.moon index 37ccb82..1e33cc4 100644 --- a/lib/midi/launchctl.moon +++ b/lib/midi/launchctl.moon @@ -1,15 +1,15 @@ -import Value, Op, Input, match from require 'core.base' +import ValueStream, EventStream, Op, Input, val, evt from require 'core.base' import apply_range, bit from require 'lib.midi.core' import bor, lshift from bit unpack or= table.unpack color = (r, g) -> bit.bor 12, r, (bit.lshift g, 4) -cc_seq = Value.meta +cc_seq = ValueStream.meta meta: name: 'cc-seq' summary: "MIDI CC-Sequencer." - examples: { '(launchctl/cc-seq port i start chan [steps [range]])' } + examples: { '(launchctl/cc-seq [port] i start chan [steps [range]])' } description: " returns the value for the i-th step steps (buttons starting from start). steps defaults to 8. @@ -23,22 +23,21 @@ range can be one of: - (num) [ 0 - num[" value: class extends Op - new: => super 'num' - - setup: (inputs) => - { port, i, start, - chan, steps, range } = match 'midi/port num num num num? any?', inputs + num = val.num + pattern = -evt['midi/port'] + num + num + num + -num + -(val.str + num) + setup: (inputs, scope) => + { port, i, start, chan, steps, range } = pattern\match inputs super - port: Input.io port - i: Input.value i - start: Input.value start - chan: Input.value chan - steps: Input.value steps or Value.num 8 - range: Input.value range or Value.str 'uni' + port: Input.hot port or scope\get '*ctrl*' + i: Input.hot i + start: Input.hot start + chan: Input.hot chan + steps: Input.hot steps or ValueStream.num 8 + range: Input.hot range or ValueStream.str 'uni' - if not @out\unwrap! - @out\set apply_range @inputs.range, 0 + @state or= {} + @out or= ValueStream 'num', apply_range @inputs.range, 0 tick: => { :port, :i, :start, :chan, :steps, :range } = @inputs @@ -52,7 +51,7 @@ range can be one of: curr_i = i! % #@state if port\dirty! changed = false - for msg in port!\receive! + for msg in *port! if msg.status == 'control-change' and msg.chan == chan! rel_i = msg.a - start! if rel_i >= 0 and rel_i < #@state @@ -62,29 +61,28 @@ range can be one of: else @out\set apply_range range, @state[curr_i+1] -gate_seq = Value.meta +gate_seq = ValueStream.meta meta: name: 'gate-seq' summary: "MIDI Gate-Sequencer." - examples: { '(launchctl/gate-seq port i start chan [steps])' } + examples: { '(launchctl/gate-seq [port] i start chan [steps])' } description: " -returns `true` or `false` for the `i`-th note-button (MIDI-notes starting from +Send `true` or `false` for the `i`-th note-button (MIDI-notes starting from `start`). `steps` defaults to 8." value: class extends Op - new: => - super 'bool', false - @state = {} - - setup: (inputs) => - { port, i, start, chan, steps } = match 'midi/port num num num num?', inputs + pattern = -evt['midi/port'] + val.num + val.num + val.num + -val.num + setup: (inputs, scope) => + @out or= ValueStream 'bool' + @state or= {} + { port, i, start, chan, steps } = pattern\match inputs super - port: Input.io port - i: Input.value i - start: Input.value start - chan: Input.value chan - steps: Input.value steps or Value.num 8 + port: Input.hot port or scope\get '*ctrl*' + i: Input.hot i + start: Input.hot start + chan: Input.hot chan + steps: Input.hot steps or ValueStream.num 8 light = (set, active) -> set = if set then 'S' else ' ' @@ -96,8 +94,8 @@ returns `true` or `false` for the `i`-th note-button (MIDI-notes starting from when 'SA' then 3, 1 display: (i, active) => - { :port, :start, :chan } = @unwrap_all! - port\send 'note-on', chan, (start + i), light @state[i+1], active + start, chan = @inputs.start!, @inputs.chan! + @inputs.port.stream\send 'note-on', chan, (start + i), light @state[i+1], active tick: => { :port, :i, :start, :chan, :steps } = @inputs @@ -111,7 +109,7 @@ returns `true` or `false` for the `i`-th note-button (MIDI-notes starting from curr_i = i! % #@state if port\dirty! - for msg in port!\receive! + for msg in *port! if msg.status == 'note-on' and msg.chan == chan! rel_i = msg.a - start! if rel_i >= 0 and rel_i < #@state @@ -126,7 +124,72 @@ returns `true` or `false` for the `i`-th note-button (MIDI-notes starting from @out\set @state[curr_i+1] +trig_seq = ValueStream.meta + meta: + name: 'trig-seq' + summary: "MIDI Trigger-Sequencer." + examples: { '(launchctl/trig-seq [port] i start chan [steps])' } + description: " +Send bangs for the `i`-th note-button (MIDI-notes starting from `start`). +`steps` defaults to 8." + + value: class extends Op + pattern = -evt['midi/port'] + val.num + val.num + val.num + -val.num + setup: (inputs, scope) => + @out or= EventStream 'bang' + @state or= {} + { port, i, start, chan, steps } = pattern\match inputs + + super + port: Input.hot port or scope\get '*ctrl*' + i: Input.hot i + start: Input.hot start + chan: Input.hot chan + steps: Input.hot steps or ValueStream.num 8 + + light = (set, active) -> + set = if set then 'S' else ' ' + active = if active then 'A' else ' ' + color switch set .. active + when ' ' then 0, 0 + when ' A' then 1, 1 + when 'S ' then 1, 0 + when 'SA' then 3, 1 + + display: (i, active) => + start, chan = @inputs.start!, @inputs.chan! + @inputs.port.stream\send 'note-on', chan, (start + i), light @state[i+1], active + + tick: => + { :port, :i, :start, :chan, :steps } = @inputs + + if steps\dirty! + while steps! > #@state + table.insert @state, false + while steps! < #@state + table.remove @state + + curr_i = i! % #@state + + if port\dirty! + for msg in *port! + if msg.status == 'note-on' and msg.chan == chan! + rel_i = msg.a - start! + if rel_i >= 0 and rel_i < #@state + @state[rel_i+1] = not @state[rel_i+1] + @display rel_i, rel_i == curr_i + + if i\dirty! + prev_i = (curr_i - 1) % #@state + + @display curr_i, true + @display prev_i, false + + if @state[curr_i+1] + @out\add true + { - 'gate-seq': gate_seq 'cc-seq': cc_seq + 'gate-seq': gate_seq + 'trig-seq': trig_seq } |
