How can I assign midi CC beyond the built in controls in a VSTi?

davidestevens's icon

Max 5 (I have my reasons)

I want to store the parameters of a VSTi (Linplug Alpha for now) as part of the settings of a patch using pattrstorage. I'm exposing the settings to autopattr using [textedit]. That bit's working fine.

Some of the parameters inside the VSTi don't have a default cc attached to them, but you can use the midi learn function to change that.

Here's the problem. [vst~] reports there being 68 parameters in Alpha. These are the existing default assignments, which are all in use. So to use the midi learn function to assign controllers to the additional parameters, I need to send controller/value pairs from cc69 upwards. But [vst~] doesn't respond to them! It seems that it won't accept controllers outside of the predefined (by the VSTi) range.

Is there any way around this?

Also rather odd (or perhaps not) is that the predefined plugin CC assignments bear no relationship to the CC numbers I have to send from max to control those functions! Eg - Osc 1 Waveform 1 is assigned to CC20 in the VSTi, but is controlled by CC1 from max.

(Edit - Ah - this relates to the order of the parameters when sending the params message to the VSTi. So I guess that what I'm sending aren't midi CC/value pairs, but parameter/value pairs)

davidestevens's icon

Ah. That's what it was. If I format midi cc messages instead of parameter messages, I get the results I want.

For channel 1, it's [176 cc# value], channel 2 is [177 cc# value] and so on.

The problem now is that the [get $1] message doesn't get the midi values. And recalling a preset in the VSTi doesn't send the midi values out of [vst~] either.

Is there a way to do that? Ie get the vales for all the parameters out of [vst~] in midi format (from the 5th outlet - plugin generated midi events)?

Roman Thilenius's icon

if you are lucky, and it is linear, you could request the parameters state and do expr int(($f1*127)+0.5) to get the CC state.

-110

davidestevens's icon

Do you mean a linear mapping between parameters and CC? 'fraid not - it's all over the place. e.g. param 1- CC20, param 2 - CC26, 3- 22, 4 - 28. And though there's a pattern to that, it doesn't remain consistent. (Though I _could change the assignments in the plugin. Hmmm)

Heath Robinson time - I'm trying dumping the parameter values out (using [get $1]) to a coll, and then sending them straight back (very quickly) one at a time to the vsti, which causes the midi values to be sent out of the 5th outlet (plugin generated midi). And I can then store the CC value pairs as a list in textedit ( a single list of value pairs). The odd thing now is, that although max says there are 68 parameters, I'm only getting 55 messages out of the midi outlet of [vst~]. I'm wondering if parameters set to zero aren't output. (Edit - on doing a bit of control counting, I think it's because not all of the available controls within the 68 are assigned. Could be wrong)

The other strange thing is what happens when I send the parameter values straight back from the intermediate coll into the vst (so that it outputs the midi cc values) . I should be sending back exactly what I've just output, so the virtual knobs in the plugin window shouldn't change. Except that they do!

Grrr.

dhjdhjdhj's icon

I bypassed this problem completely in my system by using only the parameter numbers and values to change things in plugins. I typically use it by feeding the CC value of a desired MIDI hardware knob into it. So I never use the MIDI learn stuff of my plugins at all.

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

I use a simple abstraction called VSTParam to make this easy.

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

Example using it

davidestevens's icon

Well, that's what I'd normally do, but in this case I want to store all of the possible settings in pattr . The Alpha has a routing matrix, the sources and destinations of which don't have default controller assignments, but they can be assigned to an unused CC. And they don't show up in the parameter list, so I can't access them that way.

dhjdhjdhj's icon

I store everything using a simple name/value dictionary in Javascript --- I was never able to figure out pattr :-)

That's interesting that they don't show up in the parameter list. Do they show up after you assign a CC? I had a similar problem (I think, based on what you have described) with UltraAnalog where it wanted to keep the MIDI mapping separate. What I found was that after I associated a CC with a particular control and then adjusted it, the [vst~] would send out the actual parameter number (and value) that was used. I could then use that parameter number from there on and not bother with the CC mapping any more. I wonder if that would help you find the parameter numbers?

davidestevens's icon

The thing using textedit to expose a vst to pattr is something I found in the examples. This is the first time I've used it, and it works great for me. I didn't know that pattr would store the contents of textedit.
Anyway...
I think my final step in this attempt is to assign some CCs to the unassigned parameters (perhaps in Cubase) and then try what you suggest - ie see if that makes any difference to the number of parameters that vst~ is aware of.
I sort of got the rather arcane method I described above working, but then realised that as there are (currently) no named parameters for the controls i want to access, I won't be able to access them using [get] anyway. If adding CCs to the vsti results in more parameters showing up in max then problem solved. If not, then the whole thing is bu**ered. (Can I say that?)

I guess I'll have to go back to using the presets menu. The odd thing about that is that I _have_ to have the vsti window open all the time, otherwise it won't respond to the preset recall message! Just out of interest, I got this from the developer (which would make more sense to a C74 guy than me) ...

About the program change not taking place, well I need to become technically here, can be if the host does not supply an "idle" call, that is, when nothing else is to do the plugin gets time to update itself (e.g. in responce to a program change request). However, I never heard of any host not doing so. If the GUI is open we have an alternative way of processing the program change. However, if we neither have our GUI being active, not getting any time to process ... we're lost (as I said, never had that case so far).

davidestevens's icon

Nope, didn't make any difference to preassign extra CCs. Max still only sees the 68 preassigned controls. :-(

Oh well. At least I learnt a thing or 2 :-)

dhjdhjdhj's icon

Two more suggestions:
1) Have you tried loading the VST with Max 6 just to see if you can see the parameters?
2) Have you tried asking the manufacturer if they have a list of the parameters?

davidestevens's icon

thanks for the suggestions -

1) I'll give that a go, just to see what happens. The problem I had with max6 is that this particular patch is pretty processor intensive, and in 6 I get a lot of distortion from overloading, which doesn't happen in max5. Maybe I need to rebuild the patch from the ground up in 6 and see if that makes any difference.

2). There's a list in the documentation - I already mapped parameters across to CCs.

davidestevens's icon

Well, unless I'm doing something really wrong, the situation is even worse in Max6 - it only seems to respond to and output midi event 144 (ie note messages). I opened the vst help patch and loaded Alpha into the object. (tab 2 - Instruments, where there's already a print object connected to the midi event out). Moving knobs in the plugin window sent nothing out of the midievent outlet, although parameter values were coming out ok. I also tried sending midi event 176 x x (i.e. CCs) and there was no response in the plugin window. :-(

And max still says 68 (used) parameters, so it doesn't look as though I can use the midi learn function to add more parameters.

dhjdhjdhj's icon

I've never looked at the MIDI out there, just the parameters.

But I just realized something. I don't know anything about that particular synth but I assume that when you set up one of those routings, all you are doing is configuring some CC to control some item in the synth for which there is an associated parameter, e.g. CC1 --> Filter Freq

Why can you not just use the parameter number for Filter Freq directly and use the example I mentioned earlier to map the CC event directly to that parameter, in other words, forget about the routing matrix completely? I think those matrices are more useful when you DON'T have a system like Max around. In other words, you can do routing (and much more sophisticated routing at that) outside of the synth.

davidestevens's icon

Ah! Now that's an idea! I'll take a look at that. thanks!

dhjdhjdhj's icon

Yeah, that's what I did for my rig and it rocks very well. Good luck.

dhjdhjdhj's icon

Did you get it working?

davidestevens's icon

There were some, um, "inconsistencies" in the way the algorithmic composer part of the patch was storing its settings that needed sorting out, so I parked the vsti preset issue for the time being and went back to my original method of simply recalling voices using the preset menu, which at least works. I'll revisit the thing soon, as there's a possibility of this instrument ending up in the hands of teachers, so recalling different voices needs to be a completely simple (ie invisible) process. That's why I was hoping to extract the vst settings and store them in max. There _are VSTi's that would work like this, but I very specifically want the kinds of sounds these 2 Linplug synths make. The composer is now working properly, so maybe I'll try the vst thing this week.

Thanks for asking!

davidestevens's icon

Just pondering the synth interface, and realising that your solution would only partially work.

Only some of the routed parameters are external CCs. Lots of them are internal routings in the synth - all the LFO routings for example. Quite important! As the synth doesn't output those (eg continuous LFO values) I wouldn't be able to route them in the patch, and I think it would end up pretty horrendous even if I could.

Never mind. If I ever find a nice sounding synth that _does output all of its parameters, I'll know how to build a storage patch around it (in fact, I saved it as a snippet).

dhjdhjdhj's icon

So when you connect an LFO to something (e.g, connect it to filter frequency), are you saying there's no parameter number representing (LFO1->FilterFreq) produced with a value representing on/off or an amount?

Have you contacted the company that makes the synth to ask them if there's such a parameter?