|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2015 - ROLI Ltd.
-
- Permission is granted to use this software under the terms of either:
- a) the GPL v2 (or any later version)
- b) the Affero GPL v3
-
- Details of these licenses can be found at: www.gnu.org/licenses
-
- JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- ------------------------------------------------------------------------------
-
- To release a closed-source product which uses JUCE, commercial licenses are
- available: visit www.juce.com for more information.
-
- ==============================================================================
- */
-
- namespace
- {
- void checkAndLimitZoneParameters (int minValue,
- int maxValue,
- int& valueToCheckAndLimit) noexcept
- {
- if (valueToCheckAndLimit < minValue || valueToCheckAndLimit > maxValue)
- {
- // if you hit this, one of the parameters you supplied for MPEZone
- // 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);
- }
- }
- }
-
- //==============================================================================
- MPEZone::MPEZone (int masterChannel_,
- int numNoteChannels_,
- int perNotePitchbendRange_,
- int masterPitchbendRange_) noexcept
- : masterChannel (masterChannel_),
- numNoteChannels (numNoteChannels_),
- perNotePitchbendRange (perNotePitchbendRange_),
- masterPitchbendRange (masterPitchbendRange_)
- {
- checkAndLimitZoneParameters (1, 15, masterChannel);
- checkAndLimitZoneParameters (1, 16 - masterChannel, numNoteChannels);
- checkAndLimitZoneParameters (0, 96, perNotePitchbendRange);
- checkAndLimitZoneParameters (0, 96, masterPitchbendRange);
- }
-
- //==============================================================================
- int MPEZone::getMasterChannel() const noexcept
- {
- return masterChannel;
- }
-
- int MPEZone::getNumNoteChannels() const noexcept
- {
- return numNoteChannels;
- }
-
- int MPEZone::getFirstNoteChannel() const noexcept
- {
- return masterChannel + 1;
- }
-
- int MPEZone::getLastNoteChannel() const noexcept
- {
- return masterChannel + numNoteChannels;
- }
-
- Range<int> MPEZone::getNoteChannelRange() const noexcept
- {
- return Range<int>::withStartAndLength (getFirstNoteChannel(), getNumNoteChannels());
- }
-
- bool MPEZone::isUsingChannel (int channel) const noexcept
- {
- jassert (channel > 0 && channel <= 16);
- return channel >= masterChannel && channel <= masterChannel + numNoteChannels;
- }
-
- bool MPEZone::isUsingChannelAsNoteChannel (int channel) const noexcept
- {
- jassert (channel > 0 && channel <= 16);
- return channel > masterChannel && channel <= masterChannel + numNoteChannels;
- }
-
- int MPEZone::getPerNotePitchbendRange() const noexcept
- {
- return perNotePitchbendRange;
- }
-
- int MPEZone::getMasterPitchbendRange() const noexcept
- {
- return masterPitchbendRange;
- }
-
- void MPEZone::setPerNotePitchbendRange (int rangeInSemitones) noexcept
- {
- checkAndLimitZoneParameters (0, 96, rangeInSemitones);
- perNotePitchbendRange = rangeInSemitones;
- }
-
- void MPEZone::setMasterPitchbendRange (int rangeInSemitones) noexcept
- {
- checkAndLimitZoneParameters (0, 96, rangeInSemitones);
- masterPitchbendRange = rangeInSemitones;
- }
-
- //==============================================================================
- 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;
- }
-
- //==============================================================================
- bool MPEZone::truncateToFit (MPEZone other) noexcept
- {
- const int masterChannelDiff = other.masterChannel - masterChannel;
-
- // we need at least 2 channels to be left after truncation:
- // 1 master channel and 1 note channel. otherwise we can't truncate.
- if (masterChannelDiff < 2)
- return false;
-
- numNoteChannels = jmin (numNoteChannels, masterChannelDiff - 1);
- return true;
- }
-
- //==============================================================================
- bool MPEZone::operator== (const MPEZone& other) const noexcept
- {
- return masterChannel == other.masterChannel
- && numNoteChannels == other.numNoteChannels
- && perNotePitchbendRange == other.perNotePitchbendRange
- && masterPitchbendRange == other.masterPitchbendRange;
- }
-
- bool MPEZone::operator!= (const MPEZone& other) const noexcept
- {
- return ! operator== (other);
- }
-
- //==============================================================================
- //==============================================================================
- #if JUCE_UNIT_TESTS
-
- class MPEZoneTests : public UnitTest
- {
- public:
- MPEZoneTests() : UnitTest ("MPEZone class") {}
-
- 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);
- }
- }
-
- private:
- //==============================================================================
- 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);
- }
- };
-
- static MPEZoneTests MPEZoneUnitTests;
-
- #endif // JUCE_UNIT_TESTS
|