NoiceSynth/synth_engine.h
2026-02-28 17:49:26 +01:00

129 lines
3.8 KiB
C++

#ifndef SYNTH_ENGINE_H
#define SYNTH_ENGINE_H
#include <stdint.h>
#include <mutex>
/**
* @class SynthEngine
* @brief A portable, platform-agnostic synthesizer engine.
*
* This class contains the core digital signal processing (DSP) logic.
* It has no dependencies on any specific hardware, OS, or audio API.
* It works by filling a provided buffer with 16-bit signed audio samples.
*
* The oscillator uses a 32-bit unsigned integer as a phase accumulator,
* which is highly efficient and avoids floating-point math in the audio loop,
* making it ideal for the RP2040.
*/
class SynthEngine {
public:
enum Waveform {
SAWTOOTH,
SQUARE,
SINE
};
/**
* @brief Constructs the synthesizer engine.
* @param sampleRate The audio sample rate in Hz (e.g., 44100).
*/
~SynthEngine();
SynthEngine(uint32_t sampleRate);
/**
* @brief Fills a buffer with audio samples. This is the main audio callback.
* @param buffer Pointer to the output buffer to be filled.
* @param numFrames The number of audio frames (samples) to generate.
*/
void process(int16_t* buffer, uint32_t numFrames);
/**
* @brief Sets the frequency of the oscillator.
* @param freq The frequency in Hz.
*/
void setFrequency(float freq);
/**
* @brief Sets the output volume.
* @param vol Volume from 0.0 (silent) to 1.0 (full).
*/
void setVolume(float vol);
/**
* @brief Sets the oscillator's waveform.
* @param form The waveform to use.
*/
void setWaveform(Waveform form);
/**
* @brief Opens or closes the sound gate.
* @param isOpen True to produce sound, false for silence.
*/
void setGate(bool isOpen);
/**
* @brief Gets the current frequency of the oscillator.
* @return The frequency in Hz.
*/
float getFrequency() const;
/**
* @brief Configures the ADSR envelope.
* @param attack Attack time in seconds.
* @param decay Decay time in seconds.
* @param sustain Sustain level (0.0 to 1.0).
* @param release Release time in seconds.
*/
void setADSR(float attack, float decay, float sustain, float release);
/**
* @brief Configures the filters.
* @param lpCutoff Low-pass cutoff frequency in Hz.
* @param hpCutoff High-pass cutoff frequency in Hz.
*/
void setFilter(float lpCutoff, float hpCutoff);
// --- Grid Synth ---
struct GridCell {
enum Type { EMPTY, FIXED_OSCILLATOR, INPUT_OSCILLATOR, WAVETABLE, NOISE, LFO, FORK, WIRE, LPF, HPF, VCA, BITCRUSHER, DISTORTION, GLITCH, OPERATOR, DELAY, REVERB, SINK };
enum Op { OP_ADD, OP_MUL, OP_SUB, OP_DIV, OP_MIN, OP_MAX };
Type type = EMPTY;
float param = 0.5f; // 0.0 to 1.0
int rotation = 0; // 0:N, 1:E, 2:S, 3:W (Output direction)
float value = 0.0f; // Current output sample
float phase = 0.0f; // For Oscillator, Noise state
float* buffer = nullptr; // For Delay
uint32_t buffer_size = 0; // For Delay
uint32_t write_idx = 0; // For Delay
};
GridCell grid[5][8];
std::mutex gridMutex;
// Helper to process one sample step of the grid
float processGridStep();
private:
uint32_t _sampleRate;
uint32_t _phase; // Phase accumulator for the oscillator.
uint32_t _increment; // Phase increment per sample, determines frequency.
float _volume;
Waveform _waveform;
bool _isGateOpen;
// ADSR State
enum EnvState { ENV_IDLE, ENV_ATTACK, ENV_DECAY, ENV_SUSTAIN, ENV_RELEASE };
EnvState _envState;
float _envLevel;
float _attackInc, _decayDec, _sustainLevel, _releaseDec;
// Filter State
float _lpAlpha;
float _hpAlpha;
float _lpVal;
float _hpVal;
};
#endif // SYNTH_ENGINE_H