There's no documented queue property with that effect. :-(
My workaround for all of this has been to ignore the returned mSampleTime, and synthesize my own equivalent based on the mHostTime. This means that I have to remember the host-time that the queue started, which I derive from the first-time mSampleTime and the queue's frame rate.
Here's a method from my source code that shows what I do. I use getCurrentTime() as a replacement for AudioQueueGetCurrentTime. Note that it requires keeping a piece of state (Float64 mStartTime) associated with the queue, which is initialized the first time the method is called.
With this in place, everything works perfectly. I can use the mSampleTime returned from this method as the inTimeStamp when queueing buffers (to start the next buffer "right now") and get accurate timing.
Could one of the Apple engineers please at least let me know if these, um, "undocumented behaviors" of AudioQueueGetCurrentTime are already known, so I can avoid filing a duplicate Radar?
AudioTimeStamp AudioPlayerState::getCurrentTime()
{
AudioTimeStamp t;
Boolean discontinuity;
if( AudioQueueGetCurrentTime(mQueue,mTimeline,&t,&discontinuity) == noErr ) {
if( discontinuity )
LogTo(Audio,@"DISCONTINUITY!");
// t.mSampleTime is totally %&#*ing useless. Contrary to docs, it's in _device_ samples,
// not queue samples, and resets to an arbitrary negative number when the audio hardware
// configuration changes (like when plugging in headphones on a MacBook.)
// Therefore, after wasting entire days trying to figure it out, I've decided to ignore
// it entirely and synthesize my own accurate value based on host time.
Float64 seconds = secondsFromTimeStamp(&t);
if( seconds > 0 ) {
if( mStartTime==0 ) {
mStartTime = seconds - t.mSampleTime/mDataFormat.mSampleRate;
//LogTo(Audio,@" Computed start time = %.3lf",mStartTime);
} else {
// Recompute the sample time based on the start time:
Float64 sampleTime = round((seconds-mStartTime) * mDataFormat.mSampleRate);
/*LogTo(Audio,@" Real sample time = %8.1lf (supposedly %8.1lf; off by %.3lf)",
sampleTime,t.mSampleTime, (sampleTime-t.mSampleTime));*/
t.mSampleTime = sampleTime;
}
}
} else {
t.mSampleTime = 0;
t.mHostTime = 0;
}
return t;
}