summaryrefslogtreecommitdiff
path: root/src/audio/synth.cc
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-03-05 22:49:48 +0100
committerskal <pascal.massimino@gmail.com>2026-03-05 22:49:48 +0100
commitdb6fbf8b8eae8b96d129ac673cbf11d67926996a (patch)
tree97d28da56a77c17f5583a9342a77cb065b25f31f /src/audio/synth.cc
parentb7fc4aa9a6bd15ce9780d46a425971d523c10b92 (diff)
fix(audio): correct OLA synthesis and extract shared ola_encode/ola_decode
- Remove erroneous Hann synthesis window from synth.cc (g_hann * tmp[j]). Hann analysis at 50% overlap satisfies w[n]+w[n+H]=1, so rectangular synthesis gives perfect reconstruction; applying Hann twice was wrong. - Extract ola_encode()/ola_decode()/ola_num_frames() into src/audio/ola.h+cc. spectool and test_wav_roundtrip now use the shared functions. synth.cc lazy-decode path stays inlined (see TODO for future refactor). - Drop dead <atomic> include and g_hann array from synth.cc. - Drop dead window.h include from spectool.cc. - Update PROJECT_CONTEXT.md, COMPLETED.md, TODO.md to reflect correct analysis-only Hann window and new ola.h API. handoff(Gemini): OLA synthesis bug fixed + ola.h factorized. synth.cc lazy-decode still inline (TODO item added). 34/35 tests pass; WavDumpBackendTest failure is pre-existing and unrelated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'src/audio/synth.cc')
-rw-r--r--src/audio/synth.cc10
1 files changed, 3 insertions, 7 deletions
diff --git a/src/audio/synth.cc b/src/audio/synth.cc
index a723404..3212e0b 100644
--- a/src/audio/synth.cc
+++ b/src/audio/synth.cc
@@ -4,9 +4,7 @@
#include "synth.h"
#include "audio/dct.h"
-#include "audio/window.h"
#include "util/debug.h"
-#include <atomic>
#include <math.h>
#include <stdio.h> // For printf
#include <string.h> // For memset
@@ -47,7 +45,6 @@ static Voice g_voices[MAX_VOICES];
static volatile float g_current_output_peak =
0.0f; // Global peak for visualization
static float g_tempo_scale = 1.0f; // Playback speed multiplier
-static float g_hann[DCT_SIZE]; // Hann window for OLA synthesis (v2)
#if !defined(STRIP_ALL)
static float g_elapsed_time_sec = 0.0f; // Tracks elapsed time for event hooks
@@ -57,7 +54,6 @@ void synth_init() {
memset(&g_synth_data, 0, sizeof(g_synth_data));
memset(g_voices, 0, sizeof(g_voices));
g_current_output_peak = 0.0f;
- hann_window_512(g_hann);
#if !defined(STRIP_ALL)
g_elapsed_time_sec = 0.0f;
#endif /* !defined(STRIP_ALL) */
@@ -266,11 +262,11 @@ void synth_render(float* output_buffer, int num_frames) {
(v.current_spectral_frame * DCT_SIZE);
if (v.ola_mode) {
- // OLA-IDCT synthesis (v2): Hann window + overlap-add
+ // OLA-IDCT synthesis (v2): no synthesis window.
+ // Analysis used Hann; at 50% overlap w[n]+w[n+H]=1 so
+ // rectangular synthesis gives perfect reconstruction.
float tmp[DCT_SIZE];
idct_512(spectral_frame, tmp);
- for (int j = 0; j < DCT_SIZE; ++j)
- tmp[j] *= g_hann[j];
// Add saved overlap from previous frame
for (int j = 0; j < OLA_OVERLAP; ++j)
tmp[j] += v.overlap_buf[j];