1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Added legacy mode support to MPEChannelAssigner

This commit is contained in:
ed 2018-02-26 09:57:13 +00:00
parent 11e3d17433
commit dcfd2316bf
2 changed files with 73 additions and 9 deletions

View file

@ -24,23 +24,35 @@ namespace juce
{
MPEChannelAssigner::MPEChannelAssigner (MPEZoneLayout::Zone zoneToUse)
: zone (zoneToUse),
channelIncrement (zone.isLowerZone() ? 1 : -1),
numChannels (zone.numMemberChannels),
firstChannel (zone.getFirstMemberChannel()),
lastChannel (zone.getLastMemberChannel()),
: zone (new MPEZoneLayout::Zone (zoneToUse)),
channelIncrement (zone->isLowerZone() ? 1 : -1),
numChannels (zone->numMemberChannels),
firstChannel (zone->getFirstMemberChannel()),
lastChannel (zone->getLastMemberChannel()),
midiChannelLastAssigned (firstChannel - channelIncrement)
{
// must be an active MPE zone!
jassert (numChannels > 0);
}
MPEChannelAssigner::MPEChannelAssigner (Range<int> channelRange)
: isLegacy (true),
channelIncrement (1),
numChannels (channelRange.getLength()),
firstChannel (channelRange.getStart()),
lastChannel (channelRange.getEnd() - 1),
midiChannelLastAssigned (firstChannel - channelIncrement)
{
// must have at least one channel!
jassert (! channelRange.isEmpty());
}
int MPEChannelAssigner::findMidiChannelForNewNote (int noteNumber) noexcept
{
if (numChannels == 1)
return firstChannel;
for (auto ch = firstChannel; (zone.isLowerZone() ? ch <= lastChannel : ch >= lastChannel); ch += channelIncrement)
for (auto ch = firstChannel; (isLegacy || zone->isLowerZone() ? ch <= lastChannel : ch >= lastChannel); ch += channelIncrement)
{
if (midiChannels[ch].isFree() && midiChannels[ch].lastNotePlayed == noteNumber)
{
@ -100,7 +112,7 @@ int MPEChannelAssigner::findMidiChannelPlayingClosestNonequalNote (int noteNumbe
auto channelWithClosestNote = firstChannel;
int closestNoteDistance = 127;
for (auto ch = firstChannel; (zone.isLowerZone() ? ch <= lastChannel : ch >= lastChannel); ch += channelIncrement)
for (auto ch = firstChannel; (isLegacy || zone->isLowerZone() ? ch <= lastChannel : ch >= lastChannel); ch += channelIncrement)
{
for (auto note : midiChannels[ch].notes)
{
@ -259,6 +271,7 @@ struct MPEUtilsUnitTests : public UnitTest
{
MPEZoneLayout layout;
// lower
{
layout.setLowerZone (15);
@ -301,6 +314,7 @@ struct MPEUtilsUnitTests : public UnitTest
expectEquals (channelAssigner.findMidiChannelForNewNote (20), 4);
}
// upper
{
layout.setUpperZone (15);
@ -342,6 +356,46 @@ struct MPEUtilsUnitTests : public UnitTest
expectEquals (channelAssigner.findMidiChannelForNewNote (101), 14);
expectEquals (channelAssigner.findMidiChannelForNewNote (20), 13);
}
// legacy
{
MPEChannelAssigner channelAssigner;
// check that channels are assigned in correct order
int noteNum = 60;
for (int ch = 1; ch <= 16; ++ch)
expectEquals (channelAssigner.findMidiChannelForNewNote (noteNum++), ch);
// check that note-offs are processed
channelAssigner.noteOff (60);
expectEquals (channelAssigner.findMidiChannelForNewNote (60), 1);
channelAssigner.noteOff (61);
expectEquals (channelAssigner.findMidiChannelForNewNote (61), 2);
// check that assigned channel was last to play note
channelAssigner.noteOff (65);
channelAssigner.noteOff (66);
expectEquals (channelAssigner.findMidiChannelForNewNote (66), 7);
expectEquals (channelAssigner.findMidiChannelForNewNote (65), 6);
// find closest channel playing nonequal note
expectEquals (channelAssigner.findMidiChannelForNewNote (80), 16);
expectEquals (channelAssigner.findMidiChannelForNewNote (55), 1);
// all notes off
channelAssigner.allNotesOff();
// last note played
expectEquals (channelAssigner.findMidiChannelForNewNote (66), 7);
expectEquals (channelAssigner.findMidiChannelForNewNote (65), 6);
expectEquals (channelAssigner.findMidiChannelForNewNote (80), 16);
expectEquals (channelAssigner.findMidiChannelForNewNote (55), 1);
// normal assignment
expectEquals (channelAssigner.findMidiChannelForNewNote (101), 2);
expectEquals (channelAssigner.findMidiChannelForNewNote (20), 3);
}
}
beginTest ("MPEChannelRemapper");

View file

@ -35,9 +35,18 @@ namespace juce
class MPEChannelAssigner
{
public:
/** Constructor */
/** Constructor.
This will assign channels within the range of the specified MPE zone.
*/
MPEChannelAssigner (MPEZoneLayout::Zone zoneToUse);
/** Legacy mode constructor.
This will assign channels within the specified range.
*/
MPEChannelAssigner (Range<int> channelRange = Range<int> (1, 17));
/** This method will use a set of rules recommended in the MPE specification to
determine which member channel the specified MIDI note should be assigned to
and will return this channel number.
@ -61,7 +70,8 @@ public:
void allNotesOff();
private:
MPEZoneLayout::Zone zone;
bool isLegacy = false;
ScopedPointer<MPEZoneLayout::Zone> zone;
int channelIncrement, numChannels, firstChannel, lastChannel, midiChannelLastAssigned;
//==============================================================================