aboutsummaryrefslogtreecommitdiffstats
path: root/alv-lib/midi
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2021-01-30 23:05:08 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:24:49 +0000
commit632486ca7378dc0d3e2f65c718f655c04b5a1266 (patch)
tree9fd1357e16635625fff0eeb07b9fed7caadbd990 /alv-lib/midi
parentlib: switch to losc (diff)
downloadalive-632486ca7378dc0d3e2f65c718f655c04b5a1266.tar.gz
alive-632486ca7378dc0d3e2f65c718f655c04b5a1266.zip
lib: move midi.core to _midi
Diffstat (limited to 'alv-lib/midi')
-rw-r--r--alv-lib/midi/core.moon148
1 files changed, 0 insertions, 148 deletions
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
-}