26SynthesiserSound::SynthesiserSound() {}
35 return currentPlayingMidiChannel == midiChannel;
50 currentlyPlayingNote = -1;
51 currentlyPlayingSound =
nullptr;
52 currentPlayingMidiChannel = 0;
60 return noteOnTime < other.noteOnTime;
64 int startSample,
int numSamples)
68 startSample, numSamples);
90 return voices [index];
105 newVoice->setCurrentPlaybackSampleRate (sampleRate);
111 usableVoicesToStealArray.ensureStorageAllocated (voices.size() + 1);
120 voices.remove (index);
138 sounds.remove (index);
148 jassert (numSamples > 0);
149 minimumSubBlockSize = numSamples;
156 if (! approximatelyEqual (sampleRate,
newRate))
162 for (
auto*
voice : voices)
167template <
typename floatType>
174 jassert (! exactlyEqual (sampleRate, 0.0));
205 if (samplesToNextMidiMessage < ((firstEvent && ! subBlockSubdivisionIsStrict) ? 1 : minimumSubBlockSize))
213 if (targetChannels > 0)
214 renderVoices (outputAudio, startSample, samplesToNextMidiMessage);
217 startSample += samplesToNextMidiMessage;
218 numSamples -= samplesToNextMidiMessage;
221 std::for_each (midiIterator,
223 [&] (
const MidiMessageMetadata& meta) { handleMidiEvent (meta.getMessage()); });
227template void Synthesiser::processNextBlock<float> (AudioBuffer<float>&,
const MidiBuffer&,
int,
int);
228template void Synthesiser::processNextBlock<double> (AudioBuffer<double>&,
const MidiBuffer&,
int,
int);
231 int startSample,
int numSamples)
237 int startSample,
int numSamples)
244 for (
auto*
voice : voices)
245 voice->renderNextBlock (buffer, startSample, numSamples);
250 for (
auto*
voice : voices)
301 for (
auto*
sound : sounds)
307 for (
auto*
voice : voices)
319 const int midiChannel,
325 if (
voice->currentlyPlayingSound !=
nullptr)
326 voice->stopNote (0.0f,
false);
329 voice->currentPlayingMidiChannel = midiChannel;
330 voice->noteOnTime = ++lastNoteOnCounter;
332 voice->setKeyDown (
true);
333 voice->setSostenutoPedalDown (
false);
334 voice->setSustainPedalDown (sustainPedalsDown[midiChannel]);
343 jassert (
voice !=
nullptr);
348 jassert (
allowTailOff || (
voice->getCurrentlyPlayingNote() < 0 &&
voice->getCurrentlyPlayingSound() ==
nullptr));
358 for (
auto*
voice : voices)
361 &&
voice->isPlayingChannel (midiChannel))
363 if (
auto sound =
voice->getCurrentlyPlayingSound())
366 &&
sound->appliesToChannel (midiChannel))
368 jassert (!
voice->keyIsDown ||
voice->isSustainPedalDown() == sustainPedalsDown [midiChannel]);
370 voice->setKeyDown (
false);
372 if (! (
voice->isSustainPedalDown() ||
voice->isSostenutoPedalDown()))
384 for (
auto*
voice : voices)
388 sustainPedalsDown.
clear();
395 for (
auto*
voice : voices)
414 for (
auto*
voice : voices)
423 for (
auto*
voice : voices)
425 && (midiChannel <= 0 ||
voice->isPlayingChannel (midiChannel)))
433 for (
auto*
voice : voices)
440 jassert (midiChannel > 0 && midiChannel <= 16);
445 sustainPedalsDown.
setBit (midiChannel);
447 for (
auto*
voice : voices)
448 if (
voice->isPlayingChannel (midiChannel) &&
voice->isKeyDown())
449 voice->setSustainPedalDown (
true);
453 for (
auto*
voice : voices)
455 if (
voice->isPlayingChannel (midiChannel))
457 voice->setSustainPedalDown (
false);
459 if (! (
voice->isKeyDown() ||
voice->isSostenutoPedalDown()))
464 sustainPedalsDown.
clearBit (midiChannel);
470 jassert (midiChannel > 0 && midiChannel <= 16);
473 for (
auto*
voice : voices)
475 if (
voice->isPlayingChannel (midiChannel))
478 voice->setSostenutoPedalDown (
true);
479 else if (
voice->isSostenutoPedalDown())
487 jassert (midiChannel > 0 && midiChannel <= 16);
493 jassert (midiChannel > 0 && midiChannel <= 16);
503 for (
auto*
voice : voices)
521 jassert (! voices.isEmpty());
533 usableVoicesToStealArray.clear();
535 for (
auto*
voice : voices)
539 jassert (
voice->isVoiceActive());
541 usableVoicesToStealArray.add (
voice);
550 std::sort (usableVoicesToStealArray.begin(), usableVoicesToStealArray.end(),
Sorter());
552 if (!
voice->isPlayingButReleased())
554 auto note =
voice->getCurrentlyPlayingNote();
556 if (low ==
nullptr ||
note < low->getCurrentlyPlayingNote())
559 if (
top ==
nullptr ||
note >
top->getCurrentlyPlayingNote())
570 for (
auto*
voice : usableVoicesToStealArray)
575 for (
auto*
voice : usableVoicesToStealArray)
580 for (
auto*
voice : usableVoicesToStealArray)
585 for (
auto*
voice : usableVoicesToStealArray)
590 jassert (low !=
nullptr);
void makeCopyOf(const AudioBuffer< OtherType > &other, bool avoidReallocating=false)
BigInteger & clear() noexcept
BigInteger & clearBit(int bitNumber) noexcept
BigInteger & setBit(int bitNumber)
MidiBufferIterator cend() const noexcept
bool isAftertouch() const noexcept
bool isNoteOn(bool returnTrueForVelocity0=false) const noexcept
float getFloatVelocity() const noexcept
int getChannel() const noexcept
bool isProgramChange() const noexcept
bool isController() const noexcept
bool isAllSoundOff() const noexcept
int getControllerNumber() const noexcept
int getChannelPressureValue() const noexcept
bool isNoteOff(bool returnTrueForNoteOnVelocity0=true) const noexcept
bool isPitchWheel() const noexcept
int getNoteNumber() const noexcept
int getProgramChangeNumber() const noexcept
int getAfterTouchValue() const noexcept
int getControllerValue() const noexcept
bool isAllNotesOff() const noexcept
bool isChannelPressure() const noexcept
int getPitchWheelValue() const noexcept
~SynthesiserSound() override
virtual void channelPressureChanged(int newChannelPressureValue)
virtual void renderNextBlock(AudioBuffer< float > &outputBuffer, int startSample, int numSamples)=0
virtual bool isPlayingChannel(int midiChannel) const
virtual void setCurrentPlaybackSampleRate(double newRate)
virtual void aftertouchChanged(int newAftertouchValue)
int getCurrentlyPlayingNote() const noexcept
bool wasStartedBefore(const SynthesiserVoice &other) const noexcept
virtual ~SynthesiserVoice()
virtual bool isVoiceActive() const
virtual SynthesiserVoice * findFreeVoice(SynthesiserSound *soundToPlay, int midiChannel, int midiNoteNumber, bool stealIfNoneAvailable) const
virtual void handleProgramChange(int midiChannel, int programNumber)
void removeVoice(int index)
void startVoice(SynthesiserVoice *voice, SynthesiserSound *sound, int midiChannel, int midiNoteNumber, float velocity)
virtual void handleAftertouch(int midiChannel, int midiNoteNumber, int aftertouchValue)
void renderNextBlock(AudioBuffer< float > &outputAudio, const MidiBuffer &inputMidi, int startSample, int numSamples)
virtual void handleController(int midiChannel, int controllerNumber, int controllerValue)
virtual SynthesiserVoice * findVoiceToSteal(SynthesiserSound *soundToPlay, int midiChannel, int midiNoteNumber) const
virtual void handleSoftPedal(int midiChannel, bool isDown)
void removeSound(int index)
virtual void allNotesOff(int midiChannel, bool allowTailOff)
SynthesiserVoice * addVoice(SynthesiserVoice *newVoice)
void stopVoice(SynthesiserVoice *, float velocity, bool allowTailOff)
SynthesiserSound * addSound(const SynthesiserSound::Ptr &newSound)
virtual void renderVoices(AudioBuffer< float > &outputAudio, int startSample, int numSamples)
virtual void handleMidiEvent(const MidiMessage &)
void setNoteStealingEnabled(bool shouldStealNotes)
virtual void handlePitchWheel(int midiChannel, int wheelValue)
int lastPitchWheelValues[16]
virtual void noteOn(int midiChannel, int midiNoteNumber, float velocity)
SynthesiserVoice * getVoice(int index) const
virtual void noteOff(int midiChannel, int midiNoteNumber, float velocity, bool allowTailOff)
virtual void handleChannelPressure(int midiChannel, int channelPressureValue)
virtual void setCurrentPlaybackSampleRate(double sampleRate)
void setMinimumRenderingSubdivisionSize(int numSamples, bool shouldBeStrict=false) noexcept
virtual void handleSustainPedal(int midiChannel, bool isDown)
virtual void handleSostenutoPedal(int midiChannel, bool isDown)