summaryrefslogtreecommitdiff
path: root/src/audio/ring_buffer.cc
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-15 23:56:43 +0100
committerskal <pascal.massimino@gmail.com>2026-02-15 23:56:43 +0100
commit5c7feffd3749ce4b355d0db6334cf39ca94d8d82 (patch)
tree7105aea12d0367208a37777cf53b348f35a66dad /src/audio/ring_buffer.cc
parente21127a3fc4797805d49ae2d95fc7ed6f94ac456 (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.cc39
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);
+}