feat: audio stack performance improvements

This commit is contained in:
2026-05-19 18:13:37 +02:00
parent 01ed473471
commit 79284083ca
4 changed files with 86 additions and 15 deletions
+30 -4
View File
@@ -180,6 +180,7 @@ static void refresh_master() {
static void apply_master_volume(int v) {
if (v < 0) v = 0;
if (v > 100) v = 100;
if (v == g_master_vol) return; // No change → skip syscall + HW codec hit.
g_master_vol = v;
montauk::audio_set_master_volume(v);
}
@@ -198,6 +199,7 @@ static void apply_stream_volume(int idx, int v) {
if (idx < 0 || idx >= g_stream_count) return;
if (v < 0) v = 0;
if (v > 100) v = 100;
if ((uint8_t)v == g_streams[idx].volume) return;
g_streams[idx].volume = (uint8_t)v;
montauk::audio_set_volume(g_streams[idx].handle, v);
}
@@ -433,13 +435,16 @@ extern "C" void _start() {
// Event-driven sync: the kernel bumps a mixer serial on every state
// change. Reading it is one cheap syscall; we only re-snapshot the
// full mixer state when the serial has actually moved. The master
// value is left alone while the user is dragging the master slider
// so a mid-drag wakeup can't snap the knob to the kernel value.
// full mixer state when the serial has actually moved. Only redraw
// when the snapshot differs from what we already show, otherwise
// self-driven bumps (e.g. the user dragging our own slider) would
// cause a redraw on every drag tick.
uint64_t now_serial = montauk::audio_wait(g_mixer_serial, 0);
if (now_serial != g_mixer_serial) {
g_mixer_serial = now_serial;
// Master: only refresh when we're not dragging master ourselves,
// otherwise a wake mid-drag could snap our knob to the kernel.
if (g_drag_target != -1) {
int prev_vol = g_master_vol;
bool prev_muted = g_master_muted;
@@ -448,8 +453,29 @@ extern "C" void _start() {
redraw = true;
}
// Per-stream: diff before redrawing so dragging the master slider
// (which bumps the serial) doesn't trigger redundant repaints.
int prev_count = g_stream_count;
uint8_t prev_vols[8] = {0};
uint8_t prev_mutes[8] = {0};
int prev_handles[8] = {0};
for (int i = 0; i < prev_count && i < 8; i++) {
prev_vols[i] = g_streams[i].volume;
prev_mutes[i] = g_streams[i].muted;
prev_handles[i] = g_streams[i].handle;
}
refresh_streams();
redraw = true;
if (g_stream_count != prev_count) {
redraw = true;
} else {
for (int i = 0; i < g_stream_count; i++) {
if (g_streams[i].handle != prev_handles[i] ||
g_streams[i].volume != prev_vols[i] ||
g_streams[i].muted != prev_mutes[i]) {
redraw = true; break;
}
}
}
}
if (r < 0) break;