diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-04 13:08:13 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-04 13:08:13 +0100 |
| commit | c4888bea71326f7a69e8214af0d9c2a62a60b887 (patch) | |
| tree | dd1e71be51893414c590db8a7be578ddfd6232f0 /src/audio/synth.cc | |
| parent | f64f842bb0dabd89308e2378e56358bc8abdd653 (diff) | |
feat(audio): Implement audio backend abstraction (Task #51.1)
Created interface-based audio backend system to enable testing without
hardware. This is the foundation for robust tracker timing verification.
Changes:
- Created AudioBackend interface with init/start/shutdown methods
- Added test-only hooks: on_voice_triggered() and on_frames_rendered()
- Moved miniaudio implementation to MiniaudioBackend class
- Refactored audio.cc to use backend abstraction with auto-fallback
- Added time tracking to synth.cc (elapsed time from rendered frames)
- Created test_audio_backend.cc to verify backend injection works
- Fixed audio test linking to include util/procedural dependencies
All test infrastructure guarded by #if !defined(STRIP_ALL) for zero
size impact on final build. Production path unchanged, 100% backward
compatible. All 13 tests pass.
handoff(Claude): Task #51.1 complete, audio backend abstraction ready
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src/audio/synth.cc')
| -rw-r--r-- | src/audio/synth.cc | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/audio/synth.cc b/src/audio/synth.cc index db5a96c..67bc46e 100644 --- a/src/audio/synth.cc +++ b/src/audio/synth.cc @@ -10,6 +10,11 @@ #include <stdio.h> // For printf #include <string.h> // For memset +#if !defined(STRIP_ALL) +#include "audio/audio.h" +#include "audio/audio_backend.h" +#endif /* !defined(STRIP_ALL) */ + struct Voice { bool active; int spectrogram_id; @@ -37,10 +42,17 @@ static volatile float g_current_output_peak = 0.0f; // Global peak for visualization static float g_hamming_window[WINDOW_SIZE]; // Static window for optimization +#if !defined(STRIP_ALL) +static float g_elapsed_time_sec = 0.0f; // Tracks elapsed time for event hooks +#endif /* !defined(STRIP_ALL) */ + 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; +#if !defined(STRIP_ALL) + g_elapsed_time_sec = 0.0f; +#endif /* !defined(STRIP_ALL) */ // Initialize the Hamming window once hamming_window_512(g_hamming_window); } @@ -127,6 +139,15 @@ void synth_trigger_voice(int spectrogram_id, float volume, float pan) { v.active_spectral_data = g_synth_data.active_spectrogram_data[spectrogram_id]; +#if !defined(STRIP_ALL) + // Notify backend of voice trigger event (for testing/tracking) + AudioBackend* backend = audio_get_backend(); + if (backend != nullptr) { + backend->on_voice_triggered(g_elapsed_time_sec, spectrogram_id, volume, + pan); + } +#endif /* !defined(STRIP_ALL) */ + return; // Voice triggered } } @@ -188,6 +209,12 @@ void synth_render(float* output_buffer, int num_frames) { g_current_output_peak = fmaxf( g_current_output_peak, fmaxf(fabsf(left_sample), fabsf(right_sample))); } + +#if !defined(STRIP_ALL) + // Update elapsed time for event tracking (32000 Hz sample rate) + const float sample_rate = 32000.0f; + g_elapsed_time_sec += (float)num_frames / sample_rate; +#endif /* !defined(STRIP_ALL) */ } int synth_get_active_voice_count() { |
