From: <do...@us...> - 2007-10-01 05:23:08
|
Revision: 1162 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1162&view=rev Author: dohpaz Date: 2007-09-30 22:23:11 -0700 (Sun, 30 Sep 2007) Log Message: ----------- See any operating system documentation about shared libraries for Improved handling of aux device for ring in portable audio. + Don't assume that just because the output device uses virtual mono (stereo) that the ring output device will. + Start out trying to open the ring device as mono, then fall back to stereo + Don't specify an input device (pass in NULL as per PortAudio V19 docs). + Properly handle virtual mono in pa_aux_callback. Modified Paths: -------------- trunk/lib/audio_portaudio.c Modified: trunk/lib/audio_portaudio.c =================================================================== --- trunk/lib/audio_portaudio.c 2007-09-26 20:11:06 UTC (rev 1161) +++ trunk/lib/audio_portaudio.c 2007-10-01 05:23:11 UTC (rev 1162) @@ -131,6 +131,7 @@ static int auxStream; static int virtualMonoIn; static int virtualMonoOut; +static int virtualMonoRing; static int running; @@ -227,12 +228,12 @@ } } -static void mix_slin(short *dst, short *src, int samples) +static void mix_slin(short *dst, short *src, int samples, int virtualMono) { int i=0,val=0; for ( i=0; i < samples; i++ ) { - if ( virtualMonoOut ) + if ( virtualMono ) val = ((short *)dst)[2*i] + ((short *)src)[i]; else val = ((short *)dst)[i] + ((short *)src)[i]; @@ -245,7 +246,7 @@ val = -0x7fff+1; } - if ( virtualMonoOut ) + if ( virtualMono ) { dst[2*i] = val; dst[2*i+1] = val; @@ -257,7 +258,7 @@ } } -static int pa_mix_sounds (void *outputBuffer, unsigned long frames, int channel) +static int pa_mix_sounds (void *outputBuffer, unsigned long frames, int channel, int virtualMono) { struct iaxc_sound *s; struct iaxc_sound **sp; @@ -305,7 +306,7 @@ /* mix in the frames */ mix_slin((short *)outputBuffer + outpos, - s->data+s->pos, n); + s->data+s->pos, n, virtualMono); s->pos += n; outpos += n; @@ -497,10 +498,10 @@ /* zero underflowed space [ silence might be more golden * than garbage? ] */ - pa_mix_sounds(outputBuffer, samplesPerFrame, 0); + pa_mix_sounds(outputBuffer, samplesPerFrame, 0, virtualMonoOut); if(!auxStream) - pa_mix_sounds(outputBuffer, samplesPerFrame, 1); + pa_mix_sounds(outputBuffer, samplesPerFrame, 1, virtualMonoOut); } @@ -535,13 +536,12 @@ PaStreamCallbackFlags statusFlags, void *userData) { - int totBytes = samplesPerFrame * sizeof(SAMPLE); + int totBytes = samplesPerFrame * sizeof(SAMPLE) * (virtualMonoRing + 1); - /* XXX: need to handle virtualMonoOut case!!! */ if ( outputBuffer ) { memset((char *)outputBuffer, 0, totBytes); - pa_mix_sounds(outputBuffer, samplesPerFrame, 1); + pa_mix_sounds(outputBuffer, samplesPerFrame, 1, virtualMonoRing); } return 0; } @@ -680,36 +680,20 @@ { PaError err; - /* FEEDBACK - iaxclient seems to assume that the ring device is a - * mono device. I can't find any mono devices on the Mac and so - * ring device opening will fail. My code assumes the ring device - * is a stereo device - this might break stuff */ - struct PaStreamParameters ring_stream_params, no_device; + struct PaStreamParameters ring_stream_params; - struct PaStreamParameters in_stream_params; - in_stream_params.device = selectedInput; - in_stream_params.channelCount = virtualMonoOut + 1; - in_stream_params.sampleFormat = paInt16; - in_stream_params.suggestedLatency = - Pa_GetDeviceInfo(selectedInput)->defaultLowInputLatency; - in_stream_params.hostApiSpecificStreamInfo = NULL; - + // setup the ring parameters ring_stream_params.device = selectedRing; - ring_stream_params.channelCount = virtualMonoOut+1; ring_stream_params.sampleFormat = paInt16; ring_stream_params.suggestedLatency = Pa_GetDeviceInfo(selectedRing)->defaultLowOutputLatency; ring_stream_params.hostApiSpecificStreamInfo = NULL; - no_device.device = paNoDevice; - no_device.channelCount = 0; - no_device.sampleFormat = paInt16; - no_device.suggestedLatency = - Pa_GetDeviceInfo(selectedInput)->defaultLowInputLatency; //TODOC - no_device.hostApiSpecificStreamInfo = NULL; + // first we'll try mono + ring_stream_params.channelCount = 1; err = Pa_OpenStream ( &aStream, - &in_stream_params, + NULL, &ring_stream_params, sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate @@ -719,28 +703,33 @@ if ( err != paNoError ) { - /* FEEDBACK, we try one more time, maybe ring device is a mono - * output device */ - err = Pa_OpenStream ( &aStream, - &no_device, + // next we'll try virtual mono (stereo) + ring_stream_params.channelCount = 1; + + err = Pa_OpenStream ( &aStream, + NULL, &ring_stream_params, sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate - paNoFlag, /* flags */ + paNoFlag, (PaStreamCallback *)pa_aux_callback, NULL); + } // mmok, failure... if ( err != paNoError ) { - //fprintf(stderr, "Failure opening ring device with params: id: %d, output %d, default output %d\n", - //selectedRing, selectedOutput, Pa_GetDefaultOutputDevice()); + // fprintf(stderr, "Failure opening ring device with params: id: %d, output %d, default output %d\n", + // selectedRing, selectedOutput, Pa_GetDefaultOutputDevice()); handle_paerror(err, "opening separate ring stream"); return -1; } + // Determine whether virtual mono is being used + virtualMonoRing = ring_stream_params.channelCount - 1; + return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |