comparison effects/reverb/Source/PluginProcessor.cpp @ 0:e32fe563e124

First commit
author Andrew McPherson <andrewm@eecs.qmul.ac.uk>
date Fri, 10 Oct 2014 15:41:23 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:e32fe563e124
1 /*
2 This code accompanies the textbook:
3
4 Digital Audio Effects: Theory, Implementation and Application
5 Joshua D. Reiss and Andrew P. McPherson
6
7 ---
8
9 Reverb: algorithmic reverb effect based on MVerb
10 See textbook Chapter 11: Reverberation
11
12 Original code by Martin Eastwood: MVerb (see MVerb.h)
13 Adapted for JUCE by Brecht De Man
14
15 When using this code (or a modified version thereof) please cite:
16
17 R. Stables, S. Enderby, B. De Man, G. Fazekas, J. D. Reiss, "SAFE:
18 A System for the Extraction and Retrieval of Semantic Audio
19 Descriptors," 15th International Society for Music Information
20 Retrieval Conference (ISMIR 2014), 2014.
21
22 ---
23
24 This program is free software: you can redistribute it and/or modify
25 it under the terms of the GNU General Public License as published by
26 the Free Software Foundation, either version 3 of the License, or
27 (at your option) any later version.
28
29 This program is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 GNU General Public License for more details.
33
34 You should have received a copy of the GNU General Public License
35 along with this program. If not, see <http://www.gnu.org/licenses/>.
36 */
37
38
39 #include "PluginProcessor.h"
40 #include "PluginEditor.h"
41
42 #if JUCE_INTEL
43 #define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8 || n > 1.0e-8)) n = 0;
44 #else
45 #define JUCE_SNAP_TO_ZERO(n)
46 #endif
47
48 ReverbAudioProcessor::ReverbAudioProcessor()
49 :
50 _numChannels (1)
51 ,_numSamples (1) // dummy - will be set in prepareToPlay
52 ,_sampleRate (1) // dummy - will be set in prepareToPlay
53 ,_density (1.0)
54 ,_decay (1.0)
55 ,_size (1.0)
56 ,_damp (1.0)
57 ,_bandwidth (1.0)
58 ,_predelay (0.0)
59 ,_gain (1.0)
60 ,_mix (0.5)
61 ,_lateEarly (0.5)
62 ,tempInput (1,1)// dummy - will be set in prepareToPlay
63 ,tempOutput (1,1)// dummy - will be set in prepareToPlay
64 ,_lastUIWidth (850)
65 ,_lastUIHeight (650)
66
67 {
68 // Update all parameters
69 for (int index = 0; index < MVerb<float>::NUM_PARAMS; ++index)
70 {
71 updateParameters(index);
72 }
73 }
74
75 ReverbAudioProcessor::~ReverbAudioProcessor()
76 {
77 }
78
79 //-----------------------------------------------------------------------------
80 // P R E P A R E T O P L A Y
81 void ReverbAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
82 {
83 // If sample rate/block size changes or straight after construction
84 if (_numSamples != samplesPerBlock || _sampleRate != sampleRate)
85 {
86 _sampleRate = sampleRate;
87 _numSamples = samplesPerBlock;
88 _numChannels = getNumInputChannels();
89
90 tempInput.setSize (_numChannels,_numSamples);
91 tempOutput.setSize(_numChannels,_numSamples);
92 tempInput.clear();
93 tempOutput.clear();
94
95 _mverb.reset();
96 _mverb.setSampleRate (_sampleRate); // set reverb sample rate
97 }
98 }
99
100
101 //-----------------------------------------------------------------------------
102 // P R O C E S S B L O C K
103 void ReverbAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
104 {
105 int numSamples = buffer.getNumSamples();
106 int numChannels = buffer.getNumChannels();
107
108 for(int channel = 0; channel < numChannels; channel++)
109 {
110 tempInput.copyFrom (channel, 0, buffer, channel, 0, numSamples);
111 }
112
113 float** input = tempInput.getArrayOfWritePointers();
114 float** output = tempOutput.getArrayOfWritePointers();
115
116 _mverb.process (input, output, numSamples); // processing by MVerb
117
118 for(int channel = 0; channel < numChannels; channel++)
119 {
120 buffer.copyFrom (channel, 0, output [channel], numSamples);
121 }
122 }
123
124
125 //-----------------------------------------------------------------------------
126 // U P D A T E P A R A M E T E R S
127 void ReverbAudioProcessor::updateParameters (int index)
128 {
129 switch(index)
130 {
131 case MVerb<float>::DAMPINGFREQ:
132 _mverb.setParameter (index, _damp);
133 break;
134
135 case MVerb<float>::DENSITY:
136 _mverb.setParameter (index, _density);
137 break;
138
139 case MVerb<float>::BANDWIDTHFREQ:
140 _mverb.setParameter (index, _bandwidth);
141 break;
142
143 case MVerb<float>::PREDELAY:
144 _mverb.setParameter (index, _predelay);
145 break;
146
147 case MVerb<float>::DECAY:
148 _mverb.setParameter (index, _decay);
149 break;
150
151 case MVerb<float>::SIZE:
152 _mverb.setParameter (index, _size);
153 break;
154
155 case MVerb<float>::GAIN:
156 _mverb.setParameter (index, _gain);
157 break;
158
159 case MVerb<float>::MIX:
160 _mverb.setParameter (index, _mix);
161 break;
162
163 case MVerb<float>::EARLYMIX:
164 _mverb.setParameter (index, _lateEarly);
165 break;
166 }
167 }
168
169
170 //-----------------------------------------------------------------------------
171 // R E S E T
172 void ReverbAudioProcessor::Reset()
173 {
174 _mverb.reset(); // not used
175 }
176
177
178 //-----------------------------------------------------------------------------
179 //
180 void ReverbAudioProcessor::releaseResources()
181 {
182 // When playback stops, you can use this to free up any spare memory, etc.
183 }
184
185
186 bool ReverbAudioProcessor::hasEditor() const
187 {
188 return true; // (change this to false if you choose to not supply an editor)
189 }
190
191 AudioProcessorEditor* ReverbAudioProcessor::createEditor()
192 {
193 return new ReverbAudioProcessorEditor (this);
194 }
195
196
197 //==============================================================================
198 void ReverbAudioProcessor::getStateInformation (MemoryBlock& destData)
199 {
200 // SAVE STATE INFO
201 XmlElement xml("JRAMReverb_XML");
202
203 // Knobs
204 xml.setAttribute("_density" ,_density);
205 xml.setAttribute("_decay" ,_decay);
206 xml.setAttribute("_size" ,_size);
207 xml.setAttribute("_damp" ,_damp);
208 xml.setAttribute("_bandwidth" ,_bandwidth);
209 xml.setAttribute("_predelay" ,_predelay);
210 xml.setAttribute("_gain" ,_gain);
211 xml.setAttribute("_mix" ,_mix);
212 xml.setAttribute("_lateEarly" ,_lateEarly);
213
214
215 // then use this helper function to stuff it into the binary blob and return it..
216 copyXmlToBinary(xml, destData);
217 }
218
219 void ReverbAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
220 {
221 // LOAD STATE INFO
222 ScopedPointer<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
223
224 // make sure that it's actually our type of XML object..
225 if(xmlState->hasTagName("JRAMReverb_XML"))
226 {
227 // Knobs
228 _density = (float) xmlState->getDoubleAttribute("_density",true);
229 _decay = (float) xmlState->getDoubleAttribute("_decay",true);
230 _size = (float) xmlState->getDoubleAttribute("_size",true);
231 _damp = (float) xmlState->getDoubleAttribute("_damp",true);
232 _bandwidth = (float) xmlState->getDoubleAttribute("_bandwidth",true);
233 _predelay = (float) xmlState->getDoubleAttribute("_predelay",true);
234 _gain = (float) xmlState->getDoubleAttribute("_gain",true);
235 _mix = (float) xmlState->getDoubleAttribute("_mix",true);
236 _lateEarly = (float) xmlState->getDoubleAttribute("_lateEarly",true);
237 }
238 }
239
240 // This creates new instances of the plugin..
241 AudioProcessor* JUCE_CALLTYPE createPluginFilter()
242 {
243 return new ReverbAudioProcessor();
244 }
245
246 const String ReverbAudioProcessor::getName() const
247 {
248 return JucePlugin_Name;
249 }
250
251 bool ReverbAudioProcessor::silenceInProducesSilenceOut() const
252 {
253 return true;
254 }
255
256 int ReverbAudioProcessor::getNumParameters()
257 {
258 return MVerb<float>::NUM_PARAMS;
259 }
260
261 float ReverbAudioProcessor::getParameter (int index) // externally accessible
262 {
263 switch (index)
264 {
265 case MVerb<float>::DENSITY: return GetDensity();
266 case MVerb<float>::DECAY: return GetDecay();
267 case MVerb<float>::SIZE: return GetSize();
268 case MVerb<float>::DAMPINGFREQ: return GetDamp();
269 case MVerb<float>::BANDWIDTHFREQ: return GetBandwidth();
270 case MVerb<float>::PREDELAY: return GetPredelay();
271 case MVerb<float>::GAIN: return GetGain();
272 case MVerb<float>::MIX: return GetMix();
273 case MVerb<float>::EARLYMIX: return GetLateEarly();
274 default: return 0.0f;
275 }
276 }
277
278 void ReverbAudioProcessor::setParameter (int index, float newValue) // externally accessible
279 {
280 switch (index)
281 {
282 case MVerb<float>::DENSITY:
283 SetDensity(newValue);
284 break;
285 case MVerb<float>::DECAY:
286 SetDecay(newValue);
287 break;
288 case MVerb<float>::SIZE:
289 SetSize(newValue);
290 break;
291 case MVerb<float>::DAMPINGFREQ:
292 SetDamp(newValue);
293 break;
294 case MVerb<float>::BANDWIDTHFREQ:
295 SetBandwidth(newValue);
296 break;
297 case MVerb<float>::PREDELAY:
298 SetPredelay(newValue);
299 break;
300 case MVerb<float>::GAIN:
301 SetGain(newValue);
302 break;
303 case MVerb<float>::MIX:
304 SetMix(newValue);
305 break;
306 case MVerb<float>::EARLYMIX:
307 SetLateEarly(newValue);
308 break;
309 default:
310 break;
311 }
312 }
313
314 const String ReverbAudioProcessor::getParameterName (int index) // externally accessible
315 {
316 switch (index)
317 {
318 case MVerb<float>::DENSITY: return "Density";
319 case MVerb<float>::DECAY: return "Decay";
320 case MVerb<float>::SIZE: return "Size";
321 case MVerb<float>::DAMPINGFREQ: return "Damp";
322 case MVerb<float>::BANDWIDTHFREQ: return "Bandwidth";
323 case MVerb<float>::PREDELAY: return "Predelay";
324 case MVerb<float>::GAIN: return "Gain";
325 case MVerb<float>::MIX: return "Mix";
326 case MVerb<float>::EARLYMIX: return "Late vs. early reflections";
327 default: break;
328 }
329 return String::empty;
330 }
331
332 const String ReverbAudioProcessor::getParameterText (int index)
333 {
334 return String (getParameter (index), 2);
335 }
336
337 const String ReverbAudioProcessor::getInputChannelName (int channelIndex) const
338 {
339 return String (channelIndex + 1);
340 }
341
342 const String ReverbAudioProcessor::getOutputChannelName (int channelIndex) const
343 {
344 return String (channelIndex + 1);
345 }
346
347 bool ReverbAudioProcessor::isInputChannelStereoPair (int index) const
348 {
349 return true;
350 }
351
352 bool ReverbAudioProcessor::isOutputChannelStereoPair (int index) const
353 {
354 return true;
355 }
356
357 bool ReverbAudioProcessor::acceptsMidi() const
358 {
359 #if JucePlugin_WantsMidiInput
360 return true;
361 #else
362 return false;
363 #endif
364 }
365
366 bool ReverbAudioProcessor::producesMidi() const
367 {
368 #if JucePlugin_ProducesMidiOutput
369 return true;
370 #else
371 return false;
372 #endif
373 }
374
375 int ReverbAudioProcessor::getNumPrograms()
376 {
377 return 0;
378 }
379
380 int ReverbAudioProcessor::getCurrentProgram()
381 {
382 return 0;
383 }
384
385 void ReverbAudioProcessor::setCurrentProgram (int index)
386 {
387 }
388
389 const String ReverbAudioProcessor::getProgramName (int index)
390 {
391 return String::empty;
392 }
393
394 void ReverbAudioProcessor::changeProgramName (int index, const String& newName)
395 {
396 }