andrewm@0: /* andrewm@0: This code accompanies the textbook: andrewm@0: andrewm@0: Digital Audio Effects: Theory, Implementation and Application andrewm@0: Joshua D. Reiss and Andrew P. McPherson andrewm@0: andrewm@0: --- andrewm@0: andrewm@0: Phaser: phasing effect using time-varying allpass filters andrewm@0: See textbook Chapter 4: Filter Effects andrewm@0: andrewm@0: Code by Andrew McPherson, Brecht De Man and Joshua Reiss andrewm@0: andrewm@0: --- andrewm@0: andrewm@0: This program is free software: you can redistribute it and/or modify andrewm@0: it under the terms of the GNU General Public License as published by andrewm@0: the Free Software Foundation, either version 3 of the License, or andrewm@0: (at your option) any later version. andrewm@0: andrewm@0: This program is distributed in the hope that it will be useful, andrewm@0: but WITHOUT ANY WARRANTY; without even the implied warranty of andrewm@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the andrewm@0: GNU General Public License for more details. andrewm@0: andrewm@0: You should have received a copy of the GNU General Public License andrewm@0: along with this program. If not, see . andrewm@0: */ andrewm@0: andrewm@0: #ifndef __PLUGINPROCESSOR_H_4693CB6E__ andrewm@0: #define __PLUGINPROCESSOR_H_4693CB6E__ andrewm@0: andrewm@0: #define _USE_MATH_DEFINES andrewm@0: #include "../JuceLibraryCode/JuceHeader.h" andrewm@0: #include "OnePoleAllpassFilter.h" andrewm@0: #include "TwoPoleAllpassFilter.h" andrewm@0: andrewm@0: //============================================================================== andrewm@0: /** andrewm@0: */ andrewm@0: class PhaserAudioProcessor : public AudioProcessor andrewm@0: { andrewm@0: public: andrewm@0: //============================================================================== andrewm@0: PhaserAudioProcessor(); andrewm@0: ~PhaserAudioProcessor(); andrewm@0: andrewm@0: //============================================================================== andrewm@0: void prepareToPlay (double sampleRate, int samplesPerBlock); andrewm@0: void releaseResources(); andrewm@0: void reset(); andrewm@0: void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages); andrewm@0: andrewm@0: andrewm@0: //============================================================================== andrewm@0: AudioProcessorEditor* createEditor(); andrewm@0: bool hasEditor() const; andrewm@0: andrewm@0: //============================================================================== andrewm@0: const String getName() const; andrewm@0: andrewm@0: int getNumParameters(); andrewm@0: andrewm@0: float getParameter (int index); andrewm@0: void setParameter (int index, float newValue); andrewm@0: andrewm@0: const String getParameterName (int index); andrewm@0: const String getParameterText (int index); andrewm@0: andrewm@0: const String getInputChannelName (int channelIndex) const; andrewm@0: const String getOutputChannelName (int channelIndex) const; andrewm@0: bool isInputChannelStereoPair (int index) const; andrewm@0: bool isOutputChannelStereoPair (int index) const; andrewm@0: andrewm@0: bool silenceInProducesSilenceOut() const; andrewm@0: double getTailLengthSeconds() const; andrewm@0: bool acceptsMidi() const; andrewm@0: bool producesMidi() const; andrewm@0: andrewm@0: //============================================================================== andrewm@0: int getNumPrograms(); andrewm@0: int getCurrentProgram(); andrewm@0: void setCurrentProgram (int index); andrewm@0: const String getProgramName (int index); andrewm@0: void changeProgramName (int index, const String& newName); andrewm@0: andrewm@0: //============================================================================== andrewm@0: void getStateInformation (MemoryBlock& destData); andrewm@0: void setStateInformation (const void* data, int sizeInBytes); andrewm@0: andrewm@0: //============================================================================== andrewm@0: andrewm@0: // these are used to persist the UI's size - the values are stored along with the andrewm@0: // filter's other parameters, and the UI component will update them when it gets andrewm@0: // resized. andrewm@0: int lastUIWidth_, lastUIHeight_; andrewm@0: andrewm@0: enum Parameters andrewm@0: { andrewm@0: kBaseFrequencyParam = 0, andrewm@0: kSweepWidthParam, andrewm@0: kDepthParam, andrewm@0: kFeedbackParam, andrewm@0: kLFOFrequencyParam, andrewm@0: kFiltersParam, andrewm@0: kWaveformParam, andrewm@0: kStereoParam, andrewm@0: kNumParameters andrewm@0: }; andrewm@0: andrewm@0: enum Waveforms andrewm@0: { andrewm@0: kWaveformSine = 1, andrewm@0: kWaveformTriangle, andrewm@0: kWaveformSquare, andrewm@0: kWaveformSawtooth, andrewm@0: kNumWaveforms andrewm@0: }; andrewm@0: andrewm@0: // Adjustable parameters: andrewm@0: float baseFrequency_; // Lowest frequency of allpass filters andrewm@0: float sweepWidth_; // Amount of change from min to max delay andrewm@0: float depth_; // Mix level for phase-shifted signal (0-1) andrewm@0: float feedback_; // Feedback level for feedback phaser (0-<1) andrewm@0: float lfoFrequency_; // LFO frequency (Hz) andrewm@0: int filtersPerChannel_; // How many allpass filters to use andrewm@0: int waveform_; // What shape should be used for the LFO andrewm@0: int stereo_; // Whether to use stereo phasing andrewm@0: andrewm@0: private: andrewm@0: float lfo(float phase, int waveform); andrewm@0: void allocateFilters(); // Create the filter objects... andrewm@0: void deallocateFilters(); // Delete them... andrewm@0: void reallocateFilters(); // Delete and rebuild in one combined operation andrewm@0: andrewm@0: CriticalSection lock_; // Lock for updating number of filters andrewm@0: andrewm@0: float lfoPhase_; // Phase of the low-frequency oscillator andrewm@0: double inverseSampleRate_; // It's more efficient to multiply than divide, so andrewm@0: // cache the inverse of the sample rate andrewm@0: unsigned int sampleCount_; // Counter to keep track of samples elapsed, to andrewm@0: // keep track of filter updates andrewm@0: unsigned int filterUpdateInterval_; // How often to update filter coefficients andrewm@0: andrewm@0: // Bank of allpass filters that do the phasing; N filters x M channels andrewm@0: OnePoleAllpassFilter **allpassFilters_; andrewm@0: andrewm@0: // Storage of the last output sample from each bank of filters, for use in andrewm@0: // feedback loop andrewm@0: float *lastFilterOutputs_; andrewm@0: int numLastFilterOutputs_; andrewm@0: andrewm@0: int totalNumFilters_; andrewm@0: andrewm@0: //============================================================================== andrewm@0: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PhaserAudioProcessor); andrewm@0: }; andrewm@0: andrewm@0: #endif // __PLUGINPROCESSOR_H_4693CB6E__