• ### solution for midi-style patchbay (MS20 usb controller)

Hi,

I got a MS20 controller and I have finally come around to try to make it work with Pd. For starter I would like to create a patch where the 34 jack patchbay and the knobs work as with the original software. The patchbay generates midi cc triggered by the patch chords in a specific sequence.

Question 1: I would like to have something like a list or an array with two elements for each index slot. Then a search or compare function where I can find what is connected to what.

Question 2. Creating the matrix for routing signals in the upcoming synth... I guess there are good and less good ways to go about it? Any suggestions is appreciated!

• Posts 16 | Views 1734
• @cfry

1. [text]
2. [matrix~] ..... from the iemmatrix library.

David.

• @whale-av

if I would give each jack the the three states of :

0 = not connected
same = cable inserted (index 2 = 2)
other value = connected to this jack (index 2 = 4 means 2 and 4 are connected)

Then all I need is [list], right?

I made a proof of concept. But it will be a lot of connections to cover all possible patching...

Could I avoid making all these connections "by hand" by using [matrix~]? Or what would be the benefit? ...or in combination with [snake~] ?

• @cfry The catch with your [list store] solution is jack 0 would always have jack inserted in it, but you can fix that by just making no connection be -1 instead of zero. I would use text since we can store more information this way, jack per line with s or r or the audio counterparts and the unique symbol. Now a simple abstraction can do it all for you.

So a jack is inserted we get the appropriate line from the text, other side is inserted and we get that line, pack the four symbols in the appropriate order and dynamically create the abstraction with [obj 10 10 abs \$1 \$2 \$3 \$4(, and it creates the appropriate send and receive or what ever. When disconnect happens just grab the symbol and send a bang to <that-symbol>-kill and it deletes the abstraction. This also makes the prepatched modular style of the ms-20 easy, just send the default connections to be made at startup. And we can simply check if it is a valid connection as well, not connecting two outputs or mixing data and audio, etc or treat such things as jack inserted but no connection.

The one catch is that you need to have logic to avoid duplicate connections since if 2 is connected to 4 that also means 4 is connected to 2 and using sends and receives this way means you can created duplicate connections and each duplicate doubles the data sent, if you have two of the same connections that means you get 4 copies of the data sent.

Edit: Previous edit about issues with the abstraction idea was an error in my thinking, abstraction will work fine for this.

• Could you please show me how this is done? I have a hard time grasping dynamic patching.

Also, how do you suggest using text? Would it only store current patching as two values or would it be set up similar to a list with each line and a single value is used? That is why I skipped using text, I have not figured out how to use it in the best way.

I made a simulation of how the CCs are coming in. It's pretty wild, will need to clean them up a bit.

ms-20-list-pachbay-txt.pd

• @cfry This should at least mostly work, not completely clear on how the patch panel of the MS-20 controller works or your exact intentions so I made some assumptions. It assumes sane connections and will fail if you try to connect two outs or two ins because of how the message is constructed and it does not check for duplicates which is a good thing if the controller allows the use of y-cables. It also assumes disconnects happen before a connect, which should be safe since you can not plug something into a jack without first unplugging what is there unless it works with stackable cables and in which case this is a good thing.

pb.pd
dynpb.pd
I left off the [load bang] so you can step through everything and watch it happen and see what is going on and send it incorrect messages and see what happens, etc. Open [text define \$0pb], click {clear( to load the defaults then click step 4 times and watch how the [text] is updated. Now the float atoms at the top are connected and changing the values in the top two changes the values of the bottom two. Start work through the six list boxes top to bottom and see what happens in the text and too the float atoms. You should be able to sort it out fairly quickly with the help of some {print]s and/or list boxes, the logic is fairly direct.

I have the [text] formatted as jack number being line number, its connection status as you did in your [list store] version but -1 instead of 0, followed by default connection (possibly not needed depending on how the MS20 works, does it send the default prepatched connection after a disconnect?), s or r to say if it is an input or an output and then a send or receive symbol without the \$0. The \$0 being added to the symbols externally means we can stick this all in an abstraction and just send the parents \$0 to the right inlet of the three [list \$0] and still have everything work as it should. The [iemguts/sendcanvas] should probably be replaced with a send to a subpatch and a subpatch to send too, I did it that way so you can see what happens as it happens.

• Amazing, thank you so much. Indeed it was better to do this with dynamic patching. It works really good.

I made a version with a synth just to try it out:

pb-synth.pd

-The original software can't use stackable cables but I think it can be possible on the controller end. Will find out.

-To me it seems like when you init the patching for the text object r and s should switch places. r works as s and s works as r at the moment. Maybe [route s r] or [list store r 0 s 0 0] should be adjusted but I don't get the patch fully yet so I do not want to randomly change things. Working on it though.

-Some of the patch points on the controller are "audio", simulating an audio connection. Can this be done with dynamic patching too? For example using [s~ ] [r~ ] or does it have to be another solution?

-My intention is to make a (sort of) replica of the ms20 as per functions but not necessarily sound wise. Then exchange objects to make it sound better, if need be. I hope to learn something more on general synthesis along the way. I can also imagine just using the patchbay/controller for some completely different routing and synthesis. That is why I think it is great that there is the "default connections" option, for further use. I do not think the controller works like that though. I also would like to try to combine this setup with control data from other things and sensors through arduino/serial usb connections.

• @cfry The s and r can be reversed if you want. The [obj 10 \$5 dynpb \$1 \$2 \$3 \$4( message is just creating an instance of dynpb with \$1-4 as its arguments, the abstraction has two object boxes [\$1 \$2] and \$3 \$4] which on creation get expanded to that arguments, I just did it in the order I created the objects when I patched up the abstraction so all the dollar arguments would be the same between the message and the abstraction, you can change these as you feel fit as long as you make sure r <symbol> end up in the first object of the abstraction and s <symbol> end up in the second.

No problem with s~ and r~, just add them to the routes and pass the list from the [text] foreward so we can set the first and third items of the [list store] as well, something like this but without the error in the message like I did, setting the wrong index.

And you can add in throw~ and catch~ if they suit a task better.

• @cfry [matrix~] will allow stacked connections, and with a fade time set you can avoid clicks without adding a [line~] to all of your [*~ ] objects...... argument3 set to 1 for the cyclone version....
It would also allow different levels to be sent to jacks stacked on an output, but that might get too complicated.

I think it should make the patch build easier, but @oid's logic would need to send different messages for connect/disconnect.
You would simply connect all your jacks to the inputs and outputs of [matrix~] and send it the messages.

I use it for a 64in x 64out mixer on stage and replacing it with multiple abstractions would have been a nightmare.
The cyclone version will dump all the settings on command, which could be useful, but @oid has really taken care of the storage already.
David.

• @whale-av I looked at [matrix] but I couldn't figure out how to use all the eggs(!) and eyes(!) etc. I would assume you use the same principles in [matrix~] ( or [mtx_*~] ) Could one use [matrix~] with control values too or should one then use two parallell matrixes?

Do you mind giving me an example on how to set this up? Re-route some objects in control and signal domain from input to output?

Are @oid dynamic object solution combinable with this approach? I could try both anyway. Is either one less mean on the cpu? If possible I would like to put the code on a raspberry pi later on.

The controller can do a dump of the current physical patching and knob values but it is of course great to be able to save multiple presets.

thank you for your input this is so cool.

• @oid said:

No problem with s~ and r~, just add them to the routes and pass the list from the [text] foreward so we can set the first and third items of the [list store] as well, something like this but without the error in the message like I did, setting the wrong index.

And you can add in throw~ and catch~ if they suit a task better.

Sorry but I can not figure out where to put this :/ The pd.pd abstraction looks slightly different. It looks like you have merged what was previously two paths with parallel [route] objects.

EDIT: I managed to set up some logic to make the controller ccs work with this setup. Seem promising!

• @cfry Yes.....
I had forgotten that it is the cyclone [matrix~] that I use as it is simpler for the messages.
So if you can install it then try this....... example.pd
The messages are simply setting the level at which inputs and outputs are connected, but using 100 and 0 is effectively on and off.

If the cyclone version is not available for your os then let me know and I will try to work out the strange messages for the iemmatrix version and post an example for that.
David.

• @cfry said:

Sorry but I can not figure out where to put this :/ The pd.pd abstraction looks slightly different. It looks like you have merged what was previously two paths with parallel [route] objects.

I just showed one of those parallel paths since they are identical other than where the [route]s go and the [set( messages, one side handles send and send~ and the other side handles receive and receive~ and send it to the appropriate [set( message so the correct elements of the list are edited. Here it is merged as a single path with the [obj( message tweaked to work with the new data flow.
pb1.pd

Edit: lots of mistakes fixed.

• @oid thanks for the update. Its really cool but I got a lot of errors from Pd not finding a matching send/receive and that was sort of expected, but it also only works if you enable disable connections in a specific way. Try my version with the synth to see what I mean:

oid-pb1-synth.pd

I think Pd disables the r~/s~ if it accidentally becomes duplicates of the s~.
...why can not Pd have a single send and receive object that accepts both multiple sends and receives at the same time... but I am just guessing what the problem may be.

EDIT: Would it make sense to mix the dynamic patch approach with using cyclones matrix~ for signal domain and vanilla s/r for control domain?

• @cfry Right, as I said in the post where I first posted the patch, I assumed sane connections, that a jack would have to be unplugged before something else could be plugged into it. The logic will work with y-cables and stackable cables but only the logic as things stand and that is only because I skipped error checking because of the assumption I made about sanity. I left some work for you to do. [throw~] and [catch~] don't complain as much as [s~] and [r~] do and are generally less annoying to work with. And there is maybe some external with none of the multiple defined issues, no clue.

This method and [marix~] can be mixed, just replace the symbol with what [matrix~] wants and rewire the s~ and r~ outets of the [sel]/[route] as needed.

• @oid Allright, I will try to do some safety net to make sure connections are sane. That should do it. Thank you so much for your cool patch I will continue working on understanding it!

Posts 16 | Views 1734
Internal error.

Oops! Looks like something went wrong!