# MPEInstrument in Bitwig: Zone-Pitch-Range 14-bit MIDI bug and assertion

**URL:** <https://forum.juce.com/t/mpeinstrument-in-bitwig-zone-pitch-range-14-bit-midi-bug-and-assertion/67862>\
**Category:** Audio Plugins\
**Created:** [December 29, 2025, 12:38pm UTC](https://forum.juce.com/t/mpeinstrument-in-bitwig-zone-pitch-range-14-bit-midi-bug-and-assertion/67862 "2025-12-29T12:38:33Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![kunz](https://avatars.discourse-cdn.com/v4/letter/k/f19dbf/32.png) [@kunz](https://forum.juce.com/u/kunz)\
**Post date:** [December 29, 2025, 12:38pm UTC](https://forum.juce.com/t/mpeinstrument-in-bitwig-zone-pitch-range-14-bit-midi-bug-and-assertion/67862/1 "2025-12-29T12:38:33Z")

</div>

JUCE 8.0.11 / reproduced in Bitwig 5.3.1 and 5.3.13 (actual)

We have an MPE plugin, and when we load it in Bitwig, it hits the following assertion:

```auto
void MPEZoneLayout::checkAndLimitZoneParameters (int minValue, int maxValue,
                                                 int& valueToCheckAndLimit) noexcept
{
    if (valueToCheckAndLimit < minValue || valueToCheckAndLimit > maxValue)
    {
        // if you hit this, one of the parameters you supplied for this zone
        // was not within the allowed range!
        // we fit this back into the allowed range here to maintain a valid
        // state for the zone, but probably the resulting zone is not what you
        // wanted it to be!
        jassertfalse;

        valueToCheckAndLimit = jlimit (minValue, maxValue, valueToCheckAndLimit);
    }
}

```

This is because Bitwig also sends the zone range as 14-bit value, and JUCE directly uses this to set the zones, which leads to an invalid pitch range. For 48 semitones, it is 6144 semitones:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/3X/a/b/ab4cac0a7cb7cae27b6b8ab72f067ac30851ea79.png)

Some calculation is required for 14-bit values to get the semitones range. I think this is a bug in the JUCE code.

It should be easy to reproduce this when duplicating a track that contains the loaded MPE plugin. Or when loading a session that contains an MPE plugin. In this cases Bitwig sends these MPE MIDI messages.

Any help welcome!

---

<div class="post-metadata">

**Author:** ![kunz](https://avatars.discourse-cdn.com/v4/letter/k/f19dbf/32.png) [@kunz](https://forum.juce.com/u/kunz)\
**Post date:** [December 29, 2025, 1:43pm UTC](https://forum.juce.com/t/mpeinstrument-in-bitwig-zone-pitch-range-14-bit-midi-bug-and-assertion/67862/2 "2025-12-29T13:43:36Z")

</div>

Something like this would be a temporary fix. Probably we should also consider floating point values for the pitch ranges, otherwise the 14 bit value makes no sense.

```auto
void MPEZoneLayout::processPitchbendRangeRpnMessage (MidiRPNMessage rpn)
{
    int value = rpn.is14BitValue ? (int)std::floor(rpn.value / 128.0f + 0.5f) : rpn.value;

    if (rpn.channel == 1)
    {
        updateMasterPitchbend (lowerZone, value);
    }
    else if (rpn.channel == 16)
    {
        updateMasterPitchbend (upperZone, value);
    }
    else
    {
        if (lowerZone.isUsingChannelAsMemberChannel (rpn.channel))
            updatePerNotePitchbendRange (lowerZone, value);
        else if (upperZone.isUsingChannelAsMemberChannel (rpn.channel))
            updatePerNotePitchbendRange (upperZone, value);
    }
}

```

---

<div class="post-metadata">

**Author:** ![kunz](https://avatars.discourse-cdn.com/v4/letter/k/f19dbf/32.png) [@kunz](https://forum.juce.com/u/kunz)\
**Post date:** [January 5, 2026, 9:12am UTC](https://forum.juce.com/t/mpeinstrument-in-bitwig-zone-pitch-range-14-bit-midi-bug-and-assertion/67862/3 "2026-01-05T09:12:10Z")

</div>

Has anyone reproduced this with JUCE 8.0.11 and `juce::MPEInstrument` in Bitwig (VST3)?

It looks to me like a regression introduced with the new MIDI features.

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [January 7, 2026, 6:13pm UTC](https://forum.juce.com/t/mpeinstrument-in-bitwig-zone-pitch-range-14-bit-midi-bug-and-assertion/67862/5 "2026-01-07T18:13:40Z")

</div>

I don’t think this is a regression - the recent MIDI rewrite only touched MidiInput and MidiOutput and their implementations, so MPEInstrument and the plugin wrappers should not have been affected.

In any case, we’ve pushed a change that should fix the issue you’re seeing:

> <https://github.com/juce-framework/JUCE/commit/f4ba4c1ad93c3e4da5d8940077d6b9bb4534da8e>
>
> Previously, the MPEZoneLayout could only handle pitch-bend range
> adjustments tha…t ended with the MSB. If the final controller message was
> the LSB, this resulted in the range being set as a 14-bit value, with a
> value 128 times higher than intended.

---

<div class="post-metadata">

**Author:** ![kunz](https://avatars.discourse-cdn.com/v4/letter/k/f19dbf/32.png) [@kunz](https://forum.juce.com/u/kunz)\
**Post date:** [January 8, 2026, 8:57am UTC](https://forum.juce.com/t/mpeinstrument-in-bitwig-zone-pitch-range-14-bit-midi-bug-and-assertion/67862/6 "2026-01-08T08:57:00Z")

</div>

Thanks a lot for the fix. This was important for us.
