andrewm@0
|
1 /*
|
andrewm@0
|
2 This code accompanies the textbook:
|
andrewm@0
|
3
|
andrewm@0
|
4 Digital Audio Effects: Theory, Implementation and Application
|
andrewm@0
|
5 Joshua D. Reiss and Andrew P. McPherson
|
andrewm@0
|
6
|
andrewm@0
|
7 ---
|
andrewm@0
|
8
|
andrewm@0
|
9 PVOC Passthrough: phase vocoder structure which passes input
|
andrewm@0
|
10 to output without performing any processing
|
andrewm@0
|
11
|
andrewm@0
|
12 See textbook Chapter 8: The Phase Vocoder
|
andrewm@0
|
13
|
andrewm@0
|
14 Code by Andrew McPherson, Brecht De Man and Joshua Reiss
|
andrewm@0
|
15
|
andrewm@0
|
16 This code requires the fftw library version 3 to compile:
|
andrewm@0
|
17 http://fftw.org
|
andrewm@0
|
18
|
andrewm@0
|
19 ---
|
andrewm@0
|
20
|
andrewm@0
|
21 This program is free software: you can redistribute it and/or modify
|
andrewm@0
|
22 it under the terms of the GNU General Public License as published by
|
andrewm@0
|
23 the Free Software Foundation, either version 3 of the License, or
|
andrewm@0
|
24 (at your option) any later version.
|
andrewm@0
|
25
|
andrewm@0
|
26 This program is distributed in the hope that it will be useful,
|
andrewm@0
|
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
andrewm@0
|
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
andrewm@0
|
29 GNU General Public License for more details.
|
andrewm@0
|
30
|
andrewm@0
|
31 You should have received a copy of the GNU General Public License
|
andrewm@0
|
32 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
andrewm@0
|
33 */
|
andrewm@0
|
34
|
andrewm@0
|
35 #ifndef __PLUGINPROCESSOR_H_4693CB6E__
|
andrewm@0
|
36 #define __PLUGINPROCESSOR_H_4693CB6E__
|
andrewm@0
|
37
|
andrewm@0
|
38 #include "../JuceLibraryCode/JuceHeader.h"
|
andrewm@0
|
39 #include <fftw3.h>
|
andrewm@0
|
40
|
andrewm@0
|
41 //==============================================================================
|
andrewm@0
|
42 /**
|
andrewm@0
|
43 */
|
andrewm@0
|
44 class PVOCPassthroughAudioProcessor : public AudioProcessor
|
andrewm@0
|
45 {
|
andrewm@0
|
46 public:
|
andrewm@0
|
47 //==============================================================================
|
andrewm@0
|
48 PVOCPassthroughAudioProcessor();
|
andrewm@0
|
49 ~PVOCPassthroughAudioProcessor();
|
andrewm@0
|
50
|
andrewm@0
|
51 //==============================================================================
|
andrewm@0
|
52 void prepareToPlay (double sampleRate, int samplesPerBlock);
|
andrewm@0
|
53 void releaseResources();
|
andrewm@0
|
54
|
andrewm@0
|
55 void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
|
andrewm@0
|
56
|
andrewm@0
|
57 //==============================================================================
|
andrewm@0
|
58 AudioProcessorEditor* createEditor();
|
andrewm@0
|
59 bool hasEditor() const;
|
andrewm@0
|
60
|
andrewm@0
|
61 //==============================================================================
|
andrewm@0
|
62 const String getName() const;
|
andrewm@0
|
63
|
andrewm@0
|
64 int getNumParameters();
|
andrewm@0
|
65
|
andrewm@0
|
66 float getParameter (int index);
|
andrewm@0
|
67 void setParameter (int index, float newValue);
|
andrewm@0
|
68
|
andrewm@0
|
69 const String getParameterName (int index);
|
andrewm@0
|
70 const String getParameterText (int index);
|
andrewm@0
|
71
|
andrewm@0
|
72 const String getInputChannelName (int channelIndex) const;
|
andrewm@0
|
73 const String getOutputChannelName (int channelIndex) const;
|
andrewm@0
|
74 bool isInputChannelStereoPair (int index) const;
|
andrewm@0
|
75 bool isOutputChannelStereoPair (int index) const;
|
andrewm@0
|
76
|
andrewm@0
|
77 bool silenceInProducesSilenceOut() const;
|
andrewm@0
|
78 double getTailLengthSeconds() const;
|
andrewm@0
|
79 bool acceptsMidi() const;
|
andrewm@0
|
80 bool producesMidi() const;
|
andrewm@0
|
81
|
andrewm@0
|
82 //==============================================================================
|
andrewm@0
|
83 int getNumPrograms();
|
andrewm@0
|
84 int getCurrentProgram();
|
andrewm@0
|
85 void setCurrentProgram (int index);
|
andrewm@0
|
86 const String getProgramName (int index);
|
andrewm@0
|
87 void changeProgramName (int index, const String& newName);
|
andrewm@0
|
88
|
andrewm@0
|
89 //==============================================================================
|
andrewm@0
|
90 void getStateInformation (MemoryBlock& destData);
|
andrewm@0
|
91 void setStateInformation (const void* data, int sizeInBytes);
|
andrewm@0
|
92
|
andrewm@0
|
93 //==============================================================================
|
andrewm@0
|
94
|
andrewm@0
|
95 // these are used to persist the UI's size - the values are stored along with the
|
andrewm@0
|
96 // filter's other parameters, and the UI component will update them when it gets
|
andrewm@0
|
97 // resized.
|
andrewm@0
|
98 int lastUIWidth_, lastUIHeight_;
|
andrewm@0
|
99
|
andrewm@0
|
100 enum Parameters
|
andrewm@0
|
101 {
|
andrewm@0
|
102 kFFTSizeParam = 0,
|
andrewm@0
|
103 kHopSizeParam,
|
andrewm@0
|
104 kWindowTypeParam,
|
andrewm@0
|
105 kNumParameters
|
andrewm@0
|
106 };
|
andrewm@0
|
107
|
andrewm@0
|
108 enum Window
|
andrewm@0
|
109 {
|
andrewm@0
|
110 kWindowRectangular = 1,
|
andrewm@0
|
111 kWindowBartlett,
|
andrewm@0
|
112 kWindowHann,
|
andrewm@0
|
113 kWindowHamming
|
andrewm@0
|
114 };
|
andrewm@0
|
115
|
andrewm@0
|
116 enum HopSize
|
andrewm@0
|
117 {
|
andrewm@0
|
118 kHopSize1Window = 1,
|
andrewm@0
|
119 kHopSize1_2Window,
|
andrewm@0
|
120 kHopSize1_4Window,
|
andrewm@0
|
121 kHopSize1_8Window
|
andrewm@0
|
122 };
|
andrewm@0
|
123
|
andrewm@0
|
124 // This parameter indicates the FFT size for phase vocoder computation. It is selected
|
andrewm@0
|
125 // by the GUI and may temporarily differ from the actual size used in calculations.
|
andrewm@0
|
126 int fftSelectedSize_;
|
andrewm@0
|
127 int hopSelectedSize_; // Hop size, chosen from one of the options above
|
andrewm@0
|
128 int windowType_; // Type of window used
|
andrewm@0
|
129
|
andrewm@0
|
130 private:
|
andrewm@0
|
131 // Methods to initialise and de-initialise the FFT machinery
|
andrewm@0
|
132 void initFFT(int length);
|
andrewm@0
|
133 void deinitFFT();
|
andrewm@0
|
134
|
andrewm@0
|
135 // Methods to initialise and de-initialise the window
|
andrewm@0
|
136 void initWindow(int length, int windowType);
|
andrewm@0
|
137 void deinitWindow();
|
andrewm@0
|
138
|
andrewm@0
|
139 // Methods to update the buffering for the given hop size and the output scaling
|
andrewm@0
|
140 void updateHopSize();
|
andrewm@0
|
141 void updateScaleFactor();
|
andrewm@0
|
142
|
andrewm@0
|
143 // Whether the FFT has been initialised and is therefore ready to go
|
andrewm@0
|
144 bool fftInitialised_;
|
andrewm@0
|
145
|
andrewm@0
|
146 // Variables for calculating the FFT and IFFT: complex data structures and the
|
andrewm@0
|
147 // "plan" used by the fftw library to calculate the transforms.
|
andrewm@0
|
148 fftw_complex *fftTimeDomain_, *fftFrequencyDomain_;
|
andrewm@0
|
149 fftw_plan fftForwardPlan_, fftBackwardPlan_;
|
andrewm@0
|
150
|
andrewm@0
|
151 // Size of the FFT (generally a power of two) and the hop size (in samples, generally a fraction of FFT size)
|
andrewm@0
|
152 int fftActualTransformSize_;
|
andrewm@0
|
153 int hopActualSize_;
|
andrewm@0
|
154
|
andrewm@0
|
155 // Amount by which to scale the inverse FFT to return to original amplitude: depends on the
|
andrewm@0
|
156 // transform size (because of fftw implementation) and the hop size (because of inherent overlap)
|
andrewm@0
|
157 double fftScaleFactor_;
|
andrewm@0
|
158
|
andrewm@0
|
159 // Circular buffer gathers audio samples from the input until enough are available
|
andrewm@0
|
160 // for the FFT calculation
|
andrewm@0
|
161 AudioSampleBuffer inputBuffer_;
|
andrewm@0
|
162 int inputBufferLength_;
|
andrewm@0
|
163 int inputBufferWritePosition_;
|
andrewm@0
|
164
|
andrewm@0
|
165 // Circular buffer that collects output samples from the FFT overlap-add process
|
andrewm@0
|
166 // before they are ready to be sent to the output stream
|
andrewm@0
|
167 AudioSampleBuffer outputBuffer_;
|
andrewm@0
|
168 int outputBufferLength_;
|
andrewm@0
|
169 int outputBufferReadPosition_, outputBufferWritePosition_;
|
andrewm@0
|
170
|
andrewm@0
|
171 // How many samples since the last FFT?
|
andrewm@0
|
172 int samplesSinceLastFFT_;
|
andrewm@0
|
173
|
andrewm@0
|
174 // Stored window function for pre-processing input frames
|
andrewm@0
|
175 double *windowBuffer_;
|
andrewm@0
|
176 int windowBufferLength_;
|
andrewm@0
|
177
|
andrewm@0
|
178 // Whether or not prepareToPlay() has been called, i.e. that resources are in use
|
andrewm@0
|
179 bool preparedToPlay_;
|
andrewm@0
|
180
|
andrewm@0
|
181 // Spin lock that prevents the FFT settings from changing in the middle of the audio
|
andrewm@0
|
182 // thread.
|
andrewm@0
|
183 SpinLock fftSpinLock_;
|
andrewm@0
|
184
|
andrewm@0
|
185 //==============================================================================
|
andrewm@0
|
186 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PVOCPassthroughAudioProcessor);
|
andrewm@0
|
187 };
|
andrewm@0
|
188
|
andrewm@0
|
189 #endif // __PLUGINPROCESSOR_H_4693CB6E__
|