37 template <
typename SampleType>
44 using NumericType =
typename SampleTypeHelpers::ElementType<SampleType>::Type;
55 size_t lookupTableNumPoints = 0)
61 bool isInitialised() const noexcept {
return static_cast<bool> (generator); }
65 size_t lookupTableNumPoints = 0)
67 if (lookupTableNumPoints != 0)
71 MathConstants<NumericType>::pi,
72 lookupTableNumPoints);
74 lookupTable.reset (table);
75 generator = [table] (
NumericType x) {
return (*table) (x); };
103 sampleRate =
static_cast<NumericType> (spec.sampleRate);
104 rampBuffer.
resize ((
int) spec.maximumBlockSize);
115 frequency.
reset (sampleRate, 0.05);
128 template <
typename ProcessContext>
129 void process (
const ProcessContext& context) noexcept
132 auto&& outBlock = context.getOutputBlock();
133 auto&& inBlock = context.getInputBlock();
136 jassert (outBlock.getNumSamples() <=
static_cast<size_t> (rampBuffer.
size()));
138 auto len = outBlock.getNumSamples();
139 auto numChannels = outBlock.getNumChannels();
140 auto inputChannels = inBlock.getNumChannels();
143 if (context.isBypassed)
144 context.getOutputBlock().clear();
150 for (
size_t i = 0; i < len; ++i)
154 if (! context.isBypassed)
158 if (context.usesSeparateInputAndOutputBlocks())
160 for (ch = 0; ch < jmin (numChannels, inputChannels); ++ch)
162 auto* dst = outBlock.getChannelPointer (ch);
163 auto* src = inBlock.getChannelPointer (ch);
165 for (
size_t i = 0; i < len; ++i)
166 dst[i] = src[i] + generator (buffer[i]);
171 for (ch = 0; ch < jmin (numChannels, inputChannels); ++ch)
173 auto* dst = outBlock.getChannelPointer (ch);
175 for (
size_t i = 0; i < len; ++i)
176 dst[i] += generator (buffer[i]);
180 for (; ch < numChannels; ++ch)
182 auto* dst = outBlock.getChannelPointer (ch);
184 for (
size_t i = 0; i < len; ++i)
185 dst[i] = generator (buffer[i]);
194 if (context.isBypassed)
196 frequency.
skip (static_cast<int> (len));
197 p.advance (freq * static_cast<NumericType> (len));
203 if (context.usesSeparateInputAndOutputBlocks())
205 for (ch = 0; ch < jmin (numChannels, inputChannels); ++ch)
208 auto* dst = outBlock.getChannelPointer (ch);
209 auto* src = inBlock.getChannelPointer (ch);
211 for (
size_t i = 0; i < len; ++i)
217 for (ch = 0; ch < jmin (numChannels, inputChannels); ++ch)
220 auto* dst = outBlock.getChannelPointer (ch);
222 for (
size_t i = 0; i < len; ++i)
227 for (; ch < numChannels; ++ch)
230 auto* dst = outBlock.getChannelPointer (ch);
232 for (
size_t i = 0; i < len; ++i)
243 std::function<NumericType(NumericType)> generator;
244 std::unique_ptr<LookupTableTransform<NumericType>> lookupTable;
FloatType getNextValue() noexcept
FloatType getTargetValue() const noexcept
typename SampleTypeHelpers::ElementType< SampleType >::Type NumericType
FloatType skip(int numSamples) noexcept
void reset(double sampleRate, double rampLengthInSeconds) noexcept
void setFrequency(NumericType newFrequency, bool force=false) noexcept
bool isSmoothing() const noexcept
void resize(int targetNumItems)
bool isInitialised() const noexcept
Type advance(Type increment) 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
int size() const noexcept
ElementType * getRawDataPointer() noexcept
void setTargetValue(FloatType newValue) noexcept
NumericType getFrequency() const noexcept
void setCurrentAndTargetValue(FloatType newValue)
void process(const ProcessContext &context) noexcept
void initialise(const std::function< NumericType(NumericType)> &function, size_t lookupTableNumPoints=0)