2 * iaxclient: a cross-platform IAX softphone library
5 * Copyright (C) 2006 Panfilov Dmitry
10 * This program is free software, distributed under the terms of
11 * the GNU Lesser (Library) General Public License.
15 #include "iaxclient_lib.h"
16 #include <alsa/asoundlib.h>
18 static snd_pcm_t *stream_out;
19 static snd_pcm_t *stream_in;
21 #define FRAMES_PER_BUFFER 80 /* 80 frames == 10ms */
24 static int alsa_play_sound(struct iaxc_sound *inSound, int ring) {
28 int alsa_stop_sound(int soundID) {
33 int alsa_start (struct iaxc_audio_driver *d ) {
37 int alsa_stop (struct iaxc_audio_driver *d ) {
41 void alsa_shutdown_audio()
47 int alsa_input(struct iaxc_audio_driver *d, void *samples, int *nSamples) {
49 /* we don't return partial buffers */
51 long byteread=*nSamples;
54 snd_pcm_start(stream_in);
55 if(h==1) { h=0; return 0;}
57 r = snd_pcm_readi(stream_in, samples, byteread);
62 snd_pcm_prepare(stream_in);
68 }while(r >=0 && byteread >0);
73 int alsa_output(struct iaxc_audio_driver *d, void *samples, int nSamples) {
76 snd_pcm_start(stream_out);
77 while (nSamples > 0) {
78 r = snd_pcm_writei(stream_out, samples, nSamples);
83 snd_pcm_prepare(stream_out);
87 fprintf(stderr, "r=%d\n",r);
95 int alsa_select_devices (struct iaxc_audio_driver *d, int input, int output, int ring) {
99 int alsa_selected_devices (struct iaxc_audio_driver *d, int *input, int *output, int *ring) {
106 int alsa_destroy (struct iaxc_audio_driver *d )
108 /* TODO: something should happen here */
112 double alsa_input_level_get(struct iaxc_audio_driver *d){
116 double alsa_output_level_get(struct iaxc_audio_driver *d){
120 int alsa_input_level_set(struct iaxc_audio_driver *d, double level){
124 int alsa_output_level_set(struct iaxc_audio_driver *d, double level){
129 /* initialize audio driver */
130 int alsa_initialize (struct iaxc_audio_driver *d ,int sample_rate) {
134 snd_pcm_hw_params_t *hw_params;
135 snd_pcm_sw_params_t *sw_params;
137 if ((err = snd_pcm_open (&stream_out, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
138 fprintf (stderr, "cannot open audio device default (%s)\n",
142 if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
143 fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
147 if ((err = snd_pcm_hw_params_any (stream_out, hw_params)) < 0) {
148 fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
152 if ((err = snd_pcm_hw_params_set_access (stream_out, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
153 fprintf (stderr, "cannot set access type (%s)\n",
157 if ((err = snd_pcm_hw_params_set_format (stream_out, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
158 fprintf (stderr, "cannot set sample format (%s)\n",
162 if ((err = snd_pcm_hw_params_set_rate (stream_out, hw_params, sample_rate, 0)) < 0) {
163 fprintf (stderr, "cannot set sample rate (%s)\n",
167 if ((err = snd_pcm_hw_params_set_channels (stream_out, hw_params, 1)) < 0) {
168 fprintf (stderr, "cannot set channel count (%s)\n",
172 if ((err = snd_pcm_hw_params (stream_out, hw_params)) < 0) {
173 fprintf (stderr, "cannot set parameters (%s)\n",
178 snd_pcm_sw_params_malloc(&sw_params);
180 err = snd_pcm_sw_params_current(stream_out, sw_params);
182 printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
185 err = snd_pcm_sw_params_set_start_threshold(stream_out, sw_params, 80);
187 fprintf(stderr, "Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
190 err = snd_pcm_sw_params(stream_out, sw_params);
192 fprintf(stderr, "Unable to set sw params for playback: %s\n", snd_strerror(err));
196 if ((err = snd_pcm_open (&stream_in, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0) {
197 fprintf (stderr, "cannot open audio device default (%s)\n",
201 if ((err = snd_pcm_hw_params_any (stream_in, hw_params)) < 0) {
202 fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
206 if ((err = snd_pcm_hw_params_set_access (stream_in, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
207 fprintf (stderr, "cannot set access type (%s)\n",
211 if ((err = snd_pcm_hw_params_set_format (stream_in, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
212 fprintf (stderr, "cannot set sample format (%s)\n",
216 if ((err = snd_pcm_hw_params_set_rate (stream_in, hw_params, sample_rate, 0)) < 0) {
217 fprintf (stderr, "cannot set sample rate (%s)\n",
221 if ((err = snd_pcm_hw_params_set_channels (stream_in, hw_params, 1)) < 0) {
222 fprintf (stderr, "cannot set channel count (%s)\n",
226 if ((err = snd_pcm_hw_params (stream_in, hw_params)) < 0) {
227 fprintf (stderr, "cannot set parameters (%s)\n",
232 err = snd_pcm_sw_params_current(stream_in, sw_params);
234 printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
237 err = snd_pcm_sw_params_set_start_threshold(stream_in, sw_params, 80);
239 fprintf(stderr, "Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
242 err = snd_pcm_sw_params(stream_in, sw_params);
244 fprintf(stderr, "Unable to set sw params for playback: %s\n", snd_strerror(err));
249 if ((err = snd_pcm_prepare (stream_in)) < 0) {
250 fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
255 if ((err = snd_pcm_prepare (stream_out)) < 0) {
256 fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
261 d->initialize = alsa_initialize;
262 d->destroy = alsa_destroy;
263 d->select_devices = alsa_select_devices;
264 d->selected_devices = alsa_selected_devices;
265 d->start = alsa_start;
267 d->output = alsa_output;
268 d->input = alsa_input;
269 d->input_level_get = alsa_input_level_get;
270 d->input_level_set = alsa_input_level_set;
271 d->output_level_get = alsa_output_level_get;
272 d->output_level_set = alsa_output_level_set;
273 d->play_sound = alsa_play_sound;
274 d->stop_sound = alsa_stop_sound;