X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=scripts%2Fmidimon.lua;h=7f58fd34de74de8b38c21b566164d3fa1b13760e;hb=2bb22d2a14ead4e14bc842237219a893e1226980;hp=9c8df8bf8c77681b332641557d37fed5853b9423;hpb=1f08503ada66ea3a699140adcbafddd71eb9ad95;p=ardour.git diff --git a/scripts/midimon.lua b/scripts/midimon.lua index 9c8df8bf8c..7f58fd34de 100644 --- a/scripts/midimon.lua +++ b/scripts/midimon.lua @@ -1,6 +1,6 @@ ardour { ["type"] = "dsp", - name = "MIDI Monitor", + name = "a-MIDI Monitor", category = "Visualization", license = "GPLv2", author = "Ardour Team", @@ -13,12 +13,9 @@ local evlen = 3 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 { @@ -37,7 +34,11 @@ function dsp_params () { ["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 @@ -53,23 +54,32 @@ function dsp_init (rate) 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 @@ -81,19 +91,29 @@ 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 @@ -126,10 +146,15 @@ function show_midi(ctx, x, y, buffer, event) 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) @@ -143,9 +168,15 @@ 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() @@ -159,22 +190,23 @@ function render_inline (ctx, displaywidth, max_h) 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}