ALSA Api: How to play two wave files at the same time?

What is the required API configuration / call to play two independent wavefiles overlapping? I tried to do this, I get a resource loading error. Some recommendations for solving the problem will be very helpful.

Below is the error message from snd_pcm_prepare() second wave file

 "Device or resource busy" 
+4
source share
4 answers

ALSA does not provide a mixer. If you need to play multiple audio streams at the same time, you need to mix them together.

The easiest way to do this is to decode the WAV files into float samples, add them and trim them when converting them back to whole samples.

Alternatively, you can try to open the default audio device (rather than a hardware device like “hw: 0”) several times, once for each stream you want to play, and hope that the dmix ALSA plugin will load and provide functionality mixing.

+4
source

You can configure the ALSA dmix plugin to allow multiple applications to share I / O devices.

An example configuration for this is below:

 pcm.dmixed { type dmix ipc_key 1024 ipc_key_add_uid 0 slave.pcm "hw:0,0" } pcm.dsnooped { type dsnoop ipc_key 1025 slave.pcm "hw:0,0" } pcm.duplex { type asym playback.pcm "dmixed" capture.pcm "dsnooped" } # Instruct ALSA to use pcm.duplex as the default device pcm.!default { type plug slave.pcm "duplex" } ctl.!default { type hw card 0 } 

This does the following:

  • creates a new device using the dmix plugin, which allows multiple applications to share the output stream.
  • creates another using dsnoop , which does the same for input
  • combines them into a new duplex device that will support input and output using the asym plugin
  • tell ALSA to use the new duplex device as the default device
  • tell ALSA to use hw:0 to control the default device (alsamixer, etc.).

~/.asoundrc this in both ~/.asoundrc and /etc/asound.conf and you should be good to go.

For more information, see http://www.alsa-project.org/main/index.php/Asoundrc#Software_mixing .

+17
source

You can also use this configuration.

  pcm.dmix_stream { type dmix ipc_key 321456 ipc_key_add_uid true slave.pcm "hw:0,0" } pcm.mix_stream { type plug slave.pcm dmix_stream } 

Update it in ~ / .asoundrc or /etc/asound.conf

You can use the command

For wav file

aplay -D mix_stream "file name"

For raw or pcmfile

aplay -D mix_stream -c "channels" -r "rate" -f "format" "filename"

Enter a value for the channels, speed, format and file name according to your sound file

0
source

The following is a very simplified solution for multithreaded playback (provided that both files have the same sampling format, the same channel number and the same frequency):

  • a buffer-based initial stream for each file decoding (this code needs to be done 2 times - for file1 and for file2 ):

     import wave import threading periodsize = 160 f = wave.open(file1Wave, 'rb') file1Alive = True file1Thread = threading.Thread(target=_playFile1) file1Thread.daemon = True file1Thread.start() 
  • the file decoding stream itself (should also be defined twice - for file1 and for file2 ):

     def _playFile1(): # Read data from RIFF while file1Alive: if file1dataReady: time.sleep(.001) else: data1 = f.readframes(periodsize) if not data1: file1Alive = False f.close() else: file1dataReady == True 
  • start a stream merge (aka funnel ) to combine file decoding

     import alsaaudio import threading sink = alsaaudio.PCM(alsaaudio.PCM_PLAYBACK, device="hw:CARD=default") sinkformat = 2 funnelalive = True funnelThread = threading.Thread(target=self._funnelLoop) funnelThread.daemon = True funnelThread.start() 
  • merge and play (aka funnel ) thread

     def _funnelLoop(): # Reading all Inputs while funnelalive: # if nothing to play - time to selfdestruct if not file1Alive and not file2Alive: funnelalive = False sink.close() else: if file1dataReady and file2dataReady: # merging data from others but first datamerged = audioop.add(data2, data2, sinkformat) file1dataReady = False file2dataReady = False sink.write(datamerged) time.sleep(.001) 
0
source

All Articles