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 Alsa-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/alsa-user