FastLED 3.10.8
Loading...
Searching...
No Matches
synth.cpp.hpp
Go to the documentation of this file.
1// synth.cpp.hpp - Implementation of bandlimited audio synthesizer oscillator
2//
3// This file implements the fl::ISynthOscillator interface and related APIs
4// that wrap the low-level stb_hexwave library.
5
6#include "fl/audio/synth.h"
7#include "fl/stl/cstring.h"
8#include "fl/stl/malloc.h"
9// IWYU pragma: begin_keep
11#include "fl/stl/noexcept.h"
12// IWYU pragma: end_keep
13
14namespace fl {
15namespace audio {
16
17// Short alias for third_party hexwave namespace to avoid verbose qualification
18// without polluting fl:: namespace in unity builds.
19namespace hw = third_party::hexwave;
20
21
23// SynthEngineImpl - Implementation of ISynthEngine interface
25
27public:
28 SynthEngineImpl(i32 width, i32 oversample) FL_NO_EXCEPT;
30
31 // Non-copyable
34
35 // ISynthEngine interface
36 bool isValid() const FL_NO_EXCEPT override;
37 i32 getWidth() const FL_NO_EXCEPT override { return mWidth; }
38 i32 getOversample() const FL_NO_EXCEPT override { return mOversample; }
39
40 // Internal access for SynthOscillatorImpl (same compilation unit)
41 hw::HexWaveEngine* getEngineInternal() const FL_NO_EXCEPT { return mEngine; }
42
43private:
44 hw::HexWaveEngine* mEngine = nullptr;
45 i32 mWidth;
47};
48
50// SynthOscillatorImpl - Implementation of ISynthOscillator interface
52
54public:
57
58 // Non-copyable
61
62 // ISynthOscillator interface
63 void generateSamples(float* output, i32 numSamples, float freq) FL_NO_EXCEPT override;
64 void generateSamples(fl::span<float> output, float freq) FL_NO_EXCEPT override;
65 void setShape(SynthShape shape) FL_NO_EXCEPT override;
66 void setParams(const SynthParams& params) FL_NO_EXCEPT override;
67 SynthParams getParams() const FL_NO_EXCEPT override;
68 void reset() FL_NO_EXCEPT override;
69 ISynthEnginePtr getEngine() const FL_NO_EXCEPT override { return mEngine; }
70
71private:
72 fl::shared_ptr<SynthEngineImpl> mEngine; // Shared pointer to engine (keeps it alive)
73 hw::HexWave* mHexWave = nullptr; // Typed pointer to HexWave structure
75};
76
77// SynthParams implementation
79 switch (shape) {
81 return SynthParams(1, 0.0f, 0.0f, 0.0f);
83 return SynthParams(1, 0.0f, 1.0f, 0.0f);
85 return SynthParams(1, 0.5f, 0.0f, 0.0f);
87 return SynthParams(0, 0.0f, 0.0f, 0.0f);
89 default:
90 return SynthParams(); // Default to sawtooth
91 }
92}
93
95// ISynthEngine static factory method
97
98ISynthEnginePtr ISynthEngine::create(i32 width, i32 oversample) FL_NO_EXCEPT {
99 return fl::make_shared<SynthEngineImpl>(width, oversample);
100}
101
103// SynthEngineImpl implementation
105
107 FL_NO_EXCEPT : mWidth(width), mOversample(oversample) {
108 // Clamp width to valid range
109 if (mWidth < 4) mWidth = 4;
111
112 // Clamp oversample to minimum
113 if (mOversample < 2) mOversample = 2;
114
115 mEngine = hw::hexwave_engine_create(mWidth, mOversample, nullptr);
116}
117
119 if (mEngine) {
120 hw::hexwave_engine_destroy(mEngine);
121 mEngine = nullptr;
122 }
123}
124
126 return mEngine != nullptr;
127}
128
130// ISynthOscillator static factory methods
132
133ISynthOscillatorPtr ISynthOscillator::create(ISynthEnginePtr engine, SynthShape shape) FL_NO_EXCEPT {
134 return create(engine, SynthParams::fromShape(shape));
135}
136
137ISynthOscillatorPtr ISynthOscillator::create(ISynthEnginePtr engine, const SynthParams& params) FL_NO_EXCEPT {
138 if (!engine || !engine->isValid()) {
139 return nullptr;
140 }
141 // Safe downcast - we control the factory, so we know the concrete type
142 auto engineImpl = fl::static_pointer_cast<SynthEngineImpl>(engine);
143 return fl::make_shared<SynthOscillatorImpl>(engineImpl, params);
144}
145
147// SynthOscillatorImpl implementation
149
151 FL_NO_EXCEPT : mEngine(engine), mCurrentParams(params) {
152 // Allocate HexWave structure
153 mHexWave = static_cast<hw::HexWave*>(fl::malloc(sizeof(hw::HexWave)));
154 fl::memset(mHexWave, 0, sizeof(hw::HexWave));
155
156 // Initialize the oscillator with the engine
157 hw::hexwave_create(
158 mHexWave,
159 engine->getEngineInternal(),
160 params.reflect,
161 params.peakTime,
162 params.halfHeight,
163 params.zeroWait
164 );
165}
166
173
174void SynthOscillatorImpl::generateSamples(float* output, i32 numSamples, float freq) FL_NO_EXCEPT {
175 if (mHexWave && output && numSamples > 0) {
176 hw::hexwave_generate_samples(output, numSamples, mHexWave, freq);
177 }
178}
179
181 generateSamples(output.data(), static_cast<i32>(output.size()), freq);
182}
183
187
189 if (mHexWave) {
190 mCurrentParams = params;
191 hw::hexwave_change(
192 mHexWave,
193 params.reflect,
194 params.peakTime,
195 params.halfHeight,
196 params.zeroWait
197 );
198 }
199}
200
204
206 if (mHexWave && mEngine) {
207 // Re-create the oscillator with current parameters
208 hw::hexwave_create(
209 mHexWave,
210 mEngine->getEngineInternal(),
211 mCurrentParams.reflect,
212 mCurrentParams.peakTime,
213 mCurrentParams.halfHeight,
214 mCurrentParams.zeroWait
215 );
216 }
217}
218
219} // namespace audio
220} // namespace fl
static ISynthEnginePtr create(i32 width=32, i32 oversample=16) FL_NO_EXCEPT
Factory function to create an engine with the specified quality settings.
Definition synth.cpp.hpp:98
Interface for synth engine that holds BLEP/BLAMP tables.
Definition synth.h:90
static ISynthOscillatorPtr create(ISynthEnginePtr engine, const SynthParams &params) FL_NO_EXCEPT
Factory function to create an oscillator with specified engine and parameters.
Interface class for synth oscillator.
Definition synth.h:117
SynthEngineImpl(const SynthEngineImpl &) FL_NO_EXCEPT=delete
~SynthEngineImpl() FL_NO_EXCEPT override
hw::HexWaveEngine * mEngine
Definition synth.cpp.hpp:44
i32 getOversample() const FL_NO_EXCEPT override
Get the oversample setting.
Definition synth.cpp.hpp:38
bool isValid() const FL_NO_EXCEPT override
Check if engine was initialized successfully.
hw::HexWaveEngine * getEngineInternal() const FL_NO_EXCEPT
Definition synth.cpp.hpp:41
SynthEngineImpl & operator=(const SynthEngineImpl &) FL_NO_EXCEPT=delete
SynthEngineImpl(i32 width, i32 oversample) FL_NO_EXCEPT
i32 getWidth() const FL_NO_EXCEPT override
Get the width setting.
Definition synth.cpp.hpp:37
SynthParams getParams() const FL_NO_EXCEPT override
Get current waveform parameters.
ISynthEnginePtr getEngine() const FL_NO_EXCEPT override
Get the engine this oscillator uses.
Definition synth.cpp.hpp:69
SynthOscillatorImpl(const SynthOscillatorImpl &) FL_NO_EXCEPT=delete
void setParams(const SynthParams &params) FL_NO_EXCEPT override
Change waveform parameters (takes effect at next cycle boundary)
void generateSamples(float *output, i32 numSamples, float freq) FL_NO_EXCEPT override
Generate audio samples.
void setShape(SynthShape shape) FL_NO_EXCEPT override
Change waveform shape (takes effect at next cycle boundary)
~SynthOscillatorImpl() FL_NO_EXCEPT override
SynthOscillatorImpl & operator=(const SynthOscillatorImpl &) FL_NO_EXCEPT=delete
SynthOscillatorImpl(fl::shared_ptr< SynthEngineImpl > engine, const SynthParams &params) FL_NO_EXCEPT
fl::shared_ptr< SynthEngineImpl > mEngine
Definition synth.cpp.hpp:72
void reset() FL_NO_EXCEPT override
Reset oscillator to beginning of cycle.
shared_ptr< T > make_shared(Args &&... args) FL_NO_EXCEPT
Definition shared_ptr.h:423
SynthShape
Predefined waveform shapes for synth oscillator.
Definition synth.h:59
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
FASTLED_FORCE_INLINE void free(void *ptr) FL_NO_EXCEPT
Definition malloc.h:23
FASTLED_FORCE_INLINE void * malloc(size_t size) FL_NO_EXCEPT
Definition malloc.h:21
FASTLED_FORCE_INLINE void * memset(void *s, int c, size_t n) FL_NO_EXCEPT
Definition cstring.h:148
u8 width
Definition blur.h:186
shared_ptr< T > static_pointer_cast(const shared_ptr< Y > &other) FL_NO_EXCEPT
Definition shared_ptr.h:556
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_STB_HEXWAVE_MAX_BLEP_LENGTH
Definition stb_hexwave.h:67
static SynthParams fromShape(SynthShape shape) FL_NO_EXCEPT
Create parameters for a predefined shape.
Definition synth.cpp.hpp:78
SynthParams() FL_NO_EXCEPT=default
Default constructor - sawtooth wave.
Waveform parameters for custom waveforms.
Definition synth.h:68
Bandlimited audio synthesizer - waveform oscillator module.