1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-02-06 04:00:08 +00:00

Added a couple of methods to Synthesiser to make it easier to customise note-stealing.

This commit is contained in:
jules 2014-03-18 18:53:26 +00:00
parent da43672aa3
commit be47fc8e6b
2 changed files with 35 additions and 19 deletions

View file

@ -58,6 +58,11 @@ void SynthesiserVoice::clearCurrentNote()
void SynthesiserVoice::aftertouchChanged (int) {}
bool SynthesiserVoice::wasStartedBefore (const SynthesiserVoice& other) const noexcept
{
return noteOnTime < other.noteOnTime;
}
//==============================================================================
Synthesiser::Synthesiser()
: sampleRate (0),
@ -407,12 +412,11 @@ void Synthesiser::handleSoftPedal (int midiChannel, bool /*isDown*/)
}
//==============================================================================
SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay,
const bool stealIfNoneAvailable) const
SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay, const bool stealIfNoneAvailable) const
{
const ScopedLock sl (lock);
for (int i = voices.size(); --i >= 0;)
for (int i = 0; i < voices.size(); ++i)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
@ -421,22 +425,25 @@ SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay,
}
if (stealIfNoneAvailable)
{
// currently this just steals the one that's been playing the longest, but could be made a bit smarter..
SynthesiserVoice* oldest = nullptr;
for (int i = voices.size(); --i >= 0;)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->canPlaySound (soundToPlay)
&& (oldest == nullptr || oldest->noteOnTime > voice->noteOnTime))
oldest = voice;
}
jassert (oldest != nullptr);
return oldest;
}
return findVoiceToSteal (soundToPlay);
return nullptr;
}
SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay) const
{
// currently this just steals the one that's been playing the longest, but could be made a bit smarter..
SynthesiserVoice* oldest = nullptr;
for (int i = 0; i < voices.size(); ++i)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->canPlaySound (soundToPlay)
&& (oldest == nullptr || voice->wasStartedBefore (*oldest)))
oldest = voice;
}
jassert (oldest != nullptr);
return oldest;
}

View file

@ -199,6 +199,9 @@ public:
/** Returns true if the sostenuto pedal is currently active for this voice. */
bool isSostenutoPedalDown() const noexcept { return sostenutoPedalDown; }
/** Returns true if this voice started playing its current note before the other voice did. */
bool wasStartedBefore (const SynthesiserVoice& other) const noexcept;
protected:
//==============================================================================
/** Returns the current target sample rate at which rendering is being done.
@ -481,6 +484,12 @@ protected:
virtual SynthesiserVoice* findFreeVoice (SynthesiserSound* soundToPlay,
const bool stealIfNoneAvailable) const;
/** Chooses a voice that is most suitable for being re-used.
The default method returns the one that has been playing for the longest, but
you may want to override this and do something more cunning instead.
*/
virtual SynthesiserVoice* findVoiceToSteal (SynthesiserSound* soundToPlay) const;
/** Starts a specified voice playing a particular sound.
You'll probably never need to call this, it's used internally by noteOn(), but