Alsa异步播放 [英] Alsa Asynchronous Playback

查看:246
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆