Minor GUI update bug in Mode Switch

JRR shop is blowing out C4’s for $400, I couldn’t resist.

jrrshop.com/catalog/mackie-c … 951be6cc27

I’m a programmer, so I decided to integrate the C4 with my MCU – asked on the Reaper forum – zero interest – so I have the rare luxury of custom coding a solution that suits my personal needs.

Because of this I went with a hard coded solution, which allows me to use the VPot switches instead of the rotary messages for things like the Bombardier Mode switch, as well as having complete control over layout / parameter placement on the surface.

I can cycle through just fine and the C4 LCD updates perfectly (I, II, III, IV, Flat) but the GUI remains stuck, until any other control (let’s say Release) is adjusted from the control surface, then the Mode Switch jumps to the correct position.

Seems like the simple matter of a missing GUI event trigger on that control alone.

Edit: – It’s a bit more complicated – going up (i.e. control surface changes from Mode I to Mode II) behaves as above – going down is strange, it seems to jump only 1 step at a time, even though it may have been moved 3 steps

Just for curiosity’s sake, could you see if VibeEQ’s frequency select knobs do the same?

I just spent an hour coding up the VibeEQ mapping, it seems to be just fine.

Actually there seems to be a very slight bug in the Hi Mid section.

Setting the value to 0.8333 sets the GUI and the plugin itself to 6.0KHz, but the string reported in FX param is still 3150.

If you then increase to 1.0 everthing (the GUI, the plugin, the reported string) all line up again at 8.0KHz.


Can anyone verify these, or am I up to my usual “stupid programmer tricks” again, having missed yet another obvious bug in my software :slight_smile:

Well, I certainly THOUGHT that we had it doing what it’s supposed to…and as far as I’m aware, the control class code for the detent knobs in Vibe EQ and Bombardier are effectively identical…I’m not sure I can explain it. It basically tracks two values…the “display” value that is only held while the mouse is down or mousewheel is being turned, and the parameter value, which only changes once the display value passes the halfway point between two detents. Once you release the mouse the display value should “snap” back to the closest available parameter value.

What events are you winding up sending to the plugin when you crank the knobs around?


It’s more than likely something stupid I’m doing at this end :slight_smile:

Basically I’m controlling the plugins from a control surface :

jrrshop.com/catalog/mackie-c … 951be6cc27

expand the picture – you’ll get the idea.

For the discreet value types (e.g. Bombardier Mode) I take advantage of the fact that the 32 VPots (rotary encoders) on the surface also have switch behavior – you depress the VPot top – it’s a typical membrane momentary.

I then use table lookup to cycle through the available values on each press – it’s much more clean and predictable than using the rotary encoder to set the discreet values:

FXSwitchParameter *BombardierMode = new FXSwitchParameter("Mode", 12, this); BombardierMode->numDiscreetValues = 5; BombardierMode->discreetValues[0] = 0.0; BombardierMode->discreetValues[1] = 0.25; BombardierMode->discreetValues[2] = 0.5; BombardierMode->discreetValues[3] = 0.75; BombardierMode->discreetValues[4] = 1.0; Bombardier->Add(BombardierMode)

or in the case of the Vibe EQ:

FXComboSwitchParameter *VibeEQMF2Freq = new FXComboSwitchParameter("MF 2 Freq", "", 5, this); VibeEQMF2Freq->numDiscreetValues = 7; VibeEQMF2Freq->discreetValues[0] = 0.0; VibeEQMF2Freq->discreetValues[1] = 0.16; VibeEQMF2Freq->discreetValues[2] = 0.33; VibeEQMF2Freq->discreetValues[3] = 0.5; VibeEQMF2Freq->discreetValues[4] = 0.66; VibeEQMF2Freq->discreetValues[5] = 0.83333; VibeEQMF2Freq->discreetValues[6] = 1.0; VibeEQ->Add(VibeEQMF2Freq)

This approach works perfectly on the Bombardier, Rocket, 1973, and Vibe EQ everywhere except the 2 chunks cited above.

I got the parameter values by breakpointing the debugger on the Reaper SDK call:

value = TrackFX_GetParam(trackSelectedForC4, FXInstances[i].index, currentFXParameter->index, &min, &max);

and I also use :

TrackFX_SetParam(trackSelectedForC4, FXIndex, index, parameterValue); TrackFX_FormatParamValue(trackSelectedForC4, FXIndex, index, parameterValue, parameterValueString, sizeof(parameterValueString));

So, for instance on the Vibe EQ:

Setting the value to 0.8333 sets the GUI and the plugin itself to 6.0KHz, but the string reported in “parameterValueString” in the code above is still 3150.

If you then increase to 1.0 everthing (the GUI, the plugin, the reported string) all line up again at 8.0KHz.

All other values work perfectly.

The Bombardier behavior is noted in an earlier post.

Just curious to find out if it’s something I’m doing wrong at this end.

Huh…if it’s just the formatted parameter string, then that’s probably in IPlug code rather than “my” code…one doesn’t explicitly set the value strings when manipulating the controls; that’s an inherited behavior from IPlug.

Re: GUI representation of controls not changing…that would pretty much have to be the control not getting marked as dirty…not knowing it needs to redraw. I’ll check with schwa and see if that’s a defect in IPlug, or (more likely) a defect in my brain. :slight_smile:


Cool, thanks for looking into it.

I am not familiar with the IPlug code and didn’t know where the division between it and your code was.

Seems strange that it shows up only in this one case, could still be something I’m doing wrong here.

RE: GUI representation – yes it feels exactly like a dirty flag not being set, or an event not triggering, that sort of thing.

Well, the IPlug code is freely available as part of the wdl libraries on Cockos’ website, if you’d care to grab it just for reference. You could do a lot worse for a bunch of utility/graphics than to use the rest of wdl, too… The control that does the frequency and mode knobs are actually a class I wrote (IDetentKnob) that inherit from the stock IPlug class IKnobMultiControl. IDetentKnob is not a part of IPlug, though…although I may go ahead and contribute it back to the project at some point.