/[pcsx2_0.9.7]/trunk/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core.c
ViewVC logotype

Diff of /trunk/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

--- trunk/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core.c	2010/11/12 00:35:47	272
+++ trunk/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core.c	2010/11/12 01:10:22	273
@@ -15,7 +15,7 @@
  * Olivier Tristan for feedback and testing
  * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
  * interface.
- *
+ * 
  *
  * Based on the Open Source API proposed by Ross Bencina
  * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
@@ -41,13 +41,13 @@
  */
 
 /*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however, 
  * the PortAudio community also makes the following non-binding requests:
  *
  * Any person wishing to distribute modifications to the Software is
  * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also 
+ * requested that these non-binding requests be included along with the 
  * license above.
  */
 
@@ -249,7 +249,6 @@
 static PaError IsStreamStopped( PaStream *s );
 static PaError IsStreamActive( PaStream *stream );
 static PaTime GetStreamTime( PaStream *stream );
-static void setStreamStartTime( PaStream *stream );
 static OSStatus AudioIOProc( void *inRefCon,
                                AudioUnitRenderActionFlags *ioActionFlags,
                                const AudioTimeStamp *inTimeStamp,
@@ -373,7 +372,7 @@
                 break;
              }
        }
-    }
+    }   
     if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
                      &size,
                      &auhalHostApi->defaultOut) ) {
@@ -390,7 +389,7 @@
                 break;
              }
        }
-    }
+    }   
 
     VDBUG( ( "Default in : %ld\n", auhalHostApi->defaultIn  ) );
     VDBUG( ( "Default out: %ld\n", auhalHostApi->defaultOut ) );
@@ -433,7 +432,7 @@
         deviceInfo->maxInputChannels = numChannels;
     else
         deviceInfo->maxOutputChannels = numChannels;
-
+      
     if (numChannels > 0) /* do not try to retrieve the latency if there is no channels. */
     {
        /* Get the latency.  Don't fail if we can't get this. */
@@ -535,12 +534,12 @@
     int unixErr;
 
     VVDBUG(("PaMacCore_Initialize(): hostApiIndex=%d\n", hostApiIndex));
-
+	
 	SInt32 major;
 	SInt32 minor;
 	Gestalt(gestaltSystemVersionMajor, &major);
 	Gestalt(gestaltSystemVersionMinor, &minor);
-
+	
 	// Starting with 10.6 systems, the HAL notification thread is created internally
 	if (major == 10 && minor >= 6) {
 		CFRunLoopRef theRunLoop = NULL;
@@ -550,7 +549,7 @@
 			goto error;
 		}
 	}
-
+	
     unixErr = initializeXRunListenerList();
     if( 0 != unixErr ) {
        return UNIX_ERR(unixErr);
@@ -586,7 +585,7 @@
     (*hostApi)->info.defaultInputDevice = paNoDevice;
     (*hostApi)->info.defaultOutputDevice = paNoDevice;
 
-    (*hostApi)->info.deviceCount = 0;
+    (*hostApi)->info.deviceCount = 0;  
 
     if( auhalHostApi->devCount > 0 )
     {
@@ -665,7 +664,7 @@
             PaUtil_FreeAllAllocations( auhalHostApi->allocations );
             PaUtil_DestroyAllocationGroup( auhalHostApi->allocations );
         }
-
+                
         PaUtil_FreeMemory( auhalHostApi );
     }
     return result;
@@ -714,7 +713,7 @@
                 outputParameters ? outputParameters->channelCount : -1,
                 outputParameters ? outputParameters->sampleFormat : -1,
                 (float) sampleRate ));
-
+ 
     /** These first checks are standard PA checks. We do some fancier checks
         later. */
     if( inputParameters )
@@ -726,7 +725,7 @@
             this implementation doesn't support any custom sample formats */
         if( inputSampleFormat & paCustomFormat )
             return paSampleFormatNotSupported;
-
+            
         /* unless alternate device specification is supported, reject the use of
             paUseHostApiSpecificDeviceSpecification */
 
@@ -751,7 +750,7 @@
             this implementation doesn't support any custom sample formats */
         if( outputSampleFormat & paCustomFormat )
             return paSampleFormatNotSupported;
-
+            
         /* unless alternate device specification is supported, reject the use of
             paUseHostApiSpecificDeviceSpecification */
 
@@ -767,7 +766,7 @@
     {
         outputChannelCount = 0;
     }
-
+ 
     /* FEEDBACK */
     /*        I think the only way to check a given format SR combo is     */
     /*        to try opening it. This could be disruptive, is that Okay?   */
@@ -785,7 +784,7 @@
        if( err != paNoError && err != paInvalidSampleRate )
           DBUG( ( "OpenStream @ %g returned: %d: %s\n",
                   (float) sampleRate, err, Pa_GetErrorText( err ) ) );
-       if( err )
+       if( err ) 
           return err;
        err = CloseStream( s );
        if( err ) {
@@ -798,6 +797,75 @@
     return paFormatIsSupported;
 }
 
+
+static void UpdateReciprocalOfActualOutputSampleRateFromDeviceProperty( PaMacCoreStream *stream )
+{
+	/* FIXME: not sure if this should be the sample rate of the output device or the output unit */
+	Float64 actualOutputSampleRate = stream->outDeviceSampleRate;
+	UInt32 propSize = sizeof(Float64);
+	OSStatus osErr = AudioDeviceGetProperty( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyActualSampleRate, &propSize, &actualOutputSampleRate);
+	if( osErr != noErr || actualOutputSampleRate < .01 ) // avoid divide by zero if there's an error
+		actualOutputSampleRate = stream->outDeviceSampleRate;
+	
+	stream->recipricalOfActualOutputSampleRate = 1. / actualOutputSampleRate;
+}
+
+static OSStatus AudioDevicePropertyActualSampleRateListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData )
+{
+	PaMacCoreStream *stream = (PaMacCoreStream*)inClientData;
+	
+	pthread_mutex_lock( &stream->timingInformationMutex );
+	UpdateReciprocalOfActualOutputSampleRateFromDeviceProperty( stream );
+	pthread_mutex_unlock( &stream->timingInformationMutex );
+
+	return noErr;
+}
+
+static void UpdateOutputLatencySamplesFromDeviceProperty( PaMacCoreStream *stream )
+{
+	UInt32 deviceOutputLatencySamples = 0;
+	UInt32 propSize = sizeof(UInt32);
+	OSStatus osErr = AudioDeviceGetProperty( stream->outputDevice, 0, /* isInput= */ FALSE, kAudioDevicePropertyLatency, &propSize, &deviceOutputLatencySamples);
+	if( osErr != noErr )
+		deviceOutputLatencySamples = 0;
+	
+	stream->deviceOutputLatencySamples = deviceOutputLatencySamples;
+}
+
+static OSStatus AudioDevicePropertyOutputLatencySamplesListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData )
+{
+	PaMacCoreStream *stream = (PaMacCoreStream*)inClientData;
+	
+	pthread_mutex_lock( &stream->timingInformationMutex );
+	UpdateOutputLatencySamplesFromDeviceProperty( stream );
+	pthread_mutex_unlock( &stream->timingInformationMutex );
+
+	return noErr;
+}
+
+static void UpdateInputLatencySamplesFromDeviceProperty( PaMacCoreStream *stream )
+{
+	UInt32 deviceInputLatencySamples = 0;
+	UInt32 propSize = sizeof(UInt32);
+	OSStatus osErr = AudioDeviceGetProperty( stream->inputDevice, 0, /* isInput= */ TRUE, kAudioDevicePropertyLatency, &propSize, &deviceInputLatencySamples);
+	if( osErr != noErr )
+		deviceInputLatencySamples = 0;
+	
+	stream->deviceInputLatencySamples = deviceInputLatencySamples;
+}
+
+static OSStatus AudioDevicePropertyInputLatencySamplesListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData )
+{
+	PaMacCoreStream *stream = (PaMacCoreStream*)inClientData;
+	
+	pthread_mutex_lock( &stream->timingInformationMutex );
+	UpdateInputLatencySamplesFromDeviceProperty( stream );
+	pthread_mutex_unlock( &stream->timingInformationMutex );
+
+	return noErr;
+}
+
+
 static PaError OpenAndSetupOneAudioUnit(
                                    const PaMacCoreStream *stream,
                                    const PaStreamParameters *inStreamParams,
@@ -861,7 +929,7 @@
        outChannelMap = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo)
                   ->channelMap;
        outChannelMapSize = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo)
-                  ->channelMapSize;
+                  ->channelMapSize; 
     }
     /* Override user's flags here, if desired for testing. */
 
@@ -1166,7 +1234,7 @@
                   (float)sourceFormat.mSampleRate,
                   (float)desiredFormat.mSampleRate ) );
           /* create our converter */
-          ERR_WRAP( AudioConverterNew(
+          ERR_WRAP( AudioConverterNew( 
                              &sourceFormat,
                              &desiredFormat,
                              srConverter ) );
@@ -1302,7 +1370,7 @@
     {
         outputChannelCount = outputParameters->channelCount;
         outputSampleFormat = outputParameters->sampleFormat;
-
+        
         /* unless alternate device specification is supported, reject the use of
             paUseHostApiSpecificDeviceSpecification */
 
@@ -1356,6 +1424,7 @@
     stream->inputFramesPerBuffer = 0;
     stream->outputFramesPerBuffer = 0;
     stream->bufferProcessorIsInitialized = FALSE;
+	stream->timingInformationMutexIsInitialized = 0;
 
     /* assert( streamCallback ) ; */ /* only callback mode is implemented */
     if( streamCallback )
@@ -1517,7 +1586,7 @@
           result = paInsufficientMemory;
           goto error;
        }
-
+        
        /*
         * If input and output devs are different or we are doing SR conversion,
         * we also need a
@@ -1656,7 +1725,39 @@
     stream->userInChan  = inputChannelCount;
     stream->userOutChan = outputChannelCount;
 
-    stream->isTimeSet   = FALSE;
+	pthread_mutex_init( &stream->timingInformationMutex, NULL );
+	stream->timingInformationMutexIsInitialized = 1;
+	
+	if( stream->outputUnit ) {
+		UpdateReciprocalOfActualOutputSampleRateFromDeviceProperty( stream );
+		stream->recipricalOfActualOutputSampleRate_ioProcCopy = stream->recipricalOfActualOutputSampleRate;
+		
+		AudioDeviceAddPropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyActualSampleRate, 
+									   AudioDevicePropertyActualSampleRateListenerProc, stream );
+									   		
+		UpdateOutputLatencySamplesFromDeviceProperty( stream );
+		stream->deviceOutputLatencySamples_ioProcCopy = stream->deviceOutputLatencySamples;
+		
+		AudioDeviceAddPropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyLatency, 
+									   AudioDevicePropertyOutputLatencySamplesListenerProc, stream );
+		
+	}else{
+		stream->recipricalOfActualOutputSampleRate = 1.;
+		stream->recipricalOfActualOutputSampleRate_ioProcCopy = 0.;
+		stream->deviceOutputLatencySamples_ioProcCopy = 0;
+	}
+	
+	if( stream->inputUnit ) {
+		UpdateInputLatencySamplesFromDeviceProperty( stream );
+		stream->deviceInputLatencySamples_ioProcCopy = stream->deviceInputLatencySamples;
+		
+		AudioDeviceAddPropertyListener( stream->inputDevice, 0, /* isInput = */ TRUE, kAudioDevicePropertyLatency, 
+									   AudioDevicePropertyInputLatencySamplesListenerProc, stream );
+	}else{
+		stream->deviceInputLatencySamples = 0;
+		stream->deviceInputLatencySamples_ioProcCopy = 0;
+	}
+	
     stream->state = STOPPED;
     stream->xrunFlags = 0;
 
@@ -1669,63 +1770,19 @@
     return result;
 }
 
-PaTime GetStreamTime( PaStream *s )
-{
-   /* FIXME: I am not at all sure this timing info stuff is right.
-             patest_sine_time reports negative latencies, which is wierd.*/
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    AudioTimeStamp timeStamp;
-
-    VVDBUG(("GetStreamTime()\n"));
-
-    if ( !stream->isTimeSet )
-        return (PaTime)0;
 
-    if ( stream->outputDevice ) {
-        AudioDeviceGetCurrentTime( stream->outputDevice, &timeStamp);
-        return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->outDeviceSampleRate;
-    } else if ( stream->inputDevice ) {
-        AudioDeviceGetCurrentTime( stream->inputDevice, &timeStamp);
-    return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->inDeviceSampleRate;
-    } else {
-        return (PaTime)0;
-    }
-}
+#define HOST_TIME_TO_PA_TIME( x ) ( AudioConvertHostTimeToNanos( (x) ) * 1.0E-09) /* convert to nanoseconds and then to seconds */
 
-static void setStreamStartTime( PaStream *stream )
-{
-   /* FIXME: I am not at all sure this timing info stuff is right.
-             patest_sine_time reports negative latencies, which is wierd.*/
-   PaMacCoreStream *s = (PaMacCoreStream *) stream;
-   VVDBUG(("setStreamStartTime()\n"));
-   if( s->outputDevice )
-      AudioDeviceGetCurrentTime( s->outputDevice, &s->startTime);
-   else if( s->inputDevice )
-      AudioDeviceGetCurrentTime( s->inputDevice, &s->startTime);
-   else
-      bzero( &s->startTime, sizeof( s->startTime ) );
-
-   //FIXME: we need a memory barier here
-
-   s->isTimeSet = TRUE;
-}
-
-
-static PaTime TimeStampToSecs(PaMacCoreStream *stream, const AudioTimeStamp* timeStamp)
+PaTime GetStreamTime( PaStream *s )
 {
-    VVDBUG(("TimeStampToSecs()\n"));
-    //printf( "ATS: %lu, %g, %g\n", timeStamp->mFlags, timeStamp->mSampleTime, timeStamp->mRateScalar );
-    if (timeStamp->mFlags & kAudioTimeStampSampleTimeValid)
-        return (timeStamp->mSampleTime / stream->sampleRate);
-    else
-        return 0;
+	return HOST_TIME_TO_PA_TIME( AudioGetCurrentHostTime() ); 
 }
 
 #define RING_BUFFER_EMPTY (1000)
 
-static OSStatus ringBufferIOProc( AudioConverterRef inAudioConverter,
-                             UInt32*ioDataSize,
-                             void** outData,
+static OSStatus ringBufferIOProc( AudioConverterRef inAudioConverter, 
+                             UInt32*ioDataSize, 
+                             void** outData, 
                              void*inUserData )
 {
    void *dummyData;
@@ -1741,9 +1798,9 @@
    }
    assert(sizeof(UInt32) == sizeof(ring_buffer_size_t));
    PaUtil_GetRingBufferReadRegions( rb, *ioDataSize,
-                                    outData, (ring_buffer_size_t *)ioDataSize,
+                                    outData, (ring_buffer_size_t *)ioDataSize, 
                                     &dummyData, &dummySize );
-
+      
    assert( *ioDataSize );
    PaUtil_AdvanceRingBufferReadIndex( rb, *ioDataSize );
 
@@ -1799,24 +1856,68 @@
    }
       ----------------------------------------------------------------- */
 
-   if( !stream->isTimeSet )
-      setStreamStartTime( stream );
-
-   if( isRender ) {
-      AudioTimeStamp currentTime;
-      timeInfo.outputBufferDacTime = TimeStampToSecs(stream, inTimeStamp);
-      AudioDeviceGetCurrentTime(stream->outputDevice, &currentTime);
-      timeInfo.currentTime = TimeStampToSecs(stream, &currentTime);
-   }
-   if( isRender && stream->inputUnit == stream->outputUnit )
-      timeInfo.inputBufferAdcTime = TimeStampToSecs(stream, inTimeStamp);
-   if( !isRender ) {
-      AudioTimeStamp currentTime;
-      timeInfo.inputBufferAdcTime = TimeStampToSecs(stream, inTimeStamp);
-      AudioDeviceGetCurrentTime(stream->inputDevice, &currentTime);
-      timeInfo.currentTime = TimeStampToSecs(stream, &currentTime);
-   }
-
+	/* compute PaStreamCallbackTimeInfo */
+	
+	if( pthread_mutex_trylock( &stream->timingInformationMutex ) == 0 ){
+		/* snapshot the ioproc copy of timing information */
+		stream->deviceOutputLatencySamples_ioProcCopy = stream->deviceOutputLatencySamples;
+		stream->recipricalOfActualOutputSampleRate_ioProcCopy = stream->recipricalOfActualOutputSampleRate;
+		stream->deviceInputLatencySamples_ioProcCopy = stream->deviceInputLatencySamples;
+		pthread_mutex_unlock( &stream->timingInformationMutex );
+	}
+	
+	/* For timeInfo.currentTime we could calculate current time backwards from the HAL audio 
+	 output time to give a more accurate impression of the current timeslice but it doesn't 
+	 seem worth it at the moment since other PA host APIs don't do any better.
+	 */
+	timeInfo.currentTime = HOST_TIME_TO_PA_TIME( AudioGetCurrentHostTime() );
+	
+	/*
+	 For an input HAL AU, inTimeStamp is the time the samples are received from the hardware,
+	 for an output HAL AU inTimeStamp is the time the samples are sent to the hardware. 
+	 PA expresses timestamps in terms of when the samples enter the ADC or leave the DAC
+	 so we add or subtract kAudioDevicePropertyLatency below.
+	 */
+	
+	/* FIXME: not sure what to do below if the host timestamps aren't valid (kAudioTimeStampHostTimeValid isn't set)
+	 Could ask on CA mailing list if it is possible for it not to be set. If so, could probably grab a now timestamp
+	 at the top and compute from there (modulo scheduling jitter) or ask on mailing list for other options. */
+	
+	if( isRender )
+	{
+		if( stream->inputUnit ) /* full duplex */
+		{
+			if( stream->inputUnit == stream->outputUnit ) /* full duplex AUHAL IOProc */
+			{
+				/* FIXME: review. i'm not sure this computation of inputBufferAdcTime is correct for a full-duplex AUHAL */
+				timeInfo.inputBufferAdcTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime) 
+						- stream->deviceInputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy; // FIXME should be using input sample rate here?
+				timeInfo.outputBufferDacTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime) 
+						+ stream->deviceOutputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy;
+			}
+			else /* full duplex with ring-buffer from a separate input AUHAL ioproc */
+			{
+				/* FIXME: review. this computation of inputBufferAdcTime is definitely wrong since it doesn't take the ring buffer latency into account */
+				timeInfo.inputBufferAdcTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime) 
+						- stream->deviceInputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy; // FIXME should be using input sample rate here?
+				timeInfo.outputBufferDacTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
+						+ stream->deviceOutputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy;
+			}
+		}
+		else /* output only */
+		{
+			timeInfo.inputBufferAdcTime = 0;
+			timeInfo.outputBufferDacTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
+					+ stream->deviceOutputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy;
+		}
+	}
+	else /* input only */
+	{
+		timeInfo.inputBufferAdcTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime) 
+				- stream->deviceInputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy; // FIXME should be using input sample rate here?
+		timeInfo.outputBufferDacTime = 0;
+	}
+	
    //printf( "---%g, %g, %g\n", timeInfo.inputBufferAdcTime, timeInfo.currentTime, timeInfo.outputBufferDacTime );
 
    if( isRender && stream->inputUnit == stream->outputUnit
@@ -1876,7 +1977,7 @@
        *       -- OR Simplex Output
        *
        * This case handles output data as in the full duplex case,
-       * and, if there is input data, reads it off the ring buffer
+       * and, if there is input data, reads it off the ring buffer 
        * and into the PA buffer processor. If sample rate conversion
        * is required on input, that is done here as well.
        */
@@ -1923,7 +2024,7 @@
                UInt32 size;
                float data[ inChan * frames ];
                size = sizeof( data );
-               err = AudioConverterFillBuffer(
+               err = AudioConverterFillBuffer( 
                              stream->inputSRConverter,
                              ringBufferIOProc,
                              &stream->inputRingBuffer,
@@ -1937,7 +2038,7 @@
                }
                ERR( err );
                assert( !err );
-
+               
                PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames );
                PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
                                    0,
@@ -2092,7 +2193,7 @@
             long f;
 
             size = sizeof( data );
-            err = AudioConverterFillBuffer(
+            err = AudioConverterFillBuffer( 
                           stream->inputSRConverter,
                           ringBufferIOProc,
                           &stream->inputRingBuffer,
@@ -2128,7 +2229,6 @@
    case paContinue: break;
    case paComplete:
    case paAbort:
-      stream->isTimeSet = FALSE;
       stream->state = CALLBACK_STOPPED ;
       if( stream->outputUnit )
          AudioOutputUnitStop(stream->outputUnit);
@@ -2157,6 +2257,19 @@
     VDBUG( ( "Closing stream.\n" ) );
 
     if( stream ) {
+		
+		if( stream->outputUnit ) {
+			AudioDeviceRemovePropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyActualSampleRate, 
+											  AudioDevicePropertyActualSampleRateListenerProc );
+			AudioDeviceRemovePropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyLatency, 
+											  AudioDevicePropertyOutputLatencySamplesListenerProc );
+		}
+		
+		if( stream->inputUnit ) {
+			AudioDeviceRemovePropertyListener( stream->inputDevice, 0, /* isInput = */ TRUE, kAudioDevicePropertyLatency, 
+											  AudioDevicePropertyInputLatencySamplesListenerProc );
+		}
+		
        if( stream->outputUnit ) {
           int count = removeFromXRunListenerList( stream );
           if( count == 0 )
@@ -2203,6 +2316,10 @@
           return result;
        if( stream->bufferProcessorIsInitialized )
           PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
+		
+       if( stream->timingInformationMutexIsInitialized )
+          pthread_mutex_destroy( &stream->timingInformationMutex );
+
        PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
        PaUtil_FreeMemory( stream );
     }
@@ -2232,10 +2349,7 @@
     if( stream->outputUnit && stream->outputUnit != stream->inputUnit ) {
        ERR_WRAP( AudioOutputUnitStart(stream->outputUnit) );
     }
-
-    //setStreamStartTime( stream );
-    //stream->isTimeSet = TRUE;
-
+	
     return paNoError;
 #undef ERR_WRAP
 }
@@ -2266,7 +2380,6 @@
     waitUntilBlioWriteBufferIsFlushed( &stream->blio );
     VDBUG( ( "Stopping stream.\n" ) );
 
-    stream->isTimeSet = FALSE;
     stream->state = STOPPING;
 
 #define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0)
@@ -2314,10 +2427,6 @@
     if( paErr )
        return paErr;
 
-/*
-    //stream->isTimeSet = FALSE;
-*/
-
     VDBUG( ( "Stream Stopped.\n" ) );
     return paNoError;
 #undef ERR_WRAP

 

  ViewVC Help
Powered by ViewVC 1.1.22