Browse Source

Added a velocity argument to the synthesiser noteOff methods.

tags/2021-05-28
jules 11 years ago
parent
commit
527d1459df
6 changed files with 44 additions and 23 deletions
  1. +1
    -1
      extras/Demo/Source/Demos/AudioSynthesiserDemo.cpp
  2. +4
    -3
      extras/audio plugin demo/Source/PluginProcessor.cpp
  3. +16
    -12
      modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp
  4. +19
    -3
      modules/juce_audio_basics/synthesisers/juce_Synthesiser.h
  5. +3
    -3
      modules/juce_audio_formats/sampler/juce_Sampler.cpp
  6. +1
    -1
      modules/juce_audio_formats/sampler/juce_Sampler.h

+ 1
- 1
extras/Demo/Source/Demos/AudioSynthesiserDemo.cpp View File

@@ -63,7 +63,7 @@ struct SineWaveVoice : public SynthesiserVoice
angleDelta = cyclesPerSample * 2.0 * double_Pi; angleDelta = cyclesPerSample * 2.0 * double_Pi;
} }
void stopNote (bool allowTailOff) override
void stopNote (float /*velocity*/, bool allowTailOff) override
{ {
if (allowTailOff) if (allowTailOff)
{ {


+ 4
- 3
extras/audio plugin demo/Source/PluginProcessor.cpp View File

@@ -38,11 +38,12 @@ public:
bool canPlaySound (SynthesiserSound* sound) override bool canPlaySound (SynthesiserSound* sound) override
{ {
return dynamic_cast <SineWaveSound*> (sound) != 0;
return dynamic_cast<SineWaveSound*> (sound) != nullptr;
} }
void startNote (int midiNoteNumber, float velocity, void startNote (int midiNoteNumber, float velocity,
SynthesiserSound* /*sound*/, int /*currentPitchWheelPosition*/) override
SynthesiserSound* /*sound*/,
int /*currentPitchWheelPosition*/) override
{ {
currentAngle = 0.0; currentAngle = 0.0;
level = velocity * 0.15; level = velocity * 0.15;
@@ -54,7 +55,7 @@ public:
angleDelta = cyclesPerSample * 2.0 * double_Pi; angleDelta = cyclesPerSample * 2.0 * double_Pi;
} }
void stopNote (bool allowTailOff) override
void stopNote (float velocity, bool allowTailOff) override
{ {
if (allowTailOff) if (allowTailOff)
{ {


+ 16
- 12
modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp View File

@@ -163,10 +163,7 @@ void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBu
: numSamples; : numSamples;
if (numThisTime > 0) if (numThisTime > 0)
{
for (int i = voices.size(); --i >= 0;)
voices.getUnchecked (i)->renderNextBlock (outputBuffer, startSample, numThisTime);
}
renderVoices (outputBuffer, startSample, numThisTime);
if (useEvent) if (useEvent)
handleMidiEvent (m); handleMidiEvent (m);
@@ -176,6 +173,12 @@ void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBu
} }
} }
void Synthesiser::renderVoices (AudioSampleBuffer& buffer, int startSample, int numSamples)
{
for (int i = voices.size(); --i >= 0;)
voices.getUnchecked (i)->renderNextBlock (buffer, startSample, numSamples);
}
void Synthesiser::handleMidiEvent (const MidiMessage& m) void Synthesiser::handleMidiEvent (const MidiMessage& m)
{ {
if (m.isNoteOn()) if (m.isNoteOn())
@@ -184,7 +187,7 @@ void Synthesiser::handleMidiEvent (const MidiMessage& m)
} }
else if (m.isNoteOff()) else if (m.isNoteOff())
{ {
noteOff (m.getChannel(), m.getNoteNumber(), true);
noteOff (m.getChannel(), m.getNoteNumber(), m.getFloatVelocity(), true);
} }
else if (m.isAllNotesOff() || m.isAllSoundOff()) else if (m.isAllNotesOff() || m.isAllSoundOff())
{ {
@@ -230,7 +233,7 @@ void Synthesiser::noteOn (const int midiChannel,
if (voice->getCurrentlyPlayingNote() == midiNoteNumber if (voice->getCurrentlyPlayingNote() == midiNoteNumber
&& voice->isPlayingChannel (midiChannel)) && voice->isPlayingChannel (midiChannel))
stopVoice (voice, true);
stopVoice (voice, 1.0f, true);
} }
startVoice (findFreeVoice (sound, shouldStealNotes), startVoice (findFreeVoice (sound, shouldStealNotes),
@@ -248,7 +251,7 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice,
if (voice != nullptr && sound != nullptr) if (voice != nullptr && sound != nullptr)
{ {
if (voice->currentlyPlayingSound != nullptr) if (voice->currentlyPlayingSound != nullptr)
voice->stopNote (false);
voice->stopNote (0.0f, false);
voice->startNote (midiNoteNumber, velocity, sound, voice->startNote (midiNoteNumber, velocity, sound,
lastPitchWheelValues [midiChannel - 1]); lastPitchWheelValues [midiChannel - 1]);
@@ -261,11 +264,11 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice,
} }
} }
void Synthesiser::stopVoice (SynthesiserVoice* voice, const bool allowTailOff)
void Synthesiser::stopVoice (SynthesiserVoice* voice, float velocity, const bool allowTailOff)
{ {
jassert (voice != nullptr); jassert (voice != nullptr);
voice->stopNote (allowTailOff);
voice->stopNote (velocity, allowTailOff);
// the subclass MUST call clearCurrentNote() if it's not tailing off! RTFM for stopNote()! // the subclass MUST call clearCurrentNote() if it's not tailing off! RTFM for stopNote()!
jassert (allowTailOff || (voice->getCurrentlyPlayingNote() < 0 && voice->getCurrentlyPlayingSound() == 0)); jassert (allowTailOff || (voice->getCurrentlyPlayingNote() < 0 && voice->getCurrentlyPlayingSound() == 0));
@@ -273,6 +276,7 @@ void Synthesiser::stopVoice (SynthesiserVoice* voice, const bool allowTailOff)
void Synthesiser::noteOff (const int midiChannel, void Synthesiser::noteOff (const int midiChannel,
const int midiNoteNumber, const int midiNoteNumber,
const float velocity,
const bool allowTailOff) const bool allowTailOff)
{ {
const ScopedLock sl (lock); const ScopedLock sl (lock);
@@ -291,7 +295,7 @@ void Synthesiser::noteOff (const int midiChannel,
voice->keyIsDown = false; voice->keyIsDown = false;
if (! (sustainPedalsDown [midiChannel] || voice->sostenutoPedalDown)) if (! (sustainPedalsDown [midiChannel] || voice->sostenutoPedalDown))
stopVoice (voice, allowTailOff);
stopVoice (voice, velocity, allowTailOff);
} }
} }
} }
@@ -379,7 +383,7 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown)
SynthesiserVoice* const voice = voices.getUnchecked (i); SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->isPlayingChannel (midiChannel) && ! voice->keyIsDown) if (voice->isPlayingChannel (midiChannel) && ! voice->keyIsDown)
stopVoice (voice, true);
stopVoice (voice, 1.0f, true);
} }
sustainPedalsDown.clearBit (midiChannel); sustainPedalsDown.clearBit (midiChannel);
@@ -400,7 +404,7 @@ void Synthesiser::handleSostenutoPedal (int midiChannel, bool isDown)
if (isDown) if (isDown)
voice->sostenutoPedalDown = true; voice->sostenutoPedalDown = true;
else if (voice->sostenutoPedalDown) else if (voice->sostenutoPedalDown)
stopVoice (voice, true);
stopVoice (voice, 1.0f, true);
} }
} }
} }


+ 19
- 3
modules/juce_audio_basics/synthesisers/juce_Synthesiser.h View File

@@ -127,6 +127,8 @@ public:
This will be called during the rendering callback, so must be fast and thread-safe. This will be called during the rendering callback, so must be fast and thread-safe.
The velocity indicates how quickly the note was released - 0 is slowly, 1 is quickly.
If allowTailOff is false or the voice doesn't want to tail-off, then it must stop all If allowTailOff is false or the voice doesn't want to tail-off, then it must stop all
sound immediately, and must call clearCurrentNote() to reset the state of this voice sound immediately, and must call clearCurrentNote() to reset the state of this voice
and allow the synth to reassign it another sound. and allow the synth to reassign it another sound.
@@ -136,7 +138,7 @@ public:
finishes playing (during the rendering callback), it must make sure that it calls finishes playing (during the rendering callback), it must make sure that it calls
clearCurrentNote(). clearCurrentNote().
*/ */
virtual void stopNote (bool allowTailOff) = 0;
virtual void stopNote (float velocity, bool allowTailOff) = 0;
/** Called to let the voice know that the pitch wheel has been moved. /** Called to let the voice know that the pitch wheel has been moved.
This will be called during the rendering callback, so must be fast and thread-safe. This will be called during the rendering callback, so must be fast and thread-safe.
@@ -235,6 +237,11 @@ private:
SynthesiserSound::Ptr currentlyPlayingSound; SynthesiserSound::Ptr currentlyPlayingSound;
bool keyIsDown, sostenutoPedalDown; bool keyIsDown, sostenutoPedalDown;
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// Note the new parameters for this method.
virtual int stopNote (bool) { return 0; }
#endif
JUCE_LEAK_DETECTOR (SynthesiserVoice) JUCE_LEAK_DETECTOR (SynthesiserVoice)
}; };
@@ -365,6 +372,7 @@ public:
*/ */
virtual void noteOff (int midiChannel, virtual void noteOff (int midiChannel,
int midiNoteNumber, int midiNoteNumber,
float velocity,
bool allowTailOff); bool allowTailOff);
/** Turns off all notes. /** Turns off all notes.
@@ -474,6 +482,13 @@ protected:
/** The last pitch-wheel values for each midi channel. */ /** The last pitch-wheel values for each midi channel. */
int lastPitchWheelValues [16]; int lastPitchWheelValues [16];
/** Renders the voices for the given range.
By default this just calls renderNextBlock() on each voice, but you may need
to override it to handle custom cases.
*/
virtual void renderVoices (AudioSampleBuffer& outputAudio,
int startSample, int numSamples);
/** Searches through the voices to find one that's not currently playing, and which /** Searches through the voices to find one that's not currently playing, and which
can play the given sound. can play the given sound.
@@ -511,11 +526,12 @@ private:
bool shouldStealNotes; bool shouldStealNotes;
BigInteger sustainPedalsDown; BigInteger sustainPedalsDown;
void stopVoice (SynthesiserVoice*, bool allowTailOff);
void stopVoice (SynthesiserVoice*, float velocity, bool allowTailOff);
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE #if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// Note the new parameters for this method.
// Note the new parameters for these methods.
virtual int findFreeVoice (const bool) const { return 0; } virtual int findFreeVoice (const bool) const { return 0; }
virtual int noteOff (int, int, int) { return 0; }
#endif #endif
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser)


+ 3
- 3
modules/juce_audio_formats/sampler/juce_Sampler.cpp View File

@@ -127,7 +127,7 @@ void SamplerVoice::startNote (const int midiNoteNumber,
} }
} }
void SamplerVoice::stopNote (const bool allowTailOff)
void SamplerVoice::stopNote (float /*velocity*/, bool allowTailOff)
{ {
if (allowTailOff) if (allowTailOff)
{ {
@@ -197,7 +197,7 @@ void SamplerVoice::renderNextBlock (AudioSampleBuffer& outputBuffer, int startSa
if (attackReleaseLevel <= 0.0f) if (attackReleaseLevel <= 0.0f)
{ {
stopNote (false);
stopNote (0.0f, false);
break; break;
} }
} }
@@ -216,7 +216,7 @@ void SamplerVoice::renderNextBlock (AudioSampleBuffer& outputBuffer, int startSa
if (sourceSamplePosition > playingSound->length) if (sourceSamplePosition > playingSound->length)
{ {
stopNote (false);
stopNote (0.0f, false);
break; break;
} }
} }


+ 1
- 1
modules/juce_audio_formats/sampler/juce_Sampler.h View File

@@ -124,7 +124,7 @@ public:
bool canPlaySound (SynthesiserSound*) override; bool canPlaySound (SynthesiserSound*) override;
void startNote (int midiNoteNumber, float velocity, SynthesiserSound*, int pitchWheel) override; void startNote (int midiNoteNumber, float velocity, SynthesiserSound*, int pitchWheel) override;
void stopNote (bool allowTailOff) override;
void stopNote (float velocity, bool allowTailOff) override;
void pitchWheelMoved (int newValue); void pitchWheelMoved (int newValue);
void controllerMoved (int controllerNumber, int newValue) override; void controllerMoved (int controllerNumber, int newValue) override;


Loading…
Cancel
Save