Loading...
Searching...
No Matches
juce_Synthesiser.h
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
class JUCE_API SynthesiserSound : public ReferenceCountedObject
{
protected:
//==============================================================================
SynthesiserSound();
public:
~SynthesiserSound() override;
//==============================================================================
virtual bool appliesToNote (int midiNoteNumber) = 0;
virtual bool appliesToChannel (int midiChannel) = 0;
using Ptr = ReferenceCountedObjectPtr<SynthesiserSound>;
private:
//==============================================================================
JUCE_LEAK_DETECTOR (SynthesiserSound)
};
//==============================================================================
class JUCE_API SynthesiserVoice
{
public:
//==============================================================================
SynthesiserVoice();
virtual ~SynthesiserVoice();
//==============================================================================
int getCurrentlyPlayingNote() const noexcept { return currentlyPlayingNote; }
SynthesiserSound::Ptr getCurrentlyPlayingSound() const noexcept { return currentlyPlayingSound; }
virtual bool canPlaySound (SynthesiserSound*) = 0;
virtual void startNote (int midiNoteNumber,
float velocity,
SynthesiserSound* sound,
int currentPitchWheelPosition) = 0;
virtual void stopNote (float velocity, bool allowTailOff) = 0;
virtual bool isVoiceActive() const;
virtual void pitchWheelMoved (int newPitchWheelValue) = 0;
virtual void controllerMoved (int controllerNumber, int newControllerValue) = 0;
virtual void aftertouchChanged (int newAftertouchValue);
virtual void channelPressureChanged (int newChannelPressureValue);
//==============================================================================
virtual void renderNextBlock (AudioBuffer<float>& outputBuffer,
int startSample,
int numSamples) = 0;
virtual void renderNextBlock (AudioBuffer<double>& outputBuffer,
int startSample,
int numSamples);
virtual void setCurrentPlaybackSampleRate (double newRate);
virtual bool isPlayingChannel (int midiChannel) const;
double getSampleRate() const noexcept { return currentSampleRate; }
bool isKeyDown() const noexcept { return keyIsDown; }
void setKeyDown (bool isNowDown) noexcept { keyIsDown = isNowDown; }
bool isSustainPedalDown() const noexcept { return sustainPedalDown; }
void setSustainPedalDown (bool isNowDown) noexcept { sustainPedalDown = isNowDown; }
bool isSostenutoPedalDown() const noexcept { return sostenutoPedalDown; }
void setSostenutoPedalDown (bool isNowDown) noexcept { sostenutoPedalDown = isNowDown; }
bool isPlayingButReleased() const noexcept
{
return isVoiceActive() && ! (isKeyDown() || isSostenutoPedalDown() || isSustainPedalDown());
}
bool wasStartedBefore (const SynthesiserVoice& other) const noexcept;
protected:
void clearCurrentNote();
private:
//==============================================================================
friend class Synthesiser;
double currentSampleRate = 44100.0;
int currentlyPlayingNote = -1, currentPlayingMidiChannel = 0;
uint32 noteOnTime = 0;
SynthesiserSound::Ptr currentlyPlayingSound;
bool keyIsDown = false, sustainPedalDown = false, sostenutoPedalDown = false;
AudioBuffer<float> tempBuffer;
JUCE_LEAK_DETECTOR (SynthesiserVoice)
};
//==============================================================================
class JUCE_API Synthesiser
{
public:
//==============================================================================
Synthesiser();
virtual ~Synthesiser();
//==============================================================================
void clearVoices();
int getNumVoices() const noexcept { return voices.size(); }
SynthesiserVoice* getVoice (int index) const;
SynthesiserVoice* addVoice (SynthesiserVoice* newVoice);
void removeVoice (int index);
//==============================================================================
void clearSounds();
int getNumSounds() const noexcept { return sounds.size(); }
SynthesiserSound::Ptr getSound (int index) const noexcept { return sounds[index]; }
SynthesiserSound* addSound (const SynthesiserSound::Ptr& newSound);
void removeSound (int index);
//==============================================================================
void setNoteStealingEnabled (bool shouldStealNotes);
bool isNoteStealingEnabled() const noexcept { return shouldStealNotes; }
//==============================================================================
virtual void noteOn (int midiChannel,
int midiNoteNumber,
float velocity);
virtual void noteOff (int midiChannel,
int midiNoteNumber,
float velocity,
bool allowTailOff);
virtual void allNotesOff (int midiChannel,
bool allowTailOff);
virtual void handlePitchWheel (int midiChannel,
int wheelValue);
virtual void handleController (int midiChannel,
int controllerNumber,
int controllerValue);
virtual void handleAftertouch (int midiChannel, int midiNoteNumber, int aftertouchValue);
virtual void handleChannelPressure (int midiChannel, int channelPressureValue);
virtual void handleSustainPedal (int midiChannel, bool isDown);
virtual void handleSostenutoPedal (int midiChannel, bool isDown);
virtual void handleSoftPedal (int midiChannel, bool isDown);
virtual void handleProgramChange (int midiChannel,
int programNumber);
//==============================================================================
virtual void setCurrentPlaybackSampleRate (double sampleRate);
void renderNextBlock (AudioBuffer<float>& outputAudio,
const MidiBuffer& inputMidi,
int startSample,
int numSamples);
void renderNextBlock (AudioBuffer<double>& outputAudio,
const MidiBuffer& inputMidi,
int startSample,
int numSamples);
double getSampleRate() const noexcept { return sampleRate; }
void setMinimumRenderingSubdivisionSize (int numSamples, bool shouldBeStrict = false) noexcept;
protected:
//==============================================================================
CriticalSection lock;
OwnedArray<SynthesiserVoice> voices;
ReferenceCountedArray<SynthesiserSound> sounds;
int lastPitchWheelValues [16];
virtual void renderVoices (AudioBuffer<float>& outputAudio,
int startSample, int numSamples);
virtual void renderVoices (AudioBuffer<double>& outputAudio,
int startSample, int numSamples);
virtual SynthesiserVoice* findFreeVoice (SynthesiserSound* soundToPlay,
int midiChannel,
int midiNoteNumber,
bool stealIfNoneAvailable) const;
virtual SynthesiserVoice* findVoiceToSteal (SynthesiserSound* soundToPlay,
int midiChannel,
int midiNoteNumber) const;
void startVoice (SynthesiserVoice* voice,
SynthesiserSound* sound,
int midiChannel,
int midiNoteNumber,
float velocity);
void stopVoice (SynthesiserVoice*, float velocity, bool allowTailOff);
virtual void handleMidiEvent (const MidiMessage&);
private:
//==============================================================================
double sampleRate = 0;
uint32 lastNoteOnCounter = 0;
int minimumSubBlockSize = 32;
bool subBlockSubdivisionIsStrict = false;
bool shouldStealNotes = true;
BigInteger sustainPedalsDown;
mutable CriticalSection stealLock;
mutable Array<SynthesiserVoice*> usableVoicesToStealArray;
template <typename floatType>
void processNextBlock (AudioBuffer<floatType>&, const MidiBuffer&, int startSample, int numSamples);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser)
};
} // namespace juce
juce::Array
Definition juce_Array.h:56
juce::AudioBuffer
Definition juce_AudioSampleBuffer.h:34
juce::BigInteger
Definition juce_BigInteger.h:39
juce::CriticalSection
Definition juce_CriticalSection.h:43
juce::MidiBuffer
Definition juce_MidiBuffer.h:145
juce::MidiMessage
Definition juce_MidiMessage.h:35
juce::OwnedArray
Definition juce_OwnedArray.h:50
juce::ReferenceCountedArray
Definition juce_ReferenceCountedArray.h:51
juce::ReferenceCountedObjectPtr
Definition juce_ReferenceCountedObject.h:247
juce::ReferenceCountedObject::ReferenceCountedObject
ReferenceCountedObject()=default
juce::SynthesiserSound
Definition juce_Synthesiser.h:42
juce::SynthesiserSound::Ptr
ReferenceCountedObjectPtr< SynthesiserSound > Ptr
Definition juce_Synthesiser.h:67
juce::SynthesiserSound::appliesToNote
virtual bool appliesToNote(int midiNoteNumber)=0
juce::SynthesiserSound::appliesToChannel
virtual bool appliesToChannel(int midiChannel)=0
juce::SynthesiserVoice
Definition juce_Synthesiser.h:88
juce::SynthesiserVoice::isSostenutoPedalDown
bool isSostenutoPedalDown() const noexcept
Definition juce_Synthesiser.h:235
juce::SynthesiserVoice::getSampleRate
double getSampleRate() const noexcept
Definition juce_Synthesiser.h:215
juce::SynthesiserVoice::stopNote
virtual void stopNote(float velocity, bool allowTailOff)=0
juce::SynthesiserVoice::isSustainPedalDown
bool isSustainPedalDown() const noexcept
Definition juce_Synthesiser.h:229
juce::SynthesiserVoice::setSustainPedalDown
void setSustainPedalDown(bool isNowDown) noexcept
Definition juce_Synthesiser.h:232
juce::SynthesiserVoice::SynthesiserVoice
SynthesiserVoice()
Definition juce_Synthesiser.cpp:30
juce::SynthesiserVoice::channelPressureChanged
virtual void channelPressureChanged(int newChannelPressureValue)
Definition juce_Synthesiser.cpp:56
juce::SynthesiserVoice::setSostenutoPedalDown
void setSostenutoPedalDown(bool isNowDown) noexcept
Definition juce_Synthesiser.h:238
juce::SynthesiserVoice::renderNextBlock
virtual void renderNextBlock(AudioBuffer< float > &outputBuffer, int startSample, int numSamples)=0
juce::SynthesiserVoice::isPlayingChannel
virtual bool isPlayingChannel(int midiChannel) const
Definition juce_Synthesiser.cpp:33
juce::SynthesiserVoice::isKeyDown
bool isKeyDown() const noexcept
Definition juce_Synthesiser.h:221
juce::SynthesiserVoice::setKeyDown
void setKeyDown(bool isNowDown) noexcept
Definition juce_Synthesiser.h:226
juce::SynthesiserVoice::setCurrentPlaybackSampleRate
virtual void setCurrentPlaybackSampleRate(double newRate)
Definition juce_Synthesiser.cpp:38
juce::SynthesiserVoice::aftertouchChanged
virtual void aftertouchChanged(int newAftertouchValue)
Definition juce_Synthesiser.cpp:55
juce::SynthesiserVoice::controllerMoved
virtual void controllerMoved(int controllerNumber, int newControllerValue)=0
juce::SynthesiserVoice::getCurrentlyPlayingNote
int getCurrentlyPlayingNote() const noexcept
Definition juce_Synthesiser.h:101
juce::SynthesiserVoice::startNote
virtual void startNote(int midiNoteNumber, float velocity, SynthesiserSound *sound, int currentPitchWheelPosition)=0
juce::SynthesiserVoice::canPlaySound
virtual bool canPlaySound(SynthesiserSound *)=0
juce::SynthesiserVoice::pitchWheelMoved
virtual void pitchWheelMoved(int newPitchWheelValue)=0
juce::SynthesiserVoice::isPlayingButReleased
bool isPlayingButReleased() const noexcept
Definition juce_Synthesiser.h:241
juce::SynthesiserVoice::getCurrentlyPlayingSound
SynthesiserSound::Ptr getCurrentlyPlayingSound() const noexcept
Definition juce_Synthesiser.h:106
juce::SynthesiserVoice::isVoiceActive
virtual bool isVoiceActive() const
Definition juce_Synthesiser.cpp:43
juce::Synthesiser
Definition juce_Synthesiser.h:308
juce::Synthesiser::Synthesiser
Synthesiser()
Definition juce_Synthesiser.cpp:76
juce::Synthesiser::findFreeVoice
virtual SynthesiserVoice * findFreeVoice(SynthesiserSound *soundToPlay, int midiChannel, int midiNoteNumber, bool stealIfNoneAvailable) const
Definition juce_Synthesiser.cpp:497
juce::Synthesiser::startVoice
void startVoice(SynthesiserVoice *voice, SynthesiserSound *sound, int midiChannel, int midiNoteNumber, float velocity)
Definition juce_Synthesiser.cpp:317
juce::Synthesiser::findVoiceToSteal
virtual SynthesiserVoice * findVoiceToSteal(SynthesiserSound *soundToPlay, int midiChannel, int midiNoteNumber) const
Definition juce_Synthesiser.cpp:513
juce::Synthesiser::stopVoice
void stopVoice(SynthesiserVoice *, float velocity, bool allowTailOff)
Definition juce_Synthesiser.cpp:341
juce::Synthesiser::getNumSounds
int getNumSounds() const noexcept
Definition juce_Synthesiser.h:347
juce::Synthesiser::getSampleRate
double getSampleRate() const noexcept
Definition juce_Synthesiser.h:536
juce::Synthesiser::renderVoices
virtual void renderVoices(AudioBuffer< float > &outputAudio, int startSample, int numSamples)
Definition juce_Synthesiser.cpp:242
juce::Synthesiser::handleMidiEvent
virtual void handleMidiEvent(const MidiMessage &)
Definition juce_Synthesiser.cpp:254
juce::Synthesiser::getNumVoices
int getNumVoices() const noexcept
Definition juce_Synthesiser.h:324
juce::Synthesiser::isNoteStealingEnabled
bool isNoteStealingEnabled() const noexcept
Definition juce_Synthesiser.h:374
juce::Synthesiser::getSound
SynthesiserSound::Ptr getSound(int index) const noexcept
Definition juce_Synthesiser.h:350
juce::Synthesiser::lock
CriticalSection lock
Definition juce_Synthesiser.h:563
juce::Synthesiser::lastPitchWheelValues
int lastPitchWheelValues[16]
Definition juce_Synthesiser.h:569
juce::Synthesiser::clearVoices
void clearVoices()
Definition juce_Synthesiser.cpp:93