tags:

views:

507

answers:

4

I'm developing for the iPhone and am trying to get an initial timeStamp to sync my audioQueues.

I'm using AudioQueueDeviceGetCurrentTime for this. According to the documentation this function gives back a valid mHostTime whether the queue/device is running or not. But when I try this I get back a kAudioHardwareNotRunningError (1937010544). All queues have an timeLine associated and have been initialized before I call the function.

How can I retrieve a valid mHostTime to sync my AudioQueues (prior to running the queues)?

My code:

AudioSessionInitialize(NULL, NULL, interruptionListenerCallback, self);

UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;

AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
                        sizeof(sessionCategory), &sessionCategory);

// initialize all queues
// ....

AudioSessionSetActive(true);

OSStatus result;
AudioTimestamp currentTime;

result = AudioQueueDeviceGetCurrentTime(audioQueueRef, &currentTimeStamp);

if (!result)
{
  // rest of code
}
A: 

I spent about a week stuck with this exact problem. As far as I can tell, the documentation is wrong - you must have a running audio queue to query the current device time.

My solution? It's really inelegant, but I just keep one audio queue running at all times playing silence so that I can time other queues off it.

qrunchmonkey
See my reply to your own question. I always synchronize audio queues using host time and this works just fine. If I get the current tick count, calculate 2 seconds in ticks, add them to the current tick count, set this value in the time stamp struct, setting flags to only host time being valid, and finally enqueue the buffer in the already running queue, it will play exactly in 2 seconds. If it is already playing another buffer in 2 seconds, the other buffer is interrupted and the time scheduled one is played instead.
Mecki
+1  A: 

After some googling I found a post on the CoreAudio mailing list where they say that the hostTime is the same as mach_absolute_time().

Mach_absolute_time() is indeed giving me expected timestamp values.

Kriem
A: 

you have to create a timeline before you can call AudioQueueDeviceGetCurrentTime

AudioSessionSetActive(true); // initialize all queues // ....

// initialize time line AudioQueueTimelineRef audioTimeline; status = AudioQueueCreateTimeline(audioQueueRef, &audioTimeline);

// now you can do what you want.

OSStatus result; AudioTimestamp currentTime;

result = AudioQueueDeviceGetCurrentTime(audioQueueRef, &currentTimeStamp);

if (!result) { // rest of code }

Mark Mieczkowski
A: 

Try this, the function AudioQueueGetCurrentTime() fills an AudioTimeStamp structure. If you get the mSampleTime property of this structure and divide by audio sample rate you will obtain the current seconds position. In code:

// AudioTimeStamp struct to store the value.
AudioTimeStamp timeStamp;

// Gets the current audio queue time.
AudioQueueGetCurrentTime(
                         mQueue,        // The audio queue whose current time you want to get.
                         NULL,        
                         &timeStamp,    // On output, the current audio queue time.
                         NULL         
                         );

// Return the value.
NSTimeInterval seconds = timeStamp.mSampleTime / mRecordFormat.mSampleRate;

If you doesn't known the current sample rate, this information is stored on the mSampleRate property if you are using the CAStreamBasicDescription structure to control this.

Hope it works.

SEQOY Development Team