Bidirectional Midi Dial for an external instrument.
I am building a device with a couple of dials that send CC messages which go to an external instrument but i want to figure out a way to make them work bidirectional so that the dials update when the corresponding control on the external instrument is tweaked. But i am running into Midi loops so the controls start to shiver when i turn either of them.
So i figured i need to stop inputs and outputs depending on where the signal comes from. When it originates from the Midi In i only need to update the dial and prevent it from sending out and when the dial iteself is turned i need the midi in messages prevented from updating the dial.
Has anyone doen that before?
I am currently figuring out how to use the 2 signal sources (dial out, cc out) to mute each other and figure i could make use of a held signal. Like an incoming cc triggers a bang that is held for a couple of ms which in turn mutes the dials output or diverts it to a not connected output. I have tried an adsr but i couldn make it work. Any ideas on this?
Just use the set message for incoming midi data. It will set the dial /live.dial without outputting any data.
Thx for the answer. I have used your tip on that here:
"Reply
live.dial does that, unfortunately, wen set messages arrive too fast. It has to do with the way it is implemented into Live. It’s a known issue by cycling, but considered a "design flaw" not a bug.
possible workaround:
– Pasted Max Patch, click to retract. –
Copy all of the following text. Then, in Max, select New From Clipboard.
btw. this "set flaw" only appears with M4L not within Max…
Best Jan"
And this solves one part of the problem. Meaning when i turn the knob on the external instrument only the dial gets updated without sending a message. Now i only need to stop the dial from receiving Midi when it is turned. Any hints on that part?
What i eventually want to do is create panels and instrument racks for every Reason device so that you can see the parameters in Push and have full bidirectional control.
to my knowledge the M4L set bug was fixed a while ago (i think it was Max 6.1.8), so you can simply rely on the set message:
Yeah you are right, just saw that piece of code in a psot of yours in a similar context and used it. The one you just pasted also works.
But as i said this solves one part of the equation, i can now turn a knob on my external device and the dial updates without sending out.
But when i turn the dial in Ableton, i still get the Midi loop, so i either need to make Reason not send when it receives Midi (not sure if possible since it receives on the rewire channel and sends through a different Midi Port via a Remote Codec) or which i would prefer handle that within the Maxforlive patch and stop the dial from reciving Midi when it is tweaked. Though i am not sure if that is possible without messing everything up.
I feel like i am one little step away from having a really nice Reason integration.
Update. I have now put a gate between the incoming CC that is moving the dial which gets opened and closed by a toggle and now both directions work depending on the toggle.
Now i think i only need to make the gate close when i turn the dial (maybe with a bit of a hold time) and open when the dial is not tweaked. But that takes me to my initial problem :-)
not quite sure is i understand... the loop should break at your dial object if the signal chain is set this way:
"move dial" -> "send data to external control" -> "external control sends back to dial" -> "dial receives set message" -> "end of loop"
It is currently like this:
move fader on external instrument-> dial gets updated-> nothing gets send out by it-> end of loop (perfect)
But:
move dial-> midi gets send out-> fader on external instrument receives and moves -> fader sends Midi Back-> Midi gets through to the dial-> dial starts to shiver-> Midi Loop
"Midi gets through to the dial" that shouldn't happen if all incoming data sent to the dial with a set message (see my example patch above, it works though the moved dial receives the set messages when moved).
I am probably missing something...
After applying your suggestion with the "set $1" before the dials input, the dial stopped sending when it was getting values to its In-socket and was moved by that. Before the change it would have sent Midi.
But it still sends Midi when moving it directly (and it should do that) but it should not receive or block anything on its in sockets while moving it directly. THAT is the last bit i need.
I will post my patch later on maybe then it clears up.
When i put a mousefilter (gates when mouse is clicked) before the dials inlet the problem is gone for mouse operation BUT when i tweak that parameter on the Push it is still there. Omg, getting nearer and nearer but still not quite there ;-)
The whole problems wouldnt be there if i could differenceate between different midiports but as i learned i cannot withtin maxforlive. But that gets me to a complicated idea. I can make Reason send different CC values to what it receives maybe i can use that... Never thought this could be so complicated.
Still thinking about gating the input on dial move though i think that twists everything up so that nothing moves anymore.
So here is how far i got.
The Problem i am still having is when the dial gets controlled by push (and probably by Abletons automation) because then i get a Midi Loop which results in a shivering dial.
Thx to the mousefilter the dial now works without the Midi Loop when used with the mouse - it only sends out Midi to the external Instrument and blocks any incoming Midi.
When the corresponding external control is moved, Midi is entering the patch and due to the set $ only the dial gets updated but it doesnt send, so no Midi Loop here either.
But when the dial is being controlled by push it updates AND sends Midi which results in Midi coming back in and the Midi Loop comes up.
I must find a way to get around this Midi Loop because the whole reason to do this is to have the parameters in Push.
I wonder if you can detect in the patch if a dial is being controlled by Push or by the ableton automation so i could gate the incoming midi in that case?
Finally I got it! The problem is the delay in the feedback of the MIDI messages. When the values arrive back to your device the dial has moved already a lot and will jump back.
Something like this should work also for automation etc:
(not super sleek 'cause it's based on timimg, but the solution that just popped up)
update the gate arguments should be [gate 1 1] (not [gate 1]) to ensure it is open on device load.
Man, it is working nicely. Thank you so much!
Hello,
me again. There is a problem still existing. When i have 2 ore more dials like in the below example Cutoff (CC55) and Resonance (CC78) then when i tweak Resonance after a while Cutoff jumps to 55 (or whatever CC it was set to THAT CC Number). It doesnt send out the 55 to the Midi Out and there is no value of 55 coming from Reason.
I must have done something wrong implementing your Code as it is obvious that somewhere CC Value and CC Number are mixed in the process. Can you have a look again?
Edit, found something and i think the only addition i did to the patch is causing it - the match clause which is meant to distribute the incoming CCs to the right dial. When i slowly turn Resonance one by one coming from 127 then as soon as i hit 55 Cutoff jumps to 78! So i assume my CC Filter (match 55 nn) is not working as i expect it to work? It is really weird though when i observe the values coming into the match 55 nn and what it forwards then there is 78 56 incoming (coming from 55) and 55 78 output?? At least i found something after 2 hours of testing and searching. My head explodes ;-) This should be solvable, hopefully.