Ejemplo n.º 1
0
void	AUTimestampGenerator::AddOutputTime(const AudioTimeStamp &inTimeStamp, Float64 expectedDeltaFrames, double outputSampleRate, double rateScalarAdj)
{
	mState.mRateScalarAdj = rateScalarAdj;
	mState.mLastOutputTime = mState.mCurrentOutputTime;
	mState.mInputSampleTimeForOutputPull = mState.mNextInputSampleTime;
	mState.mCurrentOutputTime = inTimeStamp;

	if (mState.mBypassed)
		return;

	if (mState.mHostTimeDiscontinuityCorrection && !(mState.mCurrentOutputTime.mFlags & kAudioTimeStampHostTimeValid) && (mState.mLastOutputTime.mFlags & kAudioTimeStampHostTimeValid)) {
		// no host time here but we had one last time, interpolate one
		double rateScalar = (mState.mCurrentOutputTime.mFlags & kAudioTimeStampRateScalarValid) ? mState.mCurrentOutputTime.mRateScalar : 1.0;
		Float64 deltaSamples = mState.mCurrentOutputTime.mSampleTime - mState.mLastOutputTime.mSampleTime;
		mState.mCurrentOutputTime.mHostTime = mState.mLastOutputTime.mHostTime +
			UInt64(CAHostTimeBase::GetFrequency() * deltaSamples * rateScalar / outputSampleRate);
		mState.mCurrentOutputTime.mFlags |= kAudioTimeStampHostTimeValid;
#if DEBUG
		if (mVerbosity > 1)
			printf("synthesized host time: %.3f (%.3f + %.f smp @ %.f Hz, rs %.3f\n", DebugHostTime(mState.mCurrentOutputTime), DebugHostTime(mState.mLastOutputTime), deltaSamples, outputSampleRate, rateScalar);
#endif
	}
	// copy rate scalar
	if (rateScalarAdj != 1.0) {
		if (mState.mCurrentOutputTime.mFlags & kAudioTimeStampRateScalarValid)
			mState.mCurrentOutputTime.mRateScalar *= rateScalarAdj;
		else {
			mState.mCurrentOutputTime.mRateScalar = rateScalarAdj;
			mState.mCurrentOutputTime.mFlags |= kAudioTimeStampRateScalarValid;
		}
	}

	if (mFirstTime) {
		mFirstTime = false;
		mState.mDiscontinuous = false;
		mState.mDiscontinuityDeltaSamples = 0.;
		if (!mState.mStartInputAtZero) {
			mState.mNextInputSampleTime = mState.mCurrentOutputTime.mSampleTime;
			mState.mInputSampleTimeForOutputPull = mState.mNextInputSampleTime;
		}
	} else {
		mState.mDiscontinuous = fnotequal(mState.mCurrentOutputTime.mSampleTime, mState.mNextOutputSampleTime);
		mState.mDiscontinuityDeltaSamples = mState.mCurrentOutputTime.mSampleTime - mState.mNextOutputSampleTime;
		// time should never go backwards...
		if (mState.mDiscontinuityDeltaSamples < 0.)
			mState.mDiscontinuityDeltaSamples = 0.;
#if DEBUG
		if (mVerbosity > 1)
			if (mState.mDiscontinuous)
				printf("%-20.20s: *** DISCONTINUOUS, got " TSGFMT ", expected " TSGFMT "\n", mDebugName, (SInt64)mState.mCurrentOutputTime.mSampleTime, (SInt64)mState.mNextOutputSampleTime);
#endif
	}
	mState.mNextOutputSampleTime = mState.mCurrentOutputTime.mSampleTime + expectedDeltaFrames;
}
Ejemplo n.º 2
0
const AudioTimeStamp &	AUTimestampGenerator::GenerateInputTime(Float64 framesToAdvance, double inputSampleRate)
{
	if (mBypassed)
		return mCurrentOutputTime;

	double inputSampleTime;
	
	mCurrentInputTime.mFlags = kAudioTimeStampSampleTimeValid;
	double rateScalar = 1.0;
	
	// propagate rate scalar
	if (mCurrentOutputTime.mFlags & kAudioTimeStampRateScalarValid) {
		mCurrentInputTime.mFlags |= kAudioTimeStampRateScalarValid;
		mCurrentInputTime.mRateScalar = rateScalar = mCurrentOutputTime.mRateScalar;
	}
	
	// propagate host time and sample time
	if (mCurrentOutputTime.mFlags & kAudioTimeStampHostTimeValid) {
		mCurrentInputTime.mFlags |= kAudioTimeStampHostTimeValid;
		mCurrentInputTime.mHostTime = mCurrentOutputTime.mHostTime;
		if (mHostTimeDiscontinuityCorrection && mDiscontinuous && (mLastOutputTime.mFlags & kAudioTimeStampHostTimeValid)) {
			// we had a discontinuous output time, need to resync by interpolating 
			// a sample time that is appropriate to the host time
			UInt64 deltaHostTime = mCurrentOutputTime.mHostTime - mLastOutputTime.mHostTime;
			double deltaSeconds = double(deltaHostTime) * CAHostTimeBase::GetInverseFrequency();
			// samples/second * seconds = samples
			double deltaSamples = floor(inputSampleRate / rateScalar * deltaSeconds + 0.5);
			double lastInputSampleTime = mCurrentInputTime.mSampleTime;
			inputSampleTime = lastInputSampleTime + deltaSamples;
#if DEBUG
			if (mVerbosity > 1)
				printf("%-20.20s: adjusted input time: "TSGFMT" -> "TSGFMT" (SR=%.3f, rs=%.3f)\n", mDebugName, (SInt64)lastInputSampleTime, (SInt64)inputSampleTime, inputSampleRate, rateScalar);
#endif
			mDiscontinuous = false;
		} else {
			inputSampleTime = mNextInputSampleTime;
		}
	} else {
		// we don't know the host time, so we can't do much
		inputSampleTime = mNextInputSampleTime;
	}

	if (!mHostTimeDiscontinuityCorrection && fnonzero(mDiscontinuityDeltaSamples))
	{
		// we had a discontinuous output time, need to resync by propagating the
		// detected discontinuity, taking the rate scalar adjustment into account
		inputSampleTime += floor(mDiscontinuityDeltaSamples / mRateScalarAdj + 0.5);
		
#if DEBUG
		if (mVerbosity > 1)
			printf("%-20.20s: adjusted input time: %.0f -> %.0f (SR=%.3f, rs=%.3f, delta=%.0f)\n", mDebugName, mNextInputSampleTime, inputSampleTime, inputSampleRate, mRateScalarAdj, mDiscontinuityDeltaSamples);
#endif
		
		mDiscontinuityDeltaSamples = 0.;
	}
	
	
	// propagate word clock
	if (mCurrentOutputTime.mFlags & kAudioTimeStampWordClockTimeValid) {
		mCurrentInputTime.mFlags |= kAudioTimeStampWordClockTimeValid;
		mCurrentInputTime.mWordClockTime = mCurrentOutputTime.mWordClockTime;
	}
	
	// propagate SMPTE time
	if (mCurrentOutputTime.mFlags & kAudioTimeStampSMPTETimeValid) {
		mCurrentInputTime.mFlags |= kAudioTimeStampSMPTETimeValid;
		mCurrentInputTime.mSMPTETime = mCurrentOutputTime.mSMPTETime;
	}
	
	// store the input sample time and expected next input time
	mCurrentInputTime.mSampleTime = inputSampleTime;
	mNextInputSampleTime = inputSampleTime + framesToAdvance;

#if DEBUG
	if (mVerbosity > 0) {
		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);
	}
#endif
	return mCurrentInputTime;
}