| @@ -26,137 +26,11 @@ | |||||
| #include "PluginProcessor.h" | #include "PluginProcessor.h" | ||||
| #include "PluginEditor.h" | #include "PluginEditor.h" | ||||
| #include "SinewaveSynth.h" | |||||
| AudioProcessor* JUCE_CALLTYPE createPluginFilter(); | AudioProcessor* JUCE_CALLTYPE createPluginFilter(); | ||||
| //============================================================================== | |||||
| /** A demo synth sound that's just a basic sine wave.. */ | |||||
| class SineWaveSound : public SynthesiserSound | |||||
| { | |||||
| public: | |||||
| SineWaveSound() {} | |||||
| bool appliesToNote (int /*midiNoteNumber*/) override { return true; } | |||||
| bool appliesToChannel (int /*midiChannel*/) override { return true; } | |||||
| }; | |||||
| //============================================================================== | |||||
| /** A simple demo synth voice that just plays a sine wave.. */ | |||||
| class SineWaveVoice : public SynthesiserVoice | |||||
| { | |||||
| public: | |||||
| SineWaveVoice() | |||||
| { | |||||
| } | |||||
| bool canPlaySound (SynthesiserSound* sound) override | |||||
| { | |||||
| return dynamic_cast<SineWaveSound*> (sound) != nullptr; | |||||
| } | |||||
| void startNote (int midiNoteNumber, float velocity, | |||||
| SynthesiserSound* /*sound*/, | |||||
| int /*currentPitchWheelPosition*/) override | |||||
| { | |||||
| currentAngle = 0.0; | |||||
| level = velocity * 0.15; | |||||
| tailOff = 0.0; | |||||
| double cyclesPerSecond = MidiMessage::getMidiNoteInHertz (midiNoteNumber); | |||||
| double cyclesPerSample = cyclesPerSecond / getSampleRate(); | |||||
| angleDelta = cyclesPerSample * 2.0 * double_Pi; | |||||
| } | |||||
| void stopNote (float /*velocity*/, bool allowTailOff) override | |||||
| { | |||||
| if (allowTailOff) | |||||
| { | |||||
| // start a tail-off by setting this flag. The render callback will pick up on | |||||
| // this and do a fade out, calling clearCurrentNote() when it's finished. | |||||
| if (tailOff == 0.0) // we only need to begin a tail-off if it's not already doing so - the | |||||
| // stopNote method could be called more than once. | |||||
| tailOff = 1.0; | |||||
| } | |||||
| else | |||||
| { | |||||
| // we're being told to stop playing immediately, so reset everything.. | |||||
| clearCurrentNote(); | |||||
| angleDelta = 0.0; | |||||
| } | |||||
| } | |||||
| void pitchWheelMoved (int /*newValue*/) override | |||||
| { | |||||
| // can't be bothered implementing this for the demo! | |||||
| } | |||||
| void controllerMoved (int /*controllerNumber*/, int /*newValue*/) override | |||||
| { | |||||
| // not interested in controllers in this case. | |||||
| } | |||||
| void renderNextBlock (AudioBuffer<float>& outputBuffer, int startSample, int numSamples) override | |||||
| { | |||||
| processBlock (outputBuffer, startSample, numSamples); | |||||
| } | |||||
| void renderNextBlock (AudioBuffer<double>& outputBuffer, int startSample, int numSamples) override | |||||
| { | |||||
| processBlock (outputBuffer, startSample, numSamples); | |||||
| } | |||||
| private: | |||||
| template <typename FloatType> | |||||
| void processBlock (AudioBuffer<FloatType>& outputBuffer, int startSample, int numSamples) | |||||
| { | |||||
| if (angleDelta != 0.0) | |||||
| { | |||||
| if (tailOff > 0) | |||||
| { | |||||
| while (--numSamples >= 0) | |||||
| { | |||||
| auto currentSample = static_cast<FloatType> (std::sin (currentAngle) * level * tailOff); | |||||
| for (int i = outputBuffer.getNumChannels(); --i >= 0;) | |||||
| outputBuffer.addSample (i, startSample, currentSample); | |||||
| currentAngle += angleDelta; | |||||
| ++startSample; | |||||
| tailOff *= 0.99; | |||||
| if (tailOff <= 0.005) | |||||
| { | |||||
| clearCurrentNote(); | |||||
| angleDelta = 0.0; | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| while (--numSamples >= 0) | |||||
| { | |||||
| auto currentSample = static_cast<FloatType> (std::sin (currentAngle) * level); | |||||
| for (int i = outputBuffer.getNumChannels(); --i >= 0;) | |||||
| outputBuffer.addSample (i, startSample, currentSample); | |||||
| currentAngle += angleDelta; | |||||
| ++startSample; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| double currentAngle = 0, angleDelta = 0, level = 0, tailOff = 0; | |||||
| }; | |||||
| //============================================================================== | //============================================================================== | ||||
| JuceDemoPluginAudioProcessor::JuceDemoPluginAudioProcessor() | JuceDemoPluginAudioProcessor::JuceDemoPluginAudioProcessor() | ||||
| : AudioProcessor (getBusesProperties()) | : AudioProcessor (getBusesProperties()) | ||||