audio: render only the frames PipeWire requests per cycle

The process callback filled the whole mapped buffer every cycle. PipeWire
sizes that buffer by clock.quantum-limit (8192 frames by default) while the
graph drives galdr at the 256-frame quantum we ask for, so each cycle did
~32x the work and everything past the quantum was dropped: choppy output,
constant deadline misses in pw-top, and envelopes that sounded 32x faster
than their settings. Use Buffer::requested (pipewire feature v0_3_49),
clamped to the buffer, with the --latency value as fallback.

tui: typing a glyph no longer advances the cursor to the right.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Bendik Aagaard Lynghaug
2026-10-07 22:37:17 +02:00
co-authored by Claude Fable 5.1
parent 392ceceeff
commit f9f06568bf
3 changed files with 9 additions and 3 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ codegen-units = 1
[dependencies]
anyhow = "1"
pipewire = "0.10"
pipewire = { version = "0.10", features = ["v0_3_49"] } # Buffer::requested
midir = "0.10"
arc-swap = "1.7"
rtrb = "0.3"
+8 -1
View File
@@ -75,6 +75,7 @@ fn run(
.add_local_listener_with_user_data(())
.process(move |stream, _| {
let Some(mut buffer) = stream.dequeue_buffer() else { return };
let requested = buffer.requested() as usize;
let datas = buffer.datas_mut();
let Some(data) = datas.first_mut() else { return };
let stride = ch * 4;
@@ -85,9 +86,15 @@ fn run(
engine.apply(ev);
}
// Render only what the graph asked for this cycle. The mapped
// buffer is sized by clock.quantum-limit (8192 frames by default),
// so filling it whole would do ~32x the work of a 256-frame
// quantum and PipeWire would drop everything past the quantum:
// choppy output and envelopes that race through their stages.
let want = if requested > 0 { requested } else { latency as usize };
let mut n_frames = 0usize;
if let Some(slice) = data.data() {
n_frames = slice.len() / stride;
n_frames = want.min(slice.len() / stride);
for f in 0..n_frames {
let smp = engine.render(&program);
let bytes = smp.to_le_bytes();
-1
View File
@@ -169,7 +169,6 @@ pub fn run(
KeyCode::Char(c) => {
grid.set(cx, cy, if c == ' ' { '.' } else { c });
edited = true;
cx = (cx + 1).min(grid.w - 1);
}
_ => {}
}