change AE definition and usage of GetCacheTime to match how it is used in players #1131

Merged
merged 1 commit into from Jul 10, 2012
@@ -809,7 +809,7 @@ double CSoftAE::GetCacheTime()
CSharedLock sinkLock(m_sinkLock);
double time;
- time = (double)m_buffer.Free() * m_sinkFormatFrameSizeMul * m_sinkFormatSampleRateMul;
+ time = (double)m_buffer.Used() * m_sinkFormatFrameSizeMul * m_sinkFormatSampleRateMul;
time += m_sink->GetCacheTime();
return time;
@@ -489,8 +489,8 @@ double CSoftAEStream::GetCacheTime()
return 0.0;
double time;
- time = (double)(m_inputBuffer.Free() / m_format.m_frameSize) / (double)m_format.m_sampleRate;
- time += (double)(m_waterLevel - m_refillBuffer) / (double)AE.GetSampleRate();
+ time = (double)(m_inputBuffer.Used() / m_format.m_frameSize) / (double)m_format.m_sampleRate;
+ time += (double)(m_waterLevel - m_framesBuffered) / (double)AE.GetSampleRate();
time += AE.GetCacheTime();
return time;
}
@@ -53,22 +53,24 @@ class IAESink
virtual bool IsCompatible(const AEAudioFormat format, const std::string device) = 0;
/*
- This method must return the delay in seconds till new data will be sent out
+ This method returns the time in seconds that it will take
+ for the next added packet to be heard from the speakers.
*/
virtual double GetDelay() = 0;
/*
- This method returns the time in seconds till the sink's cache is full
+ This method returns the time in seconds that it will take
+ to underrun the cache if no sample is added.
*/
virtual double GetCacheTime() = 0;
/*
- This method returns the total length of the cache in seconds
+ This method returns the total time in seconds of the cache.
*/
virtual double GetCacheTotal() = 0;
/*
- Adds packets to be sent out, must block after at-least one block is being rendered
+ Adds packets to be sent out, this routine MUST block or sleep.
*/
virtual unsigned int AddPackets(uint8_t *data, unsigned int frames) = 0;
@@ -59,8 +59,9 @@ class IAEStream
virtual unsigned int AddData(void *data, unsigned int size) = 0;
/**
- * Returns how long until new data will be played
- * @return The delay in seconds
+ * Returns the time in seconds that it will take
+ * for the next added packet to be heard from the speakers.
+ * @return seconds
*/
virtual double GetDelay() = 0;
@@ -71,14 +72,15 @@ class IAEStream
virtual bool IsBuffering() = 0;
/**
- * Returns how long until playback will start
- * @return The delay in seconds
+ * Returns the time in seconds that it will take
+ * to underrun the cache if no sample is added.
+ * @return seconds
*/
virtual double GetCacheTime() = 0;
/**
- * Returns the total length of the cache before playback will start
- * @return The delay in seconds
+ * Returns the total time in seconds of the cache
+ * @return seconds
*/
virtual double GetCacheTotal() = 0;
@@ -332,31 +332,22 @@ bool CAESinkWASAPI::IsCompatible(const AEAudioFormat format, const std::string d
double CAESinkWASAPI::GetDelay()
{
- HRESULT hr;
- if (!m_initialized)
- return 0.0;
-
- hr = m_pAudioClient->GetBufferSize(&m_uiBufferLen);
- if (FAILED(hr))
- {
- #ifdef _DEBUG
- CLog::Log(LOGERROR, __FUNCTION__": GetBufferSize Failed : %s", WASAPIErrToStr(hr));
- #endif
- return 0.0;
- }
- return (double)m_uiBufferLen / (double)m_format.m_sampleRate;
+ return GetCacheTime();
}
double CAESinkWASAPI::GetCacheTime()
{
if (!m_initialized)
return 0.0;
- REFERENCE_TIME hnsLatency;
- HRESULT hr = m_pAudioClient->GetStreamLatency(&hnsLatency);
-
- /** returns buffer duration in seconds */
- return hnsLatency / 10.0;
+ unsigned int numPaddingFrames;
+ HRESULT hr = m_pAudioClient->GetCurrentPadding(&numPaddingFrames);
@DDDamian

DDDamian Jul 11, 2012

Contributor

GetCurrentPadding in exclusive mode event-driven always returns the size of one complete buffer (there are two) per M$. I did write a very extensive routine that polled the hardware pointer within the current buffer and used that plus the current performance clock to track this very accurately, but never upped it for a few reasons:

  1. the required return value for of GetCacheTime() wasn't clear
  2. being polled every ~2ms it was just added overhead considering:
  3. it seemed to have zero effect on the perceived or reported OSD sync error

Regardless, good that there's some clarity/consistency now as to the purpose of this function - good work.

+ if (FAILED(hr))
+ {
+ CLog::Log(LOGERROR, __FUNCTION__": GetCurrentPadding Failed : %s", WASAPIErrToStr(hr));
+ return 0.0;
+ }
+ return (double)numPaddingFrames / (double)m_format.m_sampleRate;
}
double CAESinkWASAPI::GetCacheTotal()