JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_Oscillator.h
Go to the documentation of this file.
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
34template <typename SampleType>
36{
37public:
41 using NumericType = typename SampleTypeHelpers::ElementType<SampleType>::Type;
42
44 Oscillator() = default;
45
52 size_t lookupTableNumPoints = 0)
53 {
55 }
56
58 bool isInitialised() const noexcept { return static_cast<bool> (generator); }
59
62 size_t lookupTableNumPoints = 0)
63 {
64 if (lookupTableNumPoints != 0)
65 {
66 auto* table = new LookupTableTransform<NumericType> (function,
70
71 lookupTable.reset (table);
72 generator = [table] (NumericType x) { return (*table) (x); };
73 }
74 else
75 {
76 generator = function;
77 }
78 }
79
80 //==============================================================================
82 void setFrequency (NumericType newFrequency, bool force = false) noexcept
83 {
84 if (force)
85 {
87 return;
88 }
89
90 frequency.setTargetValue (newFrequency);
91 }
92
94 NumericType getFrequency() const noexcept { return frequency.getTargetValue(); }
95
96 //==============================================================================
98 void prepare (const ProcessSpec& spec) noexcept
99 {
100 sampleRate = static_cast<NumericType> (spec.sampleRate);
101 rampBuffer.resize ((int) spec.maximumBlockSize);
102
103 reset();
104 }
105
107 void reset() noexcept
108 {
109 phase.reset();
110
111 if (sampleRate > 0)
112 frequency.reset (sampleRate, 0.05);
113 }
114
115 //==============================================================================
117 SampleType JUCE_VECTOR_CALLTYPE processSample (SampleType input) noexcept
118 {
120 auto increment = MathConstants<NumericType>::twoPi * frequency.getNextValue() / sampleRate;
121 return input + generator (phase.advance (increment) - MathConstants<NumericType>::pi);
122 }
123
125 template <typename ProcessContext>
126 void process (const ProcessContext& context) noexcept
127 {
129 auto&& outBlock = context.getOutputBlock();
130 auto&& inBlock = context.getInputBlock();
131
132 // this is an output-only processor
133 jassert (outBlock.getNumSamples() <= static_cast<size_t> (rampBuffer.size()));
134
135 auto len = outBlock.getNumSamples();
136 auto numChannels = outBlock.getNumChannels();
137 auto inputChannels = inBlock.getNumChannels();
139
140 if (context.isBypassed)
141 context.getOutputBlock().clear();
142
143 if (frequency.isSmoothing())
144 {
145 auto* buffer = rampBuffer.getRawDataPointer();
146
147 for (size_t i = 0; i < len; ++i)
148 buffer[i] = phase.advance (baseIncrement * frequency.getNextValue())
150
151 if (! context.isBypassed)
152 {
153 size_t ch;
154
155 if (context.usesSeparateInputAndOutputBlocks())
156 {
157 for (ch = 0; ch < jmin (numChannels, inputChannels); ++ch)
158 {
159 auto* dst = outBlock.getChannelPointer (ch);
160 auto* src = inBlock.getChannelPointer (ch);
161
162 for (size_t i = 0; i < len; ++i)
163 dst[i] = src[i] + generator (buffer[i]);
164 }
165 }
166 else
167 {
168 for (ch = 0; ch < jmin (numChannels, inputChannels); ++ch)
169 {
170 auto* dst = outBlock.getChannelPointer (ch);
171
172 for (size_t i = 0; i < len; ++i)
173 dst[i] += generator (buffer[i]);
174 }
175 }
176
177 for (; ch < numChannels; ++ch)
178 {
179 auto* dst = outBlock.getChannelPointer (ch);
180
181 for (size_t i = 0; i < len; ++i)
182 dst[i] = generator (buffer[i]);
183 }
184 }
185 }
186 else
187 {
188 auto freq = baseIncrement * frequency.getNextValue();
189 auto p = phase;
190
191 if (context.isBypassed)
192 {
193 frequency.skip (static_cast<int> (len));
194 p.advance (freq * static_cast<NumericType> (len));
195 }
196 else
197 {
198 size_t ch;
199
200 if (context.usesSeparateInputAndOutputBlocks())
201 {
202 for (ch = 0; ch < jmin (numChannels, inputChannels); ++ch)
203 {
204 p = phase;
205 auto* dst = outBlock.getChannelPointer (ch);
206 auto* src = inBlock.getChannelPointer (ch);
207
208 for (size_t i = 0; i < len; ++i)
209 dst[i] = src[i] + generator (p.advance (freq) - MathConstants<NumericType>::pi);
210 }
211 }
212 else
213 {
214 for (ch = 0; ch < jmin (numChannels, inputChannels); ++ch)
215 {
216 p = phase;
217 auto* dst = outBlock.getChannelPointer (ch);
218
219 for (size_t i = 0; i < len; ++i)
220 dst[i] += generator (p.advance (freq) - MathConstants<NumericType>::pi);
221 }
222 }
223
224 for (; ch < numChannels; ++ch)
225 {
226 p = phase;
227 auto* dst = outBlock.getChannelPointer (ch);
228
229 for (size_t i = 0; i < len; ++i)
230 dst[i] = generator (p.advance (freq) - MathConstants<NumericType>::pi);
231 }
232 }
233
234 phase = p;
235 }
236 }
237
238private:
239 //==============================================================================
242 Array<NumericType> rampBuffer;
243 SmoothedValue<NumericType> frequency { static_cast<NumericType> (440.0) };
244 NumericType sampleRate = 48000.0;
245 Phase<NumericType> phase;
246};
247
248} // namespace juce::dsp
Holds a resizable array of primitive or copy-by-value objects.
Definition juce_Array.h:56
int size() const noexcept
Returns the current number of elements in the array.
Definition juce_Array.h:215
ElementType * getRawDataPointer() noexcept
Returns a pointer to the actual array data.
Definition juce_Array.h:310
void resize(int targetNumItems)
This will enlarge or shrink the array to the given number of elements, by adding or removing items fr...
Definition juce_Array.h:670
bool isSmoothing() const noexcept
Returns true if the current value is currently being interpolated.
void setCurrentAndTargetValue(FloatType newValue)
Sets the current value and the target value.
FloatType getTargetValue() const noexcept
Returns the target value towards which the smoothed value is currently moving.
A utility class for values that need smoothing to avoid audio glitches.
FloatType skip(int numSamples) noexcept
Skip the next numSamples samples.
FloatType getNextValue() noexcept
Compute the next value.
void reset(double sampleRate, double rampLengthInSeconds) noexcept
Reset to a new sample rate and ramp length.
void setTargetValue(FloatType newValue) noexcept
Set the next value to ramp towards.
Generates a signal based on a user-supplied function.
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType input) noexcept
Returns the result of processing a single sample.
Oscillator(const std::function< NumericType(NumericType)> &function, size_t lookupTableNumPoints=0)
Creates an oscillator with a periodic input function (-pi..pi).
Oscillator()=default
Creates an uninitialised oscillator.
void prepare(const ProcessSpec &spec) noexcept
Called before processing starts.
bool isInitialised() const noexcept
Returns true if the Oscillator has been initialised.
typename SampleTypeHelpers::ElementType< SampleType >::Type NumericType
The NumericType is the underlying primitive type used by the SampleType (which could be either a prim...
void reset() noexcept
Resets the internal state of the oscillator.
NumericType getFrequency() const noexcept
Returns the current frequency of the oscillator.
void process(const ProcessContext &context) noexcept
Processes the input and output buffers supplied in the processing context.
void setFrequency(NumericType newFrequency, bool force=false) noexcept
Sets the frequency of the oscillator.
void initialise(const std::function< NumericType(NumericType)> &function, size_t lookupTableNumPoints=0)
Initialises the oscillator with a waveform.
#define jassert(expression)
Platform-independent assertion macro.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
Commonly used mathematical constants.
void reset() noexcept
Resets the phase to 0.
Definition juce_Phase.h:41
Type advance(Type increment) noexcept
Returns the current value, and increments the phase by the given increment.
Definition juce_Phase.h:47
This structure is passed into a DSP algorithm's prepare() method, and contains information about vari...