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

MPE: changed default initial pressure for new notes to 0 if no pressure messages have been received before the note-on; removed virtual functions getInitialPitchbend/Pressure/TimbreForNoteOn as they are confusing and the default behaviour is reasonable.

This commit is contained in:
Timur Doumler 2016-03-23 23:44:19 +01:00
parent 6a66ff75bb
commit 86aacef11e
2 changed files with 183 additions and 202 deletions

View file

@ -39,6 +39,9 @@ MPEInstrument::MPEInstrument() noexcept
pressureDimension.value = &MPENote::pressure;
timbreDimension.value = &MPENote::timbre;
// the default value for pressure is 0, for all other dimension it is centre (= default MPEValue)
std::fill_n (pressureDimension.lastValueReceivedOnChannel, 16, MPEValue::minValue());
legacyMode.isEnabled = false;
legacyMode.pitchbendRange = 2;
legacyMode.channelRange = Range<int> (1, 17);
@ -271,22 +274,6 @@ void MPEInstrument::handleTimbreLSB (int midiChannel, int value) noexcept
lastTimbreLowerBitReceivedOnChannel[midiChannel - 1] = uint8 (value);
}
//==============================================================================
MPEValue MPEInstrument::getInitialPitchbendForNoteOn (int midiChannel, int /*midiNoteNumber*/, MPEValue /*midiNoteOnVelocity*/) const
{
return pitchbendDimension.lastValueReceivedOnChannel[midiChannel - 1];
}
MPEValue MPEInstrument::getInitialPressureForNoteOn (int /*midiChannel*/, int /*midiNoteNumber*/, MPEValue midiNoteOnVelocity) const
{
return midiNoteOnVelocity;
}
MPEValue MPEInstrument::getInitialTimbreForNoteOn (int midiChannel, int /*midiNoteNumber*/, MPEValue /*midiNoteOnVelocity*/) const
{
return timbreDimension.lastValueReceivedOnChannel[midiChannel - 1];
}
//==============================================================================
void MPEInstrument::noteOn (int midiChannel,
int midiNoteNumber,
@ -298,9 +285,9 @@ void MPEInstrument::noteOn (int midiChannel,
MPENote newNote (midiChannel,
midiNoteNumber,
midiNoteOnVelocity,
getInitialPitchbendForNoteOn (midiChannel, midiNoteNumber, midiNoteOnVelocity),
getInitialPressureForNoteOn (midiChannel, midiNoteNumber, midiNoteOnVelocity),
getInitialTimbreForNoteOn (midiChannel, midiNoteNumber, midiNoteOnVelocity),
getInitialValueForNewNote (midiChannel, pitchbendDimension),
getInitialValueForNewNote (midiChannel, pressureDimension),
getInitialValueForNewNote (midiChannel, timbreDimension),
isNoteChannelSustained[midiChannel - 1] ? MPENote::keyDownAndSustained : MPENote::keyDown);
const ScopedLock sl (lock);
@ -334,10 +321,11 @@ void MPEInstrument::noteOff (int midiChannel,
note->keyState = (note->keyState == MPENote::keyDownAndSustained) ? MPENote::sustained : MPENote::off;
note->noteOffVelocity = midiNoteOffVelocity;
// last pitchbend and timbre values received for this note should not be re-used for
// last dimension values received for this note should not be re-used for
// any new notes, so reset them:
pitchbendDimension.lastValueReceivedOnChannel[midiChannel - 1] = MPEValue();
timbreDimension.lastValueReceivedOnChannel[midiChannel - 1] = MPEValue();
pressureDimension.lastValueReceivedOnChannel[midiChannel - 1] = MPEValue::minValue();
pitchbendDimension.lastValueReceivedOnChannel[midiChannel - 1] = MPEValue::centreValue();
timbreDimension.lastValueReceivedOnChannel[midiChannel - 1] = MPEValue::centreValue();
if (note->keyState == MPENote::off)
{
@ -370,6 +358,14 @@ void MPEInstrument::timbre (int midiChannel, MPEValue value)
updateDimension (midiChannel, timbreDimension, value);
}
MPEValue MPEInstrument::getInitialValueForNewNote (int midiChannel, MPEDimension& dimension) const
{
if (getLastNotePlayedPtr (midiChannel) != nullptr)
return &dimension == &pressureDimension ? MPEValue::minValue() : MPEValue::centreValue();
return dimension.lastValueReceivedOnChannel[midiChannel - 1];
}
//==============================================================================
void MPEInstrument::updateDimension (int midiChannel, MPEDimension& dimension, MPEValue value)
{
@ -758,7 +754,7 @@ public:
test.noteOn (3, 60, MPEValue::from7BitInt (100));
expectEquals (test.getNumPlayingNotes(), 1);
expectEquals (test.noteAddedCallCounter, 1);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
// note-off
test.noteOff (3, 60, MPEValue::from7BitInt (33));
@ -774,13 +770,13 @@ public:
// note off with non-matching note number shouldn't do anything
test.noteOff (3, 61, MPEValue::from7BitInt (33));
expectEquals (test.getNumPlayingNotes(), 1);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteReleasedCallCounter, 0);
// note off with non-matching midi channel shouldn't do anything
test.noteOff (2, 60, MPEValue::from7BitInt (33));
expectEquals (test.getNumPlayingNotes(), 1);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteReleasedCallCounter, 0);
}
{
@ -791,9 +787,9 @@ public:
test.noteOn (3, 1, MPEValue::from7BitInt (100));
test.noteOn (3, 2, MPEValue::from7BitInt (100));
expectEquals (test.getNumPlayingNotes(), 3);
expectNote (test.getNote (3, 0), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 1), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 2), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 0), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 1), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 2), 100, 0, 8192, 64, MPENote::keyDown);
}
{
// pathological case: second note-on for same note should retrigger it.
@ -802,7 +798,7 @@ public:
test.noteOn (3, 0, MPEValue::from7BitInt (100));
test.noteOn (3, 0, MPEValue::from7BitInt (60));
expectEquals (test.getNumPlayingNotes(), 1);
expectNote (test.getNote (3, 0), 60, 60, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 0), 60, 0, 8192, 64, MPENote::keyDown);
}
}
@ -844,42 +840,42 @@ public:
// sustain pedal on per-note channel shouldn't do anything.
test.sustainPedal (3, true);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteKeyStateChangedCallCounter, 0);
// sustain pedal on non-zone channel shouldn't do anything either.
test.sustainPedal (1, true);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteKeyStateChangedCallCounter, 0);
// sustain pedal on master channel should sustain notes on *that* zone.
test.sustainPedal (2, true);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDownAndSustained);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDownAndSustained);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteKeyStateChangedCallCounter, 1);
// release
test.sustainPedal (2, false);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteKeyStateChangedCallCounter, 2);
// should also sustain new notes added after the press
test.sustainPedal (2, true);
expectEquals (test.noteKeyStateChangedCallCounter, 3);
test.noteOn (4, 51, MPEValue::from7BitInt (100));
expectNote (test.getNote (4, 51), 100, 100, 8192, 64, MPENote::keyDownAndSustained);
expectNote (test.getNote (4, 51), 100, 0, 8192, 64, MPENote::keyDownAndSustained);
expectEquals (test.noteKeyStateChangedCallCounter, 3);
// ...but only if that sustain came on the master channel of that zone!
test.sustainPedal (11, true);
test.noteOn (11, 52, MPEValue::from7BitInt (100));
expectNote (test.getNote (11, 52), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (11, 52), 100, 0, 8192, 64, MPENote::keyDown);
test.noteOff (11, 52, MPEValue::from7BitInt (100));
expectEquals (test.noteReleasedCallCounter, 1);
@ -890,8 +886,8 @@ public:
expectEquals (test.getNumPlayingNotes(), 2);
expectEquals (test.noteReleasedCallCounter, 2);
expectEquals (test.noteKeyStateChangedCallCounter, 5);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::sustained);
expectNote (test.getNote (4, 51), 100, 100, 8192, 64, MPENote::sustained);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::sustained);
expectNote (test.getNote (4, 51), 100, 0, 8192, 64, MPENote::sustained);
// notes should be turned off when pedal is released
test.sustainPedal (2, false);
@ -908,26 +904,26 @@ public:
// sostenuto pedal on per-note channel shouldn't do anything.
test.sostenutoPedal (3, true);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteKeyStateChangedCallCounter, 0);
// sostenuto pedal on non-zone channel shouldn't do anything either.
test.sostenutoPedal (1, true);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteKeyStateChangedCallCounter, 0);
// sostenuto pedal on master channel should sustain notes on *that* zone.
test.sostenutoPedal (2, true);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDownAndSustained);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDownAndSustained);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteKeyStateChangedCallCounter, 1);
// release
test.sostenutoPedal (2, false);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteKeyStateChangedCallCounter, 2);
// should only sustain notes turned on *before* the press (difference to sustain pedal)
@ -935,9 +931,9 @@ public:
expectEquals (test.noteKeyStateChangedCallCounter, 3);
test.noteOn (4, 51, MPEValue::from7BitInt (100));
expectEquals (test.getNumPlayingNotes(), 3);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDownAndSustained);
expectNote (test.getNote (4, 51), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDownAndSustained);
expectNote (test.getNote (4, 51), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteKeyStateChangedCallCounter, 3);
// note-off should not turn off sustained notes inside the same zone,
@ -946,7 +942,7 @@ public:
test.noteOff (4, 51, MPEValue::from7BitInt (100));
test.noteOff (10, 60, MPEValue::from7BitInt (100)); // not affected!
expectEquals (test.getNumPlayingNotes(), 1);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::sustained);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::sustained);
expectEquals (test.noteReleasedCallCounter, 2);
expectEquals (test.noteKeyStateChangedCallCounter, 4);
@ -1047,22 +1043,22 @@ public:
// applying pressure on a per-note channel should modulate one note
test.pressure (3, MPEValue::from7BitInt (33));
expectNote (test.getNote (3, 60), 100, 33, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.notePressureChangedCallCounter, 1);
// applying pressure on a master channel should modulate all notes in this zone
test.pressure (2, MPEValue::from7BitInt (44));
expectNote (test.getNote (3, 60), 100, 44, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 44, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.notePressureChangedCallCounter, 3);
// applying pressure on an unrelated channel should be ignored
test.pressure (1, MPEValue::from7BitInt (55));
expectNote (test.getNote (3, 60), 100, 44, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 44, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.notePressureChangedCallCounter, 3);
}
{
@ -1073,7 +1069,7 @@ public:
test.noteOn (3, 60, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.pressure (3, MPEValue::from7BitInt (66));
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 66, 8192, 64, MPENote::keyDown);
expectEquals (test.notePressureChangedCallCounter, 1);
}
@ -1091,6 +1087,49 @@ public:
expectNote (test.getNote (3, 60), 100, 77, 8192, 64, MPENote::keyDown);
expectEquals (test.notePressureChangedCallCounter, 1);
}
{
UnitTestInstrument test;
test.setZoneLayout (testLayout);
// if no pressure is sent before note-on, default = 0 should be used
test.noteOn (3, 60, MPEValue::from7BitInt (100));
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
}
{
UnitTestInstrument test;
test.setZoneLayout (testLayout);
// if pressure is sent before note-on, use that
test.pressure (3, MPEValue::from7BitInt (77));
test.noteOn (3, 60, MPEValue::from7BitInt (100));
expectNote (test.getNote (3, 60), 100, 77, 8192, 64, MPENote::keyDown);
}
{
UnitTestInstrument test;
test.setZoneLayout (testLayout);
// if pressure is sent before note-on, but it belonged to another note
// on the same channel that has since been turned off, use default = 0
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.pressure (3, MPEValue::from7BitInt (77));
test.noteOff (3, 61, MPEValue::from7BitInt (100));
test.noteOn (3, 60, MPEValue::from7BitInt (100));
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
}
{
UnitTestInstrument test;
test.setZoneLayout (testLayout);
// edge case: two notes on the same channel simultaneously. the second one should use
// pressure = 0 initially but then react to additional pressure messages
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.pressure (3, MPEValue::from7BitInt (77));
test.noteOn (3, 60, MPEValue::from7BitInt (100));
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
test.pressure (3, MPEValue::from7BitInt (78));
expectNote (test.getNote (3, 60), 100, 78, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 77, 8192, 64, MPENote::keyDown);
}
}
beginTest ("pitchbend");
@ -1105,9 +1144,9 @@ public:
// applying pitchbend on a per-note channel should modulate one note
test.pitchbend (3, MPEValue::from14BitInt (1111));
expectNote (test.getNote (3, 60), 100, 100, 1111, 64, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 1111, 64, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.notePitchbendChangedCallCounter, 1);
// applying pitchbend on a master channel should be ignored for the
@ -1115,16 +1154,16 @@ public:
// Note: noteChanged will be called anyway for notes in that zone
// because the total pitchbend for those notes has changed
test.pitchbend (2, MPEValue::from14BitInt (2222));
expectNote (test.getNote (3, 60), 100, 100, 1111, 64, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 1111, 64, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.notePitchbendChangedCallCounter, 3);
// applying pitchbend on an unrelated channel should do nothing.
test.pitchbend (1, MPEValue::from14BitInt (3333));
expectNote (test.getNote (3, 60), 100, 100, 1111, 64, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 1111, 64, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.notePitchbendChangedCallCounter, 3);
}
{
@ -1135,8 +1174,8 @@ public:
test.noteOn (3, 60, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.pitchbend (3, MPEValue::from14BitInt (4444));
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 100, 4444, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 0, 4444, 64, MPENote::keyDown);
expectEquals (test.notePitchbendChangedCallCounter, 1);
}
{
@ -1150,7 +1189,7 @@ public:
test.noteOff (3, 61, MPEValue::from7BitInt (100));
test.pitchbend (3, MPEValue::from14BitInt (5555));
expectEquals (test.getNumPlayingNotes(), 1);
expectNote (test.getNote (3, 60), 100, 100, 5555, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 5555, 64, MPENote::keyDown);
expectEquals (test.notePitchbendChangedCallCounter, 1);
}
{
@ -1169,14 +1208,14 @@ public:
test.sustainPedal (2, true);
test.noteOff (3, 60, MPEValue::from7BitInt (64));
expectEquals (test.getNumPlayingNotes(), 1);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::sustained);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::sustained);
expectEquals (test.noteKeyStateChangedCallCounter, 2);
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.pitchbend (3, MPEValue::from14BitInt (6666));
expectEquals (test.getNumPlayingNotes(), 2);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::sustained);
expectNote (test.getNote (3, 61), 100, 100, 6666, 64, MPENote::keyDownAndSustained);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::sustained);
expectNote (test.getNote (3, 61), 100, 0, 6666, 64, MPENote::keyDownAndSustained);
expectEquals (test.notePitchbendChangedCallCounter, 1);
}
{
@ -1193,11 +1232,11 @@ public:
test.noteOn (3, 60, MPEValue::from7BitInt (100));
test.pitchbend (3, MPEValue::from14BitInt (5555));
expectNote (test.getNote (3, 60), 100, 100, 5555, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 5555, 64, MPENote::keyDown);
test.noteOff (3, 60, MPEValue::from7BitInt (100));
test.noteOn (3, 60, MPEValue::from7BitInt (100));
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
}
{
// applying per-note pitchbend should set the note's totalPitchbendInSemitones
@ -1289,23 +1328,23 @@ public:
// modulating timbre on a per-note channel should modulate one note
test.timbre (3, MPEValue::from7BitInt (33));
expectNote (test.getNote (3, 60), 100, 100, 8192, 33, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 33, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteTimbreChangedCallCounter, 1);
// modulating timbre on a master channel should modulate all notes in this zone
test.timbre (2, MPEValue::from7BitInt (44));
expectNote (test.getNote (3, 60), 100, 100, 8192, 44, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 100, 8192, 44, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 44, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 0, 8192, 44, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteTimbreChangedCallCounter, 3);
// modulating timbre on an unrelated channel should be ignored
test.timbre (1, MPEValue::from7BitInt (55));
expectNote (test.getNote (3, 60), 100, 100, 8192, 44, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 100, 8192, 44, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 44, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 0, 8192, 44, MPENote::keyDown);
expectNote (test.getNote (10, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteTimbreChangedCallCounter, 3);
}
{
@ -1316,8 +1355,8 @@ public:
test.noteOn (3, 60, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.timbre (3, MPEValue::from7BitInt (66));
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 100, 8192, 66, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 0, 8192, 66, MPENote::keyDown);
expectEquals (test.noteTimbreChangedCallCounter, 1);
}
{
@ -1331,7 +1370,7 @@ public:
test.noteOff (3, 61, MPEValue::from7BitInt (100));
test.timbre (3, MPEValue::from7BitInt (77));
expectEquals (test.getNumPlayingNotes(), 1);
expectNote (test.getNote (3, 60), 100, 100, 8192, 77, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 77, MPENote::keyDown);
expectEquals (test.noteTimbreChangedCallCounter, 1);
}
{
@ -1341,11 +1380,11 @@ public:
// Zsolt's edge case for timbre
test.noteOn (3, 60, MPEValue::from7BitInt (100));
test.timbre (3, MPEValue::from7BitInt (42));
expectNote (test.getNote (3, 60), 100, 100, 8192, 42, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 42, MPENote::keyDown);
test.noteOff (3, 60, MPEValue::from7BitInt (100));
test.noteOn (3, 60, MPEValue::from7BitInt (100));
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
}
}
@ -1361,8 +1400,8 @@ public:
test.noteOn (3, 62, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.pressure (3, MPEValue::from7BitInt (99));
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 99, 8192, 64, MPENote::keyDown);
expectEquals (test.notePressureChangedCallCounter, 1);
}
@ -1377,8 +1416,8 @@ public:
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.pressure (3, MPEValue::from7BitInt (99));
expectNote (test.getNote (3, 60), 100, 99, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.notePressureChangedCallCounter, 1);
}
{
@ -1391,9 +1430,9 @@ public:
test.noteOn (3, 62, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.pressure (3, MPEValue::from7BitInt (99));
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 99, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.notePressureChangedCallCounter, 1);
}
{
@ -1425,9 +1464,9 @@ public:
test.noteOn (3, 62, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.pitchbend (3, MPEValue::from14BitInt (9999));
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 0, 9999, 64, MPENote::keyDown);
expectEquals (test.notePitchbendChangedCallCounter, 1);
}
{
@ -1440,9 +1479,9 @@ public:
test.noteOn (3, 62, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.pitchbend (3, MPEValue::from14BitInt (9999));
expectNote (test.getNote (3, 60), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.notePitchbendChangedCallCounter, 1);
}
{
@ -1455,9 +1494,9 @@ public:
test.noteOn (3, 62, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.pitchbend (3, MPEValue::from14BitInt (9999));
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 0, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.notePitchbendChangedCallCounter, 1);
}
{
@ -1470,9 +1509,9 @@ public:
test.noteOn (3, 62, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.pitchbend (3, MPEValue::from14BitInt (9999));
expectNote (test.getNote (3, 60), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 0, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 0, 9999, 64, MPENote::keyDown);
expectEquals (test.notePitchbendChangedCallCounter, 3);
}
}
@ -1489,9 +1528,9 @@ public:
test.noteOn (3, 62, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.timbre (3, MPEValue::from7BitInt (99));
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 100, 8192, 99, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 0, 8192, 99, MPENote::keyDown);
expectEquals (test.noteTimbreChangedCallCounter, 1);
}
{
@ -1504,9 +1543,9 @@ public:
test.noteOn (3, 62, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.timbre (3, MPEValue::from7BitInt (99));
expectNote (test.getNote (3, 60), 100, 100, 8192, 99, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 99, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteTimbreChangedCallCounter, 1);
}
{
@ -1519,9 +1558,9 @@ public:
test.noteOn (3, 62, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.timbre (3, MPEValue::from7BitInt (99));
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 100, 8192, 99, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 0, 8192, 99, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 0, 8192, 64, MPENote::keyDown);
expectEquals (test.noteTimbreChangedCallCounter, 1);
}
{
@ -1534,9 +1573,9 @@ public:
test.noteOn (3, 62, MPEValue::from7BitInt (100));
test.noteOn (3, 61, MPEValue::from7BitInt (100));
test.timbre (3, MPEValue::from7BitInt (99));
expectNote (test.getNote (3, 60), 100, 100, 8192, 99, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 100, 8192, 99, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 100, 8192, 99, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 99, MPENote::keyDown);
expectNote (test.getNote (3, 62), 100, 0, 8192, 99, MPENote::keyDown);
expectNote (test.getNote (3, 61), 100, 0, 8192, 99, MPENote::keyDown);
expectEquals (test.noteTimbreChangedCallCounter, 3);
}
}
@ -1724,7 +1763,7 @@ public:
expectEquals (test.getNumPlayingNotes(), 0);
}
beginTest ("default getInitial...ForNoteOn");
beginTest ("default initial values for pitchbend and timbre");
{
MPEInstrument test;
test.setZoneLayout (testLayout);
@ -1739,16 +1778,7 @@ public:
test.noteOn (3, 60, MPEValue::from7BitInt (100));
expectNote (test.getMostRecentNote (3), 100, 100, 3333, 66, MPENote::keyDown);
}
beginTest ("overriding getInitial...ForNoteOn");
{
CustomInitialValuesTest<33, 4444, 55> test;
test.setZoneLayout (testLayout);
test.noteOn (3, 61, MPEValue::from7BitInt (100));
expectNote (test.getMostRecentNote (3), 100, 33, 4444, 55, MPENote::keyDown);
expectNote (test.getMostRecentNote (3), 100, 0, 3333, 66, MPENote::keyDown);
}
beginTest ("Legacy mode");
@ -1806,10 +1836,10 @@ public:
test.pressure (2, MPEValue::from7BitInt (88));
test.timbre (15, MPEValue::from7BitInt (77));
expectNote (test.getNote (1, 60), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (1, 60), 100, 0, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (2, 60), 100, 88, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (15, 60), 100, 100, 8192, 77, MPENote::keyDown);
expectNote (test.getNote (16, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (15, 60), 100, 0, 8192, 77, MPENote::keyDown);
expectNote (test.getNote (16, 60), 100, 0, 8192, 64, MPENote::keyDown);
// note off should work in legacy mode
@ -1835,10 +1865,10 @@ public:
test.noteOn (16, 60, MPEValue::from7BitInt (100));
expectEquals (test.getNumPlayingNotes(), 4);
expectNote (test.getNote (3, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (6, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (7, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (3, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (4, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (6, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (7, 60), 100, 0, 8192, 64, MPENote::keyDown);
}
{
// tracking mode in legacy mode
@ -1851,9 +1881,9 @@ public:
test.noteOn (1, 62, MPEValue::from7BitInt (100));
test.noteOn (1, 61, MPEValue::from7BitInt (100));
test.pitchbend (1, MPEValue::from14BitInt (9999));
expectNote (test.getNote (1, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (1, 61), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (1, 62), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (1, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (1, 61), 100, 0, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (1, 62), 100, 0, 8192, 64, MPENote::keyDown);
}
{
UnitTestInstrument test;
@ -1864,9 +1894,9 @@ public:
test.noteOn (1, 62, MPEValue::from7BitInt (100));
test.noteOn (1, 61, MPEValue::from7BitInt (100));
test.pitchbend (1, MPEValue::from14BitInt (9999));
expectNote (test.getNote (1, 60), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (1, 61), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (1, 62), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (1, 60), 100, 0, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (1, 61), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (1, 62), 100, 0, 8192, 64, MPENote::keyDown);
}
{
UnitTestInstrument test;
@ -1877,9 +1907,9 @@ public:
test.noteOn (1, 62, MPEValue::from7BitInt (100));
test.noteOn (1, 61, MPEValue::from7BitInt (100));
test.pitchbend (1, MPEValue::from14BitInt (9999));
expectNote (test.getNote (1, 60), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (1, 61), 100, 100, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (1, 62), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (1, 60), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (1, 61), 100, 0, 8192, 64, MPENote::keyDown);
expectNote (test.getNote (1, 62), 100, 0, 9999, 64, MPENote::keyDown);
}
{
UnitTestInstrument test;
@ -1890,9 +1920,9 @@ public:
test.noteOn (1, 62, MPEValue::from7BitInt (100));
test.noteOn (1, 61, MPEValue::from7BitInt (100));
test.pitchbend (1, MPEValue::from14BitInt (9999));
expectNote (test.getNote (1, 60), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (1, 61), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (1, 62), 100, 100, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (1, 60), 100, 0, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (1, 61), 100, 0, 9999, 64, MPENote::keyDown);
expectNote (test.getNote (1, 62), 100, 0, 9999, 64, MPENote::keyDown);
}
}
{
@ -1916,7 +1946,7 @@ public:
test.noteOff (1, 60, MPEValue::from7BitInt (100));
expectEquals (test.getNumPlayingNotes(), 1);
expectNote (test.getNote (1, 60), 100, 100, 8192, 64, MPENote::sustained);
expectNote (test.getNote (1, 60), 100, 0, 8192, 64, MPENote::sustained);
test.sustainPedal (1, false);
expectEquals (test.getNumPlayingNotes(), 0);
@ -1939,7 +1969,7 @@ public:
test.noteOff (2, 61, MPEValue::from7BitInt (100));
expectEquals (test.getNumPlayingNotes(), 1);
expectNote (test.getNote (1, 60), 100, 100, 8192, 64, MPENote::sustained);
expectNote (test.getNote (1, 60), 100, 0, 8192, 64, MPENote::sustained);
test.sostenutoPedal (1, false);
expectEquals (test.getNumPlayingNotes(), 0);
@ -2081,26 +2111,6 @@ private:
}
};
//==============================================================================
template <int initial7BitPressure, int initial14BitPitchbend, int initial7BitTimbre>
class CustomInitialValuesTest : public MPEInstrument
{
MPEValue getInitialPitchbendForNoteOn (int, int, MPEValue) const override
{
return MPEValue::from14BitInt (initial14BitPitchbend);
}
MPEValue getInitialPressureForNoteOn (int, int, MPEValue) const override
{
return MPEValue::from7BitInt (initial7BitPressure);
}
MPEValue getInitialTimbreForNoteOn (int, int, MPEValue) const override
{
return MPEValue::from7BitInt (initial7BitTimbre);
}
};
//==============================================================================
void expectNote (MPENote noteToTest,
int noteOnVelocity7Bit,

View file

@ -320,36 +320,6 @@ public:
/** Re-sets the pitchbend range in semitones (0-96) to be used for notes when in legacy mode. */
void setLegacyModePitchbendRange (int pitchbendRange);
protected:
//==============================================================================
/** This method defines what initial pitchbend value should be used for newly
triggered notes. The default is to use the last pitchbend value
that has been received on the same MIDI channel (or no pitchbend
if no pitchbend messages have been received so far).
Override this method if you need different behaviour.
*/
virtual MPEValue getInitialPitchbendForNoteOn (int midiChannel,
int midiNoteNumber,
MPEValue midiNoteOnVelocity) const;
/** This method defines what initial pressure value should be used for newly
triggered notes. The default is to re-use the note-on velocity value.
Override this method if you need different behaviour.
*/
virtual MPEValue getInitialPressureForNoteOn (int midiChannel,
int midiNoteNumber,
MPEValue midiNoteOnVelocity) const;
/** This method defines what initial timbre value should be used for newly
triggered notes. The default is to use the last timbre value that has
that has been received on the same MIDI channel (or a neutral centred value
if no pitchbend messages have been received so far).
Override this method if you need different behaviour.
*/
virtual MPEValue getInitialTimbreForNoteOn (int midiChannel,
int midiNoteNumber,
MPEValue midiNoteOnVelocity) const;
private:
//==============================================================================
CriticalSection lock;
@ -384,6 +354,7 @@ private:
void updateDimensionMaster (MPEZone&, MPEDimension&, MPEValue);
void updateDimensionForNote (MPENote&, MPEDimension&, MPEValue);
void callListenersDimensionChanged (MPENote&, MPEDimension&);
MPEValue getInitialValueForNewNote (int midiChannel, MPEDimension&) const;
void processMidiNoteOnMessage (const MidiMessage&);
void processMidiNoteOffMessage (const MidiMessage&);