Alsa асинхронный обратный вызов - PullRequest
2 голосов
/ 09 февраля 2012

Я пытаюсь использовать функцию асинхронного обратного вызова ALSA, чтобы обеспечить возможность приостановки и возобновления на уровне приложения. Но функция async_add_pcm_handler() возвращает ошибку (возвращает -38, если быть более точным).

rc = snd_pcm_open(&handle, (char*)"default",SND_PCM_STREAM_PLAYBACK, 0);
snd_pcm_hw_params_alloca(&params);
snd_pcm_hw_params_any(handle, params);
snd_pcm_hw_params_set_format(handle, params,SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_channels(handle, params, 1);
val = 22050;
snd_pcm_hw_params_set_rate_near(handle, params,&val, &dir);
frames=128;
snd_pcm_hw_params_set_period_size_near(handle,params, &frames, &dir);
snd_pcm_hw_params(handle, params);
snd_pcm_hw_params_get_period_size(params, &frames,&dir);
size = frames * 2;

pcmfile=fopen("output.pcm","rb");
fseek(pcmfile,0,SEEK_SET);
buffer=(char*)malloc(size);
memset(buffer,0,size);

if(snd_async_add_pcm_handler(&pcm_callback, handle, MyCallback, NULL) != 0) {
    printf("handler not successful\n");
}

while(!feof(pcmfile)){
    returnvalue=fread(buffer,sizeof(char),size,pcmfile);
    snd_pcm_writei(handle, buffer, frames);
}

Выше приведен фрагмент кода, который я использую, и определена функция MyCallback. Не могли бы вы указать мне на возможную ошибку.

1 Ответ

1 голос
/ 14 июня 2016

У меня была проблема с теми же симптомами, что и у вас, поэтому я надеюсь, что решение будет таким же.

Мое решение состояло в том, что вместо открытия устройства «по умолчанию» вы открываете свое аудиоустройство напрямую. Это аудиоустройство с именем вроде "hw: someName". Я полагаю, что оригинальная проблема заключается в том, что устройство «по умолчанию» - это виртуальное устройство, которое связано с сервером SoundAudio Sound - на моем Ubuntu Linux это так или иначе. Поскольку звуковой сервер pulseAudio не поддерживает полный API-интерфейс ALSA, появляется ошибка «функция не реализована».

Чтобы уточнить решение, замените

rc = snd_pcm_open(&handle, (char*)"default",SND_PCM_STREAM_PLAYBACK, 0);

с

rc = snd_pcm_open(&handle, (char*)"hw:someName",SND_PCM_STREAM_PLAYBACK, 0);
...