mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
MPEZoneLayout: Correctly handle 14-bit pitch-bend ranges
Previously, the MPEZoneLayout could only handle pitch-bend range adjustments that 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.
This commit is contained in:
parent
a35c8a97d2
commit
f4ba4c1ad9
1 changed files with 42 additions and 4 deletions
|
|
@ -169,20 +169,31 @@ void MPEZoneLayout::updatePerNotePitchbendRange (MPEZone& zone, int value)
|
||||||
|
|
||||||
void MPEZoneLayout::processPitchbendRangeRpnMessage (MidiRPNMessage rpn)
|
void MPEZoneLayout::processPitchbendRangeRpnMessage (MidiRPNMessage rpn)
|
||||||
{
|
{
|
||||||
|
// When the range is specified using both MSB and LSB, then MSB corresponds to whole semitones
|
||||||
|
// and LSB corresponds to cents.
|
||||||
|
const auto range = rpn.is14BitValue
|
||||||
|
? std::div (rpn.value, 128)
|
||||||
|
: div_t { rpn.value, 0 };
|
||||||
|
|
||||||
|
// If this is hit, the requested pitchbend range is not a whole number of semitones.
|
||||||
|
// This isn't currently supported by JUCE - adding support would require
|
||||||
|
// public API updates.
|
||||||
|
jassert (range.rem == 0);
|
||||||
|
|
||||||
if (rpn.channel == 1)
|
if (rpn.channel == 1)
|
||||||
{
|
{
|
||||||
updateMasterPitchbend (lowerZone, rpn.value);
|
updateMasterPitchbend (lowerZone, range.quot);
|
||||||
}
|
}
|
||||||
else if (rpn.channel == 16)
|
else if (rpn.channel == 16)
|
||||||
{
|
{
|
||||||
updateMasterPitchbend (upperZone, rpn.value);
|
updateMasterPitchbend (upperZone, range.quot);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (lowerZone.isUsingChannelAsMemberChannel (rpn.channel))
|
if (lowerZone.isUsingChannelAsMemberChannel (rpn.channel))
|
||||||
updatePerNotePitchbendRange (lowerZone, rpn.value);
|
updatePerNotePitchbendRange (lowerZone, range.quot);
|
||||||
else if (upperZone.isUsingChannelAsMemberChannel (rpn.channel))
|
else if (upperZone.isUsingChannelAsMemberChannel (rpn.channel))
|
||||||
updatePerNotePitchbendRange (upperZone, rpn.value);
|
updatePerNotePitchbendRange (upperZone, range.quot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -424,6 +435,33 @@ public:
|
||||||
|
|
||||||
expectEquals (layout.getLowerZone().masterPitchbendRange, newPitchBend);
|
expectEquals (layout.getLowerZone().masterPitchbendRange, newPitchBend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
beginTest ("process 14-bit pitch bend sensitivity");
|
||||||
|
{
|
||||||
|
MPEZoneLayout layout;
|
||||||
|
layout.setLowerZone (15);
|
||||||
|
expect (layout.getLowerZone().isActive());
|
||||||
|
|
||||||
|
constexpr auto masterPitchBendA = 0x60;
|
||||||
|
|
||||||
|
// LSB first
|
||||||
|
layout.processNextMidiEvent ({ 0xb0, 0x64, 0x00 }); // RPN part 1
|
||||||
|
layout.processNextMidiEvent ({ 0xb0, 0x65, 0x00 }); // PRN part 2
|
||||||
|
layout.processNextMidiEvent ({ 0xb0, 0x26, 0x00 }); // pitch bend cents
|
||||||
|
layout.processNextMidiEvent ({ 0xb0, 0x06, masterPitchBendA }); // pitch bend semis
|
||||||
|
|
||||||
|
expectEquals (layout.getLowerZone().masterPitchbendRange, masterPitchBendA);
|
||||||
|
|
||||||
|
constexpr auto masterPitchBendB = 0x50;
|
||||||
|
|
||||||
|
// MSB first
|
||||||
|
layout.processNextMidiEvent ({ 0xb0, 0x64, 0x00 }); // RPN part 1
|
||||||
|
layout.processNextMidiEvent ({ 0xb0, 0x65, 0x00 }); // PRN part 2
|
||||||
|
layout.processNextMidiEvent ({ 0xb0, 0x06, masterPitchBendB }); // pitch bend semis
|
||||||
|
layout.processNextMidiEvent ({ 0xb0, 0x26, 0x00 }); // pitch bend cents
|
||||||
|
|
||||||
|
expectEquals (layout.getLowerZone().masterPitchbendRange, masterPitchBendB);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue