annotate effects/reverb/Source/PluginProcessor.cpp @ 1:04e171d2a747 tip

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