audio_alsa.c

00001 /*
00002  * iaxclient: a cross-platform IAX softphone library
00003  *
00004  * Copyrights:
00005  * Copyright (C) 2006 Panfilov Dmitry
00006  *
00007  * Contributors:
00008  * Panfilov Dmitry
00009  *
00010  * This program is free software, distributed under the terms of
00011  * the GNU Lesser (Library) General Public License.
00012  *
00013  */
00014 
00015 #include "iaxclient_lib.h"
00016 #include <alsa/asoundlib.h>
00017 
00018 static snd_pcm_t *stream_out;
00019 static snd_pcm_t *stream_in;
00020 
00021 #define FRAMES_PER_BUFFER 80 /* 80 frames == 10ms */
00022 
00023 
00024 static int alsa_play_sound(struct iaxc_sound *inSound, int ring) {
00025   return 0;
00026 }
00027 
00028 int alsa_stop_sound(int soundID) {
00029   return 0;
00030 }
00031 
00032 
00033 int alsa_start (struct iaxc_audio_driver *d ) {
00034     return 0;
00035 }
00036 
00037 int alsa_stop (struct iaxc_audio_driver *d ) {
00038     return 0;
00039 }
00040 
00041 void alsa_shutdown_audio()
00042 {
00043     return;
00044 }
00045 
00046 
00047 int alsa_input(struct iaxc_audio_driver *d, void *samples, int *nSamples) {
00048 
00049     /* we don't return partial buffers */
00050     long r;
00051     long byteread=*nSamples;
00052     static int h;
00053     *nSamples=0;
00054     snd_pcm_start(stream_in);
00055     if(h==1) { h=0; return 0;}
00056     do{
00057         r = snd_pcm_readi(stream_in, samples, byteread);
00058         if (r == -EAGAIN){
00059             continue;
00060         }
00061         if (r == - EPIPE) {
00062             snd_pcm_prepare(stream_in);
00063             continue;
00064         }
00065          samples += (r * 2);
00066          byteread -= r;
00067          *nSamples += r;
00068     }while(r >=0 && byteread >0);
00069     h=1;
00070     return 0;
00071 }
00072 
00073 int alsa_output(struct iaxc_audio_driver *d, void *samples, int nSamples) {
00074 
00075         long r;
00076         snd_pcm_start(stream_out);
00077         while (nSamples > 0) {
00078                 r = snd_pcm_writei(stream_out, samples, nSamples);
00079                 if (r == -EAGAIN){
00080                     continue;
00081                 }
00082                 if (r == - EPIPE) {
00083                     snd_pcm_prepare(stream_out);
00084                     continue;
00085                 }
00086                 if (r < 0) {
00087                     fprintf(stderr, "r=%d\n",r);
00088                 }
00089                 samples += r * 2;
00090                 nSamples -= r;
00091         }
00092         return 0;
00093 }
00094 
00095 int alsa_select_devices (struct iaxc_audio_driver *d, int input, int output, int ring) {
00096     return 0;
00097 }
00098 
00099 int alsa_selected_devices (struct iaxc_audio_driver *d, int *input, int *output, int *ring) {
00100     *input = 0;
00101     *output = 0;
00102     *ring = 0;
00103     return 0;
00104 }
00105 
00106 int alsa_destroy (struct iaxc_audio_driver *d )
00107 {
00108         /* TODO: something should happen here */
00109     return 0;
00110 }
00111 
00112 double alsa_input_level_get(struct iaxc_audio_driver *d){
00113     return -1;
00114 }
00115 
00116 double alsa_output_level_get(struct iaxc_audio_driver *d){
00117     return -1;
00118 }
00119 
00120 int alsa_input_level_set(struct iaxc_audio_driver *d, double level){
00121     return -1;
00122 }
00123 
00124 int alsa_output_level_set(struct iaxc_audio_driver *d, double level){
00125     return -1;
00126 }
00127 
00128 
00129 /* initialize audio driver */
00130 int alsa_initialize (struct iaxc_audio_driver *d ,int sample_rate) {
00131     int i;
00132     int err;
00133     short buf[128];
00134     snd_pcm_hw_params_t *hw_params;
00135     snd_pcm_sw_params_t *sw_params;
00136 
00137     if ((err = snd_pcm_open (&stream_out, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
00138         fprintf (stderr, "cannot open audio device default (%s)\n",
00139         snd_strerror (err));
00140         exit (1);
00141     }
00142     if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
00143         fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
00144         snd_strerror (err));
00145         exit (1);
00146     }
00147     if ((err = snd_pcm_hw_params_any (stream_out, hw_params)) < 0) {
00148         fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
00149         snd_strerror (err));
00150         exit (1);
00151     }
00152     if ((err = snd_pcm_hw_params_set_access (stream_out, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
00153         fprintf (stderr, "cannot set access type (%s)\n",
00154         snd_strerror (err));
00155         exit (1);
00156     }
00157     if ((err = snd_pcm_hw_params_set_format (stream_out, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
00158         fprintf (stderr, "cannot set sample format (%s)\n",
00159         snd_strerror (err));
00160         exit (1);
00161     }
00162     if ((err = snd_pcm_hw_params_set_rate (stream_out, hw_params, sample_rate, 0)) < 0) {
00163         fprintf (stderr, "cannot set sample rate (%s)\n",
00164         snd_strerror (err));
00165         exit (1);
00166     }
00167     if ((err = snd_pcm_hw_params_set_channels (stream_out, hw_params, 1)) < 0) {
00168         fprintf (stderr, "cannot set channel count (%s)\n",
00169         snd_strerror (err));
00170         exit (1);
00171     }
00172     if ((err = snd_pcm_hw_params (stream_out, hw_params)) < 0) {
00173         fprintf (stderr, "cannot set parameters (%s)\n",
00174         snd_strerror (err));
00175         exit (1);
00176     }
00177 
00178     snd_pcm_sw_params_malloc(&sw_params);
00179 
00180     err = snd_pcm_sw_params_current(stream_out, sw_params);
00181     if (err < 0) {
00182         printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
00183         return err;
00184     }
00185     err = snd_pcm_sw_params_set_start_threshold(stream_out, sw_params, 80);
00186     if (err < 0) {
00187         fprintf(stderr, "Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
00188         return err;
00189     }
00190     err = snd_pcm_sw_params(stream_out, sw_params);
00191     if (err < 0) {
00192         fprintf(stderr, "Unable to set sw params for playback: %s\n", snd_strerror(err));
00193         return err;
00194     }
00195 
00196     if ((err = snd_pcm_open (&stream_in, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0) {
00197         fprintf (stderr, "cannot open audio device default (%s)\n",
00198         snd_strerror (err));
00199         exit (1);
00200     }
00201     if ((err = snd_pcm_hw_params_any (stream_in, hw_params)) < 0) {
00202         fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
00203         snd_strerror (err));
00204         exit (1);
00205     }
00206     if ((err = snd_pcm_hw_params_set_access (stream_in, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
00207         fprintf (stderr, "cannot set access type (%s)\n",
00208         snd_strerror (err));
00209         exit (1);
00210     }
00211     if ((err = snd_pcm_hw_params_set_format (stream_in, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
00212         fprintf (stderr, "cannot set sample format (%s)\n",
00213         snd_strerror (err));
00214         exit (1);
00215     }
00216     if ((err = snd_pcm_hw_params_set_rate (stream_in, hw_params, sample_rate, 0)) < 0) {
00217         fprintf (stderr, "cannot set sample rate (%s)\n",
00218         snd_strerror (err));
00219         exit (1);
00220     }
00221     if ((err = snd_pcm_hw_params_set_channels (stream_in, hw_params, 1)) < 0) {
00222         fprintf (stderr, "cannot set channel count (%s)\n",
00223         snd_strerror (err));
00224         exit (1);
00225     }
00226     if ((err = snd_pcm_hw_params (stream_in, hw_params)) < 0) {
00227         fprintf (stderr, "cannot set parameters (%s)\n",
00228         snd_strerror (err));
00229         exit (1);
00230     }
00231 
00232     err = snd_pcm_sw_params_current(stream_in, sw_params);
00233     if (err < 0) {
00234         printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
00235         return err;
00236     }
00237     err = snd_pcm_sw_params_set_start_threshold(stream_in, sw_params, 80);
00238     if (err < 0) {
00239         fprintf(stderr, "Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
00240         return err;
00241     }
00242     err = snd_pcm_sw_params(stream_in, sw_params);
00243     if (err < 0) {
00244         fprintf(stderr, "Unable to set sw params for playback: %s\n", snd_strerror(err));
00245         return err;
00246     }
00247 
00248 
00249     if ((err = snd_pcm_prepare (stream_in)) < 0) {
00250         fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
00251         snd_strerror (err));
00252          exit (1);
00253     }
00254 
00255     if ((err = snd_pcm_prepare (stream_out)) < 0) {
00256         fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
00257         snd_strerror (err));
00258          exit (1);
00259     }
00260 
00261     d->initialize = alsa_initialize;
00262     d->destroy = alsa_destroy;
00263     d->select_devices = alsa_select_devices;
00264     d->selected_devices = alsa_selected_devices;
00265     d->start = alsa_start;
00266     d->stop = alsa_stop;
00267     d->output = alsa_output;
00268     d->input = alsa_input;
00269     d->input_level_get = alsa_input_level_get;
00270     d->input_level_set = alsa_input_level_set;
00271     d->output_level_get = alsa_output_level_get;
00272     d->output_level_set = alsa_output_level_set;
00273     d->play_sound = alsa_play_sound;
00274     d->stop_sound = alsa_stop_sound;
00275 
00276     return 0;
00277 }

Generated on Mon Sep 24 15:43:29 2007 for IAXClient by  doxygen 1.5.3