Re: AudioQueue: detecting buffer underrun (again...)
Re: AudioQueue: detecting buffer underrun (again...)
- Subject: Re: AudioQueue: detecting buffer underrun (again...)
- From: Jens Alfke <email@hidden>
- Date: Mon, 26 May 2008 08:47:53 -0700
On 25 May '08, at 11:30 PM, Brett George wrote:
Jens Alfke wrote:
My workaround for all of this has been to ignore the returned
mSampleTime, and synthesize my own equivalent based on the mHostTime.
I'm seeing my own problems with AudioQueueGetCurrentTime. Did you
ever figure this out?
A week ago I would've said "yes", but then I found situations where my
workaround didn't work. It looks as though, when I start a second
AudioQueue after stopping the first one, the mSampleTime is bogus even
on the first call (much larger than it should be), whereas my
workaround required getting a correct value the first time.
I occasionally see it fail when I call that function in the Input
callback. It fails with code "kAudioQueueErr_InvalidRunState"
I haven't seen that, though.
Here's my current code that attempts to synthesize a useable time (the
getCurrentTime method). Rated PG-13 for language and brief nudity ;-)
—Jens
static inline NSTimeInterval secondsFromHostTime( UInt64 hostTime ) {
return AudioConvertHostTimeToNanos(hostTime) / 1.0e9;
}
static NSTimeInterval secondsFromTimeStamp(const AudioTimeStamp
*stamp) {
if(stamp->mFlags & kAudioTimeStampHostTimeValid)
return secondsFromHostTime(stamp->mHostTime);
else
return 0;
}
Float64 AudioPlayerState::getDeviceSampleRate()
{
Float64 rate = 0;
UInt32 size = sizeof(rate);
AudioQueueGetProperty(mQueue,
kAudioQueueDeviceProperty_SampleRate, &rate, &size);
LogTo(Audio,@" Device sample rate = %.3lf",rate);
return rate;
}
AudioTimeStamp AudioPlayerState::getCurrentTime()
{
AudioTimeStamp t;
Boolean discontinuity;
OSStatus err =
AudioQueueGetCurrentTime(mQueue,mTimeline,&t,&discontinuity);
if( err==noErr ) {
// t.mSampleTime is totally fucking 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 ) {
//FIX: This still doesn't work right because
t.mSampleTime is often way off even on the
// first callback (if this is not the first track
being played.)--jpa 5/2008
mStartTime = seconds - t.mSampleTime/this-
>getDeviceSampleRate();
LogTo(Audio,@" seconds=%.3lf; my mSampleTime=%.
3lf; t.mSampleTime=%.3lf; Computed start time = %.3lf",
seconds,mSampleTime,t.mSampleTime,mStartTime);
} else {
// Recompute the sample time based on the start time:
Float64 sampleTime = round((seconds-mStartTime) *
mDataFormat.mSampleRate);
LogTo(Audio,@" seconds=%.3lf; my mSampleTime=%.
3lf; Real sample time = %8.1lf (supposedly %8.1lf; off by %.3lf)",
seconds,mSampleTime,sampleTime,t.mSampleTime,
(sampleTime-t.mSampleTime));
t.mSampleTime = sampleTime;
}
}
if( discontinuity )
Log(@"AudioPlayer[%@]: DISCONTINUITY! Current time is
seconds:%.3lf, sampleTime:%.5lf",
mReader, seconds,t.mSampleTime);
} else {
t.mSampleTime = 0;
t.mHostTime = 0;
}
return t;
}
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden