Hello: I am still trying to write my own basic application that captures and plays audio. I am working in an embedded linux environment and have the drivers working well. I can use arecord/aplay without any problem. However, I have been trying to follow some web examples for simple capture and playback without any success. Does anyone know of some sample code for S8 formatted, 8k rate capture and playback. I think my problem is two-fold. First is getting the hw-params set correctly. I have a function call that sets the interface up. I am trying to use the same params that aplay -v returns to me, but perhaps I have them wrong somehow. Secondly is buffering the samples. I am not sure I have that correct. Does anyone have some pointers on that? I have attached my code. If anyone has some time and insight into this, I would greatly appreciate it. Thanks. Paul
/* GRH Audio Program * * Author: Paul Kavan, Project Engineer * Date: July 3, 2007 */ #include <stdio.h> #include <stdlib.h> #include <alsa/asoundlib.h> /************************************* * Variable and Function Declarations *************************************/ long loops; unsigned int val; int nchannels = 1; static snd_pcm_uframes_t period_frames = 1000; static snd_pcm_uframes_t buffer_frames = 4000; static unsigned period_time = 125000; unsigned int sample_rate = 8000; char *buffer; snd_pcm_t *pcm_handle; int grh_capture(void); int grh_playback(void); int grh_pcm_config(void); /************************************* * Main Program Section *************************************/ int main(void) { int err; //Testing routine printf("Press enter to begin recording\n"); getchar(); err = grh_capture(); printf("Audio Captured. Press enter to playback\n"); while(1){ getchar(); err = grh_playback(); printf("Audio playback complete. Again?\n");} return 0; } /************************************************* * Capture Function: * This fuction should capture audio from the PCM * and store it in a buffer for transmission *************************************************/ int grh_capture(void) { int err; /************************************ * Open the pcm interface ************************************/ if ((err = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0) { fprintf(stderr, "Failed to open input audio device %s: %s\n", "default", snd_strerror(err)); exit(1); } /************************************ * Configure the devices ************************************/ err = grh_pcm_config(); /****************************************** * Perform capture and store to buffer ******************************************/ while(loops > 0) { loops--; if ((err = snd_pcm_readi (pcm_handle, buffer, period_frames)) != period_frames) { fprintf (stderr, "read from audio interface failed (%s)\n",snd_strerror (err)); exit (1); } } /******************************************* * Close PCM interface and exit *******************************************/ snd_pcm_close (pcm_handle); return 0; } /************************************************ * Playback Function: * This function should retrieve audio from a * buffer and send it to the PCM for playback ************************************************/ int grh_playback(void) { int err; /************************************ * Open the pcm interface ************************************/ if ((err = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) { fprintf(stderr, "Failed to open output audio device %s: %s\n", "default", snd_strerror(err)); exit(1); } /************************************ * Configure the devices ************************************/ err = grh_pcm_config(); /****************************************** * Playback from buffer ******************************************/ while (loops > 0) { loops--; if ((err = snd_pcm_writei (pcm_handle, buffer, period_frames)) != period_frames) { fprintf (stderr, "write to audio interface failed (%s)\n",snd_strerror (err)); exit (1); } } /******************************************* * Close PCM interface and exit *******************************************/ snd_pcm_close (pcm_handle); return 0; } /************************************************* * PCM configure function * This function configures the pcm for an audio * operation. Most params stay the same, the only * difference is in the pcm_handle *************************************************/ int grh_pcm_config(void) { int err; snd_pcm_hw_params_t *hw_params; 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 (pcm_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 (pcm_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 (pcm_handle, hw_params, SND_PCM_FORMAT_S8)) < 0) { fprintf (stderr, "cannot set sample format (%s)\n",snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_rate_near (pcm_handle, hw_params, &sample_rate, 0)) < 0) { fprintf (stderr, "Cannot set sample rate (%s)\n",snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_period_size_near(pcm_handle, hw_params, &period_frames, 0)) < 0) { fprintf (stderr, "Cannot set period size (%s)\n",snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_period_time_near(pcm_handle, hw_params, &period_time, 0)) < 0) { fprintf (stderr, "cannot set period time (%s)\n",snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hw_params, &buffer_frames)) < 0) { fprintf (stderr, "cannot set buffer_size (%s)\n",snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_channels (pcm_handle, hw_params, nchannels)) < 0) { fprintf (stderr, "cannot set channel count (%s)\n",snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params (pcm_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_prepare (pcm_handle)) < 0) { fprintf (stderr, "cannot prepare audio interface for use (%s)\n",snd_strerror (err)); exit (1); } /* Use a buffer large enough to hold one period */ snd_pcm_hw_params_get_period_size(hw_params, &period_frames, 0); buffer = (char *) malloc(period_frames); /* We want to loop for 5 seconds */ snd_pcm_hw_params_get_period_time(hw_params, &val, 0); loops = 5000000 / val; return 0; }
_______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel