Hi, Thanks Stan, for your response - Instead of copying pcm data from a wav file, i decided to copy all the data to a master buffer first and then see if the circular buffer implementation works - so now instead of copying from the wave file, i m copying data from the master buffer to the circular buffer.. however, as per your suggestion, if i copy the data in the while loop in main, then, it might not always be copied between 2 consecutive callbacks, but maybe more, as the callbacks are asynchronous. however, the hardware still does not ask for more data after executing the callback function about twice -- is there a way to flush the hardware buffer before beginning playback? I have pasted my code below Regards, 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 > //mpos is the position in the master buffer to write from > short int *buffer, *mbuf, *mpos; > int ind=10, fd1, length; > 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,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); > mbuf = (short int *) malloc (length * sizeof(short int)); > mpos = &mbuf[0]; > > buflen = 4*SIZE; > buffer = (short int *) malloc (buflen*sizeof(short int)); > > wto = NULL; > rfrom = &buffer[0]; > > /* reading to master buffer */ > count=0; > a=1; > while(count<length && a>0) > a=read(fd1,&mbuf[count++],sizeof(short int)); > if(a<0){ > printf("error in reading from wav file\n"); > exit(1); > } > close (fd1); > > for(count =0; count < buflen; count++) > { > buffer[count]=mbuf[count]; > } > /******************************/ > > /*ALSA DEV INIT*/ > 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; > } > if(rfrom >= &buffer[buflen-1]) > { > printf("rfm at the end, rfrom -buffer[buflen-1] > =%d\n",(*rfrom - buffer[buflen-1])); > //wto = rfrom; > rfrom = &buffer[0]; > } > > if((a = writetobuf())<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,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; // redundancy -- already checking for this > condition in MyCallback > printf("infinite loop\n"); > sleep(1); > } > > err = snd_pcm_close(handle); > if(err<0) > printf("error in closing pcm device: %s\n",snd_strerror(err)); > > 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; > > if((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"); > > } > } > > if(frames >0 && frames < SIZE) > printf("expected to write %d, wrote %d\n",SIZE,frames); > > > if(rfrom < &buffer[buflen-1]) > { > wto = rfrom; > rfrom = rfrom + SIZE; > } > if(rfrom >= &buffer[buflen-1]) > { > // wto = rfrom; > rfrom = &buffer[0]; > } //location of where to start writing > from next > > if(writetobuf()<0){ > wto=NULL; > exit(0); // returns 0 to the operating system -- so it > ends the program! > } > ++ind; > } > > printf("going out of callback, ind = %d\n",ind); > } > > /*Function to copy data from master buffer (mbuf) to circular buffer > (buffer)*/ > int writetobuf() > { > int count=-1; > > while((++count < SIZE) && (mpos < &mbuf[length])) > *(mpos++) = *(wto+count); > > if(mpos >= &mbuf[length-1]) > return -1; > else > return 0; > } > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel