Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

PipeWire host: streams set no channel positions, so a stereo input on a mono source has a silent right channel

Đang mở
#1,405 2 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
52/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
rust
Lĩnh vực
audio-video-rtc

Hướng nghiên cứu

Start with host/pipewire/stream.rs, especially connect_input and connect_output, where the issue says AudioInfoRaw is built without channel positions. Read how the stream format and properties are passed to PipeWire, then check host/pipewire/device.rs for the input_default channel count. Reproduce with a 2-channel stream on a mono source; done means both captured channels carry the source audio.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

host - pipewire platform - linux

Summary

The PipeWire host builds its streams' audio format (AudioInfoRaw in
connect_input and connect_output, host/pipewire/stream.rs) with a
format, a rate and a channel count, but no channel positions. A 2-channel
input stream on a mono source then shows two ports, input_FL and
input_FR, and the source's single capture_MONO port is linked to
input_FL only, with no channel mixing between them. The stream gets the
source in channel 0 and silence in channel 1, which halves the level for
anything that mixes the two down.

Two things make it easy to hit:

  • The synthetic default input (input_default) always reports 2 channels
    (Device::input_default() in host/pipewire/device.rs hardcodes
    channels: 2), whatever the default source has. Opening the default
    input with its own default config on a mono microphone captures a silent
    right channel.
  • When the default source changes, the stream on input_default is moved
    to the new source at the channel count it opened with, so the same
    happens after a move from a stereo source to a mono one.

The PulseAudio host does not have this: PulseAudio (and pipewire-pulse)
remixes a 2-channel record stream from a mono source into both channels.

Environment

  • cpal 0.18.2, pipewire feature
  • PipeWire 1.6.9, WirePlumber 0.5.18, Arch Linux
  • Source: a Behringer FLOW 8's "Mic 1" input, a mono source
    (pactl list sources short shows float32le 1ch 48000Hz)

Reproduction

Any mono source shows it; most USB microphones are mono. With such a
source set as the default (pactl set-default-source <name>):

// Cargo.toml: cpal = { version = "0.18.2", features = ["pipewire"] }
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use std::sync::{Arc, Mutex};

fn main() {
    let host = cpal::host_from_id(cpal::HostId::PipeWire).expect("PipeWire host");
    let device = host.default_input_device().expect("a default input");
    let config = device.default_input_config().expect("a config");
    println!("{} channels, {:?}", config.channels(), config.sample_format());
    let mut config: cpal::StreamConfig = config.into();
    config.channels = 2; // already 2 for `input_default`

    let peaks = Arc::new(Mutex::new([0.0_f32; 2]));
    let sink = Arc::clone(&peaks);
    let stream = device
        .build_input_stream(
            config,
            move |data: &[f32], _: &cpal::InputCallbackInfo| {
                let mut peaks = sink.lock().unwrap();
                for frame in data.chunks_exact(2) {
                    peaks[0] = peaks[0].max(frame[0].abs());
                    peaks[1] = peaks[1].max(frame[1].abs());
                }
            },
            |error| eprintln!("{error}"),
            None,
        )
        .expect("a stream");
    stream.play().expect("playing");
    std::thread::sleep(std::time::Duration::from_secs(2));
    let [left, right] = *peaks.lock().unwrap();
    println!("loudest: left {left}, right {right}");
}

(If the source captures i16 or another format, change the callback's
sample type to match.)

Speak into the microphone, or let it pick up the room. Expected: both
channels carry the microphone, as the PulseAudio host gives them. Actual:
the right channel is exactly 0.

Run on the FLOW 8 mic as the default source:

2 channels, F32
loudest: left 0.0027721382, right 0

and pw-link -l while it ran:

alsa_input.usb-Behringer_FLOW_8_D8-B6-73-B3-8C-44-00.Recording__Mic1__source:capture_MONO
  |-> cpal-repro:input_FL
cpal-repro:input_FL
  |<- alsa_input.usb-Behringer_FLOW_8_D8-B6-73-B3-8C-44-00.Recording__Mic1__source:capture_MONO

Nothing is linked to input_FR. Opening the mic's own node (not
input_default) at 2 channels gives the same: through fastframe-audio
0.12.0, which opens cpal streams the same way, left -53.9 dBFS and right
silence.

Suggested fix

We have not confirmed which change makes PipeWire mix, so these are
suggestions to try:

  • set channel positions on the stream's format (for example FL/FR for 2
    channels and MONO for 1), so the stream's adapter can convert between
    its layout and the node's with its channel mixer, as it does for other
    clients;
  • or set audio.position in the stream's properties.

Separately,
input_default could report the default source's real channel count
rather than 2, though with positions set that matters much less.

Until then, applications have to open each source at its own channel
count and remix themselves, and look up the default source's channels some
other way (fastframe asks PipeWire's PulseAudio server), and reopen the
stream when the default source changes.

Ngôn ngữ chính
Rust
Star
4k
Fork
554
Merge trung bình
3 ngày 3 giờ
Pull request đã merge (30 ngày)
4

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của RustAudio/cpal

Tất cả issue của RustAudio/cpal

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.