1
我想用異步播放方法播放文件。我寫了下面的代碼,但它不工作,它沒有顯示任何內容。任何幫助提前感謝。Alsa異步播放
#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);
}
對不起我的代碼格式化..
它工作時,我用一些繁忙的等待循環替換'睡眠(10)',但不能很好地播放(播放聲音有些緩慢) –