summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-04 14:00:10 +0100
committerskal <pascal.massimino@gmail.com>2026-02-04 14:00:10 +0100
commit7dec3ee015f8741e62aa2d24556426778571fc14 (patch)
tree2a2cb4b41115474d4fff56d77f360f85a8e81378 /src
parent18c553b0aaa9a574a2a40e5499120ac8a802b735 (diff)
fix(audio): WAV dump backend now properly triggers tracker patterns
Fixed critical bug where WavDumpBackend rendered only silence (zeros). Root Cause Analysis: - WavDumpBackend::start() called synth_render() in a loop - BUT never called tracker_update() to trigger patterns - Result: No voices triggered, synth rendered silence (zero-filled WAV) The Fix: - Added #include "tracker.h" to wav_dump_backend.cc - Implemented music time simulation in WavDumpBackend::start() - Now calls tracker_update(music_time) before each synth_render() - Simulates tempo scaling phases (matches main.cc logic): * 0-10s: tempo = 1.0x (steady) * 10-15s: tempo = 1.0 → 2.0x (acceleration) * 15-20s: tempo = 1.0x (reset) * 20-25s: tempo = 1.0 → 0.5x (deceleration) * 25s+: tempo = 1.0x (reset) Technical Details: - Calculate dt = kBufferSize / kSampleRate (time per audio buffer) - Track music_time, physical_time, and tempo_scale - Advance music_time by dt * tempo_scale each iteration - Call tracker_update(music_time) to trigger patterns - Then call synth_render() to render triggered voices Enhanced Progress Output: - Now shows: "Rendering: X.Xs / 60s (music: Y.Ys, tempo: Z.ZZx)" - Final summary includes total music time - Example: "60.00 seconds, 61.24 music time" (tempo scaling verified) Verification: ✓ WAV file now contains actual audio data (not zeros) ✓ Hexdump shows varying sample values (37 00, df ff, etc.) ✓ 141,307 non-zero data lines in 3.7 MB file ✓ Tempo scaling visible in progress output ✓ All 16 tests passing (100%) Before: Zero-filled WAV, no audio After: Proper drum track with tempo scaling effects handoff(Claude): WAV dump bug fixed, audio rendering confirmed Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src')
-rw-r--r--src/audio/wav_dump_backend.cc36
1 files changed, 33 insertions, 3 deletions
diff --git a/src/audio/wav_dump_backend.cc b/src/audio/wav_dump_backend.cc
index 7418a40..fbbbeaa 100644
--- a/src/audio/wav_dump_backend.cc
+++ b/src/audio/wav_dump_backend.cc
@@ -6,6 +6,7 @@
#if !defined(STRIP_ALL)
#include "synth.h"
+#include "tracker.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -49,7 +50,35 @@ void WavDumpBackend::start() {
const size_t total_samples = kSampleRate * max_duration_sec;
const size_t total_frames = total_samples / kBufferSize;
+ // Music time tracking (matches main.cc logic)
+ float music_time = 0.0f;
+ float tempo_scale = 1.0f;
+ float physical_time = 0.0f;
+ const float dt = (float)kBufferSize / kSampleRate; // Time per buffer
+
for (size_t frame = 0; frame < total_frames; ++frame) {
+ // Update tempo scaling (matches main.cc phases)
+ if (physical_time < 10.0f) {
+ tempo_scale = 1.0f;
+ } else if (physical_time < 15.0f) {
+ const float progress = (physical_time - 10.0f) / 5.0f;
+ tempo_scale = 1.0f + progress * 1.0f; // 1.0 → 2.0
+ } else if (physical_time < 20.0f) {
+ tempo_scale = 1.0f;
+ } else if (physical_time < 25.0f) {
+ const float progress = (physical_time - 20.0f) / 5.0f;
+ tempo_scale = 1.0f - progress * 0.5f; // 1.0 → 0.5
+ } else {
+ tempo_scale = 1.0f;
+ }
+
+ // Advance music time
+ music_time += dt * tempo_scale;
+ physical_time += dt;
+
+ // Update tracker to trigger patterns
+ tracker_update(music_time);
+
// Render audio from synth
synth_render(sample_buffer_.data(), kBufferSize);
@@ -69,7 +98,8 @@ void WavDumpBackend::start() {
// Progress indicator
if (frame % 100 == 0) {
const float progress_sec = (float)samples_written_ / kSampleRate;
- printf(" Rendering: %.1fs / %ds\r", progress_sec, max_duration_sec);
+ printf(" Rendering: %.1fs / %ds (music: %.1fs, tempo: %.2fx)\r",
+ progress_sec, max_duration_sec, music_time, tempo_scale);
fflush(stdout);
}
@@ -77,8 +107,8 @@ void WavDumpBackend::start() {
on_frames_rendered(kBufferSize);
}
- printf("\nWAV dump complete: %zu samples (%.2f seconds)\n", samples_written_,
- (float)samples_written_ / kSampleRate);
+ printf("\nWAV dump complete: %zu samples (%.2f seconds, %.2f music time)\n",
+ samples_written_, (float)samples_written_ / kSampleRate, music_time);
is_active_ = false;
}