monome / norns

norns is many sound instruments.
http://monome.org
GNU General Public License v3.0
632 stars 147 forks source link

add MAP support for trigger, toggle, momentary #1182

Closed andr-ew closed 3 years ago

andr-ew commented 4 years ago

the intention here is to support midi foot-switch devices or midi buttons in PARAMS/MAP. the primary thing for me would be supporting cc messages (usually 0 for off, 127 for on, to my knowledge) but I suppose midi keys could be supported someday too.

the MAP submenu would only need to show cc, ch, dev (no in, out, accum)

again, happy to PR though I know this one is less trivial maybe

tehn commented 4 years ago

i'm not seeing a clear path on this one, can you try to elaborate?

for example, mapping a TRIG, would basically any incoming cc value call the action?

for toggle, since it's basically a TRIG with internal state, would each subsequent cc input simply flip the state and call action?

as i said in just-closed issue, you get MOMENTARY for free with OPTION already, with cc mapping.

also, do you have specific gear that has foot switches/etc? i'm wondering about standardization of cc/note behavior, and program-ability of the source device.

andr-ew commented 4 years ago

the specific implementation I'm imagining is essentially just mirroring the state of the norns key with the state of the button :

for TRIG, if cc > 63 call action for TOGGLE, if cc > 63 flip state for MOMENTARY, if cc > 63 set state = 1, else set state = 0

re: hardware I'm building a teensy thing soon but I just researched some commercial options (KMI softstep, morningstar MC6, novation launch control, akai mpk mini) and it seems like they generally ship with a config tool and offer the gated cc option proposed as well as toggles (sometimes you can set the cc number for on/off, sometimes not (?)). certainly there will be weird inconsistencies as there's not really a standard, but the gated 63 boundary thing is used by default in ableton & seems like a good place to start.

true, it can happen with option but it means the trig/tog/momentary behavior is chosen on the midi device rather than by the script author (& ambiguity in the context of metaparam-type scripting)

catfact commented 4 years ago

hm, i'm also not seeing the benefit of these specializations compared to the present behavior for control, number, option and now toggle.

maybe it would be helpful to see a minimal case study that illustrates the problem you're encountering? so far, i'm not following it. with a case study we might be able to suggest an elegant solution using existing infrastructure.

andr-ew commented 4 years ago

I am pretty much wishing to develop these features for a new implementation of wrms that uses the params in a particular way (to store all states and configure the UI library) - that might clear it up ?

catfact commented 4 years ago

by "minimal case study" i mean a small piece of code that isolates the issue, or a very specific description of what you've tried and where the pain point is.

catfact commented 4 years ago

@andr-ew i'll take a look right now at the behaviors currently accessible and see if we can't clarify that way.

but real quick, plugging in a midi kb and footswitch does lead me to recall that CC 64 is the standard for "sustain pedal." i've only ever seen 127 or 0. multiple pads and switches are typically mapped to notes and these can have whatever velocity. but this is likely beside the point.

i believe all the behaviors you want are already available, and i will try to confirm / demonstrate this, but it's also possible i'm simply not understanding your issue.

catfact commented 4 years ago

here is a little script

https://gist.github.com/catfact/9cc65031e7c75b6ad00bc6408408421b

here's what i found:

but i really don't see the purpose of trigger and momentary parameter types.

i also honestly feel that toggle doesn't quite pull its weight. a new parameter type should be powerful. i would advocate for something like a cycle type which goes through N states where N can be greater than 2.

another option would be to roll all these binary types into one, and give it behavior modifiers for latched/momentary/polarity/trigger.

BTW:

andr-ew commented 4 years ago

cool - i just wrote this little guy to help clarify part of the issue (before last @catfact post, lol)

cs = require 'controlspec'

px = 48
py = 16

function init()
  params:add{ type='control', id='cntrl', controlspec=controlspec.UNIPOLAR, 
    action=function(v) print('cntrl: ' .. v) end } 
  params:add{ type='option', id='op', options={ '1', '2', '3' }, action=function(v) print('op: ' .. v) end }

  params:add{ type='toggle', id='tog', action=function(v) print('tog: ' .. tostring(v)) end }
  params:add{ type='momentary', id='mom', action=function(v) print('mom: ' .. tostring(v)) end }

  redraw()
end

function enc(n, d)
  if n==2 then
    params:delta('cntrl', d)
  elseif n==3 then
    params:delta('op', d)
  end 
  redraw()
end

function key(n, z)
  if n==2 and z==1 then
    params:delta('tog', 1)
  elseif n==3 then
    params:set('mom', z==1)
  end
  redraw()
end

function redraw()
  screen.clear()
  screen.move(py, py)
  screen.level(15)
  screen.text('cntrl: ' .. tostring(params:get('cntrl')))
  screen.move(py + px, py)
  screen.text('op: ' .. tostring(params:get('op')))
  screen.move(py, py * 2)
  screen.level(params:get('tog') and 15 or 2)
  screen.text('tog')
  screen.move(py + px, py * 2)
  screen.level(params:get('mom') and 15 or 2)
  screen.text('mom')
  screen.update()
end

pt

so you can imagine i've got a norns screen interface and I want to be able to map that UI to a midi controller in 1-to-1 type of way. obviously for regular midi knobs, params make this real easy as there's a selection of predefined interactions with correlating mappings between encoder <-> knob. in this script, I can map a knob between cntrl & op and get the same behavior I get from the encoders. I'm interested in trying to achieve the same changeability when mapping one midi button/foot switch between tog & mom. assuming my button sends gated cc messages, I could modify this script to use option for mom and get the same behavior there, but I wouldn't get the toggle behavior when I mapped of tog. to get the same behavior as the norns interface, I'd have to modify the controller to send toggle messages.

(implementing this using midi notes would be cool with me too & probably better, just seemed like more work given what's already in place)


on another level (which you can kind of start to grok from the current wrms version) what I'm really interested in doing is making a UI 'factory' lib that can build a screen interface based on a table of params supplied in a tiny config script. in the current version I sort of built my own version of the params system that had toggle & momentary behaviors, then set up some weird callbacks to sync with some actual params for midi mapping & preset-recalling some of the things. but it would be cool to use the params system internally and kind of firm up the syntax with the familiar param style

andr-ew commented 4 years ago

I would be fond of supporting midi notes and/or building a binary mega-type !

I just implemented momentary in my fork, but yea it felt weird that momentary was almost the same as toggle outside of the menu, so maybe combining these might make more sense

catfact commented 4 years ago

i'll just repeat and summarize:

tehn commented 3 years ago

@andr-ew happy to review a PR when you have one, but i'm going to close this issue given it's a feature request and i'd like to focus the issue list on active fixes