/* GRH Audio Program * * Author: Paul Kavan, Project Engineer * Date: July 3, 2007 */ #include #include #include /************************************* * 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; }