#include "synth_engine.h" SynthEngine::SynthEngine(uint32_t sampleRate) : _sampleRate(sampleRate), _phase(0), _increment(0) { // Initialize with a default frequency setFrequency(440.0f); } void SynthEngine::setFrequency(float freq) { // Calculate the phase increment for a given frequency. // The phase accumulator is a 32-bit unsigned integer (0 to 2^32 - 1). // One full cycle of the accumulator represents one cycle of the waveform. // increment = (frequency * 2^32) / sampleRate // We use a 64-bit intermediate calculation to prevent overflow. _increment = static_cast((static_cast(freq) << 32) / _sampleRate); } void SynthEngine::process(int16_t* buffer, uint32_t numFrames) { for (uint32_t i = 0; i < numFrames; ++i) { // 1. Advance the phase. Integer overflow automatically wraps it, // which is exactly what we want for a continuous oscillator. _phase += _increment; // 2. Generate the sample. For a sawtooth wave, the sample value is // directly proportional to the phase. We take the top 16 bits // of the 32-bit phase accumulator to get a signed 16-bit sample. int16_t sample = static_cast(_phase >> 16); // 3. Write the sample to the buffer. buffer[i] = sample; } }