summaryrefslogtreecommitdiff
path: root/src/audio/audio.cc
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-05-20 22:44:44 +0200
committerskal <pascal.massimino@gmail.com>2026-05-20 22:44:44 +0200
commit5d20c892dedce7bc7486acbd72fbd35da69e413e (patch)
tree05e04d5e689504c2421cd5772e91a42ee69608ab /src/audio/audio.cc
parent6ef8f578817ee0134fd5867ca3b80590e3eb2368 (diff)
fix: code review cleanup — bugs, dead code, factorization (-167 lines)
Bugs: - B1: fix dead tempo debug (prev_tempo captured after assignment) - B2: fix ReloadAssetsFromFile leak for disk-loaded assets; simplify DropAsset - B3: fix get_free_pool_slot leak (unregister synth + free data on reuse) - B4: volatile -> std::atomic with acquire/release in miniaudio_backend, synth - B5: fix unaligned reads in scene_loader (memcpy-based read_f32/read_u32) - B6: fix shader module + BGL + pipeline layout leaks in gpu.cc, pipeline_builder Dead code: - D1: remove unused particle_defs.h - D3: remove create_post_process_pipeline_simple (zero callers) - D4: remove empty gpu_draw() - D5: remove write-only Hybrid3D::initialized_ - D6: remove legacy pending buffer path in audio.cc Factorization: - F1: Effect::run_fullscreen_pass() replaces boilerplate in 5 effects - F2: particle_common.wgsl snippet, #include in 3 WGSL shaders - F3: gpu_create_shader_module() helper, used in 3 call sites - F5: get_world_aabb() shared between bvh.cc and physics.cc - F6: samples_to_seconds() replaces 6 inline expressions - F7: gpu_create_linear/nearest_sampler use SamplerCache; add nearest() preset 37/37 tests passing. handoff(Claude): code review batch — all items verified, no regressions.
Diffstat (limited to 'src/audio/audio.cc')
-rw-r--r--src/audio/audio.cc59
1 files changed, 6 insertions, 53 deletions
diff --git a/src/audio/audio.cc b/src/audio/audio.cc
index 3b98452..91dd05b 100644
--- a/src/audio/audio.cc
+++ b/src/audio/audio.cc
@@ -28,12 +28,6 @@ static void clip_samples(float* buf, int count) {
// Global ring buffer for audio streaming
static AudioRingBuffer g_ring_buffer;
-// Pending write buffer for partially written samples
-// Maximum size: one chunk (533 frames @ 60fps = 1066 samples stereo)
-#define MAX_PENDING_SAMPLES 2048
-static float g_pending_buffer[MAX_PENDING_SAMPLES];
-static int g_pending_samples = 0; // How many samples are waiting to be written
-
// Global backend pointer for audio abstraction
static AudioBackend* g_audio_backend = nullptr;
static MiniaudioBackend g_default_backend;
@@ -56,9 +50,6 @@ void audio_init() {
// In production code, use AudioEngine::init() which manages initialization
// order.
- // Clear pending buffer
- g_pending_samples = 0;
-
// Use default backend if none set
if (g_audio_backend == nullptr) {
g_audio_backend = &g_default_backend;
@@ -74,8 +65,7 @@ float audio_get_required_prefill_time() {
bool audio_is_prefilled() {
const int buffered = g_ring_buffer.available_read();
- const float buffered_time =
- (float)buffered / (RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS);
+ const float buffered_time = samples_to_seconds(buffered);
const float required = audio_get_required_prefill_time();
return buffered_time >= (required - 0.001f); // 1ms tolerance
}
@@ -89,9 +79,7 @@ void audio_start() {
#if !defined(STRIP_ALL)
if (!audio_is_prefilled()) {
const int buffered = g_ring_buffer.available_read();
- const float buffered_ms = (float)buffered /
- (RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS) *
- 1000.0f;
+ const float buffered_ms = samples_to_seconds(buffered) * 1000.0f;
printf("WARNING: Audio buffer not pre-filled (%.1fms < %.1fms)\n",
buffered_ms, audio_get_required_prefill_time() * 1000.0f);
}
@@ -116,40 +104,9 @@ void audio_render_ahead(float music_time, float dt, float target_fill) {
// Keep rendering small chunks until buffer is full enough
while (true) {
- // First, try to flush any pending samples from previous partial writes
- if (g_pending_samples > 0) {
- const int written =
- g_ring_buffer.write(g_pending_buffer, g_pending_samples);
-
- if (written > 0) {
- // Some or all samples were written
- // Move remaining samples to front of buffer
- const int remaining = g_pending_samples - written;
- if (remaining > 0) {
- for (int i = 0; i < remaining; ++i) {
- g_pending_buffer[i] = g_pending_buffer[written + i];
- }
- }
- g_pending_samples = remaining;
-
- // Notify backend (for testing/tracking)
-#if !defined(STRIP_ALL)
- if (g_audio_backend != nullptr) {
- g_audio_backend->on_frames_rendered(written / RING_BUFFER_CHANNELS);
- }
-#endif
- }
-
- // If still have pending samples, buffer is full - wait for consumption
- if (g_pending_samples > 0)
- break;
- }
-
// Check current buffer state
const int buffered_samples = g_ring_buffer.available_read();
- const float buffered_time =
- (float)buffered_samples /
- (RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS);
+ const float buffered_time = samples_to_seconds(buffered_samples);
// Stop if buffer is full enough
if (buffered_time >= target_lookahead)
@@ -238,20 +195,16 @@ float audio_get_playback_time() {
(float)(elapsed * RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS);
const float total_samples =
(float)last_callback_samples + interpolated_samples;
- return total_samples / (RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS);
+ return samples_to_seconds((int64_t)total_samples);
}
}
// Fallback: coarse ring buffer time (before first callback or no backend)
- const int64_t total_samples = g_ring_buffer.get_total_read();
- return (float)total_samples /
- (RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS);
+ return samples_to_seconds(g_ring_buffer.get_total_read());
}
float audio_get_render_time() {
- const int64_t total_samples = g_ring_buffer.get_total_written();
- return (float)total_samples /
- (RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS);
+ return samples_to_seconds(g_ring_buffer.get_total_written());
}
float audio_get_realtime_peak() {