Insulating MIDI streams

Aaron Wharton's icon

I suppose my most pressing question would be "Is there a way to get MIDItester (found under the "Extras" menu) to only display activity based on which input is chosen? Ie. If I have a Quneo connected, I'd like to not see notes jumping around when I have it selected.

My second question is if there are any other (potentially better) ways of identifying/ locating a leak in my note stream?

Thanks,
- Aaron

Source Audio's icon

why don't you connect few max objects together to capture midi input.
needs only midiin and midiparse
if you open help file for midiparse, all is allready done for you.

Aaron Wharton's icon

Ah ok, good point. :)

I guess another (potentially better) question would be: "What are best practices for insulating MIDI streams?"

Ie. I have a potential MIDI source list of:

- Quneo
- QuNexus
- Rytm
- A4

And potential MIDI destination list of:
- Rytm
- A4
- Iridium
- Heat/ Akai MB76

I've set up all MIDI IO (mostly [notein], [noteout], [ctlin], [ctlout], etc) to use specific port names via quotations when port names utilize spaces, and used the @matchport 1 attribute on all, but I’m still getting unexpected events reaching both the Rytm and Iridium.

Source Audio's icon

You should upload that patch that routes midi.
Otherwise, I can't help you much.
I can hardly believe that any Max Midi object would
let data pass from different midi source than what it is set to listen to.
Best would be to populate umenues with both Midi Inputs
and midi outputs using midiinfo and upload that patch

Aaron Wharton's icon

I totally hear you. Yeah, I'm really not sure, either.

The reason for having yet to upload it is that it has become fairly vast, and I'm not sure how to distill it down to a smaller more manageable patch, but I'll see what I can do.

Aaron Wharton's icon

Alright, here's one part of the patch that looks totally fine to my eye.

Max Patch
Copy patch and select New From Clipboard in Max.

Source Audio's icon

I remember quite few max objects, including Vst
and midi objects having inconsequent behaviour with entered arguments
like vst plugin to load, or midi port to use.
I trust only this :

or this:


I usually do this :
store symbol for device, send it to umenu to recall that device from the
issued devices list and display OK if device is present and ok.
Otherwise post allert.

Aaron Wharton's icon

Ah ok, I see. Thanks for that. :)

Re: the usage of umenus/ message boxes -- I've read a few things about them slowing performance in the context of larger patches. Would [loadmess "FastLane USB Port B"] also suffice?

Re: [loadbang/ loadmess] -- I have experienced issues in the past where either failed to bang/ send upon loading, so I've been using a single [loadbang] > [deferlow] > [s startup] and hooking up an [r startup] to anything I need banged upon loading. I'd be curious to hear what your thoughts on this is. :)

But yeah, the end goal was to never have to worry about assigning ports a label when opening the patch, so I'd probably opt for your second option.

Source Audio's icon

I don't ever use loadmess messages to things that have to initialise first.
Like detection of midi devices.
Only after that has accomplished.
I would not even use deferlow.
For such things I use short delay to bang further messages
like midiinfo -> t b -> del 100 -> message "FastLane USB Port B"
But - I am old max user, and did not really accept - trust quite few new features
included in Max 8 - like autoupdate of connected midi devices etc.
All is fine if one sits at home in front of Max, but on the stage things must be rock solid.
That's why any of my advices will be "old fashioned".
For example to load VST plugins, I send message like :
plug "/Volumes/Hd-2/My Plugs/Big Bad Plug.vst", get -7
that tells vst object to load the plug and ask if it is Instrument.
Any answer from the plug would mean that it has loaded, and I use it to either
load it's Presets Bank, or to proceed to another vst plug to load etc.
Many max objects would properly execute comma separated instructions.
like send audio file path through message :
open $1, loop 1, 1
to sfplay~
it will open the file, activate looping and start playback.
-------
And I have never experienced any problems using messages in Max...

Roman Thilenius's icon


it is not only that you can not trust a certain patch when it comes to midi stuff, the main issue is that things can work different on different platforms/OSes.

so i also always use midiinfo and then let other object choose from an umenu or coll when the data is there.

this includes patches where i have different objects for every possible port set up already.

if you want to rely on your custom port names or use the port numbers instead is a matter of taste. both is dynamic info, both might change tomorrow.

in many situations you might want to let the user press a button to save the current setup and initialize it automatically next time.

Aaron Wharton's icon

@source audio -- "All is fine if one sits at home in front of Max, but on the stage things must be rock solid."
This is what I've been trying to attain: rock solid dependability for performances. I *really* appreciate the old-fashioned advice, and examples. :)

@roman thilenius -- With regard to my port naming + @matchport usage, my aim has been to have everything load up as desired when opening the patch, and if anything isn't plugged in or recognized, then nothing should happen, etc.

Re: "things can work different on different platforms/OSes" -- Ah ok, I hear you. Might you have an example of "letting another object choose from a umenu/ coll when data is present?"

Thank you, all. :)

Roman Thilenius's icon

i mean like in the midiinfo helpfile. like you would do it for a human user. just store stuff in a menu first, and then control things programmatically by reading from this menu.

Aaron Wharton's icon

Ah ok, I see. So perhaps something like this?

Max Patch
Copy patch and select New From Clipboard in Max.

That may be few objects too many, but it seems nice.

Re: message boxes -- Generally speaking, is there any difference between using a trigger object over a message box? ie. [t "message"] -- This is what I've been doing, similarly to {prepend] when adjusting attributes.

Aaron Wharton's icon

Well. Actually, the behavior that I'm seeking is for the [notein] to become inactive, if the desired port name isn't available. I'm not sure how to achieve that without just specifying the "port symbol + @matchport 1" in the [notein] object.

Source Audio's icon

Are you sure that matchport argument does not work ?
You can allways try something like disabling midi object
or simply inserting a gate if set midi device is not found.
I tested just out of curiosity few midi routings with matchport argument and it seemed to work.

Here is one old fashioned alert - detector using a lot of objects
and taking it's time to bang all in proper order.
You can test it setting existing to Max 2 port or non existing to Max 7 port
and loadbang the old carussel.
This is only meant as a visit to a museum ....

Max Patch
Copy patch and select New From Clipboard in Max.

Aaron Wharton's icon

Re: "Are you sure that matchport argument does not work ?"

I'm sure that it works, but I haven't been certain of how to insure that the correct port name is assigned only when it is available.

Though, I do think this is gonna suffice for my use case:

Max Patch
Copy patch and select New From Clipboard in Max.

Thanks for the alerter patch, btw; that's pretty fun. :D

Aaron Wharton's icon

Ok, another question. Is there a way to insure that events sourced from channels (other than the one selected) are filtered, or have I done something incorrect?

Max Patch
Copy patch and select New From Clipboard in Max.

Aaron Wharton's icon

Yeah, it's looking like [notein]/ [ctlin]/ etc cannot take exact port names + channel numbers as a list. Not sure why that is, but it isn't working for me, so I guess it's necessary to [pack i i i ] > [zl rot 1] > [route]. Weird.

Source Audio's icon

The patch you uploaded last does not work ...
If one selects any available port in top umenu, bang - loadbang does not disable
notein if preset port is missing.
The requested port must NOT be part of midiinfo detection.
If I understand correctly, you have a midi setup with several In and Out devices.
Then you create presets - routing this In to that midi Out, maybe rechannelising etc.
If one of the devices is not there, you want to fix that, either by alerting user
to fix that, or by selecting new port or device.
But in the patch you posted requested port is NOT permanent, and gets
overwritten by new selected Port.
I am using port and device terms because on Mac it is possible to assign several devices to one hardware midi port by midi chaining etc.
Than for example I can have on my fastlane 3 master keyboards, each sending on own channel and I select them in Max by name.

------
Back to your problem -

I would first create list of requested devices, separately for Controllers
and Midi Outputs. Store them into coll.

That can be stored as Midi Setup text file and loaded on app start in case of standalone.
On start let midiinfo list the ports and let coll dump stored devices to check if they exist in the list.
If some are missing, alert and force take action to fix that.
If all is ok show it on the screen so that one needs not to worry about.
Similar to what you did in that patch, but simpler, using only 1 umenu
and preserving requested midi devices.
-----
I have been doing such setups for far more complicated on - stage
midi routing for live setups, including midi to midi rerouting of many devices,
channelising, keyboard splits, bank and preset change etc etc.
One of the most complicated I remember was for a keyboarder having 4
keyboards and more than 20 sound devices, synths, samplers etc
2 Opcode Studio 5 units and Powerbook to control all the routings.
It took time to set every needed value but then on the stage
only Preset Name and Number was visible ...
----------
Depending on situation and what you want to do if device involved in midi routing preset
is missing one would decide how to fix that.
Either to block that routing, or to choose alternative, but then
question arrises how to do that on the stage ...
And if whatever one does overwrites the stored presets with new routing ...
Many things to consider, or ?
-------
I had some problems with enabling and disabling midi objects in new Max versions.
That used to work 100 % in Max 3-6, but at least for me in Max 8
enable status did erratic things if one selected another device for the midi object.
That's why I would rather use gate to cut the midi stream between midi links
if stored device is missing.

Aaron Wharton's icon

Re: "The requested port must NOT be part of midiinfo detection."

My apologies; I do understand this. The last patch I uploaded was using the top umenu as an option to view available ports (via prepend set) and/ or override the requested port (only if you should select one).

I should have explicitly voiced this in the post and/ or with better comments. Again, my apologies.

Last night, I went ahead and created an abstraction using that patch with the option to specify a requested port on launch via [patcherargs] and "@name", with an inlet that could let you dynamically change the requested port name, as well as outlets for forwarding the met/ unmet status and available ports.

Max Patch
Copy patch and select New From Clipboard in Max.

(For the sake of uploading, I've copied the contents of my abstraction into a subpatcher.)

Re: "I had some problems with enabling and disabling midi objects in new Max versions."

This is something I'd been curious about, as I haven't been able to find an enabled/ disabled attribute on any MIDI IO object. This is why I added the outlet for "1 = met; 0 = unmet", for both attaching a toggle for a visual cue, as well as gating output.

Re: "It took time to set every needed value but then on the stage only Preset Name and Number was visible."

Yeah, this sounds like the dream. That's awesome, man. :)

Re: "I would first create list of requested devices, separately for Controllers and Midi Outputs. Store them into coll."

Yeah, that was kinda what I was hoping to use the option to override/ dynamically change the requested port with eventually. Set up a [coll] of desired port names to send out and have the respective gates applied if ports should not be available.

Re: "I can have on my fastlane 3 master keyboards, each sending on own channel and I select them in Max by name."

I'm not sure I understand how you'd select by name rather than by channel. That is, unless you're associating names with channels via [coll]. :)

All of this said, I still am curious to know if there might be a work around for specifying a channel number through a list of "exact port name" + "channel number".

Finally, I wonder if there's a way to have Max update these met/ unmet statuses, as ports are made available or unavailable.

Source Audio's icon

bin on the run, will post you some answers and patches tomorrow.

Aaron Wharton's icon

No worries, good sir. Have a nice one. :)

Source Audio's icon

Again - problem with your patch is that that message containing midi device symbol
that you want to use will get replaced by selecting different ( temporary fix ?) port
and when patch gets saved - it's lost.
Here is test patch set to listen to midi port changes, store 4 in and 4 out devices
show if they are present or not
And to make testing easier you can create some virtual ports, select them in menu
store midi setup and delete the ports to see status changes.
P.S: virtual ports work only on Mac - windows is bad when it comes to midi
in many aspects.

Midi-Setup.zip
application/zip 6.70 KB

usage :

midistuff.mov
video/quicktime 2.96 MB

You will then find the way to use this to build gates or disablers for the
missing routings... provide path to store midi setup etc etc
If you would post a bit more infos about routings and other
actions you want, it would be easier to get idea what would be usefull
like if midiselect for inputs would be best choice as gate and enabler ...

Source Audio's icon

I had no time to answer all your questions, was a bussy week.
enable 1 or enable 0 to midi objects is not argument but message.

And about selecting devices with set channels by name : ( that MasterKeys 1 - 3 I mentioned)
I use umenu objects for that.

I had no time to implement gating into example patch I posted.
If you want I can do so, together with a bit different approach
I use for midiinfo and umenus.

Aaron Wharton's icon

Re: Problem with your patch is that that message containing midi device symbol that you want to use will get replaced by selecting different ( temporary fix ?) port and when patch gets saved - it's lost:

As a subpatcher (ie. [p]), ^this is true, but as the abstraction I've been using, it seems to recall the specified port name on every session launch via the patcher arguments written in the object.

Re: If you would post a bit more infos about routings and other actions you want, it would be easier to get idea what would be useful.

Ok, so depending on the context of my performance, I'll either have my Elektrons connected to Max through USB (easiest for gigs), or through my Midihub (home).

Connecting through Midihub allows me to use the Elektrons' USB connections strictly for recording audio onto my second computer via Overbridge.

This would explain why I've set up an option to override the requested port name. So I can use a master switch on the top layer (in presentation mode) to switch between USB ports and Midihub ports.

So my current behavior is to default to USB (via patcherargs), and then override with the switch. Thursday, I set up a comment box + [multislider] (set to horizontal orientation) to show "a red bar" across the corresponding list element when the requested port wasn't available (and gated), and show "a green bar" when the requested port was available (and not gated). So far, this has seemed to work ok, and been close to my ideal behavior.

As for the less idiosyncratic/ problematic behaviors I'm seeking:

I've set up a [notein] to allow the QuNexus to address whichever device/ channel via a couple gates + trigger objects > [pack i i i]'s.

I've set up a Quneo with [qu.parse] to control many different aspects of the entire patch.

Re: Here is test patch set to listen to MIDI port changes, store 4 in and 4 out devices show if they are present or not.

Oh whoa, this is nice. It might take a bit for me to fully sort through the machinations of this, but I really appreciate it, man. <3

Re: And about selecting devices with set channels by name : ( that MasterKeys 1 - 3 I mentioned) I use umenu objects for that.

Ah ok, I see. That makes sense. :) (And totally agreed on MIDI support on Mac vs Windows. I've been on Mac for about a decade now. :))

Re: I had no time to implement gating into example patch I posted. If you want I can do so, together with a bit different approach I use for midiinfo and umenus.

I would be curious to see that when you get a spare moment, yeah. :)

Again, I very much appreciate the help, good sir.

Sincerely,
Aaron

Source Audio's icon

In such situation, I woud prefer to store things externally, not with patcher arguments etc,
because if setup changes one can simply load another configuration bank,
including all the presets , routings etc.
That anyway needs to be done to allow swithing between different routings.

Here is a patch that inserts empty item "--" into umenu populated with midi devices.
When Midi Setup stored in coll gets recalled
it selects that empty item if device is missing and same time disables midi routing.
Either by enable $1 message or using gate.
I used enable message
This example is listing only controllers, you can easily construct same thing for outputs.

Midi-IN-Enabler.zip
application/zip 9.67 KB


You will find few other things inside...

Aaron Wharton's icon

Re: if setup changes one can simply load another configuration bank:

That's a totally fair point. I guess I've always just been a bit (irrationally) afraid of text files getting misplaced or unlinked and showing up to a gig and nothing loading up as desired.

Re: Here is a patch...:

Thank you so much for both of these, man. I've still been going through the first, and this also looks super nice.