Question

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);
}

sorry for my code formatting..

Was it helpful?

Solution

Asynchronous callbacks are implemented using signals, which have many problems:

  • 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top