[alsa-devel] hardware not asking for more data using asyn call back
Hi,
In my asynchronous playback program, the hardware stops asking for any data and the program gets stuck after one call to the callback function. I have pasted the program below -- please let me know if something is wrong -
Thanks, Ashlesha.
/* Reading wav file into a buffer and then trying to play it */
#include <stdio.h> #include </usr/include/alsa/asoundlib.h> #include </usr/include/alsa/pcm.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h>
#define SIZE 128
short int *buffer; int ind=10, fd1; static snd_pcm_t *handle; static char *device = "default"; /* playback device */ snd_output_t *output = NULL; static short int *wto, *rfrom, buflen;
void MyCallback(snd_async_handler_t *pcm_callback);
int main() { int i,j,n,length,count,a,err,k=0; char c; snd_pcm_sframes_t frames; snd_async_handler_t *pcm_callback;
if((fd1=open("SA2.WAV",O_RDONLY,0))==-1) printf("error opening wav file\n"); count=0; while(count++<40) a=read(fd1,&c,sizeof(char)); a=read(fd1,&length,sizeof(int)); n=length/SIZE; printf("length = %d\n",length); buflen = 4*SIZE; buffer = (short int *) malloc (buflen*sizeof(short int)); wto = NULL; rfrom = &buffer[0]; count=0; a=1; while(count<buflen && a>0) a=read(fd1,&buffer[count++],sizeof(short int)); if(a<0) printf("error in reading from wav file\n"); if((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) <
{ printf("error opening device: %s\n",snd_strerror(err)); return -1; }
if((err = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 1, 16000, 1, 1000)) < 0) { /* 2 sec */ printf("Playback open error: %s\n", snd_strerror(err)); return -2; } printf("n=%d\n",n); for (i=0; i<50; i++) { printf("i=%d\n",i); frames = snd_pcm_writei(handle, rfrom, SIZE); if(frames < 0) // underrun { printf("underrun recovery\n"); frames = snd_pcm_recover(handle, frames,0); if(frames < 0){ printf("error in recovery\n"); return -3; } } if(frames >0 && frames < SIZE) printf("expected to write %d, wrote %d\n",SIZE,frames); printf("distance between ptrs before reinit is %d\n",rfrom - wto); if(rfrom < &buffer[buflen-1]) { wto = rfrom; rfrom = rfrom + SIZE; } else { printf("rfm at the end, rfrom -buffer[buflen-1]
=%d\n",(*rfrom - buffer[buflen-1])); wto = rfrom; rfrom = &buffer[0]; } for(k=0; k<SIZE; k++) { a=read(fd1,(wto+k),sizeof(short int)); if(a<0) printf("error in reading from wav file k = %d\n"); } printf("buffer[i*SIZE] - rfrom = %d\n",(buffer[(i+1)*SIZE] - *rfrom));
} /* Async Handler */
// err = snd_async_add_pcm_handler(&pcm_callback,handle,MyCallback,buffer); err = snd_async_add_pcm_handler(&pcm_callback,handle,MyCallback,NULL); if(err<0) printf("add pcm handler error = %d\n%s\n",err,snd_strerror(err));
err = snd_pcm_start(handle); if(err<0) printf("error in starting snd pcm start err
:%s\n",snd_strerror(err));
while (1) { if(wto == NULL) break; sleep(1); }
err = snd_pcm_close(handle); if(err<0) printf("error in closing pcm device: %s\n",snd_strerror(err)); close(fd1); return 0;
}
void MyCallback(snd_async_handler_t *pcm_callback) {
snd_pcm_t *pcm_handle = snd_async_handler_get_pcm(pcm_callback); snd_pcm_sframes_t avail; int count,a; snd_pcm_uframes_t period_size = 64; snd_pcm_sframes_t frames; //short int *bufferin =
snd_async_handler_get_callback_private(pcm_callback);
while((avail=snd_pcm_avail_update(pcm_handle)) >= period_size) { printf("available frames = %d\n",avail); frames = snd_pcm_writei(pcm_handle, rfrom, SIZE); if(frames < 0) // underrun { printf("underrun recovery\n"); frames = snd_pcm_prepare(pcm_handle); printf("error from snd_pcm_prepare is: %d\n",frames); if(frames < 0){ printf("error in recovery\n"); // break; } } if(frames >0 && frames < SIZE) printf("expected to write %d, wrote %d\n",SIZE,frames); count = 0; a=1; while(count<SIZE && a>0){ a=read(fd1,(wto+count),sizeof(short int)); //write to
the buffer from file ++count; } printf("count = %d\n",count); if(a <0){ //EOF wto = NULL; printf("end of file reached\n"); break; } else{ if(rfrom < &buffer[buflen-1]) { wto = wto+count; rfrom = rfrom + SIZE; } else { wto = wto + count; rfrom = &buffer[0]; } //location of where to start writing from next } ++ind; }
printf("going out of callback, ind = %d\n",ind);
}
On Mon, 28 May 2007 15:32:16 -0400 "Ashlesha Shintre" ashlesha.shintre@gmail.com wrote:
Hi,
In my asynchronous playback program, the hardware stops asking for any data and the program gets stuck after one call to the callback function. I have pasted the program below -- please let me know if something is wrong -
Thanks, Ashlesha.
/* Reading wav file into a buffer and then trying to play it */
#include <stdio.h> #include </usr/include/alsa/asoundlib.h> #include </usr/include/alsa/pcm.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h>
#define SIZE 128
short int *buffer; int ind=10, fd1; static snd_pcm_t *handle; static char *device = "default"; /* playback device */ snd_output_t *output = NULL; static short int *wto, *rfrom, buflen;
void MyCallback(snd_async_handler_t *pcm_callback);
int main() { int i,j,n,length,count,a,err,k=0; char c; snd_pcm_sframes_t frames; snd_async_handler_t *pcm_callback;
if((fd1=open("SA2.WAV",O_RDONLY,0))==-1) printf("error opening wav file\n"); count=0; while(count++<40) a=read(fd1,&c,sizeof(char)); a=read(fd1,&length,sizeof(int)); n=length/SIZE; printf("length = %d\n",length); buflen = 4*SIZE; buffer = (short int *) malloc (buflen*sizeof(short int)); wto = NULL; rfrom = &buffer[0]; count=0; a=1; while(count<buflen && a>0) a=read(fd1,&buffer[count++],sizeof(short int)); if(a<0) printf("error in reading from wav file\n"); if((err = snd_pcm_open(&handle, device,
SND_PCM_STREAM_PLAYBACK, 0)) < 0) { printf("error opening device: %s\n",snd_strerror(err)); return -1; }
if((err = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 1, 16000, 1, 1000)) < 0) { /* 2 sec */ printf("Playback open error: %s\n", snd_strerror(err)); return -2; } printf("n=%d\n",n); for (i=0; i<50; i++) { printf("i=%d\n",i); frames = snd_pcm_writei(handle, rfrom, SIZE); if(frames < 0) // underrun { printf("underrun recovery\n"); frames = snd_pcm_recover(handle, frames,0); if(frames < 0){ printf("error in recovery\n"); return -3; } } if(frames >0 && frames < SIZE) printf("expected to write %d, wrote %d\n",SIZE,frames); printf("distance between ptrs before reinit is %d\n",rfrom
- wto); if(rfrom < &buffer[buflen-1]) { wto = rfrom; rfrom = rfrom + SIZE; } else { printf("rfm at the end, rfrom -buffer[buflen-1]
=%d\n",(*rfrom - buffer[buflen-1])); wto = rfrom; rfrom = &buffer[0]; } for(k=0; k<SIZE; k++) { a=read(fd1,(wto+k),sizeof(short int)); if(a<0) printf("error in reading from wav file k = %d\n"); } printf("buffer[i*SIZE] - rfrom = %d\n",(buffer[(i+1)*SIZE] - *rfrom));
} /* Async Handler */
// err = snd_async_add_pcm_handler(&pcm_callback,handle,MyCallback,buffer); err = snd_async_add_pcm_handler(&pcm_callback,handle,MyCallback,NULL); if(err<0) printf("add pcm handler error = %d\n%s\n",err,snd_strerror(err));
err = snd_pcm_start(handle); if(err<0) printf("error in starting snd pcm start err
:%s\n",snd_strerror(err));
while (1) { if(wto == NULL) break; sleep(1);
I think you should be filling the buffer in this loop instead of in the callback function below.
} err = snd_pcm_close(handle); if(err<0) printf("error in closing pcm device:
%s\n",snd_strerror(err)); close(fd1); return 0; }
void MyCallback(snd_async_handler_t *pcm_callback) {
snd_pcm_t *pcm_handle = snd_async_handler_get_pcm(pcm_callback); snd_pcm_sframes_t avail; int count,a; snd_pcm_uframes_t period_size = 64; snd_pcm_sframes_t frames; //short int *bufferin =
snd_async_handler_get_callback_private(pcm_callback);
while((avail=snd_pcm_avail_update(pcm_handle)) >= period_size) { printf("available frames = %d\n",avail); frames = snd_pcm_writei(pcm_handle, rfrom, SIZE); if(frames < 0) // underrun { printf("underrun recovery\n"); frames = snd_pcm_prepare(pcm_handle); printf("error from snd_pcm_prepare is:
%d\n",frames); if(frames < 0){ printf("error in recovery\n"); // break; } }
if(frames >0 && frames < SIZE) printf("expected to write %d, wrote
%d\n",SIZE,frames); count = 0; a=1; while(count<SIZE && a>0){ a=read(fd1,(wto+count),sizeof(short int)); //write to the buffer from file ++count; } printf("count = %d\n",count); if(a <0){ //EOF wto = NULL; printf("end of file reached\n"); break; } else{ if(rfrom < &buffer[buflen-1]) { wto = wto+count; rfrom = rfrom + SIZE; } else { wto = wto + count; rfrom = &buffer[0]; } //location of where to start writing from next } ++ind; }
printf("going out of callback, ind = %d\n",ind);
}
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Could you post the output of all the printfs when the program runs, and describe the behavior. I read what you read above as saying that it hangs. The printf output will indicate where it is hanging.
participants (2)
-
Ashlesha Shintre
-
stan