// The synthesiser: harmonic oscillators, noise from inverse FFTs, pulses, and a 160-sample overlap-add. // Each frame interpolates from the previous frame's parameters to the current one's. #pragma once #include #include #include "decoder_options.h" namespace halfrate::dec { constexpr int kFrameSamples = 160; constexpr int kHarmonicSlots = 58; // per-harmonic arrays, indexed by harmonic number 1..L (L <= 56) // What the synthesiser makes of one frame. struct SynthFrame { int32_t active = 0; // nonzero: the frame has sound float fundamental = 0.0f; // cycles per sample int32_t harmonic_count = 0; // L std::array amplitude{}; // linear std::array voiced{}; // weight of the harmonic's oscillator std::array unvoiced{}; // weight of noise around the harmonic std::array pulse{}; // weight of the harmonic in the pulse shape std::array phase{}; // phase offset, cycles int32_t pulse_count = 0; // 0..2 std::array pulse_position{}; std::array pulse_gain{}; }; struct SynthState { SynthFrame previous; std::array harmonic_phase{}; // per-harmonic oscillators, 2^64 = one cycle uint64_t fundamental_phase = 0; // phase_tracking 1: the fundamental's phase std::array noise_phase{}; // drifting phases of the low noise bins (13 bits) std::array overlap{}; // the next frame's first 160 samples, and the rest uint32_t random = 0; // LCG state std::array window320{}; // sine windows std::array window80{}; }; // Clears the state, seeds the noise generator and sets the initial oscillator phases. void synth_reset(SynthState& state, const Options& options); // One frame: out[0..159]. void synth_frame(SynthState& state, const Options& options, const SynthFrame& frame, float* out); // 160 samples of uniform noise of rms level. void synth_comfort_noise(SynthState& state, float level, float* out); // cos(2 pi x), x in cycles, linearly interpolated in the cosine table. float cosine_interpolated(float x); } // namespace halfrate::dec