Helo needed on implementing the call back- ALSA record...

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi All
I am trying to implement test code for recording using the callback.
The Mic is USB based.
With the simple application, continous recording (while loop ) it is fine.
Now i am trying to implement the recording using the callback,
Here is the code,
1. With this i see only once the callback is called. After that the call back never comes again.
2. I changed the open mode to SND_PCM_ASYNC during open, I have not got the callback even once.
What could be the problem.? Am i missing something for configuring the callback?
Please help.
-----------------------------------------------------
 
#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
#define FORMAT_DEFAULT  -1
#define FORMAT_RAW  0
#define FORMAT_VOC  1
#define FORMAT_WAVE  2
#define FORMAT_AU  3
#ifndef timersub
#define timersub(a, b, result) \
do { \
 (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
 (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
 if ((result)->tv_usec < 0) { \
  --(result)->tv_sec; \
  (result)->tv_usec += 1000000; \
 } \
} while (0)
#endif

static struct {
 snd_pcm_format_t format;
 unsigned int channels;
 unsigned int rate;
} hwparams, rhwparams;
static snd_pcm_t *capture_handle;
static snd_pcm_uframes_t buffer_frames = 0;
static size_t bits_per_sample, bits_per_frame;
static size_t chunk_bytes;
static snd_pcm_uframes_t chunk_size = 0;
static snd_pcm_uframes_t buffer_size;
static int quiet_mode = 0;
static snd_output_t *log;
  short buf[128 * 1024];
  static int fd1 = -1;
static  snd_pcm_sframes_t frames_to_deliver;
static void do_test_position(void);
static void suspend(void);
static void xrun(void);
snd_async_handler_t *pcm_callback = 0;

void MyCallback(snd_async_handler_t *pcm_callback);
void MyCallback(snd_async_handler_t *p1)
{
      snd_pcm_t *handle = snd_async_handler_get_pcm(p1);
        snd_pcm_sframes_t avail;
        int err;
        printf (" GSS inside the handler\n");
        avail = snd_pcm_avail_update(capture_handle);
  printf("avail :%d chunk_size :%d ", avail, chunk_size);
        while (avail >= chunk_size) {
//                snd_pcm_writei(pcm_handle, MyBuffer, period_size);
   err = snd_pcm_readi (capture_handle, buf, chunk_size);
   if (write(fd1, &buf[0], chunk_bytes)!= chunk_bytes )
    {
    printf(" WRITE FAILED");
    }
        }
}
     
int main (int argc, char *argv[])
{
  int i;
  int err;

  snd_pcm_hw_params_t *hw_params;
  char *pcm_name = "default";
  static snd_pcm_stream_t stream = SND_PCM_STREAM_CAPTURE; 
//  static int open_mode = SND_PCM_ASYNC ;
  static int open_mode = 0 ;
  static int file_type = FORMAT_RAW;
  static FILE * fd = NULL;
  char *name = "TEST.RAW";
      void* private_data = malloc(256);
  hwparams.format = SND_PCM_FORMAT_S16_LE;
  hwparams.channels = 2;
  hwparams.rate = 44100;

  if ((fd = fopen("record.raw", "wb")) == NULL) {
    fprintf (stderr, "cannot open file for writing )\n");
   exit(1);
  }
  if ((fd1 = open64(name, O_WRONLY | O_CREAT, 0644)) == -1) {
    exit(1);
  }
  
  if ((err = snd_pcm_open (&capture_handle, pcm_name, stream,open_mode)) < 0) {
   fprintf (stderr, "cannot open audio device %s (%s)\n",
     argv[1],
     snd_strerror (err));
   exit (1);
  }
  printf("\n snd_pcm_open DONE \n");
   err = snd_output_stdio_attach(&log, stderr, 0);  
  if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
   fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
     snd_strerror (err));
   exit (1);
  }
  printf("\n snd_pcm_hw_params_malloc DONE \n");  
    
  if ((err = snd_pcm_hw_params_any (capture_handle, hw_params)) < 0) {
   fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
     snd_strerror (err));
   exit (1);
  }
  printf("\n snd_pcm_hw_params_any DONE \n"); 
 if ((err = snd_pcm_hw_params_set_format (capture_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
   fprintf (stderr, "cannot set sample format (%s)\n",
     snd_strerror (err));
   exit (1);
  }
 printf("\n snd_pcm_hw_params_set_format DONE \n"); 
  
  
  if ((err = snd_pcm_hw_params_set_access (capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
   fprintf (stderr, "cannot set access type (%s)\n",
     snd_strerror (err));
   exit (1);
  }
  printf("\n snd_pcm_hw_params_set_access DONE \n");    

  if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, &hwparams.rate , 0)) < 0) {
   fprintf (stderr, "cannot set sample rate (%s)\n",
     snd_strerror (err));
   exit (1);
  }
  printf("\n snd_pcm_hw_params_set_rate_near DONE \n");      
  if ((err = snd_pcm_hw_params_set_channels (capture_handle, hw_params, 2)) < 0) {
   fprintf (stderr, "cannot set channel count (%s)\n",
     snd_strerror (err));
   exit (1);
  }
  printf("\n snd_pcm_hw_params_set_channels DONE \n");  
  err = snd_pcm_hw_params_set_buffer_size_near(capture_handle, hw_params,
            &buffer_frames);
  if (err < 0)
  { 
   fprintf (stderr, "cannot set buffer_size  (%s)\n",
     snd_strerror (err));
   exit (1);
   
  }
    printf("\n snd_pcm_hw_params_set_buffer_size_near DONE \n");  
 
  if ((err = snd_pcm_hw_params (capture_handle, hw_params)) < 0) {
   fprintf (stderr, "cannot set parameters (%s)\n",
     snd_strerror (err));
   exit (1);
  }
  printf("\n snd_pcm_hw_params DONE \n"); 
 bits_per_sample = snd_pcm_format_physical_width(hwparams.format);
 snd_pcm_hw_params_get_period_size(hw_params, &chunk_size, 0);
 snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size);
 
 bits_per_frame = bits_per_sample * hwparams.channels;
 chunk_bytes = chunk_size * bits_per_frame / 8;
 
 printf("\nchunk_size : %d \n", chunk_size);
 printf("\n chunk_bytes :%d bits_per_frame :%dbits_per_sample :%d   \n", chunk_bytes, bits_per_frame, bits_per_sample);
 
  snd_pcm_hw_params_free (hw_params);
  printf("\n snd_SW and HW parameted set DONE \n");
 
  if ((err = snd_pcm_prepare (capture_handle)) < 0) {
   fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
     snd_strerror (err));
   exit (1);
  }
  printf("\n snd_pcm_prepare DONE \n");
  do_test_position();
  snd_async_add_pcm_handler((snd_async_handler_t**)&pcm_callback, capture_handle, MyCallback, private_data);
  snd_pcm_start(capture_handle);
 
 while (1)
  {

 #if 0 
 /* wait till the interface is ready for data, or 1 second
      has elapsed.
   */
 
   if ((err = snd_pcm_wait (capture_handle, 1000)) < 0) {
           fprintf (stderr, "poll failed (%s)\n", strerror (errno));
           break;
   }           
 
   /* find out how much space is available for playback data */
 
   if ((frames_to_deliver = snd_pcm_avail_update (capture_handle)) < 0) {
    if (frames_to_deliver == -EPIPE) {
     fprintf (stderr, "an xrun occured\n");
     break;
    } else {
     fprintf (stderr, "unknown ALSA avail update return value (%d)\n",
       frames_to_deliver);
     break;
    }
   }
 
   frames_to_deliver = frames_to_deliver > 4096 ? 4096 : frames_to_deliver;
 
   /* deliver the data */
//   frames_to_deliver = 128;
   if (playback_callback (frames_to_deliver) != frames_to_deliver) {
           fprintf (stderr, "playback callback failed\n");
    break;
   }
   #endif
  }
#if 0
   for (i = 0; i < 128; ++i)
   {
    printf("Buffer value buf [%d]:%x \n", i, buf[i]);
   }
#endif  
 
  snd_pcm_close (capture_handle);
  fclose(fd);
   snd_output_close(log);
   close(fd1);
  exit (0);
 }
static void do_test_position(void)
{
 static int counter = 0;
 snd_pcm_sframes_t avail, delay;
 int err;
 err = snd_pcm_avail_delay(capture_handle, &avail, &delay);
 if (err < 0)
  return;
 if (avail > 4 * (snd_pcm_sframes_t)buffer_frames ||
     avail < -4 * (snd_pcm_sframes_t)buffer_frames ||
     delay > 4 * (snd_pcm_sframes_t)buffer_frames ||
     delay < -4 * (snd_pcm_sframes_t)buffer_frames) {
   fprintf(stderr, "Suspicious buffer position (%i total): avail = %li, delay = %li, buffer = %li\n", ++counter, (long)avail, (long)delay, (long)buffer_frames);
 } else  {
   fprintf(stderr, "Buffer position: %li/%li (%li)\n", (long)avail, (long)delay, (long)buffer_frames);
 }
}
static void xrun(void)
{
 snd_pcm_status_t *status;
 int res;
 
 snd_pcm_status_alloca(&status);
 if ((res = snd_pcm_status(capture_handle, status))<0) {
  error(("status error: %s"), snd_strerror(res));
  exit(EXIT_FAILURE);
 }
 if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN) {
  struct timeval now, diff, tstamp;
  gettimeofday(&now, 0);
  snd_pcm_status_get_trigger_tstamp(status, &tstamp);
  timersub(&now, &tstamp, &diff);
 
  if ((res = snd_pcm_prepare(capture_handle))<0) {
   error(("xrun: prepare error: %s"), snd_strerror(res));
   exit(EXIT_FAILURE);
  }
  return;  /* ok, data should be accepted again */
 } if (snd_pcm_status_get_state(status) == SND_PCM_STATE_DRAINING) {
  
   fprintf(stderr,("capture stream format change? attempting recover...\n"));
   if ((res = snd_pcm_prepare(capture_handle))<0) {
    error(("xrun(DRAINING): prepare error: %s"), snd_strerror(res));
    exit(EXIT_FAILURE);
   }
   return;
 
 }
 
 error(("read/write error, state = %s"), snd_pcm_state_name(snd_pcm_status_get_state(status)));
 exit(EXIT_FAILURE);
}
/* I/O suspend handler */
static void suspend(void)
{
 int res;
 if (!quiet_mode)
  fprintf(stderr, ("Suspended. Trying resume. ")); fflush(stderr);
 while ((res = snd_pcm_resume(capture_handle)) == -EAGAIN)
  sleep(1); /* wait until suspend flag is released */
 if (res < 0) {
  if (!quiet_mode)
   fprintf(stderr, ("Failed. Restarting stream. ")); fflush(stderr);
  if ((res = snd_pcm_prepare(capture_handle)) < 0) {
   error(("suspend: prepare error: %s"), snd_strerror(res));
   exit(EXIT_FAILURE);
  }
 }
 if (!quiet_mode)
  fprintf(stderr, ("Done.\n"));
}
--------------------------------------------------
------------------------------------------------------------------------------
Protect Your Site and Customers from Malware Attacks
Learn about various malware tactics and how to avoid them. Understand 
malware threats, the impact they can have on your business, and how you 
can protect your company and customers by using code signing.
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
Alsa-user mailing list
Alsa-user@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-user

[Index of Archives]     [ALSA Devel]     [Linux Audio Users]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]

  Powered by Linux