Alsa异步播放 [英] Alsa Asynchronous Playback
本文介绍了Alsa异步播放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想使用异步播放方法播放文件。我写了下面的代码,但它不起作用。,它什么也没显示。
I want to play a file using asynchronous playback method. I wrote the below code but it is not working., it is showing nothing. Any help thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <poll.h>
#include <alsa/asoundlib.h>
snd_pcm_t *playback_handle;
short buf[1024];
snd_pcm_uframes_t period_size = 64;
void playback_callback (snd_async_handler_t *pcm_callback)
{
int err;
// snd_pcm_t *playback_handle = snd_async_handler_get_pcm(pcm_callback);
void *private_data = snd_async_handler_get_callback_private(pcm_callback);
FILE *fp = (FILE *)private_data;
snd_pcm_sframes_t avail;
if(feof(fp)){
fclose(fp);
snd_pcm_drain(playback_handle);
snd_pcm_close(playback_handle);
exit(2);
}
avail = snd_pcm_avail_update(playback_handle);
printf("avil returned : %d\n",(int)avail);
while (avail >= period_size) {
fread(buf, 1, period_size, fp);
snd_pcm_writei (playback_handle, buf, period_size);
avail = snd_pcm_avail_update(playback_handle);
}
}
int main (int argc, char *argv[])
{
snd_pcm_hw_params_t *hw_params;
snd_pcm_sw_params_t *sw_params;
snd_pcm_sframes_t frames_to_deliver;
int nfds,rate=48000;
int err;
struct pollfd *pfds;
#if 1
FILE *fp=fopen("beep-fl.wav","rb");
fseek(fp ,44, SEEK_SET);
#endif
if ((err = snd_pcm_open (&playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) <0) {
fprintf (stderr, "cannot open audio device %s (%s)\n",
"default",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_access(playback_handle,hw_params,
SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
fprintf (stderr, "cannot set access type (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
fprintf (stderr, "cannot set sample format (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, &rate, 0)) < 0) {
fprintf (stderr, "cannot set sample rate (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 1)) < 0) {
fprintf (stderr, "cannot set channel count (%s)\n",
snd_strerror (err));
exit (1);
}
snd_pcm_uframes_t buffer_size = 1024;
snd_pcm_hw_params_set_buffer_size_near (playback_handle, hw_params, &buffer_size);
snd_pcm_hw_params_set_period_size_near (playback_handle, hw_params, &period_size, 0 );
if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
fprintf (stderr, "cannot set parameters (%s)\n",
snd_strerror (err));
exit (1);
}
snd_pcm_hw_params_free (hw_params);
if ((err = snd_pcm_sw_params_malloc (&sw_params)) < 0) {
fprintf (stderr, "cannot allocate software parameters structure (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_sw_params_current (playback_handle, sw_params)) < 0) {
fprintf (stderr, "cannot initialize software parameters structure (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_sw_params_set_avail_min(playback_handle, sw_params, period_size)) < 0) {
fprintf (stderr, "cannot set minimum available count (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_sw_params_set_start_threshold(playback_handle, sw_params, (buffer_size-period_size) )) < 0) {
fprintf (stderr, "cannot set start mode (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_sw_params (playback_handle, sw_params)) < 0) {
fprintf (stderr, "cannot set software parameters (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_prepare (playback_handle)) < 0) {
fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
snd_strerror (err));
exit (1);
}
fread( buf , 1 , 2 * period_size , fp );
snd_async_handler_t *pcm_callback;
snd_async_add_pcm_handler(&pcm_callback, playback_handle, playback_callback, (void *)fp);
snd_pcm_start(playback_handle);
snd_pcm_writei (playback_handle, buf, 2 * period_size);
sleep(10);
fclose(fp);
snd_pcm_drain (playback_handle);
snd_pcm_close (playback_handle);
exit (0);
}
很抱歉我的代码格式。
推荐答案
异步回调是使用信号实现的,该信号有很多问题:
Asynchronous callbacks are implemented using signals, which have many problems:
- 许多设备不支持此功能。和
- 您不能在回调中使用任何功能,但异步信号安全功能列表;和
- 任何信号都会中断
sleep
呼叫。
- Many devices do not support this; and
- you cannot use any functions in the callback except those from the list of async-signal-safe functions; and
- any signal will interrupt the
sleep
call.
强烈建议不要使用异步回调。
It is strongly recommended never to use asynchronous callbacks.
这篇关于Alsa异步播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文