MIDI Remote, Relative value mode

@Jochen_Trappe Can the MIDI script API be used to create a work-around? Can the raw, absolute values (those of any VST or internal Cubase parameter) be accessed via the API to allow me to do something like this?

MIDITriggerEvent(device, channel, value1, value2) {
	if (value2 ==65) {
		SelectedChannel.EQ1.level =+ 0.002;
	} else if (value2==63)  {
		SelectedChannel.EQ1.level =- 0.002;
}

Please excuse my rudimentary pseudocode. I have not yet looked into API and it’s been a minute since I coded anything in JS.

Sorry, can’t recommend that.

Well currently there are no official provisions for handling relative CC controllers. So what do you recommend?

We provide all common relative cc modes out of the box. After setting “bindToControlChange(…)” you can append “.setTypeRelativeXYZ()”
These are the options you have:

  • setTypeRelativeSignedBit
  • setTypeRelativeBinaryOffset
  • setTypeRelativeTwosComplement
1 Like

And where do I specify the scaling factor? Why would I want limit myself to a 7-bit resolution when I’m using encoders? It’s like buying a sports car and then finding out only the first two gears work.
It’s all in this thread in the first couple of posts.

Hmm, I’ll think about it. Good night! :sleeping:

You can use custom variables to develop a trigger system to scale, I had to do it for a Komplete Kontrol DAW mode mapping as the encoders were super sensitive unless the shift button was held (i.e. the smallest turn was 3 steps I believe, instead of 1.)

Very rudimentary attempt, but I first declared a constant for the scale I wanted:-

const kk_knobscale = 0.16;
//Knob public arrays
var kk_knob = new Array();  //Surface 'make' object
var kk_knob_trig = new Array();  //Surface trigger
var kk_knob_trigval = new Array(); //Surface trigger current val

Then within the surface setups I created customValueVariable’s to act as triggers, and the knobs set to absolute mode so that I could manipulate the raw values being received :-

    for (var knset = 0; knset < surfaceElements.numStrips; ++knset) {

        kk_knob.push(surface.makeKnob(0 + (2 * knset), 0, 0, 0));
        kk_knob[knset].mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(CTRL_CHAN, 80 + knset).setTypeAbsolute()

        kk_knob_trig.push(surface.makeCustomValueVariable('kk_knob_trig_' + knset))
        kk_knob_trigval.push(0.0)

        kk_knob[knset].mSurfaceValue.mOnProcessValueChange = (function (activeDevice, value) {
            kk_knob_trigval[this.knset] = kk_scaleme(kk_knob_trigval[this.knset], value);
            kk_knob_trig[this.knset].setProcessValue(activeDevice, kk_knob_trigval[this.knset]);
        }).bind({ knset })
    }

Then the kk_scaleme function just deals with the relative splits and applies the scale based on the previous value and the new value:-

function kk_scaleme(oldVal, newVal) {

    var sendVal = 0.0;
    var turnVelocity = 0;

    if (newVal > 0.5) {
        //Anticlock
        turnVelocity = (newVal - (1 + (1 / 127)));
        sendVal = oldVal + (turnVelocity * kk_knobscale);
    } else {
        //Clock
        turnVelocity = newVal;
        sendVal = oldVal + (turnVelocity * kk_knobscale);
    }
    if (sendVal < 0) { sendVal = 0; } else if (sendVal > 1) { sendVal = 1; }
    return sendVal;

}

Then for the map binds, you just use the triggers as setup, i.e.

page.makeValueBinding(kk_knob_trig[0], focus_eq.mBand1.mFreq)

If that doesn’t make sense, I’ll try and break it down into an easier/more generic example - as the above is pushing into arrays as I needed to track the states of each in a systematic nature.

4 Likes

Thank you @skijumptoes !
It doesn’t look too complicated, but I would have to tinker with it and familiarize myself with the API. But it does seem there is a workaround by scripting the remote as opposed to using the mapping assistant which I find very promising!


My controller that I’m focused on, a Midi Fighter Twister, only supports one relative mode: Relative Binary Offset (manufacturer calls it “Enc 3FH/41H”). It basically sends 065 on clockwise turns and 063 on counter clockwise turns.
My goal is to have it configured so that one “click” on the encoder represents 1dB gain +/- on an EQ.
The Twister also supports sending MIDI when pressing down on the encoder. I would like it to toggle sensitivity so that when the encoder is pressed down, one “click” now represents 0.1dB on an EQ gain e.g. (Basically toggling a scaling variable value like the kk_knobscale in your above example (so not a constant in my case)).
I’m excited to try this out and will report back my findings in this thread.
Thanks again!

1 Like

I tried to use FaderFox EC4 for remote midi control with Cubase 12 Pro using “generic remote”. The EC4 offers 16 physical endless encoders with 256 mapping pages. It worked well in relative mode with the endless encoders of EC4 in its CCR1 mode. However, for the control room I missed some topics for the metronome as click level, click panorama etc…

Thus I tried to use “MIDI remote” mapping assistant and failed completely!
The main problem is that I could not find the “Item Properties” to adjust the relative CC mode of each encoder.

How can I access this “Item Properties”?

Click Edit MIDI Controller Surface and then click one of the encoders, which should turn blue. The Knob Properties will show up to the right.

Thanks, I got it!

It would be nice to have this within the mapping assistant as with “Genric Remote” and not only visible after clicking on the virtual encoders.

Thanks @Jochen_Trappe.
Love all the work you do for the MIDI Remote and that you are active to help us out in here.

Been playing around with encoders sending relative values for a couple of hours now.
I do like it for some plugin values because it makes a lot of sense. For instance changing a bypass settings is only a single small turn, compared to an absolute fader where you have to move it all the way up or down. Or changing the slope on an EQ band will be a single turn for each value. Very efficient.

But for some other values that needs more resolution it falls through a bit.
For instance controlling selected track volume it jumps with 1db on the upper half of the volume spectrum. I just seems really only scaled, almost upper site of what you’d want (considering decibels is a logarithmic scale)

When I was counting the amount of changes I could send to various plugin, it seems to me that the highest “resolution” a plugin would receive from a knob set to TypeRelativeSignedBit is 100 steps in total, which is sadly lower then just using a regular absolute fader/encoder with 127 steps.

So just chiming in that it’s something I’d also love to see extended/improvements on.

Thanks

If you’re using the API, the resolution/steps of the encoder in one of the relative modes, depends on the JS code. You can scale it to any resolusion—10,000 steps or more if you like!

If you post your JS code I’ll show you how to increase the resolution.

Thanks @mlib :pray:

Do you mean with skijumptoes method?
I did try that at least, and as you wrote that opens up another can of worms in terms of feedback, which is also just the displayValue feedback which I’m relying on.
Or did you mean in some other way?

I actually also programmed in SoundFlow a way that converted the encoders to relative Pitchbend, and receiving the Absolute value from the MIDI remote. But a bit of a hack and you loose the concept of the encoders adapting to what ever they will be controlling.

I don’t know what method you used. I was replying specifically to this statement:

Where are you getting 100 steps from? If this is from using the API, then all I’m saying is you can increase (or decrease) how many “ticks” on your encoder it takes to go from minimum to maximum of what you’re controlling.

1 Like

I don’t know what method you used. I was replying specifically to this statement:

Well that sounds awesome! I’d love to be pointed in a direction.

This is all I do to bind the controllers:

	channelControl.pushEncoder.mEncoderValue.mMidiBinding
		.setInputPort(midiInput)
		.bindToControlChange(0, 1 + channelControl.instance)
		.setTypeRelativeSignedBit()

I don’t find more settings then this!

Where are you getting 100 steps from?

If I take a plugin like the Waves H-Delay and adjust the Feedback button, that has 200 steps, and controls it with a MIDI remote mapping, it evenly jumps 2 steps through the whole range.
And it’s basically the same, on a lot of plugins with more values.
It wasn’t a number I found anywhere, but an observation.
It holds especially true for the selected track volume. Here it seems to be even less, but maybe that’s because all the steps are connect to values below -40db…

Or did you want me to post my full script? Let me know

@saxmand Sorry for the late reply.
The idea, or work-around really, is to use customVariable and tie the encoder to that. Then you can scale the outgoing value. I’ll post some code snippets of what I have in a bit.

1 Like

That would be awesome.

I think I might have found a nice way to also get what I want through SoundFlow as well. But will need to actually work with the whole setup befor I know how it feels, and there’s still some quirks for sure. Will also share a video of that if it turns out to work well.

Thanks.

I totally agree that it is very much needed feature for encoders !
And at the same time, I understand why this stands a bit aside the MIDI control concept (-:
If Steinberg team can do something about, that’d be awesom and would really leverage the power of encoders vs. potentiometers.