From f554b546f5219de8bbd685c0c9e980651c5a4bcb Mon Sep 17 00:00:00 2001 From: s-ol Date: Sun, 31 Jan 2021 00:05:08 +0100 Subject: lib: move midi.core to _midi --- Makefile | 1 + alv-lib/_midi.moon | 148 +++++++++++++++++++++++++++++++++++++++++++++++++ alv-lib/midi.moon | 3 +- alv-lib/midi/core.moon | 148 ------------------------------------------------- 4 files changed, 150 insertions(+), 150 deletions(-) create mode 100644 alv-lib/_midi.moon delete mode 100644 alv-lib/midi/core.moon diff --git a/Makefile b/Makefile index 2643a30..e14f5f3 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ MODULES:=$(sort $(wildcard alv-lib/*.moon)) +MODULES:=$(filter-out $(wildcard alv-lib/_*.moon), $(MODULES)) MODULES:=$(MODULES:alv-lib/%.moon=docs/reference/module/%.html) REFERENCE=docs/reference/index.md $(sort $(wildcard docs/reference/[01]*.md)) docs/reference/builtins.html $(MODULES) REFTOC=$(REFERENCE:%.md=%.html) diff --git a/alv-lib/_midi.moon b/alv-lib/_midi.moon new file mode 100644 index 0000000..c456a01 --- /dev/null +++ b/alv-lib/_midi.moon @@ -0,0 +1,148 @@ +import Constant, T, Struct, Op, Input, T, Error, const from require 'alv.base' +import RtMidiIn, RtMidiOut, RtMidi from require 'luartmidi' + +bit = if _VERSION == 'Lua 5.4' + { + band: (a, b) -> a & b + bor: (a, b) -> a | b + lshift: (a, b) -> a << b + rshift: (a, b) -> a >> b + } +else + ok, bit = pcall require, 'bit32' + if ok then bit else require 'bit' +import band, bor, lshift, rshift from bit + +MIDI = { + [0x9]: 'note-on' + [0x8]: 'note-off' + + [0xa]: 'after-key' + [0xd]: 'after-channel' + + [0xb]: 'control-change' + [0xe]: 'pitch-bend' + [0xc]: 'program-change' +} + +rMIDI = {v,k for k,v in pairs MIDI} + +find_port = (Klass, name) -> + with Klass RtMidi.Api.UNIX_JACK + id = nil + for port=1, \getportcount! + if name == \getportname port + id = port + break + + \openport id + +class InPort + new: (@name) => + @port = find_port RtMidiIn, @name + @msgs = {} + + poll: => + @msgs = while true + delta, bytes = @port\getmessage! + break unless delta + { status, a, b } = bytes + chan = band status, 0xf + status = MIDI[rshift status, 4] + { :status, :chan, :a, :b } + + __tostring: => "[#{@name}]" + __tojson: => string.format '%q', tostring @ + +class OutPort + new: (@name) => + @port = find_port RtMidiOut, @name + + send: (status, chan, a, b) => + if 'string' == type 'status' + status = bor (lshift rMIDI[status], 4), chan + @port\sendmessage status, a, b + + __tostring: => "[#{@name}]" + __tojson: => string.format '%q', tostring @ + +class PortOp extends Op + setup: (inputs) => + super inputs + { :inp, :out } = @unwrap_all! + + if inp and out + type = Struct in: T['midi/in'], out: T['midi/out'] + @out = type\mk_const { 'in': InPort(inp), out: OutPort(out) } + elseif inp + @out = T['midi/in']\mk_const InPort inp + elseif out + @out = T['midi/out']\mk_const OutPort out + else + error "no port opened" + +input = Constant.meta + meta: + name: 'input' + summary: "Create a MIDI input port." + examples: { '(midi/input name)' } + + value: class extends PortOp + setup: (inputs) => + name = const.str\match inputs + super inp: Input.hot name + + poll: => + @.out!\poll! + false + +output = Constant.meta + meta: + name: 'output' + summary: "Create a MIDI output port." + examples: { '(midi/output name)' } + + value: class extends PortOp + setup: (inputs) => + name = const.str\match inputs + super out: Input.hot name + +port = Constant.meta + meta: + name: 'port' + summary: "Create a bidirectional MIDI port." + examples: { '(midi/port name)' } + + value: class extends PortOp + setup: (inputs) => + { inp, out } = (const.str + const.str)\match inputs + super + inp: Input.hot inp + out: Input.hot out + + poll: => + @.out!.in\poll! + false + +apply_range = (range, val) -> + if range\type! == T.str + switch range! + when 'raw' then val + when 'uni' then val / 128 + when 'bip' then val / 64 - 1 + when 'rad' then val / 64 * math.pi + when 'deg' then val / 128 * 360 + else + error Error 'argument', "unknown range '#{range!}'" + elseif range\type! == T.num + val / 128 * range! + else + error Error 'argument', "range has to be a string or number" + +{ + :input + :output + :port + :apply_range + :bit +} diff --git a/alv-lib/midi.moon b/alv-lib/midi.moon index 83fe32f..4d95163 100644 --- a/alv-lib/midi.moon +++ b/alv-lib/midi.moon @@ -1,5 +1,5 @@ import Constant, Op, Input, T, Struct, sig, evt from require 'alv.base' -import input, output, port, apply_range from require 'alv-lib.midi.core' +import input, output, port, apply_range from require 'alv-lib._midi' import monotime from require 'system' gate = Constant.meta @@ -140,7 +140,6 @@ send_notes = Constant.meta summary: "`send MIDI note events." examples: { '(midi/send-notes [port] [chan] note-events)' } description: " -`chan` can be `note-events` is a !-stream of structs with the following keys: - `pitch`: MIDI pitch (num) diff --git a/alv-lib/midi/core.moon b/alv-lib/midi/core.moon deleted file mode 100644 index c456a01..0000000 --- a/alv-lib/midi/core.moon +++ /dev/null @@ -1,148 +0,0 @@ -import Constant, T, Struct, Op, Input, T, Error, const from require 'alv.base' -import RtMidiIn, RtMidiOut, RtMidi from require 'luartmidi' - -bit = if _VERSION == 'Lua 5.4' - { - band: (a, b) -> a & b - bor: (a, b) -> a | b - lshift: (a, b) -> a << b - rshift: (a, b) -> a >> b - } -else - ok, bit = pcall require, 'bit32' - if ok then bit else require 'bit' -import band, bor, lshift, rshift from bit - -MIDI = { - [0x9]: 'note-on' - [0x8]: 'note-off' - - [0xa]: 'after-key' - [0xd]: 'after-channel' - - [0xb]: 'control-change' - [0xe]: 'pitch-bend' - [0xc]: 'program-change' -} - -rMIDI = {v,k for k,v in pairs MIDI} - -find_port = (Klass, name) -> - with Klass RtMidi.Api.UNIX_JACK - id = nil - for port=1, \getportcount! - if name == \getportname port - id = port - break - - \openport id - -class InPort - new: (@name) => - @port = find_port RtMidiIn, @name - @msgs = {} - - poll: => - @msgs = while true - delta, bytes = @port\getmessage! - break unless delta - { status, a, b } = bytes - chan = band status, 0xf - status = MIDI[rshift status, 4] - { :status, :chan, :a, :b } - - __tostring: => "[#{@name}]" - __tojson: => string.format '%q', tostring @ - -class OutPort - new: (@name) => - @port = find_port RtMidiOut, @name - - send: (status, chan, a, b) => - if 'string' == type 'status' - status = bor (lshift rMIDI[status], 4), chan - @port\sendmessage status, a, b - - __tostring: => "[#{@name}]" - __tojson: => string.format '%q', tostring @ - -class PortOp extends Op - setup: (inputs) => - super inputs - { :inp, :out } = @unwrap_all! - - if inp and out - type = Struct in: T['midi/in'], out: T['midi/out'] - @out = type\mk_const { 'in': InPort(inp), out: OutPort(out) } - elseif inp - @out = T['midi/in']\mk_const InPort inp - elseif out - @out = T['midi/out']\mk_const OutPort out - else - error "no port opened" - -input = Constant.meta - meta: - name: 'input' - summary: "Create a MIDI input port." - examples: { '(midi/input name)' } - - value: class extends PortOp - setup: (inputs) => - name = const.str\match inputs - super inp: Input.hot name - - poll: => - @.out!\poll! - false - -output = Constant.meta - meta: - name: 'output' - summary: "Create a MIDI output port." - examples: { '(midi/output name)' } - - value: class extends PortOp - setup: (inputs) => - name = const.str\match inputs - super out: Input.hot name - -port = Constant.meta - meta: - name: 'port' - summary: "Create a bidirectional MIDI port." - examples: { '(midi/port name)' } - - value: class extends PortOp - setup: (inputs) => - { inp, out } = (const.str + const.str)\match inputs - super - inp: Input.hot inp - out: Input.hot out - - poll: => - @.out!.in\poll! - false - -apply_range = (range, val) -> - if range\type! == T.str - switch range! - when 'raw' then val - when 'uni' then val / 128 - when 'bip' then val / 64 - 1 - when 'rad' then val / 64 * math.pi - when 'deg' then val / 128 * 360 - else - error Error 'argument', "unknown range '#{range!}'" - elseif range\type! == T.num - val / 128 * range! - else - error Error 'argument', "range has to be a string or number" - -{ - :input - :output - :port - :apply_range - :bit -} -- cgit v1.2.3