Krotos Modules 3
Loading...
Searching...
No Matches
ConvolutionReverb.cpp
Go to the documentation of this file.
1namespace krotos
2{
4 {
5 for (int i = 0; i < 4; i++)
6 m_convolvers.add(new IRConvolver());
7 }
8
10
11 void ConvolutionReverb::prepareNextBlock(const float* const* buffer, int numSamples, int numChannels)
12 {
13 // TODO: make this class optionally mono
14 jassert(numChannels == 2);
15
16 m_dryBuffer.copyFrom(LEFT, 0, buffer[LEFT], numSamples);
17 m_dryBuffer.copyFrom(RIGHT, 0, buffer[RIGHT], numSamples);
18
19 std::fill(m_convolutionBufferLL.begin(), m_convolutionBufferLL.end(), 0.0f);
20 std::fill(m_convolutionBufferLR.begin(), m_convolutionBufferLR.end(), 0.0f);
21 std::fill(m_convolutionBufferRL.begin(), m_convolutionBufferRL.end(), 0.0f);
22 std::fill(m_convolutionBufferRR.begin(), m_convolutionBufferRR.end(), 0.0f);
23
24 for (int i = 0; i < numSamples; i++)
25 for (int j = 0; j < numChannels; j++)
26 m_wetBuffer.setSample(j, i, 0.0f);
27
28 IRConvolver* convolverLL = m_convolvers[0];
29 IRConvolver* convolverLR = m_convolvers[1];
30 IRConvolver* convolverRL = m_convolvers[2];
31 IRConvolver* convolverRR = m_convolvers[3];
32
33 if (convolverLL && convolverLL->getConvolver())
34 {
35 convolverLL->process(buffer[LEFT], &m_convolutionBufferLL[0], numSamples);
36 m_wetBuffer.addFrom(0, 0, &m_convolutionBufferLL[0], numSamples);
37 }
38
39 if (convolverLR && convolverLR->getConvolver())
40 {
41 convolverLR->process(buffer[LEFT], &m_convolutionBufferLR[0], numSamples);
42 m_wetBuffer.addFrom(1, 0, &m_convolutionBufferLR[0], numSamples);
43 }
44
45 if (convolverRL && convolverRL->getConvolver())
46 {
47 convolverRL->process(buffer[RIGHT], &m_convolutionBufferRL[0], numSamples);
48 m_wetBuffer.addFrom(0, 0, &m_convolutionBufferRL[0], numSamples);
49 }
50
51 if (convolverRR && convolverRR->getConvolver())
52 {
53 convolverRR->process(buffer[RIGHT], &m_convolutionBufferRR[0], numSamples);
54 m_wetBuffer.addFrom(1, 0, &m_convolutionBufferRR[0], numSamples);
55 }
56 }
57
58 float ConvolutionReverb::getNextSample(int sampleIdx, int channelIdx)
59 {
60 float wetSample = m_wetBuffer.getSample(channelIdx, sampleIdx);
61 float drySample = m_dryBuffer.getSample(channelIdx, sampleIdx);
62 auto predelayPtr = m_predelayBuffers[channelIdx];
63
64 predelayPtr->copySample(wetSample);
65 float idx = predelayPtr->getHead() - m_predelay - 1.0f;
66 wetSample = m_outputGain * predelayPtr->getSample(idx);
67
68 return m_mix.dry() * drySample + m_mix.wet() * wetSample;
69 }
70
71 void ConvolutionReverb::processBlock(AudioBuffer<float>& buffer)
72 {
73 auto bufferPtr = buffer.getArrayOfWritePointers();
74 int numSamples = buffer.getNumSamples();
75 int numChannels = buffer.getNumChannels();
76
77 prepareNextBlock(bufferPtr, numSamples, numChannels);
78
79 for (int i = 0; i < numSamples; i++)
80 for (int j = 0; j < numChannels; j++)
81 bufferPtr[j][i] = getNextSample(i, j);
82 }
83
85 {
86 juce::ScopedLock convolverLock(m_convolverMutex);
87 return m_sampleRate;
88 }
89
90 void ConvolutionReverb::setSampleRate(double newSampleRate)
91 {
92 {
93 juce::ScopedLock convolverLock(m_convolverMutex);
94 m_sampleRate = newSampleRate;
95 }
96
97 reset();
98 }
99
100 void ConvolutionReverb::setMix(float mix) { m_mix = mix; }
101
102 void ConvolutionReverb::setOutputGainDb(float gainDb) { m_outputGain = std::pow(10.0f, gainDb / 20.0f); }
103
104 void ConvolutionReverb::setPredelayMs(float predelayMs)
105 {
106 m_predelay = static_cast<float>(predelayMs * m_sampleRate / 1e3f);
107 }
108
110 {
111 int predelayBufferSize = static_cast<int>(m_maxPredelayMs * m_sampleRate / 1e3f);
112 for (int i = 0; i < m_numOutputChannels; i++)
113 m_predelayBuffers.set(i,
114 new AudioSampleCircularBuffer(predelayBufferSize, static_cast<long>(m_sampleRate)));
115 }
116
117 void ConvolutionReverb::prepareToPlay(double sampleRate, int samplesPerBlock)
118 {
119 if (m_sampleRate != sampleRate)
120 setSampleRate(sampleRate);
121
122 {
123 juce::ScopedLock convolverLock(m_convolverMutex);
125 while (m_convolverHeadBlockSize < static_cast<size_t>(samplesPerBlock))
126 {
128 }
129 m_convolverTailBlockSize = std::max(size_t(8192), 2 * m_convolverHeadBlockSize);
130 }
131
132 m_wetBuffer.setSize(m_numOutputChannels, samplesPerBlock);
133 m_dryBuffer.setSize(m_numOutputChannels, samplesPerBlock);
134 m_convolutionBufferLL.resize(static_cast<size_t>(samplesPerBlock));
135 m_convolutionBufferLR.resize(static_cast<size_t>(samplesPerBlock));
136 m_convolutionBufferRL.resize(static_cast<size_t>(samplesPerBlock));
137 m_convolutionBufferRR.resize(static_cast<size_t>(samplesPerBlock));
138
140 }
141
142 const OwnedArray<IRConvolver>& ConvolutionReverb::getConvolvers() const
143 {
144 juce::ScopedLock convolverLock(m_convolverMutex);
145 return m_convolvers;
146 }
147
149 {
150 juce::ScopedLock irCalculationlock(m_irCalculationMutex);
151 if (m_irCalculation)
152 {
153 m_irCalculation->stopThread(-1);
154 m_irCalculation = nullptr;
155 }
157 }
158
160 {
161 for (int i = 0; i < m_convolvers.size(); i++)
162 m_convolvers[i]->clearConvolver();
163 }
164
166 {
167 juce::ScopedLock convolverLock(m_convolverMutex);
169 }
170
172 {
173 juce::ScopedLock convolverLock(m_convolverMutex);
175 }
176
178 {
179 juce::ScopedLock convolverLock(m_convolverMutex);
181 }
182
183 void ConvolutionReverb::setImpulseResponseFilePath(const String& impulseResponseFilePath)
184 {
185 {
186 juce::ScopedLock convolverLock(m_convolverMutex);
187 m_impulseResponseFilePath = impulseResponseFilePath;
188 }
190 }
191} // namespace krotos
A fractional delay line with several interpolation methods.
Definition AudioSampleCircularBuffer.h:10
A thread class designed to load and preprocess an impulse response.
Definition ConvolutionComputationThread.h:8
@ RIGHT
Definition ConvolutionReverb.h:43
@ LEFT
Definition ConvolutionReverb.h:42
void prepareToPlay(double sampleRate, int samplesPerBlock)
Definition ConvolutionReverb.cpp:117
size_t getConvolverTailBlockSize() const
Definition ConvolutionReverb.cpp:171
void prepareNextBlock(const float *const *buffer, int numSamples, int numChannels)
Definition ConvolutionReverb.cpp:11
AudioBuffer< float > m_dryBuffer
Definition ConvolutionReverb.h:55
void setPredelayMs(float predelayMs)
Definition ConvolutionReverb.cpp:104
void setOutputGainDb(float outputGainValueIndB)
Definition ConvolutionReverb.cpp:102
String getImpulseResponseFilePath() const
Definition ConvolutionReverb.cpp:177
~ConvolutionReverb()
Definition ConvolutionReverb.cpp:9
float getNextSample(int sampleIdx, int channelIdx)
Definition ConvolutionReverb.cpp:58
std::vector< float > m_convolutionBufferLR
Definition ConvolutionReverb.h:58
std::vector< float > m_convolutionBufferRR
Definition ConvolutionReverb.h:60
ConvolutionReverb()
Definition ConvolutionReverb.cpp:3
OwnedArray< AudioSampleCircularBuffer > m_predelayBuffers
Definition ConvolutionReverb.h:53
OwnedArray< IRConvolver > m_convolvers
Definition ConvolutionReverb.h:37
void updateConvolvers()
Definition ConvolutionReverb.cpp:148
std::vector< float > m_convolutionBufferLL
Definition ConvolutionReverb.h:57
void clearConvolvers()
Definition ConvolutionReverb.cpp:159
float m_predelay
Definition ConvolutionReverb.h:50
void setImpulseResponseFilePath(const String &impulseResponseFilePath)
Definition ConvolutionReverb.cpp:183
void setMix(float mixValue)
Definition ConvolutionReverb.cpp:100
CriticalSection m_irCalculationMutex
Definition ConvolutionReverb.h:66
CriticalSection m_convolverMutex
Definition ConvolutionReverb.h:62
const int m_numOutputChannels
Definition ConvolutionReverb.h:45
size_t m_convolverTailBlockSize
Definition ConvolutionReverb.h:64
String m_impulseResponseFilePath
Definition ConvolutionReverb.h:38
size_t getConvolverHeadBlockSize() const
Definition ConvolutionReverb.cpp:165
DryWet m_mix
Definition ConvolutionReverb.h:48
std::unique_ptr< Thread > m_irCalculation
Definition ConvolutionReverb.h:67
float m_outputGain
Definition ConvolutionReverb.h:49
size_t m_convolverHeadBlockSize
Definition ConvolutionReverb.h:63
const OwnedArray< IRConvolver > & getConvolvers() const
Definition ConvolutionReverb.cpp:142
std::vector< float > m_convolutionBufferRL
Definition ConvolutionReverb.h:59
void processBlock(AudioBuffer< float > &buffer)
Definition ConvolutionReverb.cpp:71
AudioBuffer< float > m_wetBuffer
Definition ConvolutionReverb.h:55
void setSampleRate(double newSampleRate)
Definition ConvolutionReverb.cpp:90
void reset()
Definition ConvolutionReverb.cpp:109
double m_sampleRate
Definition ConvolutionReverb.h:47
double getSampleRate() const
Definition ConvolutionReverb.cpp:84
const float m_maxPredelayMs
Definition ConvolutionReverb.h:52
float wet() const
Definition DryWet.h:26
float dry() const
Definition DryWet.h:25
Used in the ConvolutionReverb class, performs single-channel convolution.
Definition IRConvolver.h:29
Convolver * getConvolver()
Definition IRConvolver.cpp:15
void process(const float *input, float *output, int len)
Definition IRConvolver.cpp:49
Definition AirAbsorptionFilter.cpp:2