如何一起使用 ALSA dmix 和多插件?

如何一起使用 ALSA dmix 和多插件?

我正在玩控制台声音可视化器它想要自己的 ALSA 设备进行监听。我正在编辑~/.asoundrc。我知道我需要multi 插入将声音数据分割到单独的设备上。然而,我的声卡没有硬件混音,所以我还需要一个dmix插件来进行软件混音。

如果我尝试添加 amulti作为 的从属dmix,我会收到此错误(换行)

ALSA lib pcm_direct.c:1525:(_snd_pcm_direct_get_slave_ipc_offset)
Invalid type 'multi' for slave PCM

我尝试创建一个“虚拟中间人”plug作为multi奴隶,并dmix指向,但仍然得到相同的错误。看起来dmix想要整个链条是plug或者hw……

如果我尝试添加一个dmix模块作为 a 的从属模块multi,我会得到

Device or resource busy

正如您所期望的那样,软件混合不是管道中的第一步,而是多个程序试图获取声卡。

这两件事(dmixing 和multi-ing 到环回设备)单独工作效果很好。

为什么一起工作dmixmulti不一起工作?我怎样才能做到这一点?


这是我的~/.asoundrc,其中的选项给出从属 PCM 的“multi”类型无效:

# thx
# http://wiki.ubuntuusers.de/.asoundrc
# http://alsa.opensrc.org/Dmix
# http://forums.linuxmint.com/viewtopic.php?f=196&t=94877

pcm.snd_card {
    type hw
    card 1
    device 0
}

# allows multiple programs to output sound simultanously ("software mixing")
pcm.dmixer {
    type dmix
    ipc_key 1024
    ipc_perm 0666 # allow other users
    slave.pcm "out"
    slave {
        period_time 0
        period_size 1024
        buffer_size 4096
        ### if having problems
        # rate 44100
        ### some sound cards need the exact data format
        # format S32_LE
        ### Available formats: S8 U8 S16_LE S16_BE U16_LE U16_BE S24_LE S24_BE
        ###                    U24_LE U24_BE S32_LE S32_BE U32_LE U32_BE
        ###                    FLOAT_LE FLOAT_BE FLOAT64_LE FLOAT64_BE
        ###                    IEC958_SUBFRAME_LE IEC958_SUBFRAME_BE MU_LAW
        ###                    A_LAW IMA_ADPCM MPEG GSM
        channels 2 # must match bindings
    }
    bindings {
        0 0
        1 1
    }
}

# allows multiple programs to capture simultaneously
pcm.dsnooper {
    type dsnoop
    ipc_key 2048
    ipc_perm 0666 
    slave.pcm "snd_card"
    slave 
    {
        period_time 0
        period_size 1024
        buffer_size 4096
        channels 2 
    }
    bindings {
        0 0
        1 1
    }
}

pcm.!default {
    type asym
    playback.pcm "dmixer"
    capture.pcm "dsnooper"
}

pcm.out {
    type plug
    slave.pcm {
        type multi
        slaves {
            a { channels 2 pcm "snd_card" }
            b { channels 2 pcm "hw:Loopback,0,0" }
        }
        bindings {
            0 { slave a channel 0 }
            1 { slave a channel 1 }
            2 { slave b channel 0 }
            3 { slave b channel 1 }
        }
    }
    ttable [
        [ 1 0 1 0 ]   # left  -> a.left,  b.left
        [ 0 1 0 1 ]   # right -> a.right, b.right
    ]
}

# In case I ever want to use PulseAudio, for bluetooth speakers or such.
#pcm.!default {
#    type pulse
#}
#ctl.!default {
#    type pulse
#}

答案1

结果每个输出设备都需要自己的dmix

[!default] → multi → dmix → hw [normal]
                   ↳ dmix → hw [loopback]

我在和 回送-dmix之间错过了一秒钟,所以虽然我常用的卡没问题,但回送卡没有混合。multihw

非常感谢CL。耐心和专业知识。


对于技术细节,这是我~/.asoundrc现在的:

pcm.snd_card { # my usual sound card
    type hw
    card 2
}

ctl.!default { # default control; alsamixer and such will use this
    type hw
    card 2
}

# software mixer for sound card
pcm.dmixer {
    type dmix
    ipc_key 1024
    ipc_perm 0666 # allow other users
    slave.pcm "snd_card"
    slave {
        period_time 0
        period_size 1024
        buffer_size 4096
        channels 2 # must match bindings
    }
    bindings {
        0 0
        1 1
    }
}

# software mixer for loopback device
pcm.dmixerloop {
    type dmix
    ipc_key 2048
    ipc_perm 0666 # allow other users
    slave.pcm "hw:Loopback,0,0"
    slave {
        period_time 0
        period_size 1024
        buffer_size 4096
        channels 2 # must match bindings
    }
    bindings {
        0 0
        1 1
    }
}

# allows multiple programs to capture simultaneously
pcm.dsnooper {
    type dsnoop
    ipc_key 2048
    ipc_perm 0666 
    slave.pcm "snd_card"
    slave 
    {
        period_time 0
        period_size 1024
        buffer_size 4096
        channels 2 
    }
    bindings {
        0 0
        1 1
    }
}

pcm.!default {
    type asym
    playback.pcm "out"
    capture.pcm "dsnooper"
}

# Multi, splitting onto usual card and loopback
pcm.out {
    type plug
    slave.pcm {
        type multi
        slaves {
            a { channels 2 pcm "dmixer" }
            b { channels 2 pcm "dmixerloop" }
        }
        bindings {
            0 { slave a channel 0 }
            1 { slave a channel 1 }
            2 { slave b channel 0 }
            3 { slave b channel 1 }
        }
    }
    ttable [
        [ 1 0 1 0 ]   # left  -> a.left,  b.left
        [ 0 1 0 1 ]   # right -> a.right, b.right
    ]
}

相关内容