OpenShot Audio Library | OpenShotAudio 0.4.0
Loading...
Searching...
No Matches
juce_Phaser.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce::dsp
27{
28
39template <typename SampleType>
40class Phaser
41{
42public:
43 //==============================================================================
45 Phaser();
46
47 //==============================================================================
51 void setRate (SampleType newRateHz);
52
56 void setDepth (SampleType newDepth);
57
60 void setCentreFrequency (SampleType newCentreHz);
61
65 void setFeedback (SampleType newFeedback);
66
70 void setMix (SampleType newMix);
71
72 //==============================================================================
74 void prepare (const ProcessSpec& spec);
75
77 void reset();
78
79 //==============================================================================
81 template <typename ProcessContext>
82 void process (const ProcessContext& context) noexcept
83 {
84 const auto& inputBlock = context.getInputBlock();
85 auto& outputBlock = context.getOutputBlock();
86 const auto numChannels = outputBlock.getNumChannels();
87 const auto numSamples = outputBlock.getNumSamples();
88
89 jassert (inputBlock.getNumChannels() == numChannels);
90 jassert (inputBlock.getNumChannels() == lastOutput.size());
91 jassert (inputBlock.getNumSamples() == numSamples);
92
93 if (context.isBypassed)
94 {
95 outputBlock.copyFrom (inputBlock);
96 return;
97 }
98
99 int numSamplesDown = 0;
100 auto counter = updateCounter;
101
102 for (size_t i = 0; i < numSamples; ++i)
103 {
104 if (counter == 0)
105 numSamplesDown++;
106
107 counter++;
108
109 if (counter == maxUpdateCounter)
110 counter = 0;
111 }
112
113 if (numSamplesDown > 0)
114 {
115 auto freqBlock = AudioBlock<SampleType> (bufferFrequency).getSubBlock (0, (size_t) numSamplesDown);
116 auto contextFreq = ProcessContextReplacing<SampleType> (freqBlock);
117 freqBlock.clear();
118
119 osc.process (contextFreq);
120 freqBlock.multiplyBy (oscVolume);
121 }
122
123 auto* freqSamples = bufferFrequency.getWritePointer (0);
124
125 for (int i = 0; i < numSamplesDown; ++i)
126 {
127 auto lfo = jlimit (static_cast<SampleType> (0.0),
128 static_cast<SampleType> (1.0),
129 freqSamples[i] + normCentreFrequency);
130
131 freqSamples[i] = mapToLog10 (lfo, static_cast<SampleType> (20.0),
132 static_cast<SampleType> (jmin (20000.0, 0.49 * sampleRate)));
133 }
134
135 auto currentFrequency = filters[0]->getCutoffFrequency();
136 dryWet.pushDrySamples (inputBlock);
137
138 for (size_t channel = 0; channel < numChannels; ++channel)
139 {
140 counter = updateCounter;
141 int k = 0;
142
143 auto* inputSamples = inputBlock .getChannelPointer (channel);
144 auto* outputSamples = outputBlock.getChannelPointer (channel);
145
146 for (size_t i = 0; i < numSamples; ++i)
147 {
148 auto input = inputSamples[i];
149 auto output = input - lastOutput[channel];
150
151 if (i == 0 && counter != 0)
152 for (int n = 0; n < numStages; ++n)
153 filters[n]->setCutoffFrequency (currentFrequency);
154
155 if (counter == 0)
156 {
157 for (int n = 0; n < numStages; ++n)
158 filters[n]->setCutoffFrequency (freqSamples[k]);
159
160 k++;
161 }
162
163 for (int n = 0; n < numStages; ++n)
164 output = filters[n]->processSample ((int) channel, output);
165
166 outputSamples[i] = output;
167 lastOutput[channel] = output * feedbackVolume[channel].getNextValue();
168
169 counter++;
170
171 if (counter == maxUpdateCounter)
172 counter = 0;
173 }
174 }
175
176 dryWet.mixWetSamples (outputBlock);
177 updateCounter = (updateCounter + (int) numSamples) % maxUpdateCounter;
178 }
179
180private:
181 //==============================================================================
182 void update();
183
184 //==============================================================================
188 std::vector<SmoothedValue<SampleType, ValueSmoothingTypes::Linear>> feedbackVolume { 2 };
189 DryWetMixer<SampleType> dryWet;
190 std::vector<SampleType> lastOutput { 2 };
191 AudioBuffer<SampleType> bufferFrequency;
192 SampleType normCentreFrequency = 0.5;
193 double sampleRate = 44100.0;
194
195 int updateCounter = 0;
196 static constexpr int maxUpdateCounter = 4;
197
198 SampleType rate = 1.0, depth = 0.5, feedback = 0.0, mix = 0.5;
199 SampleType centreFrequency = 1300.0;
200 static constexpr int numStages = 6;
201};
202
203} // namespace juce::dsp
Type * getWritePointer(int channelNumber) noexcept
AudioBlock getSubBlock(size_t newOffset, size_t newLength) const noexcept
void prepare(const ProcessSpec &spec)
void process(const ProcessContext &context) noexcept
Definition juce_Phaser.h:82
void setDepth(SampleType newDepth)
void setFeedback(SampleType newFeedback)
void setMix(SampleType newMix)
void setRate(SampleType newRateHz)
void setCentreFrequency(SampleType newCentreHz)