Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alsa: how to duplicate a stream on 2 outputs and save system configs?

Tags:

linux

alsa

My sound card is Audigy SE [SB0570].

I want to play the same stereo stream not only on speakers but on headphones too, simultaneously.

I try this config on my empty ~/.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

and it works just as I want. But sharing channel between many streams is broken now and I can't play 2 mp3 files at the same time.

By the way /etc/asound.conf is empty too. I don't know where is the real system alsa configs are, may be this /var/lib/alsa/asound.state fat extremely hard understandable with 4705 lines and hundreds of control.## blocks.

like image 769
Kroll Avatar asked May 12 '17 13:05

Kroll


1 Answers

Your idea is correct. You can use "type multi" alsa module to play sound to two different devices. You just need to extend it a little to build full chain.

Card name. It's usually better to use card names instead of indexes: "hw:CardName,2" instead of "hw:0,2" because card index may change on reboot, and names usually don't change. You can see card names in cat /proc/asound/cards and aplay -l output. For your card the name is probably "CA0106".

Dmix. To allow several apps playing simultaneously put "type dmix" between "type multi" and "hw" in your playback chain. The "type dmix" module mixes multiple apps into the same hardware buffer.

Route. Your "type multi" module maps input channels 0,1,2,3 to output channels 0,1 of slave "a" and channels 0,1 of slave "b", which implies that you have 4 input channels, while you have just 2 channels (stereo). To convert 2 channels stereo into 4 channels for "type multi" precede it with "type route" pcm duplicating channels 0,1 both to 0,1 and 2,3.

Plug. Different applications may try playing formats/rates, not directly supported by your hardware. So it's a good practice to put "type plug" autoconversion module first in the playback chain chain — it will convert whatever input format/rate into a supported output.

Overall the playback chain would be like:

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

Asym: But that's just playback chain. It's not enough if you want to point "default" pcm to it, because "default" is a pcm used by default both for playback and capture. To allow apps recording from "default" you need to define different playback and capture chains for it using "type asym" module. Capture chain can look like:

default = plug <- dsnoop <- hw

("type dsnoop" is a dmix-like module for capture — it allows multiple apps capturing from the same device)

You can define each of those pcms by hand, but I suggest to take a shortcut and reuse predefined "plug", "dmix" and "dsnoop" pcms (defined in /usr/share/alsa/alsa.conf, /usr/share/alsa/pcm/dmix.conf, /usr/share/alsa/pcm/dsnoop.conf). Then the whole config would be:

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"
}

Put this in ~/.asoundrc (your user only) or /etc/asound.conf (all users).

PS: People often want their volumes to be preserved across reboot. So many distros run alsactl store on shutdown to save current volume controls and alsactl restore on startup to load those volume controls back. By default alsactl saves those volume controls in /var/lib/alsa/asound.state. That's the only purpose of that file.

Links:

  • .asoundrc syntax
  • alsa plugins
like image 175
alsauser Avatar answered Nov 13 '22 01:11

alsauser