OpenShot Audio Library | OpenShotAudio: juce_Oscillator.h Source File

OpenShot Audio Library | OpenShotAudio 0.3.2

Loading...
Searching...
No Matches
juce_Oscillator.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
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 5 End-User License
11 Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
12 27th April 2017).
13
14 End User License Agreement: www.juce.com/juce-5-licence
15 Privacy Policy: www.juce.com/juce-5-privacy-policy
16
17 Or: You may also use this code under the terms of the GPL v3 (see
18 www.gnu.org/licenses).
19
20 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 DISCLAIMED.
23
24 ==============================================================================
25*/
26
27namespace juce
28{
29namespace dsp
30{
31
37template <typename SampleType>
38 class Oscillator
39{
40public:
44 using NumericType = typename SampleTypeHelpers::ElementType<SampleType>::Type;
45
47 Oscillator() = default;
48
54 Oscillator (const std::function<NumericType(NumericType)>& function,
55 size_t lookupTableNumPoints = 0)
56 {
57 initialise (function, lookupTableNumPoints);
58 }
59
61 bool isInitialised() const noexcept { return static_cast<bool> (generator); }
62
64 void initialise (const std::function<NumericType(NumericType)>& function,
65 size_t lookupTableNumPoints = 0)
66 {
67 if (lookupTableNumPoints != 0)
68 {
69 auto* table = new LookupTableTransform<NumericType> (function,
70 -MathConstants<NumericType>::pi,
71 MathConstants<NumericType>::pi,
72 lookupTableNumPoints);
73
74 lookupTable.reset (table);
75 generator = [table] (NumericType x) { return (*table) (x); };
76 }
77 else
78 {
79 generator = function;
80 }
81 }
82
83 //==============================================================================
85 void setFrequency (NumericType newFrequency, bool force = false) noexcept
86 {
87 if (force)
88 {
89 frequency.setCurrentAndTargetValue (newFrequency);
90 return;
91 }
92
93 frequency.setTargetValue (newFrequency);
94 }
95
97 NumericType getFrequency() const noexcept { return frequency.getTargetValue(); }
98
99 //==============================================================================
101 void prepare (const ProcessSpec& spec) noexcept
102 {
103 sampleRate = static_cast<NumericType> (spec.sampleRate);
104 rampBuffer.resize ((int) spec.maximumBlockSize);
105
106 reset();
107 }
108
110 void reset() noexcept
111 {
112 phase.reset();
113
114 if (sampleRate > 0)
115 frequency.reset (sampleRate, 0.05);
116 }
117
118 //==============================================================================
120 SampleType JUCE_VECTOR_CALLTYPE processSample (SampleType input) noexcept
121 {
122 jassert (isInitialised());
123 auto increment = MathConstants<NumericType>::twoPi * frequency.getNextValue() / sampleRate;
124 return input + generator (phase.advance (increment) - MathConstants<NumericType>::pi);
125 }
126
128 template <typename ProcessContext>
129 void process (const ProcessContext& context) noexcept
130 {
131 jassert (isInitialised());
132 auto&& outBlock = context.getOutputBlock();
133 auto&& inBlock = context.getInputBlock();
134
135 // this is an output-only processor
136 jassert (outBlock.getNumSamples() <= static_cast<size_t> (rampBuffer.size()));
137
138 auto len = outBlock.getNumSamples();
139 auto numChannels = outBlock.getNumChannels();
140 auto inputChannels = inBlock.getNumChannels();
141 auto baseIncrement = MathConstants<NumericType>::twoPi / sampleRate;
142
143 if (context.isBypassed)
144 context.getOutputBlock().clear();
145
146 if (frequency.isSmoothing())
147 {
148 auto* buffer = rampBuffer.getRawDataPointer();
149
150 for (size_t i = 0; i < len; ++i)
151 buffer[i] = phase.advance (baseIncrement * frequency.getNextValue())
152 - MathConstants<NumericType>::pi;
153
154 if (! context.isBypassed)
155 {
156 size_t ch;
157
158 if (context.usesSeparateInputAndOutputBlocks())
159 {
160 for (ch = 0; ch < jmin (numChannels, inputChannels); ++ch)
161 {
162 auto* dst = outBlock.getChannelPointer (ch);
163 auto* src = inBlock.getChannelPointer (ch);
164
165 for (size_t i = 0; i < len; ++i)
166 dst[i] = src[i] + generator (buffer[i]);
167 }
168 }
169 else
170 {
171 for (ch = 0; ch < jmin (numChannels, inputChannels); ++ch)
172 {
173 auto* dst = outBlock.getChannelPointer (ch);
174
175 for (size_t i = 0; i < len; ++i)
176 dst[i] += generator (buffer[i]);
177 }
178 }
179
180 for (; ch < numChannels; ++ch)
181 {
182 auto* dst = outBlock.getChannelPointer (ch);
183
184 for (size_t i = 0; i < len; ++i)
185 dst[i] = generator (buffer[i]);
186 }
187 }
188 }
189 else
190 {
191 auto freq = baseIncrement * frequency.getNextValue();
192 auto p = phase;
193
194 if (context.isBypassed)
195 {
196 frequency.skip (static_cast<int> (len));
197 p.advance (freq * static_cast<NumericType> (len));
198 }
199 else
200 {
201 size_t ch;
202
203 if (context.usesSeparateInputAndOutputBlocks())
204 {
205 for (ch = 0; ch < jmin (numChannels, inputChannels); ++ch)
206 {
207 p = phase;
208 auto* dst = outBlock.getChannelPointer (ch);
209 auto* src = inBlock.getChannelPointer (ch);
210
211 for (size_t i = 0; i < len; ++i)
212 dst[i] = src[i] + generator (p.advance (freq) - MathConstants<NumericType>::pi);
213 }
214 }
215 else
216 {
217 for (ch = 0; ch < jmin (numChannels, inputChannels); ++ch)
218 {
219 p = phase;
220 auto* dst = outBlock.getChannelPointer (ch);
221
222 for (size_t i = 0; i < len; ++i)
223 dst[i] += generator (p.advance (freq) - MathConstants<NumericType>::pi);
224 }
225 }
226
227 for (; ch < numChannels; ++ch)
228 {
229 p = phase;
230 auto* dst = outBlock.getChannelPointer (ch);
231
232 for (size_t i = 0; i < len; ++i)
233 dst[i] = generator (p.advance (freq) - MathConstants<NumericType>::pi);
234 }
235 }
236
237 phase = p;
238 }
239 }
240
241private:
242 //==============================================================================
243 std::function<NumericType(NumericType)> generator;
244 std::unique_ptr<LookupTableTransform<NumericType>> lookupTable;
245 Array<NumericType> rampBuffer;
246 SmoothedValue<NumericType> frequency { static_cast<NumericType> (440.0) };
247 NumericType sampleRate = 48000.0;
248 Phase<NumericType> phase;
249};
250
251} // namespace dsp
252} // namespace juce
juce::Array
Definition: juce_Array.h:56
juce::Array::size
int size() const noexcept
Definition: juce_Array.h:215
juce::Array::getRawDataPointer
ElementType * getRawDataPointer() noexcept
Definition: juce_Array.h:310
juce::Array::resize
void resize(int targetNumItems)
Definition: juce_Array.h:670
juce::SmoothedValueBase::isSmoothing
bool isSmoothing() const noexcept
Definition: juce_SmoothedValue.h:65
juce::SmoothedValueBase::setCurrentAndTargetValue
void setCurrentAndTargetValue(FloatType newValue)
Definition: juce_SmoothedValue.h:77
juce::SmoothedValueBase::getTargetValue
FloatType getTargetValue() const noexcept
Definition: juce_SmoothedValue.h:72
juce::SmoothedValue
Definition: juce_SmoothedValue.h:229
juce::SmoothedValue::skip
FloatType skip(int numSamples) noexcept
Definition: juce_SmoothedValue.h:318
juce::SmoothedValue::getNextValue
FloatType getNextValue() noexcept
Definition: juce_SmoothedValue.h:297
juce::SmoothedValue::reset
void reset(double sampleRate, double rampLengthInSeconds) noexcept
Definition: juce_SmoothedValue.h:254
juce::SmoothedValue::setTargetValue
void setTargetValue(FloatType newValue) noexcept
Definition: juce_SmoothedValue.h:273
juce::dsp::LookupTableTransform
Definition: juce_LookupTable.h:176
juce::dsp::Oscillator
Definition: juce_Oscillator.h:39
juce::dsp::Oscillator::processSample
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType input) noexcept
Definition: juce_Oscillator.h:120
juce::dsp::Oscillator::Oscillator
Oscillator(const std::function< NumericType(NumericType)> &function, size_t lookupTableNumPoints=0)
Definition: juce_Oscillator.h:54
juce::dsp::Oscillator::Oscillator
Oscillator()=default
juce::dsp::Oscillator::prepare
void prepare(const ProcessSpec &spec) noexcept
Definition: juce_Oscillator.h:101
juce::dsp::Oscillator::isInitialised
bool isInitialised() const noexcept
Definition: juce_Oscillator.h:61
juce::dsp::Oscillator::NumericType
typename SampleTypeHelpers::ElementType< SampleType >::Type NumericType
Definition: juce_Oscillator.h:44
juce::dsp::Oscillator::reset
void reset() noexcept
Definition: juce_Oscillator.h:110
juce::dsp::Oscillator::getFrequency
NumericType getFrequency() const noexcept
Definition: juce_Oscillator.h:97
juce::dsp::Oscillator::process
void process(const ProcessContext &context) noexcept
Definition: juce_Oscillator.h:129
juce::dsp::Oscillator::setFrequency
void setFrequency(NumericType newFrequency, bool force=false) noexcept
Definition: juce_Oscillator.h:85
juce::dsp::Oscillator::initialise
void initialise(const std::function< NumericType(NumericType)> &function, size_t lookupTableNumPoints=0)
Definition: juce_Oscillator.h:64
juce::MathConstants
Definition: juce_MathsFunctions.h:363
juce::dsp::Phase::reset
void reset() noexcept
Definition: juce_Phase.h:44
juce::dsp::Phase::advance
Type advance(Type increment) noexcept
Definition: juce_Phase.h:50
juce::dsp::ProcessSpec
Definition: juce_ProcessContext.h:39