Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mix multiple PCM streams using ALSA

Tags:

alsa

playback

I have two different streams of PCM samples. Is it possible to somehow mix them and play with ALSA on the same output device?

I read it may be possible using the mixer but I'm finding it difficult to understand given the lack of documentation. Could anyone please provide some more information of any kind about how this may be implemented (if it actually is)?

Thanks!

like image 357
Luca Carlon Avatar asked Aug 09 '11 20:08

Luca Carlon


2 Answers

For that, check if you are having .asoundrc file our system. If its not there, then create one and you can place it in your /home folder. Update it with these settings:

pcm.!default {
              type plug
              slave.pcm "dmixer"
}
pcm.dmixer  {
            type dmix
        ipc_key 1024
        slave {
          pcm "hw:1,0"
          period_time 0
              period_size 1024
          buffer_size 4096
          rate 44100
        }
        bindings {
          0 0
          1 1
        }
}
ctl.dmixer {
       type hw
       card 0
}

Use $aplay -l to get a list of the devices on your system. The hw:X,Y comes from this mapping of your hardware, where X is the card number, while Y is the device number.

Now, open the terminal, and play your first PCM stream with: $aplay -f cd pcm_sound1.wav And in other tab, play your second PCM stream: $aplay -f cd -D default pcm_sound2.wav

It will mix your two PCM data streams.

Cheers,

like image 184
HSC Avatar answered Nov 01 '22 17:11

HSC


I'm not sure if this deserves a separate answer. I used HSC's answer and the examples at "ALSA Wiki - The Dmix Howto". The Dmix documentation is indeed a bit frustrating.

Here is an example ~/.asoundrc that works for me. The "bindings" section is unnecessary, but the HOWTO says it helps "multichannel chips work faster" (not sure if I care?). If I bind "0 1 1 0" then it switches the right/left channels. If I bind "0 1 1 1" then I get garbage in my right ear... Apparently ipc_key is a required parameter; I just chose a random integer.

# example 1
pcm.hw3mix {
    type dmix
    ipc_key 1939 # must be unique
    slave {
        pcm "hw:3"
        period_time 0
        period_size 1024 # must be power of 2
        buffer_size 4096
        rate 44100
    }
    bindings {
        0 0
        1 1
    }
}

pcm.!default hw3mix

The last line makes my new hw3mix the default device.

I simplified the above to:

# example 2
pcm.hw3mix {
    type dmix
    ipc_key 1939 # must be unique
    slave { pcm "hw:3" }
}

pcm.!default hw3mix

and it seems to work just fine.

As suggested on the ALSA Wiki link above, I can further simplify it to:

# example 3
pcm.dsp0 {
    type plug
    slave.pcm "dmix"
}

pcm.!default dsp0

and this can be further simplified to:

# example 4
pcm.!default {
    type plug
    slave.pcm "dmix"
}

or even:

# example 5
pcm.!default plug:dmix

However, the last three examples don't allow me to specify parameters for the Dmix plugin. I wanted to create a device which mixes multiple streams to "hw:3". I think this has to be specified as a parameter to Dmix since it is not the default device, so I went with my second example above. In my actual ~/.asoundrc, there is also a block for "hw:0,0" called "hw0mix", so by changing the comments on the following lines, I can switch the output of (newly created) streams between my headphones and speakers:

#pcm.!default hw0mix
pcm.!default hw3mix

NB: The above refers to devices like "hw:0,0" and "hw:3" ... it was a bit hard to find out how to ensure stable device numbers for my various USB sound devices, I found the instructions here under "Ordering multiple cards of the same type". The configuration consists of one line in a file in /etc/modprobe.d/. That's how I get numbers like 0 and 3 to refer to the same devices across reboots.

like image 35
Metamorphic Avatar answered Nov 01 '22 17:11

Metamorphic