void Synthesiser::noteOff (const int midiChannel, const int midiNoteNumber, const bool allowTailOff) { const ScopedLock sl (lock); for (int i = voices.size(); --i >= 0;) { SynthesiserVoice* const voice = voices.getUnchecked (i); if (voice->getCurrentlyPlayingNote() == midiNoteNumber) { SynthesiserSound* const sound = voice->getCurrentlyPlayingSound(); if (sound != nullptr && sound->appliesToNote (midiNoteNumber) && sound->appliesToChannel (midiChannel)) { voice->keyIsDown = false; if (! (sustainPedalsDown [midiChannel] || voice->sostenutoPedalDown)) stopVoice (voice, allowTailOff); } } } }
void Synthesiser::handleSustainPedal (int midiChannel, bool isDown) { jassert (midiChannel > 0 && midiChannel <= 16); const ScopedLock sl (lock); if (isDown) { sustainPedalsDown.setBit (midiChannel); for (int i = voices.size(); --i >= 0;) { SynthesiserVoice* const voice = voices.getUnchecked (i); if (voice->isPlayingChannel (midiChannel) && voice->isKeyDown()) voice->sustainPedalDown = true; } } else { for (int i = voices.size(); --i >= 0;) { SynthesiserVoice* const voice = voices.getUnchecked (i); if (voice->isPlayingChannel (midiChannel)) { voice->sustainPedalDown = false; if (! voice->isKeyDown()) stopVoice (voice, 1.0f, true); } } sustainPedalsDown.clearBit (midiChannel); } }
//============================================================================== void Synthesiser::noteOn (const int midiChannel, const int midiNoteNumber, const float velocity) { const ScopedLock sl (lock); for (int i = sounds.size(); --i >= 0;) { SynthesiserSound* const sound = sounds.getUnchecked(i); if (sound->appliesToNote (midiNoteNumber) && sound->appliesToChannel (midiChannel)) { // If hitting a note that's still ringing, stop it first (it could be // still playing because of the sustain or sostenuto pedal). for (int j = voices.size(); --j >= 0;) { SynthesiserVoice* const voice = voices.getUnchecked (j); if (voice->getCurrentlyPlayingNote() == midiNoteNumber && voice->isPlayingChannel (midiChannel)) stopVoice (voice, true); } startVoice (findFreeVoice (sound, shouldStealNotes), sound, midiChannel, midiNoteNumber, velocity); } } }
int Soloud::findFreeVoice() { int i; unsigned int lowest_play_index_value = 0xffffffff; int lowest_play_index = -1; // (slowly) drag the highest active voice index down if (mHighestVoice > 0 && mVoice[mHighestVoice - 1] == NULL) mHighestVoice--; for (i = 0; i < VOICE_COUNT; i++) { if (mVoice[i] == NULL) { if (i+1 > (signed)mHighestVoice) { mHighestVoice = i + 1; } return i; } if (((mVoice[i]->mFlags & AudioSourceInstance::PROTECTED) == 0) && mVoice[i]->mPlayIndex < lowest_play_index_value) { lowest_play_index_value = mVoice[i]->mPlayIndex; lowest_play_index = i; } } stopVoice(lowest_play_index); return lowest_play_index; }
void Synthesiser::handleSustainPedal (int midiChannel, bool isDown) { jassert (midiChannel > 0 && midiChannel <= 16); const ScopedLock sl (lock); if (isDown) { sustainPedalsDown.setBit (midiChannel); for (auto* voice : voices) if (voice->isPlayingChannel (midiChannel) && voice->isKeyDown()) voice->setSustainPedalDown (true); } else { for (auto* voice : voices) { if (voice->isPlayingChannel (midiChannel)) { voice->setSustainPedalDown (false); if (! (voice->isKeyDown() || voice->isSostenutoPedalDown())) stopVoice (voice, 1.0f, true); } } sustainPedalsDown.clearBit (midiChannel); } }
void Synthesiser::noteOff (const int midiChannel, const int midiNoteNumber, const float velocity, const bool allowTailOff) { const ScopedLock sl (lock); for (auto* voice : voices) { if (voice->getCurrentlyPlayingNote() == midiNoteNumber && voice->isPlayingChannel (midiChannel)) { if (auto sound = voice->getCurrentlyPlayingSound()) { if (sound->appliesToNote (midiNoteNumber) && sound->appliesToChannel (midiChannel)) { jassert (! voice->keyIsDown || voice->isSustainPedalDown() == sustainPedalsDown [midiChannel]); voice->setKeyDown (false); if (! (voice->isSustainPedalDown() || voice->isSostenutoPedalDown())) stopVoice (voice, velocity, allowTailOff); } } } } }
void Soloud::stopAll() { int i; if (mLockMutexFunc) mLockMutexFunc(mMutex); for (i = 0; i < VOICE_COUNT; i++) { stopVoice(i); } if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex); }
void Soloud::stopAll() { int i; lockAudioMutex(); for (i = 0; i < (signed)mHighestVoice; i++) { stopVoice(i); } unlockAudioMutex(); }
void Soloud::stop(int aVoiceHandle) { int ch = getVoiceFromHandle(aVoiceHandle); if (ch == -1) { return; } if (mLockMutexFunc) mLockMutexFunc(mMutex); stopVoice(ch); if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex); }
void MPESynthesiser::noteReleased (MPENote finishedNote) { const ScopedLock sl (voicesLock); for (int i = voices.size(); --i >= 0;) { MPESynthesiserVoice* const voice = voices.getUnchecked (i); if (voice->isCurrentlyPlayingNote(finishedNote)) stopVoice (voice, finishedNote, true); } }
void Synthesiser::handleSostenutoPedal (int midiChannel, bool isDown) { jassert (midiChannel > 0 && midiChannel <= 16); const ScopedLock sl (lock); for (auto* voice : voices) { if (voice->isPlayingChannel (midiChannel)) { if (isDown) voice->setSostenutoPedalDown (true); else if (voice->isSostenutoPedalDown()) stopVoice (voice, 1.0f, true); } } }
void Soloud::stopAudioSource(AudioSource &aSound) { if (aSound.mAudioSourceID) { if (mLockMutexFunc) mLockMutexFunc(mMutex); int i; for (i = 0; i < VOICE_COUNT; i++) { if (mVoice && mVoice[i] && mVoice[i]->mAudioSourceID == aSound.mAudioSourceID) { stopVoice(i); } } if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex); } }
void Soloud::stopAudioSource(AudioSource &aSound) { if (aSound.mAudioSourceID) { lockAudioMutex(); int i; for (i = 0; i < (signed)mHighestVoice; i++) { if (mVoice[i] && mVoice[i]->mAudioSourceID == aSound.mAudioSourceID) { stopVoice(i); } } unlockAudioMutex(); } }
void Synthesiser::handleSostenutoPedal (int midiChannel, bool isDown) { jassert (midiChannel > 0 && midiChannel <= 16); const ScopedLock sl (lock); for (int i = voices.size(); --i >= 0;) { SynthesiserVoice* const voice = voices.getUnchecked (i); if (voice->isPlayingChannel (midiChannel)) { if (isDown) voice->sostenutoPedalDown = true; else if (voice->sostenutoPedalDown) stopVoice (voice, true); } } }
//============================================================================== void Synthesiser::noteOn (const int midiChannel, const int midiNoteNumber, const float velocity) { const ScopedLock sl (lock); for (auto* sound : sounds) { if (sound->appliesToNote (midiNoteNumber) && sound->appliesToChannel (midiChannel)) { // If hitting a note that's still ringing, stop it first (it could be // still playing because of the sustain or sostenuto pedal). for (auto* voice : voices) if (voice->getCurrentlyPlayingNote() == midiNoteNumber && voice->isPlayingChannel (midiChannel)) stopVoice (voice, 1.0f, true); startVoice (findFreeVoice (sound, midiChannel, midiNoteNumber, shouldStealNotes), sound, midiChannel, midiNoteNumber, velocity); } } }
void Soloud::stop(handle aVoiceHandle) { FOR_ALL_VOICES_PRE stopVoice(ch); FOR_ALL_VOICES_POST }
void Sound::stopAll() { stopVoice(); stopSound(); }