Skip to content

PortAudio sink plays little-endian PCM as native-endian on big-endian hosts #78

Open

Description

@chrisuthe

Found while auditing for #70 (fixed in #77).

The problem

The PCM we hand every sink is little-endian. src/portaudio_sink.cpp opens its stream with paInt16, paInt24 or paInt32 (PROBE_FORMATS, chosen by pa_format_for()), and PortAudio defines those as native-endian. The callback copies our bytes straight into PortAudio's buffer, so on a big-endian host PortAudio reads every 16-, 24- and 32-bit sample with its bytes reversed and plays noise, at any volume including unity.

The doc comment on pa_format_for() says it maps onto "the interleaved little-endian PCM format PortAudio wants", which is only true on a little-endian host.

8-bit is unaffected. The other sinks are unaffected: ALSA, PulseAudio, PipeWire and CoreAudio all open explicitly little-endian formats.

Status

Read-confirmed only, not reproduced. Unlike #70 it cannot be tested with a standalone file under qemu-mips-static, since it needs PortAudio and a device.

Fix

PortAudio has no little-endian format to ask for, so this needs a byte swap of each sample in the callback on big-endian hosts, after the volume is applied (apply_volume_ramp() expects little-endian). Little-endian hosts should compile to no extra work.

Impact

Big-endian builds using --output portaudio only. ALSA is the usual backend on the OpenWrt MIPS targets that prompted #70, so this is low priority.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions