2 * iaxclient: a cross-platform IAX softphone library
5 * Copyright (C) 2003-2006, Horizon Wimba, Inc.
6 * Copyright (C) 2007, Wimba, Inc.
9 * Steve Kann <stevek@stevek.com>
10 * Michael Van Donselaar <mvand@vandonselaar.org>
11 * Shawn Lawrence <shawn.lawrence@terracecomm.com>
12 * Erik Bunce <kde@bunce.us>
14 * This program is free software, distributed under the terms of
15 * the GNU Lesser (Library) General Public License.
17 * Module: audio_portaudio
18 * Purpose: Audio code to provide portaudio driver support for IAX library
19 * Developed by: Shawn Lawrence, Terrace Communications Inc.
20 * Creation Date: April 18, 2003
22 * This library uses the PortAudio Portable Audio Library
23 * For more information see: http://www.portaudio.com/
24 * PortAudio Copyright (c) 1999-2000 Ross Bencina and Phil Burk
28 #if defined(WIN32) || defined(_WIN32_WCE)
30 #define strcasecmp _stricmp
35 #include "audio_portaudio.h"
36 #include "iaxclient_lib.h"
37 #include "ringbuffer.h"
38 #include "portmixer.h"
43 static echo_can_state_t *ec;
49 static echo_can_state_t *ec;
52 #if defined(SPEEX_EC) && ! defined (WIN32)
54 #define restrict __restrict
55 #include "speex/speex_echo.h"
56 static SpeexEchoState *ec;
59 #define EC_RING_SZ 8192 /* must be pow(2) */
64 static PaStream *iStream, *oStream, *aStream;
65 static PxMixer *iMixer = NULL, *oMixer = NULL;
67 static int selectedInput, selectedOutput, selectedRing;
69 static int sample_rate = 8000;
70 static int mixers_initialized;
73 #define MAX_SAMPLE_RATE 48000
75 # define MS_PER_FRAME 40
77 #define SAMPLES_PER_FRAME (MS_PER_FRAME * sample_rate / 1000)
79 /* static frame buffer allocation */
80 #define MAX_SAMPLES_PER_FRAME (MS_PER_FRAME * MAX_SAMPLE_RATE / 1000)
82 /* echo_tail length, in frames must be pow(2) for mec/span ? */
83 #define ECHO_TAIL 4096
85 /* RingBuffer Size; Needs to be Pow(2), 1024 = 512 samples = 64ms */
87 # define OUTRBSZ 32768
90 /* Input ringbuffer size; this doesn't seem to be as critical, and making it big
91 * causes issues when we're answering calls, etc., and the audio system is running
92 * but not being drained */
97 /* TUNING: The following constants may help in tuning for situations
98 * where you are getting audio-level under/overruns.
100 * If you are running iaxclient on a system where you cannot get
101 * low-latency scheduling, you may need to increase these. This tends
102 * to be an issue on non-MacOSX unix systems, when you are not running
103 * as root, and cannot ask the OS for higher priority.
105 * RBOUTTARGET: This a target size of the output ringbuffer, in milliseconds,
106 * where audio for your speakers goes after being decoded and mixed, and
107 * before the audio callback asks for it. It can get larger than this
108 * (up to OUTRBSZ, above), but when it does, for a bit, we will start
109 * dropping some frames. For no drops at all, this needs to be set to
110 * contain the number of samples in your largest scheduling gap
112 * PA_NUMBUFFERS: This is the number of buffers that the low-level
113 * operating system driver will use, for buffering our output (and also
114 * our input) between the soundcard and portaudio. This should also be
115 * set to the maximum scheduling delay. Some drivers, though, will
116 * callback _into_ portaudio with a higher priority, so this doesn't
117 * necessarily need to be as big as RBOUTMAXSZ, although on linux, it
118 * does. The default is to leave this up to portaudio..
121 /* 80ms if average outRing length is more than this many bytes, start dropping */
123 # define RBOUTTARGET (80)
126 /* size in bytes of ringbuffer target */
127 #define RBOUTTARGET_BYTES (RBOUTTARGET * (sample_rate / 1000) * sizeof(SAMPLE))
129 static char inRingBuf[INRBSZ], outRingBuf[OUTRBSZ];
130 static rb_RingBuffer inRing, outRing;
132 static int outRingLenAvg;
134 static int oneStream;
135 static int auxStream;
136 static int virtualMonoIn;
137 static int virtualMonoOut;
138 static int virtualMonoRing;
142 static struct iaxc_sound *sounds;
143 static int nextSoundId = 1;
145 static MUTEX sound_lock;
147 /* forward declarations */
148 static int pa_start (struct iaxc_audio_driver *d );
149 static void handle_paerror(PaError err, char * where);
150 static int pa_input_level_set(struct iaxc_audio_driver *d, float level);
151 static float pa_input_level_get(struct iaxc_audio_driver *d);
153 /* scan devices and stash pointers to dev structures.
154 * But, these structures only remain valid while Pa is initialized,
155 * which, with pablio, is only while it's running!
156 * Also, storing these things in two separate arrays loses the actual
157 * PaDeviceID's associated with devices (since their index in these
158 * input/output arrays isn't the same as their index in the combined
160 static int scan_devices(struct iaxc_audio_driver *d)
165 d->nDevices = nDevices = Pa_GetDeviceCount();
166 d->devices = (struct iaxc_audio_device *)
167 malloc(nDevices * sizeof(struct iaxc_audio_device));
169 for ( i=0; i < nDevices; i++ )
171 const PaDeviceInfo *pa;
172 struct iaxc_audio_device *dev;
174 pa=Pa_GetDeviceInfo(i);
175 dev = &(d->devices[i]);
177 if ( pa ) //frik: under Terminal Services this is NULL
179 dev->name = (char *)pa->name;
181 dev->capabilities = 0;
183 if ( pa->maxInputChannels > 0 )
184 dev->capabilities |= IAXC_AD_INPUT;
186 if ( pa->maxOutputChannels > 0 )
188 dev->capabilities |= IAXC_AD_OUTPUT;
189 dev->capabilities |= IAXC_AD_RING;
192 if ( i == Pa_GetDefaultInputDevice() )
193 dev->capabilities |= IAXC_AD_INPUT_DEFAULT;
195 if ( i == Pa_GetDefaultOutputDevice() )
197 dev->capabilities |= IAXC_AD_OUTPUT_DEFAULT;
198 dev->capabilities |= IAXC_AD_RING_DEFAULT;
201 else //frik: under Terminal Services
203 dev->name = "Not usable device";
205 dev->capabilities = 0;
212 static void mono2stereo(SAMPLE *out, SAMPLE *in, int nSamples)
215 //fprintf(stderr, "mono2stereo: %d samples\n", nSamples);
216 for ( i=0; i < nSamples; i++ )
223 static void stereo2mono(SAMPLE *out, SAMPLE *in, int nSamples)
226 //fprintf(stderr, "stereo2mono: %d samples\n", nSamples);
227 for ( i=0; i < nSamples; i++ )
231 //*(out++) += *(in++);
235 static void mix_slin(short *dst, short *src, int samples, int virtualMono)
238 for ( i=0; i < samples; i++ )
241 val = ((short *)dst)[2*i] + ((short *)src)[i];
243 val = ((short *)dst)[i] + ((short *)src)[i];
248 } else if (val < -0x7fff)
265 static int pa_mix_sounds (void *outputBuffer, unsigned long frames, int channel, int virtualMono)
267 struct iaxc_sound *s;
268 struct iaxc_sound **sp;
269 unsigned long outpos;
271 MUTEXLOCK(&sound_lock);
272 /* mix each sound into the outputBuffer */
279 if ( s->channel == channel )
281 /* loop over the sound until we've played it enough
282 * times, or we've filled the outputBuffer */
287 if ( outpos == frames )
288 break; /* we've filled the buffer */
289 if ( s->pos == s->len )
291 if ( s->repeat == 0 )
293 // XXX free the sound
294 // structure, and maybe the
306 /* how many frames do we add in this loop? */
307 n = (frames - outpos) < (unsigned long)(s->len - s->pos) ?
309 (unsigned long)(s->len - s->pos);
311 /* mix in the frames */
312 mix_slin((short *)outputBuffer + outpos,
313 s->data+s->pos, n, virtualMono);
319 if ( *sp ) /* don't advance if we removed this member */
322 MUTEXUNLOCK(&sound_lock);
326 static int pa_play_sound(struct iaxc_sound *inSound, int ring)
328 struct iaxc_sound *sound;
330 sound = (struct iaxc_sound *)malloc(sizeof(struct iaxc_sound));
336 MUTEXLOCK(&sound_lock);
337 sound->channel = ring;
338 sound->id = nextSoundId++;
341 sound->next = sounds;
343 MUTEXUNLOCK(&sound_lock);
346 pa_start(NULL); /* XXX fixme: start/stop semantics */
351 static int pa_stop_sound(int soundID)
353 struct iaxc_sound **sp;
354 int retval = 1; /* not found */
356 MUTEXLOCK(&sound_lock);
357 for ( sp = &sounds; *sp; (*sp) = (*sp)->next )
359 struct iaxc_sound *s = *sp;
360 if ( s->id == soundID )
364 /* remove from list */
368 retval= 0; /* found */
372 MUTEXUNLOCK(&sound_lock);
374 return retval; /* found? */
377 static void iaxc_echo_can(short *inputBuffer, short *outputBuffer, int n)
379 static rb_RingBuffer ecOutRing;
380 static char outRingBuf[EC_RING_SZ];
381 static long bias = 0;
382 short delayedBuf[1024];
385 /* remove bias -- whether ec is on or not. */
386 for ( i = 0; i < n; i++ )
388 bias += ((((long int) inputBuffer[i]) << 15) - bias) >> 14;
389 inputBuffer[i] -= (short int) (bias >> 15);
392 /* if ec is off, clear ec state -- this way, we start fresh if/when
393 * it's turned back on. */
394 if ( !(iaxc_get_filters() & IAXC_FILTER_ECHO) )
399 #if defined(USE_MEC2) || defined(SPAN_EC)
402 #elif defined(SPEEX_EC)
403 speex_echo_state_destroy(ec);
412 /* we want echo cancellation */
417 rb_InitializeRingBuffer(&ecOutRing, EC_RING_SZ, &outRingBuf);
418 #if defined(USE_MEC2) || defined(SPAN_EC)
419 ec = echo_can_create(ECHO_TAIL, 0);
420 #elif defined(SPEEX_EC)
421 ec = speex_echo_state_init(SAMPLES_PER_FRAME, ECHO_TAIL);
427 rb_WriteRingBuffer(&ecOutRing, outputBuffer, n * 2);
429 // Make sure we have enough buffer.
430 // Currently, just one SAMPLES_PER_FRAME's worth.
431 if ( rb_GetRingBufferReadAvailable(&ecOutRing) < ((n + SAMPLES_PER_FRAME) * 2) )
434 rb_ReadRingBuffer(&ecOutRing, delayedBuf, n * 2);
436 #if defined(DO_EC) && defined(SPEEX_EC)
438 short cancelledBuffer[1024];
440 speex_echo_cancel(ec, inputBuffer, delayedBuf,
441 cancelledBuffer, NULL);
443 for ( i = 0; i < n; i++ )
444 inputBuffer[i] = cancelledBuffer[i];
448 #if defined(USE_MEC2) || defined(SPAN_EC)
449 for ( i = 0; i < n; i++ )
450 inputBuffer[i] = echo_can_update(ec, delayedBuf[i],
455 static int pa_callback(void *inputBuffer, void *outputBuffer,
456 unsigned long samplesPerFrame,
457 const PaStreamCallbackTimeInfo* outTime,
458 PaStreamCallbackFlags statusFlags,
461 int totBytes = samplesPerFrame * sizeof(SAMPLE);
463 short virtualInBuffer[MAX_SAMPLES_PER_FRAME * 2];
464 short virtualOutBuffer[MAX_SAMPLES_PER_FRAME * 2];
467 /* I think this can't happen */
468 if(virtualMono && samplesPerFrame > SAMPLES_PER_FRAME) {
469 fprintf(stderr, "ERROR: buffer in callback is too big!\n");
477 /* output underflow might happen here */
480 bWritten = rb_ReadRingBuffer(&outRing, virtualOutBuffer,
482 /* we zero "virtualOutBuffer", then convert the whole thing,
483 * yes, because we use virtualOutBuffer for ec below */
484 if ( bWritten < totBytes )
486 memset(((char *)virtualOutBuffer) + bWritten,
487 0, totBytes - bWritten);
488 //fprintf(stderr, "*U*");
490 mono2stereo((SAMPLE *)outputBuffer, virtualOutBuffer,
495 bWritten = rb_ReadRingBuffer(&outRing, outputBuffer, totBytes);
496 if ( bWritten < totBytes)
498 memset((char *)outputBuffer + bWritten,
499 0, totBytes - bWritten);
500 //fprintf(stderr, "*U*");
504 /* zero underflowed space [ silence might be more golden
507 pa_mix_sounds(outputBuffer, samplesPerFrame, 0, virtualMonoOut);
510 pa_mix_sounds(outputBuffer, samplesPerFrame, 1, virtualMonoOut);
516 /* input overflow might happen here */
519 stereo2mono(virtualInBuffer, (SAMPLE *)inputBuffer,
521 iaxc_echo_can(virtualInBuffer, virtualOutBuffer,
524 rb_WriteRingBuffer(&inRing, virtualInBuffer, totBytes);
528 iaxc_echo_can((short *)inputBuffer,
529 (short *)outputBuffer,
532 rb_WriteRingBuffer(&inRing, inputBuffer, totBytes);
539 static int pa_aux_callback(void *inputBuffer, void *outputBuffer,
540 unsigned long samplesPerFrame,
541 const PaStreamCallbackTimeInfo* outTime,
542 PaStreamCallbackFlags statusFlags,
545 int totBytes = samplesPerFrame * sizeof(SAMPLE) * (virtualMonoRing + 1);
549 memset((char *)outputBuffer, 0, totBytes);
550 pa_mix_sounds(outputBuffer, samplesPerFrame, 1, virtualMonoRing);
555 static int pa_open(int single, int inMono, int outMono)
558 PaDeviceInfo *result;
560 struct PaStreamParameters in_stream_params, out_stream_params, no_device;
561 in_stream_params.device = selectedInput;
562 in_stream_params.channelCount = (inMono ? 1 : 2);
563 in_stream_params.sampleFormat = paInt16;
564 result = (PaDeviceInfo *)Pa_GetDeviceInfo(selectedInput);
565 if ( result == NULL ) return -1;
566 in_stream_params.suggestedLatency = result->defaultLowInputLatency;
567 in_stream_params.hostApiSpecificStreamInfo = NULL;
569 out_stream_params.device = selectedOutput;
570 out_stream_params.channelCount = (outMono ? 1 : 2);
571 out_stream_params.sampleFormat = paInt16;
572 result = (PaDeviceInfo *)Pa_GetDeviceInfo(selectedOutput);
573 if ( result == NULL ) return -1;
574 out_stream_params.suggestedLatency = result->defaultLowOutputLatency;
575 out_stream_params.hostApiSpecificStreamInfo = NULL;
577 no_device.device = paNoDevice;
578 no_device.channelCount = 0;
579 no_device.sampleFormat = paInt16;
580 result = (PaDeviceInfo *)Pa_GetDeviceInfo(selectedInput);
581 if ( result == NULL ) return -1;
582 no_device.suggestedLatency = result->defaultLowInputLatency; // FEEDBACK - unsure if appropriate
583 no_device.hostApiSpecificStreamInfo = NULL;
587 err = Pa_OpenStream(&iStream,
591 paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate
593 (PaStreamCallback *)pa_callback,
595 if (err != paNoError) return -1;
600 err = Pa_OpenStream(&iStream,
604 paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate
606 (PaStreamCallback *)pa_callback,
608 if ( err != paNoError ) return -1;
610 err = Pa_OpenStream(&oStream,
614 paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate
616 (PaStreamCallback *)pa_callback,
619 if ( err != paNoError )
621 Pa_CloseStream(iStream);
628 virtualMonoIn = (inMono ? 0 : 1);
629 virtualMonoOut = (outMono ? 0 : 1);
633 /* some commentary here:
634 * 1: MacOSX: MacOSX often needs "virtual mono" and a single stream.
635 * That doesn't work for some USB devices (a Platronics headset), so
636 * mono in, virtual mono out, and mono in/out are also tried.
638 * 2: Unix/OSS: most cards are OK with real mono, and a single stream.
639 * Except some. For those, a single open with real mono will succeed,
640 * but execution will fail. Maybe others will open OK with a single
641 * stream, and real mono, but fail later? Two stream mono is tried first,
642 * since it reportedly provides better sound quality with ALSA
643 * and Sound Blaster Live.
645 * The failure mode I saw with a volunteer was that reads/writes would
646 * return -enodev (down in the portaudio code). Bummer.
648 * Win32 works fine, in all cases, with a single stream and real mono,
651 * We could probably do this more cleanly, because there are still cases
652 * where we will fail (i.e. if the user has only mono in and out on a Mac).
655 static int pa_openstreams (struct iaxc_audio_driver *d )
660 err = pa_open(0, 1, 1) && /* two stream mono */
661 pa_open(1, 1, 1) && /* one stream mono */
662 pa_open(0, 0, 0); /* two stream stereo */
665 err = pa_open(1, 0, 0) && /* one stream stereo */
666 pa_open(1, 1, 0) && /* one stream mono in stereo out */
667 pa_open(1, 1, 1) && /* one stream mono */
668 pa_open(0, 0, 0); /* two stream stereo */
670 err = pa_open(1, 1, 1) && /* one stream mono */
671 pa_open(1, 0, 0) && /* one stream stereo */
672 pa_open(1, 1, 0) && /* one stream mono in stereo out */
673 pa_open(0, 0, 0); /* two stream stereo */
679 handle_paerror(err, "Unable to open streams");
685 static int pa_openauxstream (struct iaxc_audio_driver *d )
689 struct PaStreamParameters ring_stream_params;
691 // setup the ring parameters
692 ring_stream_params.device = selectedRing;
693 ring_stream_params.sampleFormat = paInt16;
694 ring_stream_params.suggestedLatency =
695 Pa_GetDeviceInfo(selectedRing)->defaultLowOutputLatency;
696 ring_stream_params.hostApiSpecificStreamInfo = NULL;
698 // first we'll try mono
699 ring_stream_params.channelCount = 1;
701 err = Pa_OpenStream(&aStream,
705 paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate
707 (PaStreamCallback *)pa_aux_callback,
710 if ( err != paNoError )
712 // next we'll try virtual mono (stereo)
713 ring_stream_params.channelCount = 1;
715 err = Pa_OpenStream(&aStream,
719 paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate
721 (PaStreamCallback *)pa_aux_callback,
726 if ( err != paNoError )
728 // fprintf(stderr, "Failure opening ring device with params: id: %d, output %d, default output %d\n",
729 // selectedRing, selectedOutput, Pa_GetDefaultOutputDevice());
731 handle_paerror(err, "opening separate ring stream");
735 // Determine whether virtual mono is being used
736 virtualMonoRing = ring_stream_params.channelCount - 1;
741 static int pa_start(struct iaxc_audio_driver *d)
743 static int errcnt = 0;
748 /* re-open mixers if necessary */
751 Px_CloseMixer(iMixer);
757 Px_CloseMixer(oMixer);
763 iaxci_usermsg(IAXC_TEXT_TYPE_FATALERROR,
764 "iaxclient audio: Can't open Audio Device. "
765 "Perhaps you do not have an input or output device?");
766 /* OK, we'll give the application the option to abort or
767 * not here, but we will throw a fatal error anyway */
768 iaxc_millisleep(1000);
769 //return -1; // Give Up. Too many errors.
772 /* flush the ringbuffers */
773 rb_InitializeRingBuffer(&inRing, INRBSZ, inRingBuf);
774 rb_InitializeRingBuffer(&outRing, OUTRBSZ, outRingBuf);
776 if ( pa_openstreams(d) )
782 errcnt = 0; // only count consecutive errors.
784 if ( Pa_StartStream(iStream) != paNoError )
787 iMixer = Px_OpenMixer(iStream, 0);
791 PaError err = Pa_StartStream(oStream);
792 oMixer = Px_OpenMixer(oStream, 0);
793 if ( err != paNoError )
795 Pa_StopStream(iStream);
800 if ( selectedRing != selectedOutput )
812 if ( Pa_StartStream(aStream) != paNoError )
818 /* select the microphone as the input source */
819 if ( iMixer != NULL && !mixers_initialized )
821 /* First, select the "microphone" device, if it's available */
822 /* try the new method, reverting to the old if it fails */
823 if ( Px_SetCurrentInputSourceByName( iMixer, "microphone" ) != 0 )
825 int n = Px_GetNumInputSources( iMixer ) - 1;
828 if ( !strcasecmp("microphone",
829 Px_GetInputSourceName(iMixer, n)) )
831 Px_SetCurrentInputSource( iMixer, n );
836 /* try to set the microphone boost -- we just turn off this
837 * "boost" feature, because it often leads to clipping, which
838 * we can't fix later -- but we can deal with low input levels
839 * much more gracefully */
840 Px_SetMicrophoneBoost( iMixer, 0 );
842 /* If the input level is very low, raise it up a bit.
843 * Otherwise, AGC cannot detect speech, and cannot adjust
845 if ( pa_input_level_get(d) < 0.5f )
846 pa_input_level_set(d, 0.6f);
847 mixers_initialized = 1;
854 static int pa_stop (struct iaxc_audio_driver *d )
864 err = Pa_AbortStream(iStream);
865 err = Pa_CloseStream(iStream);
869 err = Pa_AbortStream(oStream);
870 err = Pa_CloseStream(oStream);
875 err = Pa_AbortStream(aStream);
876 err = Pa_CloseStream(aStream);
883 /* Mihai: apparently nobody loves this function. Some actually hate it.
884 * I bet if it's gone, no one will miss it. Such a cold, cold world!
885 static void pa_shutdown()
887 CloseAudioStream( iStream );
888 if(!oneStream) CloseAudioStream( oStream );
889 if(auxStream) CloseAudioStream( aStream );
893 static void handle_paerror(PaError err, char * where)
895 fprintf(stderr, "PortAudio error at %s: %s\n", where,
896 Pa_GetErrorText(err));
899 static int pa_input(struct iaxc_audio_driver *d, void *samples, int *nSamples)
903 bytestoread = *nSamples * sizeof(SAMPLE);
905 /* we don't return partial buffers */
906 if ( rb_GetRingBufferReadAvailable(&inRing) < bytestoread )
912 rb_ReadRingBuffer(&inRing, samples, bytestoread);
917 static int pa_output(struct iaxc_audio_driver *d, void *samples, int nSamples)
919 int bytestowrite = nSamples * sizeof(SAMPLE);
922 outRingLen = rb_GetRingBufferReadAvailable(&outRing);
923 outRingLenAvg = (outRingLenAvg * 9 + outRingLen ) / 10;
925 /* if we've got a big output buffer, drop this */
926 if (outRingLen > (int)RBOUTTARGET_BYTES &&
927 outRingLenAvg > (int)RBOUTTARGET_BYTES)
929 //fprintf(stderr, "*O*");
933 //if(rb_GetRingBufferWriteAvailable(&outRing) < bytestowrite)
934 // fprintf(stderr, "O");
936 rb_WriteRingBuffer(&outRing, samples, bytestowrite);
938 return (outRingLen + bytestowrite)/2;
942 static int pa_select_devices(struct iaxc_audio_driver *d, int input,
943 int output, int ring)
945 selectedInput = input;
946 selectedOutput = output;
950 /* stop/start audio, in order to switch devices */
956 /* start/stop audio, in order to initialize mixers and levels */
963 static int pa_selected_devices(struct iaxc_audio_driver *d, int *input,
964 int *output, int *ring)
966 *input = selectedInput;
967 *output = selectedOutput;
968 *ring = selectedRing;
972 static int pa_destroy(struct iaxc_audio_driver *d)
976 Px_CloseMixer(iMixer);
981 Px_CloseMixer(oMixer);
992 return Pa_Terminate();
995 static float pa_input_level_get(struct iaxc_audio_driver *d)
997 /* iMixer should be non-null if we using either one or two streams */
1001 /* make sure this device supports input volume controls */
1002 if ( Px_GetNumInputSources( iMixer ) == 0 )
1005 return Px_GetInputVolume(iMixer);
1008 static float pa_output_level_get(struct iaxc_audio_driver *d)
1012 /* oMixer may be null if we're using one stream,
1013 in which case, iMixer should not be null,
1014 if it is, return an error */
1023 /* prefer the pcm output, but default to the master output */
1024 if ( Px_SupportsPCMOutputVolume(mix) )
1025 return Px_GetPCMOutputVolume(mix);
1027 return Px_GetMasterVolume(mix);
1030 static int pa_input_level_set(struct iaxc_audio_driver *d, float level)
1032 /* make sure this device supports input volume controls */
1033 if ( !iMixer || Px_GetNumInputSources(iMixer) == 0 )
1036 Px_SetInputVolume(iMixer, level);
1041 static int pa_output_level_set(struct iaxc_audio_driver *d, float level)
1052 /* prefer the pcm output, but default to the master output */
1053 if ( Px_SupportsPCMOutputVolume(mix) )
1054 Px_SetPCMOutputVolume(mix, level);
1056 Px_SetMasterVolume(mix, level);
1061 static int pa_mic_boost_get(struct iaxc_audio_driver* d)
1066 return Px_GetMicrophoneBoost(iMixer);
1069 int pa_mic_boost_set(struct iaxc_audio_driver* d, int enable)
1074 return Px_SetMicrophoneBoost(iMixer, enable);
1077 /* initialize audio driver */
1078 static int _pa_initialize (struct iaxc_audio_driver *d, int sr)
1084 /* initialize portaudio */
1085 if ( paNoError != (err = Pa_Initialize()) )
1087 iaxci_usermsg(IAXC_TEXT_TYPE_ERROR, "Failed Pa_Initialize");
1095 d->initialize = pa_initialize;
1096 d->destroy = pa_destroy;
1097 d->select_devices = pa_select_devices;
1098 d->selected_devices = pa_selected_devices;
1099 d->start = pa_start;
1101 d->output = pa_output;
1102 d->input = pa_input;
1103 d->input_level_get = pa_input_level_get;
1104 d->input_level_set = pa_input_level_set;
1105 d->output_level_get = pa_output_level_get;
1106 d->output_level_set = pa_output_level_set;
1107 d->play_sound = pa_play_sound;
1108 d->stop_sound = pa_stop_sound;
1109 d->mic_boost_get = pa_mic_boost_get;
1110 d->mic_boost_set = pa_mic_boost_set;
1112 /* setup private data stuff */
1113 selectedInput = Pa_GetDefaultInputDevice();
1114 selectedOutput = Pa_GetDefaultOutputDevice();
1115 selectedRing = Pa_GetDefaultOutputDevice();
1117 MUTEXINIT(&sound_lock);
1119 rb_InitializeRingBuffer(&inRing, INRBSZ, inRingBuf);
1120 rb_InitializeRingBuffer(&outRing, OUTRBSZ, outRingBuf);
1127 /* standard initialization: Do the normal initialization, and then
1128 also initialize mixers and levels */
1129 int pa_initialize(struct iaxc_audio_driver *d, int sr)
1131 _pa_initialize(d, sr);
1133 /* TODO: Kludge alert. We only do the funny audio start-stop
1134 * business if iaxci_audio_output_mode is not set. This is a
1135 * hack to allow certain specific users of iaxclient to avoid
1136 * certain problems associated with portaudio initialization
1137 * hitting a deadlock condition.
1139 if ( iaxci_audio_output_mode )
1142 /* start/stop audio, in order to initialize mixers and levels */
1149 /* alternate initialization: delay mixer/level initialization until
1150 we actually start the device. This is somewhat useful when you're about to start
1151 the device as soon as you've initialized it, and want to avoid the time it
1152 takes to start/stop the device before starting it again */
1153 int pa_initialize_deferred(struct iaxc_audio_driver *d, int sr)
1155 _pa_initialize(d, sr);