]> Repos - portaudio/commitdiff
fixed regression in r1718 (PA/coreaudio) where PA callback timestamps would be offset...
authorrossb <rossb@0f58301d-fd10-0410-b4af-bbb618454e57>
Tue, 27 Dec 2011 08:58:59 +0000 (08:58 +0000)
committerrossb <rossb@0f58301d-fd10-0410-b4af-bbb618454e57>
Tue, 27 Dec 2011 08:58:59 +0000 (08:58 +0000)
src/hostapi/coreaudio/pa_mac_core.c
src/hostapi/coreaudio/pa_mac_core_internal.h

index b182dac05a999ad80380155d25b99dd22db75081..55ce9f0c0eec9cb9f1418414e7addf125e046d74 100644 (file)
@@ -990,18 +990,19 @@ static void UpdateTimeStampOffsets( PaMacCoreStream *stream )
 }
 
 /* ================================================================================= */
-/* Query sample rate property. */
-static OSStatus UpdateSampleRateFromDeviceProperty( PaMacCoreStream *stream, AudioDeviceID deviceID, Boolean isInput )
+
+/* can be used to update from nominal or actual sample rate */
+static OSStatus UpdateSampleRateFromDeviceProperty( PaMacCoreStream *stream, AudioDeviceID deviceID, Boolean isInput, AudioDevicePropertyID sampleRatePropertyID )
 {
     PaMacCoreDeviceProperties * deviceProperties = isInput ? &stream->inputProperties : &stream->outputProperties;
-       /* FIXME: not sure if this should be the sample rate of the output device or the output unit */
-       Float64 actualSampleRate = deviceProperties->sampleRate;
+       
+       Float64 sampleRate = 0.0;
        UInt32 propSize = sizeof(Float64);
-    OSStatus osErr = AudioDeviceGetProperty( deviceID, 0, isInput, kAudioDevicePropertyActualSampleRate, &propSize, &actualSampleRate);
-       if( (osErr == noErr) && (actualSampleRate > 1000.0) ) // avoid divide by zero if there's an error
+    OSStatus osErr = AudioDeviceGetProperty( deviceID, 0, isInput, sampleRatePropertyID, &propSize, &sampleRate);
+       if( (osErr == noErr) && (sampleRate > 1000.0) ) /* avoid divide by zero if there's an error */
        {
-        deviceProperties->sampleRate = actualSampleRate;
-        deviceProperties->samplePeriod = 1.0 / actualSampleRate;
+        deviceProperties->sampleRate = sampleRate;
+        deviceProperties->samplePeriod = 1.0 / sampleRate;
     }
     return osErr;
 }
@@ -1013,7 +1014,7 @@ static OSStatus AudioDevicePropertyActualSampleRateListenerProc( AudioDeviceID i
     // Make sure the callback is operating on a stream that is still valid!
     assert( stream->streamRepresentation.magic == PA_STREAM_MAGIC );
 
-       OSStatus osErr = UpdateSampleRateFromDeviceProperty( stream, inDevice, isInput );
+       OSStatus osErr = UpdateSampleRateFromDeviceProperty( stream, inDevice, isInput, kAudioDevicePropertyActualSampleRate );
     if( osErr == noErr )
     {
         UpdateTimeStampOffsets( stream );
@@ -1077,9 +1078,6 @@ static OSStatus SetupDevicePropertyListeners( PaMacCoreStream *stream, AudioDevi
     OSStatus osErr = noErr;
     PaMacCoreDeviceProperties *deviceProperties = isInput ? &stream->inputProperties : &stream->outputProperties;
     
-    // Start with the current values for the device properties.
-    UpdateSampleRateFromDeviceProperty( stream, deviceID, isInput );
-    
     if( (osErr = QueryUInt32DeviceProperty( deviceID, isInput,
                                            kAudioDevicePropertyLatency, &deviceProperties->deviceLatency )) != noErr ) return osErr;
     if( (osErr = QueryUInt32DeviceProperty( deviceID, isInput,
@@ -1993,53 +1991,48 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
     
     stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
 
-    stream->sampleRate  = sampleRate;
-    stream->outDeviceSampleRate = 0;
-    if( stream->outputUnit ) {
-       Float64 rate;
-       UInt32 size = sizeof( rate );
-       result = ERR( AudioDeviceGetProperty( stream->outputDevice,
-                                    0,
-                                    FALSE,
-                                    kAudioDevicePropertyNominalSampleRate,
-                                    &size, &rate ) );
-       if( result )
-          goto error;
-       stream->outDeviceSampleRate = rate;
-    }
-    stream->inDeviceSampleRate = 0;
-    if( stream->inputUnit ) {
-       Float64 rate;
-       UInt32 size = sizeof( rate );
-       result = ERR( AudioDeviceGetProperty( stream->inputDevice,
-                                    0,
-                                    TRUE,
-                                    kAudioDevicePropertyNominalSampleRate,
-                                    &size, &rate ) );
-       if( result )
-          goto error;
-       stream->inDeviceSampleRate = rate;
-    }
+    stream->sampleRate = sampleRate;
+    
     stream->userInChan  = inputChannelCount;
     stream->userOutChan = outputChannelCount;
 
     // Setup property listeners for timestamp and latency calculations.
        pthread_mutex_init( &stream->timingInformationMutex, NULL );
        stream->timingInformationMutexIsInitialized = 1;
-    InitializeDeviceProperties( &stream->inputProperties );
-    InitializeDeviceProperties( &stream->outputProperties );
+    InitializeDeviceProperties( &stream->inputProperties );     // zeros the struct. doesn't actually init it to useful values
+    InitializeDeviceProperties( &stream->outputProperties );    // zeros the struct. doesn't actually init it to useful values
        if( stream->outputUnit )
     {
         Boolean isInput = FALSE;
+        
+        // Start with the current values for the device properties.
+        // Init with nominal sample rate. Use actual sample rate where available
+        
+        result = ERR( UpdateSampleRateFromDeviceProperty( 
+                stream, stream->outputDevice, isInput, kAudioDevicePropertyNominalSampleRate )  );
+        if( result )
+            goto error; /* fail if we can't even get a nominal device sample rate */
+        
+        UpdateSampleRateFromDeviceProperty( stream, stream->outputDevice, isInput, kAudioDevicePropertyActualSampleRate );
+        
         SetupDevicePropertyListeners( stream, stream->outputDevice, isInput );
     }
        if( stream->inputUnit )
     {
         Boolean isInput = TRUE;
+       
+        // as above
+        result = ERR( UpdateSampleRateFromDeviceProperty( 
+                stream, stream->inputDevice, isInput, kAudioDevicePropertyNominalSampleRate )  );
+        if( result )
+            goto error;
+        
+        UpdateSampleRateFromDeviceProperty( stream, stream->inputDevice, isInput, kAudioDevicePropertyActualSampleRate );
+        
         SetupDevicePropertyListeners( stream, stream->inputDevice, isInput );
        }
     UpdateTimeStampOffsets( stream );
-    // Setup copies to be used by audio callback.
+    // Setup timestamp copies to be used by audio callback.
     stream->timestampOffsetCombined_ioProcCopy = stream->timestampOffsetCombined;
     stream->timestampOffsetInputDevice_ioProcCopy = stream->timestampOffsetInputDevice;
     stream->timestampOffsetOutputDevice_ioProcCopy = stream->timestampOffsetOutputDevice;
index 462240bb4bb27d08e5b39d4fe4eaac63740c842d..14e3d075deea3974a06396b111e8c3f1a11f5c43 100644 (file)
@@ -120,7 +120,11 @@ typedef struct PaMacCoreDeviceProperties
     UInt32 bufferFrameSize;
     // UInt32 streamLatency; // Seems to be the same as deviceLatency!?
     UInt32 deviceLatency;
-    /* Current device sample rate. May change! */
+    /* Current device sample rate. May change! 
+       These are initialized to the nominal device sample rate, 
+       and updated with the actual sample rate, when/where available. 
+       Note that these are the *device* sample rates, prior to any required 
+       SR conversion. */
     Float64 sampleRate;
     Float64 samplePeriod; // reciprocal
 }
@@ -166,10 +170,6 @@ typedef struct PaMacCoreStream
        ACTIVE           = 3  /* The stream is active and running. */
     } state;
     double sampleRate;
-    //these may be different from the stream sample rate due to SR conversion:
-    double outDeviceSampleRate;
-    double inDeviceSampleRate;
-       
     PaMacCoreDeviceProperties  inputProperties;
     PaMacCoreDeviceProperties  outputProperties;