【问题标题】:Alsa: how to duplicate a stream on 2 outputs and save system configs?Alsa:如何在 2 个输出上复制流并保存系统配置?
【发布时间】:2017-10-18 22:15:45
【问题描述】:

我的声卡是 Audigy SE [SB0570]。

我想同时在扬声器和耳机上播放相同的立体声流。

我在空的 ~/.asoundrc 上尝试这个配置

pcm.quad {
    type multi

    slaves.a.pcm "hw:0,0" #green hole
    slaves.a.channels 2
    slaves.b.pcm "hw:0,2" #black hole
    slaves.b.channels 2

    bindings.0.slave a
    bindings.0.channel 0
    bindings.1.slave a
    bindings.1.channel 1
    bindings.2.slave b
    bindings.2.channel 0
    bindings.3.slave b
    bindings.3.channel 1
}

pcm.!default quad

它就像我想要的那样工作。但是现在多个流之间的共享频道已损坏,我无法同时播放 2 个 mp3 文件。

顺便说一下 /etc/asound.conf 也是空的。我不知道真正的系统 alsa 配置在哪里,这可能是 /var/lib/alsa/asound.state 非常难以理解,有 4705 行和数百个 控制。# # 块。

【问题讨论】:

    标签: linux alsa


    【解决方案1】:

    你的想法是正确的。您可以使用“type multi”alsa 模块向两个不同的设备播放声音。您只需要稍微扩展它即可构建完整的链。

    卡名。通常最好使用卡名而不是索引:“hw:CardName,2”而不是“hw:0,2”,因为卡索引可能会在重新启动时更改,而名称通常不会更改。您可以在cat /proc/asound/cardsaplay -l 输出中看到卡名称。对于您的卡,名称可能是“CA0106”。

    混音。要允许同时播放多个应用程序,请在播放链中的“type multi”和“hw”之间放置“type dmix”。 “type dmix”模块将多个应用程序混合到同一个硬件缓冲区中。

    路线。您的“type multi”模块将输入通道 0,1,2,3 映射到从属“a”的输出通道 0,1 和从属“b”的通道 0,1,这意味着您有 4 个输入通道,而您有只有 2 个通道(立体声)。要将 2 声道立体声转换为 4 声道以用于“type multi”,请在其前面加上“type route” pcm,将声道 0,1 复制到 0,1 和 2,3。

    插头。不同的应用程序可能会尝试播放您的硬件不直接支持的格式/速率。因此,最好将“type plug”自动转换模块放在播放链的首位——它将任何输入格式/速率转换为支持的输出。

    整个播放链如下:

    default = plug -> route -> multi -> (dmix->hw:CA0106,0 + dmix->hw:CA0106,2)
    

    Asym:但这只是播放链。如果您想将“默认” pcm 指向它是不够的,因为“默认”是默认情况下用于播放和捕获的 pcm。要允许应用程序从“默认”录制,您需要使用“type asym”模块为其定义不同的播放和捕获链。捕获链可能如下所示:

    default = plug <- dsnoop <- hw
    

    (“type dsnoop”是一个类似于 dmix 的捕获模块——它允许从同一设备捕获多个应用程序)

    您可以手动定义这些 pcms,但我建议采取捷径并重用预定义的“plug”、“dmix”和“dsnoop”pcms(在/usr/share/alsa/alsa.conf/usr/share/alsa/pcm/dmix.conf/usr/share/alsa/pcm/dsnoop.conf 中定义) .那么整个配置将是:

    pcm.quad {
        type multi
        slaves.a.pcm "dmix:CA0106,0"
        slaves.a.channels 2
        slaves.b.pcm "dmix:CA0106,2"
        slaves.b.channels 2
        bindings.0 { slave a; channel 0; }
        bindings.1 { slave a; channel 1; }
        bindings.2 { slave b; channel 0; }
        bindings.3 { slave b; channel 1; }
    }
    pcm.stereo2quad {
        type route
        slave.pcm "quad"
        ttable.0.0 1
        ttable.1.1 1
        ttable.0.2 1
        ttable.1.3 1
    }
    pcm.!default {
        type asym
        playback.pcm "plug:stereo2quad"
        capture.pcm "plug:dsnoop:CA0106"
    }
    

    将其放入~/.asoundrc(仅限您的用户)或/etc/asound.conf(所有用户)。

    PS:人们通常希望在重新启动后保留其卷。许多发行版在关机时运行alsactl store 以保存当前的音量控制,并在启动时运行alsactl restore 以重新加载这些音量控制。默认情况下alsactl 将这些音量控制保存在/var/lib/alsa/asound.state 中。这是该文件的唯一用途。

    链接:

    【讨论】:

    • 我无法理解“奴隶”和插件链的概念。哪个必须是哪个的奴隶,他们的顺序?什么必须在最小集合中,什么是可选的?什么时候需要插头类型,什么时候不需要?以及这两个链接中未描述的许多其他问题。
    • @Kroll,“Slave”是链中的下一个模块。 Alsa-lib 是模块化的:type dmix 混合多个应用程序,type route 修改/复制频道,type plug 自动转换格式/速率等。因此,要执行多项操作,请将这些模块链接在一起。这样,每个模块做它的一件事并将输出传递给它的从属,它做一些其他的事情并将输出传递给它的从属,依此类推。这就是“奴隶”的概念。
    • 关于模块的顺序。 type hw 模块将输出传递给硬件,它没有从设备,因此它始终是链中的最后一个。另外type hwtype dmix 唯一接受的从属设备,所以 dmix 总是倒数第二个。 type plug 自动转换模块接受几乎所有可能的输入,因此它被放置在链中的第一个位置,以允许应用程序播放它们想要的任何格式。链中的其他模块及其顺序取决于您希望它们做什么。如果您需要将不同的通道传递给不同的从站,则添加 type multi。并且type route 执行额外的频道操作。
    • 我遇到了一个与此相关的问题。我有两个设备,但它们接受不同的格式,一个是 S32_LE,另一个是 S24_3LE。我的猜测是,如果 plug 在链的早期,它就无法转换为通用格式并且失败。如果我把它放在最后,或者使用plughw,那么我就不能使用dmix,并且我不能让多个应用程序在多个设备上播放。有什么解决办法吗?
    猜你喜欢
    • 2011-05-09
    • 2016-01-18
    • 2012-08-06
    • 1970-01-01
    • 2014-10-23
    • 2010-10-13
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多