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>
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 {
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,
73
74 lookupTable.reset (table);
75 generator = [table] (NumericType x) { return (*table) (x); };
76 }
77 else
78 {
79 generator = function;
80 }
81 }
82
83 //==============================================================================
86 {
87 if (force)
88 {
90 return;
91 }
92
93 frequency.setTargetValue (newFrequency);
94 }
95
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
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();
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())
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
int size() const noexcept
Definition juce_Array.h:215
ElementType * getRawDataPointer() noexcept
Definition juce_Array.h:310
void resize(int targetNumItems)
Definition juce_Array.h:670
void clear()
Definition juce_Array.h:188
bool isSmoothing() const noexcept
void setCurrentAndTargetValue(FloatType newValue)
FloatType getTargetValue() const noexcept
FloatType skip(int numSamples) noexcept
FloatType getNextValue() noexcept
void reset(double sampleRate, double rampLengthInSeconds) noexcept
void setTargetValue(FloatType newValue) noexcept
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType input) noexcept
Oscillator(const std::function< NumericType(NumericType)> &function, size_t lookupTableNumPoints=0)
void prepare(const ProcessSpec &spec) noexcept
bool isInitialised() const noexcept
typename SampleTypeHelpers::ElementType< SampleType >::Type NumericType
NumericType getFrequency() const noexcept
void process(const ProcessContext &context) noexcept
void setFrequency(NumericType newFrequency, bool force=false) noexcept
void initialise(const std::function< NumericType(NumericType)> &function, size_t lookupTableNumPoints=0)
void reset() noexcept
Definition juce_Phase.h:44
Type advance(Type increment) noexcept
Definition juce_Phase.h:50