Skip to content

fix(qbz-audio): use alsa::pcm::Frames for ALSA buffer and period sizes - #662

Merged
vicrodh merged 1 commit into
vicrodh:pre-releasefrom
b0bbywan:bugfix/external/alsa-frames-32-bit
Jul 26, 2026
Merged

fix(qbz-audio): use alsa::pcm::Frames for ALSA buffer and period sizes#662
vicrodh merged 1 commit into
vicrodh:pre-releasefrom
b0bbywan:bugfix/external/alsa-frames-32-bit

Conversation

@b0bbywan

Copy link
Copy Markdown

Context

Following up on #104, where I offered to help test qbzd on a Pi B+ / Pi 3B+ (comment):
I am trying to package qbzd for Raspberry Pi OS in odio.
A Pi B+ is 32-bit ARMv6, and this is the first blocker: qbz-audio does not compile for any 32-bit target.

To be upfront: I'm a developer, but not a Rust developer, I used Claude to diagnose this and write the fix, and ran the verification below myself.

Problem

HwParams::set_buffer_size_near and set_period_size_near take alsa::pcm::Frames, which is libc::c_long: i64 on 64-bit targets but i32 on 32-bit ones. The three buffer_size computations in alsa_direct.rs cast to i64 explicitly, so a 32-bit build fails with six E0308s (nothing in CI exercises this, the release workflows cover x86_64
and aarch64 only):

error[E0308]: mismatched types
   --> qbz-audio/src/alsa_direct.rs:225:38
    |
225 |             hwp.set_buffer_size_near(buffer_size)
    |                 -------------------- ^^^^^^^^^^^ expected `i32`, found `i64`

Change

Cast to alsa::pcm::Frames instead of a concrete width. This is a no-op on 64-bit, where Frames already is i64, and correct on 32-bit: every value involved is a sample rate divided by 2, 4 or 8, so at most 96000, far below an i32 overflow.

Since CONTRIBUTING lists the audio backends as a protected area: this is a types-only change, the same numbers reach the same ALSA calls. Happy to rework or drop it if you would rather handle 32-bit support differently. Targeting
pre-release per CONTRIBUTING.

Verification

cargo check -p qbz-audio, run from crates/ as CONTRIBUTING describes:

target before after
x86_64-unknown-linux-gnu passes passes
arm-unknown-linux-gnueabihf six E0308s passes

Heads-up: two more obstacles sit behind this on 32-bit

Neither needs a change in qbz right now; I am flagging them so the 32-bit picture is complete.

  1. The rustls providers' bundled ARM assembly is pinned at ARMv7 (.arch armv7-a, which overrides -march), so once this compiles, the armhf binary still SIGILLs on an ARMv6 board. There is no clean fix to send upstream: the obvious answer, linking the system OpenSSL through native-tls, conflicts with the self-contained appImage/Flatpak/Snap builds, so I carry it as a downstream packaging patch. Happy to open an issue laying out the options if that is useful to you.

  2. Debian trixie's 64-bit time_t transition widened struct timespec to 16 bytes on 32-bit architectures, while the alsa crate still hands libasound an 8-byte libc::timespec, stack corruption on the first note played through cpal/rodio. This is an ecosystem bug with fixes in flight upstream (pcm/rawmidi/ump: fix stack overflow from timespec/time64 mismatch diwic/alsa-rs#158, fix(alsa): timespec segfault with 64-bit time_t on 32-bit systems RustAudio/cpal#1285, fix: measure sizeof(struct timespec) instead of reading __TIMESIZE diwic/alsa-sys#20); qbz gets it by bumping dependencies once those release, with nothing to change in your code.

HwParams::set_buffer_size_near and set_period_size_near take
alsa::pcm::Frames, which is libc::c_long: i64 on 64-bit targets but i32 on
32-bit ones. The three buffer_size computations in alsa_direct.rs cast to
i64 explicitly, so the crate does not compile for any 32-bit target.

Casting to the alsa type instead is a no-op on 64-bit, where Frames already
is i64, and correct on 32-bit. No behavioural change on any currently
supported target: every value involved is a sample rate divided by 2, 4 or
8, so at most 96000, far below an i32 overflow.

Verified with cargo check -p qbz-audio:
  x86_64-unknown-linux-gnu       passes before and after
  arm-unknown-linux-gnueabihf    6 x E0308 before, passes after

Note this touches crates/qbz-audio, which CONTRIBUTING lists as a protected
area. The change is types only: no routing, no device selection and no
buffer-sizing arithmetic is altered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vicrodh
vicrodh merged commit 82fea62 into vicrodh:pre-release Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants