Issue on MidiList::insertRepeatedControllerValue(...)

I was trying the
MidiList::insertRepeatedControllerValue (int type, int startVal, int endVal, juce::Range<double> beats, double intervalBeats, juce::UndoManager* um)
method the insert multiple controller events.

Now focusing on the second and third parameters ( startVal and endVal ) that i have to pass, they are limited between 0 and 127.

In the method’s body there is this line of code :
auto maxNumSteps = std::max(2, type == MidiControllerEvent::pitchWheelType ? std::abs(rangeValues) : std::abs(rangeValues) >> 7);
that takes the rangeValue = endVal - startVal ( rangeVal can at most be 127 ) and right-shift it of 7 bits given always a 0 result… so maxNumSteps is always 2 ( exept in the case of a pitchWheelType controller ).

The method then calculates the numSteps in this way :
auto numSteps = juce::roundToInt (rangeBeats / intervalBeats);
but then it compares numStep with maxNumSteps and performs numStep = maxNumSteps if the are not equals…
So the numStep is always equal to 2 and independently from rangeBeat it will create only 3 controller events!

How to deal with it ?

I think startVal and endVal are 14-bit values.
We should really add a type for this as it’s unclear currently when 7-bit and 14-bit values are used.

Yes it can be bery usefull.
So i must leftShift startVal and endVal before pass them to the method ?
For example :

  • 127 << 7 = 16.256
  • 30 << 7 = 3.840

rangeValues = 16.256 - 3.840 = 12.416, so in the method we’ll have 12.416 >>7 = 97.
Am i right ?

Yes, that’s the original range you started with.

Its done like that because all MIDI values internally are stored at 14-bit numbers as that the resolution of some MIDI numbers (e.g. pitch wheel, aftertouch IIRC). This will hopefully help us when moving to higher resolution MIDI2 values as well.

Ok perfect.
One last question : if i pass (startVal<<7) and (endVal<<7) to the method there will be some errors just because the rangeValues is correct but the value used to create the events is wrong…
Mybe i need to modify the method ?

I’m not sure I follow what will be wrong?

After evaluating the numStep value there is a loop based on it in which a value is calculated (with the interpolate method) and its value is not more included between 0 and 127, but betwenn 0<<7 and 127<<7.

for (int i = 0; i < numSteps; ++i)
        const int value = interpolate (startVal, rangeValues, beats.getStart(), beat, rangeBeats);
        addControllerEvent (beat, type, value, um);
        beat += intervalBeats;
static int interpolate (int startValue, int rangeValues, double startBeat, double beat, double rangeBeats) noexcept
    return juce::roundToInt (startValue + (rangeValues * (beat - startBeat) / rangeBeats));

So it will add controller events with an over-range values.

But addControllerEvent also expect a 14-bit number so it should be fine.

Excuse me but when i call the add controllerEvent ( for example by double clicking on the component ) i pass an int value included between 0 and 127…
So you are telling me that i must always pass a value between 0<<7 and 127<<7 ?
I’m a bit confused.

Yes. If the source is a 7 bit value (0-127) shift it up before passing it to the MidiList methods.