Controller 7 filter not working as expected I think

Hi, I ran into a problem with a controller filter.

My controller keyboard will always send a controller 7 volume with a program change. I can set which level it will send though.

I whish to filter out this initial volume control level. But if i need to adjust a sound level during the song, it should receive controller 7.
I can program the keyboard to send initial controller 7 level say 01. Using the Cantabile filter, to filter only level 01, or a range from say 0 to 3, does not work as expected. It filters all controller 7 ‘s, always. I understand all the settings, and what they should do, and I tried many different approaches and setting. But it keeps filtering all controller 7’s not a range or specific level. So the conditional part seems to fail.

Below is a screenshot of an example setting I tried (filtering out a different range than in my text above, I know), it is by far not the only thing I tried. It seems impossible to filter out a small range or value, you’ll end up filtering the whole 0-127 range, with every setting. The ‘discard when out of range’ also does not work. Unless I missed something, but I think i tried everything.

Searching the forum I figured out a solution :
Filtering all controller 7’s at the input. Then creating a binding for controller 7 at that input,
passing levels 4-127 to the VSTi and discarding ie. levels 0-3.
My problem is actually multitimbral for multiple channels, so, I end up filtering all controller 7’s and then create 5 bindings to 5 channels, to still forward controller 7 the bigger range. Instead of just filtering what I don’t want.

I would feel better about the binding solution if I knew this extra overhead is super negligible. Is it?

I felt I should report this finding. Btw I think Cantabile is super awesome and I’m very thrilled it’s even possible to do anything like this. I’m a big user and advocate of it with my keyboard friends.

Actually, it works when you think more “positive” - i.e. filtering what you want to pass through, and not what you want to block.

Look at this filter:

It will let all CC7 values between 4 and 127 pass through and discard everything from 0…3.

That’s the logic of the “out of range” selection.

I put this filter inside an embedded rack between Rack MIDI in and Rack Midi Out. Here is the Midi Monitor with messages coming in and going out:

All done!




Just a quick comment on the function of the “Controller Map” filter: the general logic is that it looks for values that fall into the range you specify, and then does something to them, e.g. map them to a different range. The “Out of range” determines what Cantabile will do if the input values don’t fall into that range. Cantabile will either:

  • discard: i.e. suppress these events
  • clamp: change the value of the events to fit into the range
  • slide: adapt the range so the values fit

In your case, using “discard”, all values of CC7 will be suppressed: values 100…127 will be mapped to “none” and the rest will be discarded. But other values of “out of range” will also not help - using “clamp” or “slide”, CC7 events would be mapped to fit into the range - and then suppressed!

So, in essence: using a controller map filter to map to “none” will always suppress ALL VALUES of the respective CC. In that sense, everything is working as designed.

Essentially what is missing would be an “out of range” option of “pass through” - that way, you could map everything between 100…127 to “none” and everything else would be passed through as is. Maybe something for @brad’s backlog…




Thank you so much for your quick and clear answer!
I wouldn’t have come up with a ‘invert the filter’ solution, but it’s very clear to me now.
I just did a quick test in Cantabile and I got it to work. Now I’ll need some more time to really implement it in my setup, but now I can make it work the way I want it.

As a side effect I learned some more about the binding system and did some nice stuff with mapping the full physical range of a sloppy fader to volume 70-127 with a special curve for more precision. Incredible!

1 Like

There is a way to get around the lack of a ‘pass through’ function: use two filters and make sure that Copy Event is selected for the first one (but NOT the second one). I use this approach to create an expression/swell pedal with a ‘taper’ – technically, a linear approximation of one – for the ComboF VST. It has a great Farfisa organ emulation, but the volume pedal’s travel range greatly favors the top end of the pedal.

The first filter scales the upper third of the pedal travel, and passes the data to the next filter; this filter scales the middle third, and passes on the data. The third filter scales the bottom third, and does not pass anything on.

One could easily substitute a To: value of None in any of these three filters to eliminate that range of CC4 (my swell pedal).


1 Like

I like that! Still, it would be a lot easier if @brad could implement a pass-through option for “Out of range” - make it really simple to e.g. create a “compressor/limiter” type filter by just compressing the upper 20% of CC values. So quick request to @brad - could you put that on the backlog?

1 Like

Logged it here:

Add a passthrough option to the Controller Map CC Filter on Cantabile | Trello

fwiw: going forwards, all new features will probably be added only to the 41xx branch as I don’t want to get into maintaining two separate code bases. So this might come soon, but only on the currently experimental 41xx builds.


drawbars, nice to see your pedal range conversion construction. For fun I like to add this idea: When I was trying to solve my original post, I got to know more about the bindings, and ended up fixing a lousy controller fader, with a range conversion like yours, but different. I couldn’t get fine volume control, as the fader was electronically not precise and had a difficult curve. I wanted to use all of the physical fader range for a more usefull volume range of -20 to + 6 dB instead of -00 to +27db.
First I take out all controller 7 at the input so it doesn’t reach my target yet. Then I pick it up at a binding and route it to the destination while also adding a scale function which does what I described.
These flexible mapping curves are not available in the mapping filter near the input but they are in the bindings. I thought it would be interesting to show in this context.

Filtering controller 7 at input.

Binding that will transform it

Value setting of the binding. This makes the full fader range control only level 76 - 127 with some added precision in the top end. ( 0.6*127 = 76)

Hope this is of interest.

(Also, just yesterday I picked up a used Roland A-500 pro controller keyboard to get rid of the bad fader and the original post problem all together, so all is solved and I learned something in the process :smile: I’m done with the old A-30)

That’s a great approach, too. I think I might use something similar on a song or two somewhere in my mess; I’ll have to check. It never dawned on me to use it for an expression pedal, though!

Between Cantabile and the native support of many VSTs, there are often 3 or 4 different ways to solve a problem. I tend to use the Filter method because it’s similar to two items that I know well: the MIDI Solutions Event Processor Plus and MidiOx. But the Bindings method is perfect for situations where you want to say, add 3dB of volume to a solo part, then drop back for the rest of the song, and the curve feature can be used to make the effect seamless.

Speaking of the Event Processor Plus: This box allows one to save off the data value of a CC (or NRPN, SysEx, etc.) in 8 locations for later use. My (former) Alesis QuadraSynth insisted on setting the volume to CC7=127 on every patch change. The EP+ allowed me to remember the last CC7 setting, then send it after each PC message. So, no embarrassing volume jumps mid-song! Even MidiOx can’t do this.

Does anyone know if there is a way to accomplish this in Cantabile? If not, @Brad this is another item for the Future Features List™. :wink:


Hi Bruce,

I found a way to create memory storage of continuous CC values using embedded rack gain sliders combined with bindings. The way you set one up is fairly simple.

  • add an embedded rack for the rack make sure the correct states behaviors are selected. I renamed it to Memory One in the example. You could route from the MIDI out of the rack the stored values but I choose to use a binding(s) for that which I show later.

  • Create bindings inside the embedded rack. Inside the embedded rack I put some bindings. One that receives a CC switch message that invokes a re-sending of any bound values in the rack. In this case I am tasking the Outer Gain Slider value to a CC7 output from the rack’s MIDI out. That is the “Bound” value used for the whole deal. There is the option to use any of the gain sliders associated with the embedded rack, the Outer Gain, Output Gain & Input Gain, with the last 2 inside the rack. You could use all 3 effectively if you channelized the binding outputs as I show in the picture. I only have the Outer Gain enabled to demonstrate the simple path of one storage element.

  • At the Song level you have a number of options as to how to recall the memory and send it elsewhere. You could use a Song Load or an input from an external KB that sends a PG change or a Song State change and a host of other possibles. Also you could use a binding at song level to send value from the Memory rack to an external synth.

Anyway, that’s one take on it.

Cheers, :slight_smile:



@dave_dore Thanks, that will certainly work! I’ll use that approach for what I need, most likely triggering from a PC change. Cantabile keeps surprising me with its tricks!

I think I will still keep my future request for @Brad, though. A Filter that maps a CC value to a stored memory location would likely be better for two reasons:

  1. It would be easier for a newbie programmer (or non-programmer) to wrap one’s head around “map [store] a CC value to Memory 1” than using an embedded rack and a collection of Bindings to accomplish the same thing. This is particularly true if the problem is in external gear, rather than a VST.

  2. It would seem (to an outsider, who’s also a S/W programmer) that initializing and managing an embedded rack is a lot of Cantabile overhead to keep track of 1 or 2 7-bit data values.


Going through the backlog… coming soon, out of range “passthrough” mode: