quantumVERB  1.0.0
A FOSS convolution reverb plugin
PreDelay.cpp
1 /*
2  ==============================================================================
3 
4  PreDelay.cpp
5  Created: 14 Feb 2018 3:26:12pm
6  Author: Eric Seguin
7 
8  ==============================================================================
9 */
10 
11 #include "PreDelay.h"
12 
13 #include "Logger.h"
14 
15 #include <algorithm>
16 
17 namespace reverb
18 {
19 
20  //==============================================================================
21  /**
22  * @brief Constructs a PreDelay object associated with an AudioProcessor
23  *
24  * @param [in] processor Pointer to main processor
25  */
26  PreDelay::PreDelay(juce::AudioProcessor * processor)
27  : Task(processor)
28  {
29  }
30 
31  /**
32  * @brief Updates parameters from processor parameter tree
33  *
34  * @param [in] params Processor parameter tree
35  * @param [in] blockId ID of block whose paramters should be checked
36  */
37  void PreDelay::updateParams(const juce::AudioProcessorValueTreeState& params,
38  const juce::String& blockId)
39  {
40  float _delayMs = getParam(params, blockId);
41 
42  if (delayMs != _delayMs)
43  {
44  delayMs = _delayMs;
45  mustExec = true;
46  }
47  }
48 
49  //==============================================================================
50  /**
51  * @brief Applies predelay to impulse response
52  *
53  * Zero-pads beginning of impulse response buffer to match requested predelay.
54  * Expects given audio block to be large enough to accomodate predelay.
55  *
56  * @param [in,out] ir Impulse response to modify
57  */
59  {
60  const size_t numSamplesToAdd = getNumSamplesToAdd();
61  const size_t lengthWithoutPreDelay = (ir.getNumSamples() - numSamplesToAdd);
62 
63  if (numSamplesToAdd > 0)
64  {
65  // Shift audio samples in memory to leave room for predelay
66  // NB: Use memmove instead of memcpy since dst and src will probably overlap
67  float * irPtr = ir.getChannelPointer(0);
68  memmove(irPtr + numSamplesToAdd, irPtr, lengthWithoutPreDelay * sizeof(float));
69 
70  // Clear predelay samples
71  memset(irPtr, 0, numSamplesToAdd * sizeof(float));
72  }
73 
74  // Reset mustExec flag
75  mustExec = false;
76 
77  return ir;
78  }
79 
80  //==============================================================================
81  /**
82  * @brief Resizes given IR before processing
83  *
84  * @param [in,out] ir IR to prepare
85  */
86  void PreDelay::prepareIR(juce::AudioSampleBuffer& ir)
87  {
88  ir.setSize(ir.getNumChannels(),
89  ir.getNumSamples() + getNumSamplesToAdd(),
90  true, false, false);
91  }
92 
93  /**
94  * @brief Returns expected number of samples after processing
95  *
96  * @param [in] inputNumSamples Number of samples in input buffer
97  */
99  {
100  return (int)std::ceil(sampleRate * (delayMs / 1000.0));
101  }
102 
103 }
float getParam(const juce::AudioProcessorValueTreeState &params, const juce::String &blockId) const
Internal method used to get (and check) a parameter&#39;s value.
Definition: Task.h:111
int getNumSamplesToAdd()
Returns expected number of samples after processing.
Definition: PreDelay.cpp:98
virtual void updateParams(const juce::AudioProcessorValueTreeState &params, const juce::String &blockId) override
Updates parameters from processor parameter tree.
Definition: PreDelay.cpp:37
void prepareIR(juce::AudioSampleBuffer &ir)
Resizes given IR before processing.
Definition: PreDelay.cpp:86
PreDelay(juce::AudioProcessor *processor)
Constructs a PreDelay object associated with an AudioProcessor.
Definition: PreDelay.cpp:26
virtual AudioBlock exec(AudioBlock ir) override
Applies predelay to impulse response.
Definition: PreDelay.cpp:58