diff options
| author | skal <pascal.massimino@gmail.com> | 2026-03-05 22:49:48 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-03-05 22:49:48 +0100 |
| commit | db6fbf8b8eae8b96d129ac673cbf11d67926996a (patch) | |
| tree | 97d28da56a77c17f5583a9342a77cb065b25f31f /src/audio/ola.cc | |
| parent | b7fc4aa9a6bd15ce9780d46a425971d523c10b92 (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/ola.cc')
| -rw-r--r-- | src/audio/ola.cc | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/audio/ola.cc b/src/audio/ola.cc new file mode 100644 index 0000000..738df85 --- /dev/null +++ b/src/audio/ola.cc @@ -0,0 +1,34 @@ +// This file is part of the 64k demo project. +// Implements batch OLA encode/decode shared by spectool and tests. +// See ola.h for API documentation. + +#include "audio/ola.h" +#include "audio/window.h" +#include <string.h> + +void ola_encode(const float* pcm, int n_samples, float* spec, int num_frames) { + float win[DCT_SIZE]; + hann_window_512(win); + float chunk[DCT_SIZE]; + for (int f = 0; f < num_frames; ++f) { + const int start = f * OLA_HOP_SIZE; + const int avail = + (start + DCT_SIZE <= n_samples) ? DCT_SIZE : n_samples - start; + for (int i = 0; i < avail; ++i) + chunk[i] = pcm[start + i] * win[i]; + memset(chunk + avail, 0, (DCT_SIZE - avail) * sizeof(float)); + fdct_512(chunk, spec + f * DCT_SIZE); + } +} + +void ola_decode(const float* spec, int num_frames, float* pcm) { + float overlap[OLA_OVERLAP] = {}; + float tmp[DCT_SIZE]; + for (int f = 0; f < num_frames; ++f) { + idct_512(spec + f * DCT_SIZE, tmp); + for (int j = 0; j < OLA_HOP_SIZE; ++j) + pcm[f * OLA_HOP_SIZE + j] = tmp[j] + overlap[j]; + for (int j = 0; j < OLA_OVERLAP; ++j) + overlap[j] = tmp[OLA_HOP_SIZE + j]; + } +} |
