Воспроизводить несколько файлов WAV одновременно, используя Alsa C API
Я хочу реализовать определенные функции в моем проекте, которые включают в себя непрерывное воспроизведение sample-default.wav
на заднем плане и играть sample-specific.wav
файл, когда какое-то конкретное условие соответствует. Что я действительно хочу, так это когда sample-specific.wav
файл работает, объем sample-default.wav
файл становится 0 (или просто, я хочу отключить звук sample-default.wav
файл, когда sample-specific.wav
бежит).
Я пытаюсь реализовать эту функцию с помощью alsa-library
для ц. Я испробовал почти все подходы для достижения этой цели, но мне кажется, что ничего не работает.
Мой нынешний подход
Я пытаюсь добавить два виртуальных звуковых устройства, используя dmix
плагин из alsa
уход default
для системных звуков. Я искал в Google и обнаружил, что мне нужно отредактировать /etc/asound.conf
файл для создания разных звуковых устройств.
Я добавил два звуковых устройства, названных notification
а также sample-sound
, Мой текущий /etc/asound.conf
Файл выглядит примерно так, как показано ниже:
pcm.notification {
type dmix
ipc_key 1024
slave {
pcm "hw:1,0"
}
}
ctl.notification {
type hw
card 2
}
pcm.sample-sound {
type dmix
ipc_key 1025
slave {
pcm "hw:1,0"
}
}
ctl.sample-sound {
type hw
card 3
}
Это прекрасно работает с aplay
то есть когда я играю sample-default.wav
использование файла aplay
по следующей команде:-
aplay -D plug:notification sample-default.wav
Это работает, но когда я пытаюсь запустить следующий код, чтобы играть sample-default.wav
с помощью alsa library
на моем notification
устройство:-
#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
#include <pthread.h>
void default_sound (char * str) {
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
snd_pcm_uframes_t frames;
/* Open PCM device for playback */
int status = snd_pcm_open(&handle, "notification", SND_PCM_STREAM_PLAYBACK, 0);
if (status < 0) {
printf("Unable to open pcm deveice%s\n", snd_strerror(status));
return;
}
/* Allocate a hardware parameter obejct */
snd_pcm_hw_params_alloca(¶ms);
/* Fill it with default values */
snd_pcm_hw_params_any(handle, params);
/* Set the desired hardware parameters */
/* Interleaved mode */
snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
/* Signed 16-bit little-endian format */
snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
/* Single Channel (mono) */
snd_pcm_hw_params_set_channels(handle, params, 1);
/* sampling rate */
unsigned int sample_rate = 16000;
int dir;
snd_pcm_hw_params_set_rate_near(handle, params, &sample_rate, &dir);
/* set period size to 32 frames */
frames = 32;
snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);
/* Write the parameters to the driver */
status = snd_pcm_hw_params(handle, params);
if(status < 0) {
printf("Unable to set hw params: %s\n", snd_strerror(status));
return;
}
/* Use a buffer large enough to hold one period */
snd_pcm_hw_params_get_period_size(params, &frames, &dir);
int size = frames * 2;
char *buffer = (char *)malloc(size);
int readfd = open("sample-call.wav", O_RDONLY);
if(readfd < 0) {
printf("Error in opening wav file\n");
exit(1);
}
int readval;
while(readval = read(readfd, buffer, size) > 0) {
status = snd_pcm_writei(handle, buffer, frames);
if(status == -EPIPE) {
printf("underrun occured\n");
snd_pcm_prepare(handle);
}
else if(status < 0) {
printf("Error from writei: %s\n", snd_strerror(status));
}
}
snd_pcm_drain(handle);
snd_pcm_close(handle);
free(buffer);
}
int main() {
pthread_t pthread_id;
int status = pthread_create(&pthread_id, NULL, default_sound, "running");
if (status != 0) {
printf("Error in creating thread\n");
}
pthread_join(pthread_id, NULL);
return 0;
}
Он успешно компилируется, но выдает ошибку во время выполнения:-
8211 segmentation fault (core dumped) ./play-multiple-sound
Я не знаю, что не так с приведенным выше кодом.
Если приведенный выше код работает нормально, я воспроизведу два звуковых файла на двух устройствах (notification
а также sample-sound
) и контролировать громкость этих устройств с помощью alsa-mixer
библиотека, которую я уже реализовал.
Я пытаюсь добиться этого за последние несколько недель, и ни одно из решений, похоже, не работает для меня, поэтому, пожалуйста, помогите мне с этим, и если вы знаете лучший подход, то, пожалуйста, предложите.