I am using `alsa-lib-1.2.9` in my embedded Linux system, and now I want to play
multiple audio from different threads, so I googled internet (I am NOT familiar
with ALSA) and found I can use `dmix`.
Here is the main part of my `/etc/asound.conf` in the board.
```
pcm.!default
{
type asym
playback.pcm "play_softvol"
capture.pcm "cap_chn0"
}
pcm.play_softvol {
type softvol
slave {
pcm play_chn0
}
control {
name "Speaker Volume"
}
min_dB -60.0
max_dB -10.0
resolution 50
}
pcm.play_chn0 {
type plug
slave {
pcm dmixer
}
}
pcm.dmixer {
type dmix
ipc_key 77235
ipc_key_add_uid true
slave {
pcm "hw:0,0"
period_time 0
period_size 320
buffer_size 2560
rate 32000
}
}
ctl.dmixer {
type hw
card 0
}
pcm.cap_chn0 {
type plug
slave {
pcm dsnooper
}
}
pcm.tloop_cap {
type plug
slave.pcm "hw:Loopback,0,0"
}
pcm.dsnooper {
type dsnoop
ipc_key 77236
ipc_key_add_uid true
slave {
pcm "hw:0,0"
channels 4
rate 16000
}
bindings {
0 0
1 1
2 2
3 3
}
}
ctl.dsnooper {
type hw
card 0
}
```
I think the `default` device is using `play_softvol`->`play_chn0`->`dmix`.
So I tried to play 2 PCM files as follows,
```
#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
#include <pthread.h>
pthread_t tid, tid2;
static snd_pcm_t *playback_handle;
static int size;
static snd_pcm_uframes_t frames;
void *play_func(void *arg)
{
char *buffer;
int ret;
FILE *fp = fopen(arg, "rb");
if(fp == NULL)
return 0;
buffer = (char *) malloc(size);
fprintf(stderr, "size = %d ", size);
while (1)
{
ret = fread(buffer, 1, size, fp);
if(ret == 0)
{
fprintf(stderr, "end of file on input ");
break;
}
while(ret = snd_pcm_writei(playback_handle, buffer, frames)<0)
{
usleep(2000);
if (ret == -EPIPE)
{
/* EPIPE means underrun */
fprintf(stderr, "underrun occurred ");
snd_pcm_prepare(playback_handle);
}
else if (ret < 0)
{
fprintf(stderr, "error from writei: %s ", snd_strerror(ret));
}
}
}
free(buffer);
return NULL;
}
void *play_func2(void *arg)
{
char *buffer;
int ret;
FILE *fp = fopen(arg, "rb");
if(fp == NULL)
return 0;
buffer = (char *) malloc(size);
fprintf(stderr, "size = %d ", size);
while (1)
{
ret = fread(buffer, 1, size, fp);
if(ret == 0)
{
fprintf(stderr, "end of file on input ");
break;
}
while(ret = snd_pcm_writei(playback_handle, buffer, frames)<0)
{
usleep(2000);
if (ret == -EPIPE)
{
/* EPIPE means underrun */
fprintf(stderr, "underrun occurred ");
snd_pcm_prepare(playback_handle);
}
else if (ret < 0)
{
fprintf(stderr, "error from writei: %s ", snd_strerror(ret));
}
}
}
free(buffer);
return NULL;
}
int main(int argc, char *argv[])
{
int ret;
int dir=0;
snd_pcm_uframes_t periodsize;
snd_pcm_hw_params_t *hw_params;
if (argc < 2) {
printf("error: alsa_play_test [music name] [2nd name] ");
exit(1);
}
//1.
ret = snd_pcm_open(&playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
if (ret < 0) {
perror("snd_pcm_open");
exit(1);
}
.......
ret = pthread_create(&tid, NULL, play_func, argv[1]);
if (argc > 2)
ret = pthread_create(&tid2, NULL, play_func2, argv[2]);
pthread_join(tid, NULL);
if (argc > 2)
pthread_join(tid2, NULL);
snd_pcm_close(playback_handle);
return 0;
}
```
```
asound_threads 1.pcm 2.pcm
play song 1.pcm and 2.pcm
size = 320
size = 320
```
But it sounds messy, the two PCMs are played in an interleaved way, but the
speed is wrong and flittered.
So in my case, how can I play multiple audios (audio mixing) in multithreading?
thanks,
-Tao
_______________________________________________
Alsa-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/alsa-user