Hi, Thanks for the link you emailed earlier. I tried writing my own code, based on the how to in the alsa wiki. I have attached that code with this email. The problem it faces is a buffer underrun every alternate time, i try writing to the device. In my code, to take care of underruns, I do the following: period_size=64; buffer is a short int array which is 16000 in length. every alternate call to snd_pcm_writei is successful but only write in the vicinity of 1350 frames, instead of size which is initialised to length of buffer. Now, in the code below, the snd_pcm_recover function prints a message indicating a buffer under-run has occured, however, it returns a 0, indicating success in recovery from the error! I am not sure how to deal with this -- is there a problem with my ALSA libraries? Sorry about the length of this email and thanks again, Ashlesha. while(size>(2*period_size))
{ frames = snd_pcm_writei (pcm_handle, buffer, size); printf("frames returned is %d\n",frames); if (frames>0) temp=frames; if (frames == -32){ frames = snd_pcm_recover(pcm_handle, frames, 0); printf("recover returned %d\n",frames); } if (frames < 0){ printf("snd_pcm_writei failed: %s\n", snd_strerror(frames)); return -1; } printf("%d frames written\n",frames); if(temp>0) size=size-temp; }
/* My code using the ALSA Asynchronous playback wiki */ #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 126976 /*Global Variables */ int err; const char *device_name = "default"; int main() { snd_pcm_t *pcm_handle; unsigned int rrate = 16000; int fd1,count,bytesread=1,a,err,frames,i,size=SIZE,temp; short int buffer[SIZE]; char d; char errstr[50]; snd_pcm_uframes_t buffer_size = 1024; snd_pcm_uframes_t period_size = 64; snd_pcm_hw_params_t *hw_params; snd_pcm_sw_params_t *sw_params; if((fd1=open("orig.wav",O_RDONLY,0))==-1) { printf("error opening file\n"); return -1; } for(count=0;count<44;count++) { a=read(fd1,&d,sizeof(char)); //first 40 bytes of the wav file } count=0; while(bytesread >0 && count<SIZE) bytesread = read( fd1 , &buffer[count++], sizeof( short int ) ); printf("no. of samples @16000Hz are %d\n",count); // count is the size of the wave file printf("bytesread = %d\n",bytesread); if((err = snd_pcm_open (&pcm_handle, device_name, SND_PCM_STREAM_PLAYBACK, 0))!=0) { printf("err in pcm open\n"); printf("errstr is %s\n",snd_strerror (err)); return -1; } if((err=snd_pcm_hw_params_malloc (&hw_params))!=0){ printf("malloc err\n"); printf("errstr is %s\n",snd_strerror (err)); return -1; } if ((err = snd_pcm_set_params( pcm_handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 1, 16000, 1, 100)) < 0) { printf("Playback open error: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } if ((err=snd_pcm_prepare (pcm_handle))<0){ printf("pcm prepare error %d\n",err); printf("errstr is %s\n",snd_strerror (err)); } frames=0; size=SIZE; temp=0; while(size>(2*period_size)) { frames = snd_pcm_writei (pcm_handle, buffer, size); printf("frames returned is %d\n",frames); if (frames>0) temp=frames; if (frames == -32){ frames = snd_pcm_recover(pcm_handle, frames, 0); printf("recover returned %d\n",frames); } if (frames < 0){ printf("snd_pcm_writei failed: %s\n", snd_strerror(frames)); return -1; } printf("%d frames written\n",frames); if(temp>0) size=size-temp; } snd_pcm_close (pcm_handle); return 0; }
_______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel