From 18c553b0aaa9a574a2a40e5499120ac8a802b735 Mon Sep 17 00:00:00 2001 From: skal Date: Wed, 4 Feb 2026 13:55:45 +0100 Subject: feat(audio): Add WAV dump backend for debugging audio output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented WavDumpBackend that renders audio to .wav file instead of playing on audio device. Useful for debugging audio synthesis, tempo scaling, and tracker output without needing real-time playback. New Files: - src/audio/wav_dump_backend.h: WAV dump backend interface - src/audio/wav_dump_backend.cc: Implementation with WAV file writing Features: - Command line option: --dump_wav [filename] - Default output: audio_dump.wav - Format: 16-bit PCM, mono, 32kHz - Duration: 60 seconds (configurable in code) - Progress indicator during rendering - Properly writes WAV header (RIFF format) Integration (src/main.cc): - Added --dump_wav command line parsing - Optional filename parameter - Sets WavDumpBackend before audio_init() - Skips main loop in WAV dump mode (just render and exit) - Zero size impact (all code under !STRIP_ALL) Usage: ./demo64k --dump_wav # outputs audio_dump.wav ./demo64k --dump_wav my_audio.wav # custom filename Technical Details: - Uses AudioBackend interface (from Task #51) - Calls synth_render() in loop to capture audio - Converts float samples to int16_t for WAV format - Updates WAV header with final sample count on shutdown - Renders 60s worth of audio (1,920,000 samples @ 32kHz) Test Results: ✓ All 16 tests passing (100%) ✓ Successfully renders 3.7 MB WAV file ✓ File verified as valid RIFF WAVE format ✓ Playback in audio players confirmed Perfect for: - Debugging tempo scaling behavior - Verifying tracker pattern timing - Analyzing audio output offline - Creating reference audio for tests handoff(Claude): WAV dump debugging feature complete Co-Authored-By: Claude Sonnet 4.5 --- src/main.cc | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'src/main.cc') diff --git a/src/main.cc b/src/main.cc index 3d05822..12f4b3d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -7,6 +7,9 @@ #include "audio/gen.h" #include "audio/synth.h" #include "audio/tracker.h" +#if !defined(STRIP_ALL) +#include "audio/wav_dump_backend.h" +#endif #include "generated/assets.h" // Include generated asset header #include "gpu/gpu.h" #include "platform.h" @@ -51,6 +54,8 @@ int main(int argc, char** argv) { float seek_time = 0.0f; int width = 1280; int height = 720; + bool dump_wav = false; + const char* wav_output_file = "audio_dump.wav"; #if !defined(STRIP_ALL) for (int i = 1; i < argc; ++i) { @@ -68,6 +73,12 @@ int main(int argc, char** argv) { } } else if (strcmp(argv[i], "--debug") == 0) { Renderer3D::SetDebugEnabled(true); + } else if (strcmp(argv[i], "--dump_wav") == 0) { + dump_wav = true; + // Optional: allow specifying output filename + if (i + 1 < argc && argv[i + 1][0] != '-') { + wav_output_file = argv[++i]; + } } } #else @@ -78,6 +89,17 @@ int main(int argc, char** argv) { platform_state = platform_init(fullscreen_enabled, width, height); gpu_init(&platform_state); + +#if !defined(STRIP_ALL) + // Set WAV dump backend if requested + WavDumpBackend wav_backend; + if (dump_wav) { + wav_backend.set_output_file(wav_output_file); + audio_set_backend(&wav_backend); + printf("WAV dump mode enabled: %s\n", wav_output_file); + } +#endif + audio_init(); synth_init(); tracker_init(); @@ -178,9 +200,19 @@ int main(int argc, char** argv) { } #endif /* !defined(STRIP_ALL) */ - // Start real audio + // Start audio (or render to WAV file) audio_start(); +#if !defined(STRIP_ALL) + // In WAV dump mode, audio_start() renders everything and we can exit + if (dump_wav) { + audio_shutdown(); + gpu_shutdown(); + platform_shutdown(&platform_state); + return 0; + } +#endif + int last_width = platform_state.width; int last_height = platform_state.height; -- cgit v1.2.3