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];
102 newVoice->setCurrentPlaybackSampleRate (sampleRate);
137 jassert (numSamples > 0);
138 minimumSubBlockSize = numSamples;
151 for (
auto*
voice : voices)
156template <
typename floatType>
163 jassert (sampleRate != 0);
175 while (numSamples > 0)
185 const int samplesToNextMidiMessage = midiEventPos - startSample;
187 if (samplesToNextMidiMessage >= numSamples)
189 if (targetChannels > 0)
204 if (targetChannels > 0)
205 renderVoices (outputAudio, startSample, samplesToNextMidiMessage);
208 startSample += samplesToNextMidiMessage;
209 numSamples -= samplesToNextMidiMessage;
212 while (midiIterator.getNextEvent (m, midiEventPos))
217template void Synthesiser::processNextBlock<float> (AudioBuffer<float>&,
const MidiBuffer&,
int,
int);
218template void Synthesiser::processNextBlock<double> (AudioBuffer<double>&,
const MidiBuffer&,
int,
int);
221 int startSample,
int numSamples)
227 int startSample,
int numSamples)
234 for (
auto*
voice : voices)
235 voice->renderNextBlock (buffer, startSample, numSamples);
240 for (
auto*
voice : voices)
291 for (
auto*
sound : sounds)
297 for (
auto*
voice : voices)
309 const int midiChannel,
315 if (
voice->currentlyPlayingSound !=
nullptr)
316 voice->stopNote (0.0f,
false);
319 voice->currentPlayingMidiChannel = midiChannel;
320 voice->noteOnTime = ++lastNoteOnCounter;
322 voice->setKeyDown (
true);
323 voice->setSostenutoPedalDown (
false);
324 voice->setSustainPedalDown (sustainPedalsDown[midiChannel]);
333 jassert (
voice !=
nullptr);
338 jassert (
allowTailOff || (
voice->getCurrentlyPlayingNote() < 0 &&
voice->getCurrentlyPlayingSound() ==
nullptr));
348 for (
auto*
voice : voices)
351 &&
voice->isPlayingChannel (midiChannel))
353 if (
auto sound =
voice->getCurrentlyPlayingSound())
356 &&
sound->appliesToChannel (midiChannel))
358 jassert (!
voice->keyIsDown ||
voice->isSustainPedalDown() == sustainPedalsDown [midiChannel]);
360 voice->setKeyDown (
false);
362 if (! (
voice->isSustainPedalDown() ||
voice->isSostenutoPedalDown()))
374 for (
auto*
voice : voices)
378 sustainPedalsDown.
clear();
385 for (
auto*
voice : voices)
404 for (
auto*
voice : voices)
413 for (
auto*
voice : voices)
415 && (midiChannel <= 0 ||
voice->isPlayingChannel (midiChannel)))
423 for (
auto*
voice : voices)
430 jassert (midiChannel > 0 && midiChannel <= 16);
435 sustainPedalsDown.
setBit (midiChannel);
437 for (
auto*
voice : voices)
438 if (
voice->isPlayingChannel (midiChannel) &&
voice->isKeyDown())
439 voice->setSustainPedalDown (
true);
443 for (
auto*
voice : voices)
445 if (
voice->isPlayingChannel (midiChannel))
447 voice->setSustainPedalDown (
false);
449 if (! (
voice->isKeyDown() ||
voice->isSostenutoPedalDown()))
454 sustainPedalsDown.
clearBit (midiChannel);
460 jassert (midiChannel > 0 && midiChannel <= 16);
463 for (
auto*
voice : voices)
465 if (
voice->isPlayingChannel (midiChannel))
468 voice->setSostenutoPedalDown (
true);
469 else if (
voice->isSostenutoPedalDown())
477 ignoreUnused (midiChannel);
478 jassert (midiChannel > 0 && midiChannel <= 16);
484 jassert (midiChannel > 0 && midiChannel <= 16);
494 for (
auto*
voice : voices)
522 for (
auto*
voice : voices)
526 jassert (
voice->isVoiceActive());
539 if (!
voice->isPlayingButReleased())
541 auto note =
voice->getCurrentlyPlayingNote();
546 if (
top ==
nullptr ||
note >
top->getCurrentlyPlayingNote())
577 jassert (
low !=
nullptr);
bool isEmpty() const noexcept
void ensureStorageAllocated(int minNumElements)
int size() const noexcept
void remove(int indexToRemove)
ElementType * begin() noexcept
ElementType * end() noexcept
void add(const ElementType &newElement)
void makeCopyOf(const AudioBuffer< OtherType > &other, bool avoidReallocating=false)
void clearBit(int bitNumber) noexcept
void setBit(int bitNumber)
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)