41 #include "AUTimestampGenerator.h"
45 static double DebugHostTime(
const AudioTimeStamp &ts)
47 static UInt64 baseHostTime = 0;
48 if (!(ts.mFlags & kAudioTimeStampHostTimeValid))
50 if (baseHostTime == 0)
51 baseHostTime = ts.mHostTime;
52 return double(SInt64(ts.mHostTime) - SInt64(baseHostTime)) * CAHostTimeBase::GetInverseFrequency();
56 void AUTimestampGenerator::AddOutputTime(
const AudioTimeStamp &inTimeStamp, Float64 expectedDeltaFrames,
double outputSampleRate,
double rateScalarAdj)
58 mRateScalarAdj = rateScalarAdj;
59 mLastOutputTime = mCurrentOutputTime;
60 mCurrentOutputTime = inTimeStamp;
63 if (mHostTimeDiscontinuityCorrection && !(mCurrentOutputTime.mFlags & kAudioTimeStampHostTimeValid) && (mLastOutputTime.mFlags & kAudioTimeStampHostTimeValid)) {
65 double rateScalar = (mCurrentOutputTime.mFlags & kAudioTimeStampRateScalarValid) ? mCurrentOutputTime.mRateScalar : 1.0;
66 Float64 deltaSamples = mCurrentOutputTime.mSampleTime - mLastOutputTime.mSampleTime;
67 mCurrentOutputTime.mHostTime = mLastOutputTime.mHostTime +
68 UInt64(CAHostTimeBase::GetFrequency() * deltaSamples * rateScalar / outputSampleRate);
69 mCurrentOutputTime.mFlags |= kAudioTimeStampHostTimeValid;
72 printf(
"synthesized host time: %.3f (%.3f + %.f smp @ %.f Hz, rs %.3f\n", DebugHostTime(mCurrentOutputTime), DebugHostTime(mLastOutputTime), deltaSamples, outputSampleRate, rateScalar);
76 if (rateScalarAdj != 1.0) {
77 if (mCurrentOutputTime.mFlags & kAudioTimeStampRateScalarValid)
78 mCurrentOutputTime.mRateScalar *= rateScalarAdj;
80 mCurrentOutputTime.mRateScalar = rateScalarAdj;
81 mCurrentOutputTime.mFlags |= kAudioTimeStampRateScalarValid;
87 mDiscontinuous =
false;
88 mDiscontinuityDeltaSamples = 0.;
89 if (!mStartInputAtZero)
90 mNextInputSampleTime = mCurrentOutputTime.mSampleTime;
92 mDiscontinuous = fnotequal(mCurrentOutputTime.mSampleTime, mNextOutputSampleTime);
93 mDiscontinuityDeltaSamples = mCurrentOutputTime.mSampleTime - mNextOutputSampleTime;
95 if (mDiscontinuityDeltaSamples < 0.)
96 mDiscontinuityDeltaSamples = 0.;
100 printf(
"%-20.20s: *** DISCONTINUOUS, got "TSGFMT
", expected "TSGFMT
"\n", mDebugName, (SInt64)mCurrentOutputTime.mSampleTime, (SInt64)mNextOutputSampleTime);
103 mNextOutputSampleTime = mCurrentOutputTime.mSampleTime + expectedDeltaFrames;
106 const AudioTimeStamp & AUTimestampGenerator::GenerateInputTime(Float64 framesToAdvance,
double inputSampleRate)
109 return mCurrentOutputTime;
111 double inputSampleTime;
113 mCurrentInputTime.mFlags = kAudioTimeStampSampleTimeValid;
114 double rateScalar = 1.0;
117 if (mCurrentOutputTime.mFlags & kAudioTimeStampRateScalarValid) {
118 mCurrentInputTime.mFlags |= kAudioTimeStampRateScalarValid;
119 mCurrentInputTime.mRateScalar = rateScalar = mCurrentOutputTime.mRateScalar;
123 if (mCurrentOutputTime.mFlags & kAudioTimeStampHostTimeValid) {
124 mCurrentInputTime.mFlags |= kAudioTimeStampHostTimeValid;
125 mCurrentInputTime.mHostTime = mCurrentOutputTime.mHostTime;
126 if (mHostTimeDiscontinuityCorrection && mDiscontinuous && (mLastOutputTime.mFlags & kAudioTimeStampHostTimeValid)) {
129 UInt64 deltaHostTime = mCurrentOutputTime.mHostTime - mLastOutputTime.mHostTime;
130 double deltaSeconds = double(deltaHostTime) * CAHostTimeBase::GetInverseFrequency();
132 double deltaSamples = floor(inputSampleRate / rateScalar * deltaSeconds + 0.5);
133 double lastInputSampleTime = mCurrentInputTime.mSampleTime;
134 inputSampleTime = lastInputSampleTime + deltaSamples;
137 printf(
"%-20.20s: adjusted input time: "TSGFMT
" -> "TSGFMT
" (SR=%.3f, rs=%.3f)\n", mDebugName, (SInt64)lastInputSampleTime, (SInt64)inputSampleTime, inputSampleRate, rateScalar);
139 mDiscontinuous =
false;
141 inputSampleTime = mNextInputSampleTime;
145 inputSampleTime = mNextInputSampleTime;
148 if (!mHostTimeDiscontinuityCorrection && fnonzero(mDiscontinuityDeltaSamples))
152 inputSampleTime += floor(mDiscontinuityDeltaSamples / mRateScalarAdj + 0.5);
156 printf(
"%-20.20s: adjusted input time: %.0f -> %.0f (SR=%.3f, rs=%.3f, delta=%.0f)\n", mDebugName, mNextInputSampleTime, inputSampleTime, inputSampleRate, mRateScalarAdj, mDiscontinuityDeltaSamples);
159 mDiscontinuityDeltaSamples = 0.;
164 if (mCurrentOutputTime.mFlags & kAudioTimeStampWordClockTimeValid) {
165 mCurrentInputTime.mFlags |= kAudioTimeStampWordClockTimeValid;
166 mCurrentInputTime.mWordClockTime = mCurrentOutputTime.mWordClockTime;
170 if (mCurrentOutputTime.mFlags & kAudioTimeStampSMPTETimeValid) {
171 mCurrentInputTime.mFlags |= kAudioTimeStampSMPTETimeValid;
172 mCurrentInputTime.mSMPTETime = mCurrentOutputTime.mSMPTETime;
176 mCurrentInputTime.mSampleTime = inputSampleTime;
177 mNextInputSampleTime = inputSampleTime + framesToAdvance;
180 if (mVerbosity > 0) {
181 printf(
"%-20.20s: out = "TSGFMT
" (%10.3fs) in = "TSGFMT
" (%10.3fs) delta = "TSGFMT
" advance = "TSGFMT
"\n", mDebugName, (SInt64)mCurrentOutputTime.mSampleTime, DebugHostTime(mCurrentOutputTime), (SInt64)inputSampleTime, DebugHostTime(mCurrentInputTime), (SInt64)(mCurrentOutputTime.mSampleTime - inputSampleTime), (SInt64)framesToAdvance);
184 return mCurrentInputTime;