ardour {
["type"] = "dsp",
- name = "MIDI Monitor",
+ name = "a-MIDI Monitor",
category = "Visualization",
license = "GPLv2",
author = "Ardour Team",
local hpadding, vpadding = 4, 2
function dsp_ioconfig ()
- return { { audio_in = 0, audio_out = 0}, }
+ return { { midi_in = 1, midi_out = 1, audio_in = -1, audio_out = -1}, }
end
-function dsp_has_midi_input () return true end
-function dsp_has_midi_output () return true end
-
function dsp_params ()
return
{
{ ["type"] = "input",
name = "System messages",
doc = "If enabled, the monitor will show System Control and Real-Time messages",
- min = 0, max = 1, default = 0, toggled = true }
+ min = 0, max = 1, default = 0, toggled = true },
+ { ["type"] = "input",
+ name = "Numeric Notes",
+ doc = "If enabled, note-events displayed numerically",
+ min = 0, max = 1, default = 0, toggled = true },
}
end
end
end
-function dsp_run (_, _, n_samples)
- assert (type(midiin) == "table")
- assert (type(midiout) == "table")
-
+function dsp_runmap (bufs, in_map, out_map, n_samples, offset)
local pos = self:shmem():atomic_get_int(0)
local buffer = self:shmem():to_int(1):array()
- -- passthrough midi data, and fill the event buffer
- for i, d in pairs(midiin) do
- local ev = d["data"]
- midiout[i] = { time = d["time"], data = ev }
- pos = pos % ringsize + 1
- for j = 1, math.min(#ev,evlen) do
- buffer[(pos-1)*evlen + j] = ev[j]
- end
- for j = #ev+1, evlen do
- buffer[(pos-1)*evlen + j] = 0
+ -- passthrough all data
+ ARDOUR.DSP.process_map (bufs, in_map, out_map, n_samples, offset, ARDOUR.DataType ("audio"))
+ ARDOUR.DSP.process_map (bufs, in_map, out_map, n_samples, offset, ARDOUR.DataType ("midi"))
+
+ -- then fill the event buffer
+ local ib = in_map:get (ARDOUR.DataType ("midi"), 0) -- index of 1st midi input
+
+ if ib ~= ARDOUR.ChanMapping.Invalid then
+ local events = bufs:get_midi (ib):table () -- copy event list into a lua table
+
+ -- iterate over all MIDI events
+ for _, e in pairs (events) do
+ local ev = e:buffer():array()
+ pos = pos % ringsize + 1
+ -- copy the data
+ for j = 1, math.min(e:size(),evlen) do
+ buffer[(pos-1)*evlen + j] = ev[j]
+ end
+ -- zero unused slots
+ for j = e:size()+1, evlen do
+ buffer[(pos-1)*evlen + j] = 0
+ end
end
end
local txt = nil -- a pango context
local cursize = 0
local hex = nil
+local format_note = nil
local show_scm = nil
+function format_note_name(b)
+ return string.format ("%5s", ARDOUR.ParameterDescriptor.midi_note_name (b))
+end
+
+function format_note_num(b)
+ return string.format (hex, b)
+end
+
+
function show_midi(ctx, x, y, buffer, event)
local base = (event - 1) * evlen
- if buffer[base+1] == -1 then return end
+ if buffer[base+1] == -1 then return false end
local evtype = buffer[base + 1] >> 4
local channel = (buffer[base + 1] & 15) + 1 -- for System Common Messages this has no use
if evtype == 8 then
- txt:set_text(string.format("%02u \u{2669}Off" .. hex .. hex, channel, buffer[base+2], buffer[base+3]))
+ txt:set_text(string.format("%02u \u{2669}Off%s" .. hex, channel, format_note(buffer[base+2]), buffer[base+3]))
elseif evtype == 9 then
- txt:set_text(string.format("%02u \u{2669}On " .. hex .. hex, channel, buffer[base+2], buffer[base+3]))
+ txt:set_text(string.format("%02u \u{2669}On %s" .. hex, channel, format_note(buffer[base+2]), buffer[base+3]))
elseif evtype == 10 then
- txt:set_text(string.format("%02u \u{2669}KP " .. hex .. hex, channel, buffer[base+2], buffer[base+3]))
+ txt:set_text(string.format("%02u \u{2669}KP %s" .. hex, channel, format_note(buffer[base+2]), buffer[base+3]))
elseif evtype == 11 then
txt:set_text(string.format("%02u CC " .. hex .. hex, channel, buffer[base+2], buffer[base+3]))
elseif evtype == 12 then
txt:set_text("-- Active")
elseif message == 15 then
txt:set_text("-- Reset")
+ else
+ return false
end
+ else
+ return false
end
ctx:move_to (x, y)
txt:show_in_cairo_context (ctx)
+ return true
end
function render_inline (ctx, displaywidth, max_h)
txt = Cairo.PangoLayout (ctx, "Mono " .. cursize)
end
- if ctrl[3] > 0 then hex = " %2X" else hex = " %3u" end
+ if ctrl[3] > 0 then hex = " %02X" else hex = " %3u" end
show_scm = ctrl[4]
+ if ctrl[5] > 0 then
+ format_note = format_note_num
+ else
+ format_note = format_note_name
+ end
+
-- compute the size of the display
txt:set_text("0")
local _, lineheight = txt:get_pixel_size()
ctx:set_source_rgba (.2, .2, .2, 1.0)
ctx:fill ()
- -- print latest event
+ -- color of latest event
ctx:set_source_rgba (1.0, 1.0, 1.0, 1.0)
- show_midi(ctx, x, y, buffer, pos)
- y = y - lineheight - vpadding
- -- and remaining events
- ctx:set_source_rgba (.8, .8, .8, 1.0)
- for i = pos-1, 1, -1 do
+ -- print events
+ for i = pos, 1, -1 do
if y < 0 then break end
- show_midi(ctx, x, y, buffer, i)
- y = y - lineheight - vpadding
+ if show_midi(ctx, x, y, buffer, i) then
+ y = y - lineheight - vpadding
+ ctx:set_source_rgba (.8, .8, .8, 1.0)
+ end
end
for i = ringsize, pos+1, -1 do
if y < 0 then break end
- show_midi(ctx, x, y, buffer, i)
- y = y - lineheight - vpadding
+ if show_midi(ctx, x, y, buffer, i) then
+ y = y - lineheight - vpadding
+ ctx:set_source_rgba (.8, .8, .8, 1.0)
+ end
end
return {displaywidth, displayheight}