diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-04 14:00:10 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-04 14:00:10 +0100 |
| commit | 7dec3ee015f8741e62aa2d24556426778571fc14 (patch) | |
| tree | 2a2cb4b41115474d4fff56d77f360f85a8e81378 | |
| parent | 18c553b0aaa9a574a2a40e5499120ac8a802b735 (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>
| -rw-r--r-- | src/audio/wav_dump_backend.cc | 36 |
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; } |
