MPEZone* MPEZoneLayout::getZoneByNoteChannel (int channel) const noexcept { for (MPEZone* zone = zones.begin(); zone != zones.end(); ++zone) if (zone->isUsingChannelAsNoteChannel (channel)) return zone; return nullptr; }
MPEZone* MPEZoneLayout::getZoneByFirstNoteChannel (int channel) const noexcept { for (MPEZone* zone = zones.begin(); zone != zones.end(); ++zone) if (zone->getFirstNoteChannel() == channel) return zone; return nullptr; }
//============================================================================== void testOverlapsWith (int masterChannelFirst, int numNoteChannelsFirst, int masterChannelSecond, int numNoteChannelsSecond, bool expectedRetVal) { MPEZone first (masterChannelFirst, numNoteChannelsFirst); MPEZone second (masterChannelSecond, numNoteChannelsSecond); expect (first.overlapsWith (second) == expectedRetVal); expect (second.overlapsWith (first) == expectedRetVal); }
//============================================================================== void testTruncateToFit (int masterChannelFirst, int numNoteChannelsFirst, int masterChannelSecond, int numNoteChannelsSecond, bool expectedRetVal, int masterChannelFirstAfter, int numNoteChannelsFirstAfter) { MPEZone first (masterChannelFirst, numNoteChannelsFirst); MPEZone second (masterChannelSecond, numNoteChannelsSecond); expect (first.truncateToFit (second) == expectedRetVal); expectEquals (first.getMasterChannel(), masterChannelFirstAfter); expectEquals (first.getNumNoteChannels(), numNoteChannelsFirstAfter); }
MidiBuffer MPEMessages::addZone (MPEZone zone) { MidiBuffer buffer (MidiRPNGenerator::generate (zone.getFirstNoteChannel(), zoneLayoutMessagesRpnNumber, zone.getNumNoteChannels(), false, false)); buffer.addEvents (perNotePitchbendRange (zone), 0, -1, 0); buffer.addEvents (masterPitchbendRange (zone), 0, -1, 0); return buffer; }
//============================================================================== bool MPEZone::overlapsWith (MPEZone other) const noexcept { if (masterChannel == other.masterChannel) return true; if (masterChannel > other.masterChannel) return other.overlapsWith (*this); return masterChannel + numNoteChannels >= other.masterChannel; }
void runTest() override { beginTest ("initialisation"); { { MPEZone zone (1, 10); expectEquals (zone.getMasterChannel(), 1); expectEquals (zone.getNumNoteChannels(), 10); expectEquals (zone.getFirstNoteChannel(), 2); expectEquals (zone.getLastNoteChannel(), 11); expectEquals (zone.getPerNotePitchbendRange(), 48); expectEquals (zone.getMasterPitchbendRange(), 2); expect (zone.isUsingChannel (1)); expect (zone.isUsingChannel (2)); expect (zone.isUsingChannel (10)); expect (zone.isUsingChannel (11)); expect (! zone.isUsingChannel (12)); expect (! zone.isUsingChannel (16)); expect (! zone.isUsingChannelAsNoteChannel (1)); expect (zone.isUsingChannelAsNoteChannel (2)); expect (zone.isUsingChannelAsNoteChannel (10)); expect (zone.isUsingChannelAsNoteChannel (11)); expect (! zone.isUsingChannelAsNoteChannel (12)); expect (! zone.isUsingChannelAsNoteChannel (16)); } { MPEZone zone (5, 4); expectEquals (zone.getMasterChannel(), 5); expectEquals (zone.getNumNoteChannels(), 4); expectEquals (zone.getFirstNoteChannel(), 6); expectEquals (zone.getLastNoteChannel(), 9); expectEquals (zone.getPerNotePitchbendRange(), 48); expectEquals (zone.getMasterPitchbendRange(), 2); expect (! zone.isUsingChannel (1)); expect (! zone.isUsingChannel (4)); expect (zone.isUsingChannel (5)); expect (zone.isUsingChannel (6)); expect (zone.isUsingChannel (8)); expect (zone.isUsingChannel (9)); expect (! zone.isUsingChannel (10)); expect (! zone.isUsingChannel (16)); expect (! zone.isUsingChannelAsNoteChannel (5)); expect (zone.isUsingChannelAsNoteChannel (6)); expect (zone.isUsingChannelAsNoteChannel (8)); expect (zone.isUsingChannelAsNoteChannel (9)); expect (! zone.isUsingChannelAsNoteChannel (10)); } } beginTest ("getNoteChannelRange"); { MPEZone zone (2, 10); Range<int> noteChannelRange = zone.getNoteChannelRange(); expectEquals (noteChannelRange.getStart(), 3); expectEquals (noteChannelRange.getEnd(), 13); } beginTest ("setting master pitchbend range"); { MPEZone zone (1, 10); zone.setMasterPitchbendRange (96); expectEquals (zone.getMasterPitchbendRange(), 96); zone.setMasterPitchbendRange (0); expectEquals (zone.getMasterPitchbendRange(), 0); expectEquals (zone.getPerNotePitchbendRange(), 48); } beginTest ("setting per-note pitchbend range"); { MPEZone zone (1, 10); zone.setPerNotePitchbendRange (96); expectEquals (zone.getPerNotePitchbendRange(), 96); zone.setPerNotePitchbendRange (0); expectEquals (zone.getPerNotePitchbendRange(), 0); expectEquals (zone.getMasterPitchbendRange(), 2); } beginTest ("checking overlap"); { testOverlapsWith (1, 10, 1, 10, true); testOverlapsWith (1, 4, 6, 3, false); testOverlapsWith (1, 4, 8, 3, false); testOverlapsWith (2, 10, 2, 8, true); testOverlapsWith (1, 10, 3, 2, true); testOverlapsWith (3, 10, 5, 9, true); } beginTest ("truncating"); { testTruncateToFit (1, 10, 3, 10, true, 1, 1); testTruncateToFit (3, 10, 1, 10, false, 3, 10); testTruncateToFit (1, 10, 5, 8, true, 1, 3); testTruncateToFit (5, 8, 1, 10, false, 5, 8); testTruncateToFit (1, 10, 4, 3, true, 1, 2); testTruncateToFit (4, 3, 1, 10, false, 4, 3); testTruncateToFit (1, 3, 5, 3, true, 1, 3); testTruncateToFit (5, 3, 1, 3, false, 5, 3); testTruncateToFit (1, 3, 7, 3, true, 1, 3); testTruncateToFit (7, 3, 1, 3, false, 7, 3); testTruncateToFit (1, 10, 2, 10, false, 1, 10); testTruncateToFit (2, 10, 1, 10, false, 2, 10); } }
void runTest() override { beginTest ("initialisation"); { MPEZoneLayout layout; expectEquals (layout.getNumZones(), 0); } beginTest ("adding zones"); { MPEZoneLayout layout; expect (layout.addZone (MPEZone (1, 7))); expectEquals (layout.getNumZones(), 1); expectEquals (layout.getZoneByIndex (0)->getMasterChannel(), 1); expectEquals (layout.getZoneByIndex (0)->getNumNoteChannels(), 7); expect (layout.addZone (MPEZone (9, 7))); expectEquals (layout.getNumZones(), 2); expectEquals (layout.getZoneByIndex (0)->getMasterChannel(), 1); expectEquals (layout.getZoneByIndex (0)->getNumNoteChannels(), 7); expectEquals (layout.getZoneByIndex (1)->getMasterChannel(), 9); expectEquals (layout.getZoneByIndex (1)->getNumNoteChannels(), 7); expect (! layout.addZone (MPEZone (5, 3))); expectEquals (layout.getNumZones(), 3); expectEquals (layout.getZoneByIndex (0)->getMasterChannel(), 1); expectEquals (layout.getZoneByIndex (0)->getNumNoteChannels(), 3); expectEquals (layout.getZoneByIndex (1)->getMasterChannel(), 9); expectEquals (layout.getZoneByIndex (1)->getNumNoteChannels(), 7); expectEquals (layout.getZoneByIndex (2)->getMasterChannel(), 5); expectEquals (layout.getZoneByIndex (2)->getNumNoteChannels(), 3); expect (! layout.addZone (MPEZone (5, 4))); expectEquals (layout.getNumZones(), 2); expectEquals (layout.getZoneByIndex (0)->getMasterChannel(), 1); expectEquals (layout.getZoneByIndex (0)->getNumNoteChannels(), 3); expectEquals (layout.getZoneByIndex (1)->getMasterChannel(), 5); expectEquals (layout.getZoneByIndex (1)->getNumNoteChannels(), 4); expect (! layout.addZone (MPEZone (6, 4))); expectEquals (layout.getNumZones(), 2); expectEquals (layout.getZoneByIndex (0)->getMasterChannel(), 1); expectEquals (layout.getZoneByIndex (0)->getNumNoteChannels(), 3); expectEquals (layout.getZoneByIndex (1)->getMasterChannel(), 6); expectEquals (layout.getZoneByIndex (1)->getNumNoteChannels(), 4); } beginTest ("querying zones"); { MPEZoneLayout layout; layout.addZone (MPEZone (2, 5)); layout.addZone (MPEZone (9, 4)); expect (layout.getZoneByMasterChannel (1) == nullptr); expect (layout.getZoneByMasterChannel (2) != nullptr); expect (layout.getZoneByMasterChannel (3) == nullptr); expect (layout.getZoneByMasterChannel (8) == nullptr); expect (layout.getZoneByMasterChannel (9) != nullptr); expect (layout.getZoneByMasterChannel (10) == nullptr); expectEquals (layout.getZoneByMasterChannel (2)->getNumNoteChannels(), 5); expectEquals (layout.getZoneByMasterChannel (9)->getNumNoteChannels(), 4); expect (layout.getZoneByFirstNoteChannel (2) == nullptr); expect (layout.getZoneByFirstNoteChannel (3) != nullptr); expect (layout.getZoneByFirstNoteChannel (4) == nullptr); expect (layout.getZoneByFirstNoteChannel (9) == nullptr); expect (layout.getZoneByFirstNoteChannel (10) != nullptr); expect (layout.getZoneByFirstNoteChannel (11) == nullptr); expectEquals (layout.getZoneByFirstNoteChannel (3)->getNumNoteChannels(), 5); expectEquals (layout.getZoneByFirstNoteChannel (10)->getNumNoteChannels(), 4); expect (layout.getZoneByNoteChannel (2) == nullptr); expect (layout.getZoneByNoteChannel (3) != nullptr); expect (layout.getZoneByNoteChannel (4) != nullptr); expect (layout.getZoneByNoteChannel (6) != nullptr); expect (layout.getZoneByNoteChannel (7) != nullptr); expect (layout.getZoneByNoteChannel (8) == nullptr); expect (layout.getZoneByNoteChannel (9) == nullptr); expect (layout.getZoneByNoteChannel (10) != nullptr); expect (layout.getZoneByNoteChannel (11) != nullptr); expect (layout.getZoneByNoteChannel (12) != nullptr); expect (layout.getZoneByNoteChannel (13) != nullptr); expect (layout.getZoneByNoteChannel (14) == nullptr); expectEquals (layout.getZoneByNoteChannel (5)->getNumNoteChannels(), 5); expectEquals (layout.getZoneByNoteChannel (13)->getNumNoteChannels(), 4); } beginTest ("clear all zones"); { MPEZoneLayout layout; expect (layout.addZone (MPEZone (1, 7))); expect (layout.addZone (MPEZone (10, 2))); layout.clearAllZones(); expectEquals (layout.getNumZones(), 0); } beginTest ("process MIDI buffers"); { MPEZoneLayout layout; MidiBuffer buffer; buffer = MPEMessages::addZone (MPEZone (1, 7)); layout.processNextMidiBuffer (buffer); expectEquals (layout.getNumZones(), 1); expectEquals (layout.getZoneByIndex (0)->getMasterChannel(), 1); expectEquals (layout.getZoneByIndex (0)->getNumNoteChannels(), 7); buffer = MPEMessages::addZone (MPEZone (9, 7)); layout.processNextMidiBuffer (buffer); expectEquals (layout.getNumZones(), 2); expectEquals (layout.getZoneByIndex (0)->getMasterChannel(), 1); expectEquals (layout.getZoneByIndex (0)->getNumNoteChannels(), 7); expectEquals (layout.getZoneByIndex (1)->getMasterChannel(), 9); expectEquals (layout.getZoneByIndex (1)->getNumNoteChannels(), 7); MPEZone zone (1, 10); buffer = MPEMessages::addZone (zone); layout.processNextMidiBuffer (buffer); expectEquals (layout.getNumZones(), 1); expectEquals (layout.getZoneByIndex (0)->getMasterChannel(), 1); expectEquals (layout.getZoneByIndex (0)->getNumNoteChannels(), 10); zone.setPerNotePitchbendRange (33); zone.setMasterPitchbendRange (44); buffer = MPEMessages::masterPitchbendRange (zone); buffer.addEvents (MPEMessages::perNotePitchbendRange (zone), 0, -1, 0); layout.processNextMidiBuffer (buffer); expectEquals (layout.getZoneByIndex (0)->getPerNotePitchbendRange(), 33); expectEquals (layout.getZoneByIndex (0)->getMasterPitchbendRange(), 44); } beginTest ("process individual MIDI messages"); { MPEZoneLayout layout; layout.processNextMidiEvent (MidiMessage (0x80, 0x59, 0xd0)); // unrelated note-off msg layout.processNextMidiEvent (MidiMessage (0xb1, 0x64, 0x06)); // RPN part 1 layout.processNextMidiEvent (MidiMessage (0xb1, 0x65, 0x00)); // RPN part 2 layout.processNextMidiEvent (MidiMessage (0xb8, 0x0b, 0x66)); // unrelated CC msg layout.processNextMidiEvent (MidiMessage (0xb1, 0x06, 0x03)); // RPN part 3 layout.processNextMidiEvent (MidiMessage (0x90, 0x60, 0x00)); // unrelated note-on msg expectEquals (layout.getNumZones(), 1); expectEquals (layout.getZoneByIndex (0)->getMasterChannel(), 1); expectEquals (layout.getZoneByIndex (0)->getNumNoteChannels(), 3); } }
MidiBuffer MPEMessages::masterPitchbendRange (MPEZone zone) { return MidiRPNGenerator::generate (zone.getMasterChannel(), 0, zone.getMasterPitchbendRange(), false, false); }
MidiBuffer MPEMessages::perNotePitchbendRange (MPEZone zone) { return MidiRPNGenerator::generate (zone.getFirstNoteChannel(), 0, zone.getPerNotePitchbendRange(), false, false); }