do you know what kind of data the midi button is sending? if it’s cc’s it should just work. if it’s note on/off the current param system doesn’t support it, but theoretically could be added via a MOD or feature addition
i just checked in the diagnostic/config software with my laptop and it appears to assign each button to a cc (outputting 127 on downpress and 0 on release)
if so i think it should just work as you mention but midi learn doesn’t seem to recognize the toggling
i did get it to work, but not via the params menu. i just added something like:
local m = midi.connect()
-- midi controls --
local function midi_control(data)
local msg = midi.to_msg(data)
if msg.type == "note_on" then
if msg.note == 1 then
-- do something
elseif msg.note == 2 then
-- do something else
-- etc
end
elseif msg.type == "note_off" then
if msg.note == 1 then
-- note off stuff here
end
elseif msg.type == "cc" then
-- the params menu can handle this
end
end
to the script i wanted to interact with.
edit:
somewhere in the init function you’ll also need
-- set the midi event function
m.event = midi_control
if the answer is, “extend the parameter mapping system to allow mapping noteons(/offs) to binary params,” it is a little complicated.
the code above is simply how you handle midi messages in a script. mods extend the norns system code which is not as ergonomic and not well documented. so it’s inherently sort of an intermediate level project.
… i’ll post some details for this particular feature in a moment.
this function actually could use some work. it doesn’t explicitly filter on the MIDI command nybble; noteons/noteoffs are processed. however, the hacky subtraction of 176 from the comand byte (to remove the 0xb_ command nybble for CCs) corrupts the so-called “channel” number when passing to the mapping command. (another issue here is misleading variable names.) i would like whoever wrote this to either explicitly test for 0xb_ and avoid passing garbage down the stack, or (much bigger ask) update the mapping module to accept all possible command bytes. (or just notes, aftertouch, CC? idk.)
anyways, the mod would have to totally redefine this function because it is not broken up at all. so not the cleanest thing for maintenance. (the mod will have to be manually updated to track any upstream changes to mapping behavior.)
i’d propose we just clean up this function and (if it’s not too gnarly) simply allow any command byte to be used for mapping. idk.
as it happens, params of type 'trigger' are not mappable. (the allow_pmap field is ignored.) that happens in the same menu/params.lua. triggers are caught by this case: norns/params.lua at main · monome/norns · GitHub
but to be mappable they would need to be processed by this one:
however, parameters declared as type 'binary' will work. (and with the default behavior setting they behave exactly like triggers.)
doing this change (“allow triggers to be mappable from the menu”) in a mod will be an even worse maintenance problem and actually i would say it’s just not a great idea. if we want that change we should just make it on main.
i just started digging into mods docs this week, so this was a super rad use-case to ponder.
fwiw, i spun up a mod which sorta abuses the current norns.menu_midi_event structure by muscling note events to fit the desired cc channels.
kinda doofy + i agree with your points, but proofing it out a bit raised some interesting design q’s – eg. should an incoming note’s velocity be considered, should note off’s always reset the parameter back to 0, etc.
oh, ok - yeah that is certainly another way to approach it. but of course there are huge issues with that. (e.g. it will break if a script uses the same midi devices at all, even for different command types.) that can be worked around with metamethods on the vports for when the script wants to set .event field… yeesh
but yeah good point that seems like a valuable way to start working out some reasonable behaviors.
this is exactly what i’m gunning for with this docs pass – the potential yeesh moments of mod development, where stuff might collide and get squashed. metamethods are a really good call – i’ll try to do a revision! thanks ezra!
revision done! @zebra , that’s what you meant, yeah? seems to work in testing, but just want to make sure i understood
well for the record - your idea (spoofing the menu midi handler) is much better and more appropriate for a mod than my very naive idea. (replacing the same handler.) gotta get in that mod frame of mind…
like i could use a general reminder - and probably docs could too - that it’s always preferable to work around the APIs of existing system modules, even if it looks like “bad architecture.” (mods are almost bad architecture by definition.)
@dan_derks in the revision it looks like you would also need to run the mod init after the script init. as is, it’s in the pre-init hook so no events will be defined. IIRC there is no post-init hook, you have to compose the script’s existing init function with the new stuff.
arg - pardon me, i missed that you already added that change.
this is of course assuming that only the script’s init function will define midi events. that’s why i suggested a metamethod. something like (totally untested etc)
function fwd_midi(data)
if midi.to_msg(data).type == "note_on" then
local ch_val = (data[1]-144)+176
norns.menu_midi_event({ch_val,data[2],data[3]},i)
--- etc...
end
end
--- dev is a vport
dev.__newindex = function(tab, key, val)
if key == 'event' then
-- `val` is a function that we need to save and call from our midi handler
-- alternatively, we could inject our code into this thing (via composition)
local g = function(data)
val(data)
fwd_midi(data)
end
tab[key] = g
end
end
-- TODO: reset the metamethod in mod cleanup
(caveat: i haven’t checked whether we are already using the __newindex metamethod on vports. if we are then it would need to compose that as well. also __newindex will not fire if there is already an event key)
code injection is a perfect use case for metamethods and i think this approach is less likely to lead to bugs since it doesn’t need to assume anything about how the script operates.
(this version shouldn’t be called after init btw, it can just live a normal life in the pre-init hook.)
Just got an Akai Midimix and would very much like to be able to assign the buttons as toggling on-off switches so gonna read this thread when less tired. My old controller had settings in the editor to make buttons toggle or momentary but the midimix doesn’t alas
Also if so would be great if the buttons could illumintate tho I’m not sure if that’s something Norns can access at all? Presumably it’s the DAW/device which controls that that generally speaking, as there’s no options in the Midimix editor for this sort of thing
hey damon @sunbeamer! louis from ig here. would it be possible for you to share details on how you managed to get the intech grid buttons work with norns? @glia and i started this thread some time ago… i’m not the only one who has trouble figuring out what to do with the editor. please take your time as i know your energy level is close to 0 but it would be fantastic if you could help us out.