Midi_messages2
Re-writing my old midi-event listener. Still using external command aseqdump
, but separated the reader and the parser into separate fibers.
Right now only tested on one controller (keystation 49es
).. but will make it work with oxygen 25
, KORG padKONTROL
and Zoom R16
.
I will add on event subscription via wisper
.
require 'open3'
CLIENT = 'Keystation 49es'
symbolize = ->(str) { str.tr(' ', '_').downcase.to_sym }
hashify = ->(str) { str.split(',').map { it.split(' ') }
.map {|k,v| [k.to_sym, v.to_i] }.to_h }
midi = Fiber.new {
port = `aseqdump -l`.lines(chomp: true)
.select { it.include?(CLIENT) }[0]
.then { it[/(\d+:\d+)/] ? $1 : abort('No such client') }
wr, rd = Open3.popen2("aseqdump -p #{port}"); wr.close
while line = rd.gets.chomp; Fiber.yield line end
}
parse = Fiber.new {
loop {
if /(?<event>\w+ \w+).*?\d+, (?<data>.*)$/ =~ midi.resume
Fiber.yield [symbolize[event], hashify[data]]
end
}
}
loop { p parse.resume }
Made some additions…
require 'wisper'
require 'open3'
CLIENT = 'Keystation 49es'
# CLIENT = 'R16'
symbolize = ->(str) { str.tr(' ', '_').downcase.to_sym }
hashify = ->(str) { str.split(',').map { it.split(' ') }
.map {|k,v| [k.to_sym, v.to_i] }.to_h }
midi = Fiber.new {
port = `aseqdump -l`.lines(chomp: true)
.select { it.include?(CLIENT) }[0]
.then { it[/(\d+:\d+)/] ? $1 : abort('No such client') }
wr, rd = Open3.popen2("aseqdump -p #{port}"); wr.close
while line = rd.gets.chomp; Fiber.yield line end
}
parse = Fiber.new {
include Wisper::Publisher
loop {
if /(?<event>\w+ \w+).*?(?<channel>\d+), (?<data>.*)$/ =~ midi.resume
publish(symbolize[event], hashify["channel #{channel}," + data])
end
}
}
# output all events and data
# class Lizten
# def note_on(msg) = ( p msg )
# def note_off(msg) = ( p msg )
# def control_change(msg) = ( p msg )
# def pitch_bend(msg) = ( p msg )
# end
# Wisper.subscribe(Lizten.new)
# output note-name
class Notename
def append(data)
p %w(C C♯/D♭ D D♯/E♭ E F F♯/G♭ G G♯/A♭ A A♯/B♭ B)[data[:note] % 12]
end
end
Wisper.subscribe(Notename.new, on: [:note_on, :note_off], with: :append )
loop { parse.resume }