diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-15 23:56:43 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-15 23:56:43 +0100 |
| commit | 5c7feffd3749ce4b355d0db6334cf39ca94d8d82 (patch) | |
| tree | 7105aea12d0367208a37777cf53b348f35a66dad /src/audio/ring_buffer.cc | |
| parent | e21127a3fc4797805d49ae2d95fc7ed6f94ac456 (diff) | |
perf(audio): smooth playback time and RMS-based peak at 60Hz
Interpolates audio playback time between callbacks using CLOCK_MONOTONIC
for smooth 60Hz updates instead of coarse 8-10Hz steps.
Replaces artificial peak decay with true RMS calculation over 50ms
window. Ring buffer computes RMS directly on internal buffer without
copies for efficiency.
All backends updated with get_callback_state() interface for time
interpolation. Tests passing (34/34).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src/audio/ring_buffer.cc')
| -rw-r--r-- | src/audio/ring_buffer.cc | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/audio/ring_buffer.cc b/src/audio/ring_buffer.cc index 30566c9..54dd25b 100644 --- a/src/audio/ring_buffer.cc +++ b/src/audio/ring_buffer.cc @@ -5,6 +5,7 @@ #include "util/debug.h" #include "util/fatal_error.h" #include <algorithm> +#include <cmath> #include <cstring> AudioRingBuffer::AudioRingBuffer() @@ -178,3 +179,41 @@ void AudioRingBuffer::commit_write(int num_samples) { std::memory_order_release); total_written_.fetch_add(num_samples, std::memory_order_release); } + +float AudioRingBuffer::get_past_rms(int window_samples) const { + const int avail = available_read(); + const int to_read = std::min(window_samples, avail); + + if (to_read <= 0) { + return 0.0f; + } + + // Calculate start position (backward from read position) + int start = read_pos_.load(std::memory_order_acquire); + start = (start - to_read + capacity_) % capacity_; + + // Calculate RMS directly from ring buffer + float sum_squares = 0.0f; + const int space_to_end = capacity_ - start; + + if (to_read <= space_to_end) { + // One contiguous chunk + for (int i = 0; i < to_read; ++i) { + const float sample = buffer_[start + i]; + sum_squares += sample * sample; + } + } else { + // Two chunks (wrap around) + for (int i = 0; i < space_to_end; ++i) { + const float sample = buffer_[start + i]; + sum_squares += sample * sample; + } + const int remainder = to_read - space_to_end; + for (int i = 0; i < remainder; ++i) { + const float sample = buffer_[i]; + sum_squares += sample * sample; + } + } + + return sqrtf(sum_squares / (float)to_read); +} |
