Skip to content

PortAudio ALSA Backend Reports Different Channel Count for Plug/Asym Devices #1126

@7053n9

Description

@7053n9

PortAudio ALSA Backend Reports Different Channel Count for Plug/Asym Devices

Describe the bug

PortAudio reports 128 channels for ALSA virtual devices configured with 32-channel limits via plug/asym wrappers, even though the underlying dmix/dsnoop devices correctly report 32 channels.

Device Type Reported Actual Limit
my_32ch_dmix dmix 32 ch 32 ch ✅
my_32ch_dsnoop dsnoop 32 ch 32 ch ✅
My_32ch_MultiClient plug → asym → dmix/dsnoop 128 ch 32 ch ❌

The dmix and dsnoop devices individually report correct channel counts. When combined via asym plugin and wrapped with plug, PortAudio reports 128 (hardware max) instead of 32.

To Reproduce

  1. Create an .asoundrc with a plug → asym → dmix/dsnoop device chain (config below)
  2. Run this Python script:
import pyaudio
p = pyaudio.PyAudio()
for i in range(p.get_device_count()):
    info = p.get_device_info_by_index(i)
    if 'MultiClient' in info['name']:
        print(f"{info['name']}: {info['maxOutputChannels']} channels")
p.terminate()
  1. Observe that maxOutputChannels reports 128 instead of 32
ALSA Configuration (.asoundrc)
pcm.my_32ch_dmix {
    type dmix
    ipc_key 1024
    slave {
        pcm { type hw; card "MyCard" }
        channels 32
        period_size 1024
        buffer_size 4096
        rate 48000
        format S32_LE
    }
}

pcm.my_32ch_dsnoop {
    type dsnoop
    ipc_key 1025
    slave {
        pcm { type hw; card "MyCard" }
        channels 32
        period_size 1024
        buffer_size 4096
        rate 48000
        format S32_LE
    }
}

pcm.My_32ch_MultiClient {
    type plug
    slave {
        pcm {
            type asym
            playback.pcm "my_32ch_dmix"
            capture.pcm "my_32ch_dsnoop"
        }
        channels 32
        rate 48000
        format S32_LE
    }
}

Expected behavior

PortAudio should report 32 channels for My_32ch_MultiClient to match the configured channel limit in the plug/dmix/dsnoop chain.

Actual behavior

PortAudio reports 128 channels (hardware maximum) instead of 32 (configured limit). Opening a stream with >32 channels fails even though PortAudio reports 128 available.

Impact:

  • Applications trust reported channel count and request more than supported
  • Runtime errors when opening streams with 33-128 channels
  • Automatic device selection fails when filtering by channel count

Desktop

  • OS: Linux (Ubuntu 24.04 LTS)
  • OS Version: Tested on Kernel 6.14.0-37-generic and 6.19-rc5
  • PortAudio version: 19.6.0 (libportaudio2 19.6.0-1.2build3, Ubuntu package)
  • Host API: ALSA
  • Audio Device: 128-channel USB audio interface

Additional context

Root Cause: PortAudio uses snd_pcm_hw_params_get_channels_max() which queries hardware capabilities. This is expected ALSA behavior — the plug plugin passes through hardware capabilities rather than enforcing configured constraints during capability queries. Constraints are only applied at stream open time.

Possible solutions (since ALSA's plug behavior is by design):

  1. Recognize plug devices may have constraints not reflected in hardware queries
  2. Document this limitation for ALSA users
  3. Implement detection of plug/dmix/dsnoop constraints

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Priority: Normalsrc-alsaALSA Host API /src/hostapi/alsa

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions