Modified by: [EMAIL PROTECTED]
Date: 12/5/06
Project: Mac OS X
Bug Number: internal PR 183844, PR 183850, PR 183834
Synopsis: Additions to the CoreAudio audio device code to detect when
there's not enough data making it to CoreAudio.
Overview:
The OS X CoreAudio device implementation is described here:
http://lists.helixcommunity.org/pipermail/audio-dev/2006-July/000745.html
But it wasn't detecting dryness -- when there wasn't enough data making it
into CoreAudio.
These changes note when more data is required than exists, and halts the
timeline until more audio data arrives.
Files Modified:
audio/device/pub/platform/mac/osxaudio.h
audio/device/platform/mac/osxaudio.cpp
Image Size and Heap Use impact (Client -Only): negligible
Platforms and Profiles Affected: OS X only
Platforms and Profiles Build Verified: OS X
Platforms and Profiles Functionality verified: OS X
Branch: HEAD and 150Cay
Copyright assignment: I am a RealNetworks employee
Index: pub/platform/mac/osxaudio.h
===================================================================
RCS file: /cvsroot/audio/device/pub/platform/mac/osxaudio.h,v
retrieving revision 1.2
diff -u -w -r1.2 osxaudio.h
--- pub/platform/mac/osxaudio.h 30 Aug 2006 20:54:10 -0000 1.2
+++ pub/platform/mac/osxaudio.h 5 Dec 2006 20:16:25 -0000
@@ -116,6 +116,8 @@
UInt64 mResetTimeNanos;
UInt64 mElapsedNanos;
UInt64 mElapsedNanosAtPause;
+ UInt64 mNanoSecondsThatCoreAudioDrynessOccurred;
+ UInt64 mAccumulatedNanoSecondsOfCoreAudioDryness;
double mCurrentVolume;
static HXMutex* zm_pMutex;
Index: platform/mac/osxaudio.cpp
===================================================================
RCS file: /cvsroot/audio/device/platform/mac/osxaudio.cpp,v
retrieving revision 1.2
diff -u -w -r1.2 osxaudio.cpp
--- platform/mac/osxaudio.cpp 30 Aug 2006 20:54:10 -0000 1.2
+++ platform/mac/osxaudio.cpp 5 Dec 2006 20:16:25 -0000
@@ -57,9 +57,12 @@
, mDeviceNumberOfChannels(0)
, mInputNumberOfChannels(0)
, mStaleBytesInFirstBuffer(0)
+ , mCurrentTime(0)
, mResetTimeNanos(0)
, mElapsedNanos(0)
, mElapsedNanosAtPause(0)
+ , mNanoSecondsThatCoreAudioDrynessOccurred(0)
+ , mAccumulatedNanoSecondsOfCoreAudioDryness(0)
, mCurrentVolume(75.0)
{
OSStatus err = noErr;
@@ -199,6 +202,8 @@
mResetTimeNanos -= mElapsedNanosAtPause;
mCurrentTime = mElapsedNanosAtPause;
mElapsedNanosAtPause = 0;
+ mNanoSecondsThatCoreAudioDrynessOccurred = 0;
+ mAccumulatedNanoSecondsOfCoreAudioDryness = 0;
// This is important!
OnTimeSync();
@@ -225,6 +230,8 @@
mResetTimeNanos =
::AudioConvertHostTimeToNanos(::AudioGetCurrentHostTime());
mElapsedNanos = 0;
mElapsedNanosAtPause = 0;
+ mNanoSecondsThatCoreAudioDrynessOccurred = 0;
+ mAccumulatedNanoSecondsOfCoreAudioDryness = 0;
return HXR_OK;
}
@@ -378,7 +385,35 @@
}
UInt64 inNano = ::AudioConvertHostTimeToNanos(inCurTime->mHostTime);
- mCurrentTime = inNano;
+
+ if (outOutputData->mBuffers[0].mDataByteSize > bytesWritten)
+ {
+ // we're experiencing dryness
+
+ UInt64 bytesPerSecond = (UInt64)(m_AudioFmt.uBitsPerSample/8)
+ * (UInt64)(m_AudioFmt.uChannels) *
(UInt64)(m_AudioFmt.ulSamplesPerSec);
+
+ UInt64 nanoSecondsPlayed = (UInt64)bytesWritten *
(UInt64)1000000000 / bytesPerSecond;
+
+ if (!mNanoSecondsThatCoreAudioDrynessOccurred)
+ {
+ mNanoSecondsThatCoreAudioDrynessOccurred = mCurrentTime +
nanoSecondsPlayed;
+ }
+
+ mCurrentTime += nanoSecondsPlayed; // estimate timeline
progression since this chunk may only be "partly dry"
+ }
+ else
+ {
+ if (mNanoSecondsThatCoreAudioDrynessOccurred)
+ {
+ // we're just coming out of "dry mode"
+ mAccumulatedNanoSecondsOfCoreAudioDryness = inNano -
mNanoSecondsThatCoreAudioDrynessOccurred;
+ mNanoSecondsThatCoreAudioDrynessOccurred = 0;
+ }
+
+ mCurrentTime = inNano - mAccumulatedNanoSecondsOfCoreAudioDryness;
+ }
+
return noErr;
}
_______________________________________________
Audio-dev mailing list
[email protected]
http://lists.helixcommunity.org/mailman/listinfo/audio-dev