First, I know this is a lot of text to parse. I've tried to break it down as simply as possible to articulate what I'm asking for. Thanks in advance for your patience and understanding as this is somewhat difficult to relay as I'm relatively new to MAX/MSP in M4L. Also I'm trying to relay the entire situation as it is now, so that includes what I've succeeded with and my strategy of what I did. This is not to toot my own horn, it's so that I can give the most information to increase the likelihood of getting help
OK so, I'm looking for a bit of help for M4L. I've built a device for my Korg MS-2000 to control it, much thanks to Rozzer! By dissecting one of his devices I was able to get something built quickly for my microKORG which translated into this MS-2000 device.
Here is a screenshot of the MS-2000 so far:

Here is a screenshot of the MS-2000 patch so far:

Here is the MS-2000 Hardware Controller MIDI Device on maxforlive.com.
I eventually want to skin it, make it open in a window so it's not stuck at the bottom and so freaking long
Regardless of my pending work, this device is fully functional as it is, just not as perfect as I want it to be. It's a hell of a lot better than nothing. .
the native integration with Live is a dream to work with as I have almost a 1:1 symbiotic relationship between my MS-2000 and Live:
- When I adjust a control in Live on the device, it sends it to the MS-2000. This includes everything NOT sysex (which props to Korg for having a lot of foresight and only putting really fiddly bits deep into sysex) e.g. CCs and NRPNs.
- When I adjust a control on the MS-2000, it sends it to Live device. So far this only works with CCs and not NRPNs from the MS-2000 (this is what I need help with)
I'm only missing NRPNs inbound from the MS-2000 to change the controls of the M4L device. e.g. if I turn on the ARP on the MS-2000 I want the M4L device to light up the ARP ON state. I think this is possible using a similar tactic that I used in a js file but I'm stumped. Except for sysex which is unsupported in M4L because Live doesn't do sysex, it's fully implemented outbound from the M4L device.
I've been able to solve the following:
- Mapping controls in M4L device to the CC outputs into MS-2000.
- Mapping controls in M4L device to NRPN outputs into MS-2000.
- Mapping controls from MS-2000 into M4L device for CCs.
Let me explain a bit.
How it works right now, I have ctlouts and ctlins for all the CC stuff, that part is easy. The NRPN approach I took was to code a js file called nrpn.js, then use receives for MSB: CC98, LSB: CC99, and VAL: CC6. The js file has an inlets to accept the VAL from the M4L UI control. When the control is adjusted it uses messnamed() function to send the NRPN values to each receive, perfect. This is elegant as I only need 2 boxes for every control to support NRPNs outbound.

There is one receive for MSB, LSB, and VAL, and they go directly to the MS-2000.

This works already, and I simply pass values to these receives through the js nrpn file like this:
Code: Select all
send_nrpn {MSB} {LSB} $1
---8<---
To elegantly solve the NRPNs inbound from the MS-2000 here is what I tried so far:
Creating a ctlin 98, ctlin 99, and ctlin 6 - these go into sends, but this isn't exactly perfect like the NRPNs output FROM M4L strategy I used because I need a conditional to only pass through the according values and filter the rest out.
So what I tried was creating receives for the MSB, LSB, and VALs, then referring to them in an if box:
Code: Select all
if $i1==0 && $i2==4 then $i3 Connected to inlet 2 is r nrpn_in_lsb
Connected to inlet 3 is r nrpn_in_val
The outlet of the if is going into the control modifier value (for example inlet 1 on a knob, or switch so if MS-2000 sends 127, in a toggle it lights up). Inlet 1 and 2 of the if are only filters to make sure that no NRPNs go in that shouldn't (I don't know a better way to do this but I'm sure this isn't perfect).
My theory is that if I send a NRPN FROM the MS-2000, it SHOULD parse each CC into the sends from the ctlins for the MSB, LSB, and VAL, and these should be received into the receives, then pass through (assuming the conditions are met) the if box to the M4L UI controls inlet to update it's value/state.
What's strange is, the if statement never emits a value. No matter what I try.
I've put watch monitors on the wires from the ctlins to the sends, they show the proper values.
I've put watch monitors on the wires from the receives into the if and those also show proper values.
HOWEVER, nothing ever comes out of the if as the watch monitor on that always shows a 0 and it never changes. EVEN THOUGH $i1 == 0 and $i2 == 4 (which is boolean true and thus $i3 should come through). The ONLY thing I can think of is that the receives aren't happening at the identical time. I read about a MAX object that will collect values into it's inlets and only bang out all of the values simultaneously when they have accumulated/changed each one from left to right (or it may have been right to left) but I cannot remember what it was called (and this is just a developers hunch anyway).
So even if my strategy worked as expected for inbound NRPNs to the M4L device, I have a concern:
If I am receiving an NRPN and updating the value of the M4L control wont that trigger a bang?
I don't want to trigger a bang right?
Would that not cause some sort of endless loop: e.g. the MS-2000 button sends the NRPN to change the control which is wired up to send the NRPN BACK to the MS-2000, if not an endless loop and the MS-2000 is smart enough to know I did not PHYSICALLY make this change, at the very least it's going to send the same message twice right?
Anyway, thanks very much in advance for the help!
*edit* Added screenshot of the patch.
