From: <man...@us...> - 2015-04-24 15:21:33
|
Revision: 4979 http://sourceforge.net/p/modplug/code/4979 Author: manxorist Date: 2015-04-24 15:21:18 +0000 (Fri, 24 Apr 2015) Log Message: ----------- [Ref] sounddev: Move TimeInfo calculation to a single place in SourceAudioPreRead(). [Ref] sounddev: Move stream position calculation from ASIO to generic code for devices that provides hardware timing information. [Fix] sounddev: Avoid blocking on the stream position mutex for any device that provides GetStreamPosition() or GetTimeInfo(). [Fix] sounddev: Avoid blocking on the stream position mutex when only gathering statistics. [Ref] sounddev: Move the current chunk size and render stream position information into struct TimeInfo. [Ref] sounddev: Simplify parameter list of the SourceAudioDone() callback. [Mod] OpenMPT: Version is now 1.25.00.02 Modified Paths: -------------- trunk/OpenMPT/common/versionNumber.h trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/sounddev/SoundDevice.cpp trunk/OpenMPT/sounddev/SoundDevice.h trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp trunk/OpenMPT/sounddev/SoundDeviceASIO.h trunk/OpenMPT/sounddev/SoundDeviceDirectSound.cpp trunk/OpenMPT/sounddev/SoundDeviceDirectSound.h trunk/OpenMPT/sounddev/SoundDevicePortAudio.cpp trunk/OpenMPT/sounddev/SoundDevicePortAudio.h trunk/OpenMPT/sounddev/SoundDeviceWaveout.cpp Modified: trunk/OpenMPT/common/versionNumber.h =================================================================== --- trunk/OpenMPT/common/versionNumber.h 2015-04-23 19:56:35 UTC (rev 4978) +++ trunk/OpenMPT/common/versionNumber.h 2015-04-24 15:21:18 UTC (rev 4979) @@ -19,7 +19,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 25 #define VER_MINOR 00 -#define VER_MINORMINOR 01 +#define VER_MINORMINOR 02 //Version string. For example "1.17.02.28" #define MPT_VERSION_STR VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR) Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2015-04-23 19:56:35 UTC (rev 4978) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2015-04-24 15:21:18 UTC (rev 4979) @@ -718,12 +718,12 @@ //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- { MPT_TRACE(); - ASSERT(InAudioThread()); + MPT_ASSERT(InAudioThread()); OPENMPT_PROFILE_FUNCTION(Profiler::Audio); TimingInfo timingInfo; timingInfo.OutputLatency = bufferAttributes.Latency; - timingInfo.StreamFrames = timeInfo.StreamFrames; - timingInfo.SystemTimestamp = timeInfo.SystemTimestamp; + timingInfo.StreamFrames = timeInfo.SyncPointStreamFrames; + timingInfo.SystemTimestamp = timeInfo.SyncPointSystemTimestamp; timingInfo.Speed = timeInfo.Speed; m_pSndFile->m_TimingInfo = timingInfo; m_Dither.SetMode((DitherMode)settings.DitherType); @@ -747,17 +747,18 @@ } -void CMainFrame::SoundSourceDone(const SoundDevice::Settings &settings, const SoundDevice::Flags &flags, const SoundDevice::BufferAttributes &bufferAttributes, SoundDevice::TimeInfo timeInfo, std::size_t numFrames, SoundDevice::StreamPosition streamPosition) -//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void CMainFrame::SoundSourceDone(const SoundDevice::Settings &settings, const SoundDevice::Flags &flags, const SoundDevice::BufferAttributes &bufferAttributes, SoundDevice::TimeInfo timeInfo) +//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- { MPT_TRACE(); MPT_UNREFERENCED_PARAMETER(settings); MPT_UNREFERENCED_PARAMETER(flags); MPT_UNREFERENCED_PARAMETER(bufferAttributes); - MPT_UNREFERENCED_PARAMETER(timeInfo); - ASSERT(InAudioThread()); + MPT_ASSERT(InAudioThread()); OPENMPT_PROFILE_FUNCTION(Profiler::Notify); - DoNotification(numFrames, streamPosition.Frames); + std::size_t numFrames = static_cast<std::size_t>(timeInfo.RenderStreamPositionAfter.Frames - timeInfo.RenderStreamPositionBefore.Frames); + int64 streamPosition = timeInfo.RenderStreamPositionAfter.Frames; + DoNotification(numFrames, streamPosition); //m_pSndFile->m_TimingInfo = TimingInfo(); // reset } Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2015-04-23 19:56:35 UTC (rev 4978) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2015-04-24 15:21:18 UTC (rev 4979) @@ -411,7 +411,7 @@ bool SoundSourceIsLockedByCurrentThread() const; void SoundSourceLock(); void SoundSourceRead(const SoundDevice::Settings &settings, const SoundDevice::Flags &flags, const SoundDevice::BufferAttributes &bufferAttributes, SoundDevice::TimeInfo timeInfo, std::size_t numFrames, void *buffer); - void SoundSourceDone(const SoundDevice::Settings &settings, const SoundDevice::Flags &flags, const SoundDevice::BufferAttributes &bufferAttributes, SoundDevice::TimeInfo timeInfo, std::size_t numFrames, SoundDevice::StreamPosition streamPosition); + void SoundSourceDone(const SoundDevice::Settings &settings, const SoundDevice::Flags &flags, const SoundDevice::BufferAttributes &bufferAttributes, SoundDevice::TimeInfo timeInfo); void SoundSourceUnlock(); // from SoundDevice::IMessageReceiver Modified: trunk/OpenMPT/sounddev/SoundDevice.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDevice.cpp 2015-04-23 19:56:35 UTC (rev 4978) +++ trunk/OpenMPT/sounddev/SoundDevice.cpp 2015-04-24 15:21:18 UTC (rev 4979) @@ -142,7 +142,6 @@ m_DeviceUnavailableOnOpen = false; m_IsPlaying = false; - m_CurrentUpdateInterval = 0.0; m_StreamPositionRenderFrames = 0; m_StreamPositionOutputFrames = 0; @@ -168,14 +167,6 @@ } -void Base::UpdateTimeInfo(SoundDevice::TimeInfo timeInfo) -//------------------------------------------------------- -{ - MPT_TRACE(); - m_TimeInfo = timeInfo; -} - - bool Base::Init(const SoundDevice::AppInfo &appInfo) //-------------------------------------------------- { @@ -295,37 +286,45 @@ } -void Base::SourceAudioPreRead(std::size_t numFrames) -//-------------------------------------------------- +void Base::SourceAudioPreRead(std::size_t numFrames, std::size_t framesLatency) +//----------------------------------------------------------------------------- { MPT_TRACE(); if(!InternalHasTimeInfo()) { + SoundDevice::TimeInfo timeInfo; if(InternalHasGetStreamPosition()) { - SoundDevice::TimeInfo timeInfo; - timeInfo.StreamFrames = InternalHasGetStreamPosition(); - timeInfo.SystemTimestamp = SourceGetReferenceClockNowNanoseconds(); + timeInfo.SyncPointStreamFrames = InternalHasGetStreamPosition(); + timeInfo.SyncPointSystemTimestamp = SourceGetReferenceClockNowNanoseconds(); timeInfo.Speed = 1.0; - UpdateTimeInfo(timeInfo); } else { - SoundDevice::TimeInfo timeInfo; - { - Util::lock_guard<Util::mutex> lock(m_StreamPositionMutex); - timeInfo.StreamFrames = m_StreamPositionRenderFrames + numFrames; - } - timeInfo.SystemTimestamp = SourceGetReferenceClockNowNanoseconds() + Util::Round<int64>(GetEffectiveBufferAttributes().Latency * 1000000000.0); + timeInfo.SyncPointStreamFrames = m_StreamPositionRenderFrames + numFrames; + timeInfo.SyncPointSystemTimestamp = SourceGetReferenceClockNowNanoseconds() + Util::Round<int64>(GetEffectiveBufferAttributes().Latency * 1000000000.0); timeInfo.Speed = 1.0; - UpdateTimeInfo(timeInfo); } + timeInfo.RenderStreamPositionBefore = StreamPositionFromFrames(m_StreamPositionRenderFrames); + timeInfo.RenderStreamPositionAfter = StreamPositionFromFrames(m_StreamPositionRenderFrames + numFrames); + SetTimeInfo(timeInfo); } + m_StreamPositionRenderFrames += numFrames; + if(!InternalHasGetStreamPosition() && !InternalHasTimeInfo()) + { + Util::lock_guard<Util::mutex> lock(m_StreamPositionMutex); + m_StreamPositionOutputFrames = m_StreamPositionRenderFrames - framesLatency; + } else + { + // unused, no locking + m_StreamPositionOutputFrames = 0; + } } void Base::SourceAudioRead(void *buffer, std::size_t numFrames) //------------------------------------------------------------- { + MPT_TRACE(); if(numFrames <= 0) { return; @@ -334,23 +333,11 @@ } -void Base::SourceAudioDone(std::size_t numFrames, std::size_t framesLatency) -//-------------------------------------------------------------------------- +void Base::SourceAudioDone() +//-------------------------- { MPT_TRACE(); - if(numFrames <= 0) - { - return; - } - int64 framesRendered = 0; - { - Util::lock_guard<Util::mutex> lock(m_StreamPositionMutex); - m_CurrentUpdateInterval = (double)numFrames / (double)m_Settings.Samplerate; - m_StreamPositionRenderFrames += numFrames; - m_StreamPositionOutputFrames = m_StreamPositionRenderFrames - framesLatency; - framesRendered = m_StreamPositionRenderFrames; - } - m_Source->SoundSourceDone(m_Settings, m_Flags, GetEffectiveBufferAttributes(), m_TimeInfo, numFrames, StreamPosition(framesRendered, StreamPositionFramesToSeconds(framesRendered))); + m_Source->SoundSourceDone(m_Settings, m_Flags, GetEffectiveBufferAttributes(), m_TimeInfo); } @@ -373,10 +360,9 @@ if(!IsOpen()) return false; if(!IsPlaying()) { + m_StreamPositionRenderFrames = 0; { Util::lock_guard<Util::mutex> lock(m_StreamPositionMutex); - m_CurrentUpdateInterval = 0.0; - m_StreamPositionRenderFrames = 0; m_StreamPositionOutputFrames = 0; } SourceNotifyPreStart(); @@ -411,23 +397,13 @@ m_IsPlaying = false; { Util::lock_guard<Util::mutex> lock(m_StreamPositionMutex); - m_CurrentUpdateInterval = 0.0; - m_StreamPositionRenderFrames = 0; m_StreamPositionOutputFrames = 0; } + m_StreamPositionRenderFrames = 0; } } -double Base::GetLastUpdateInterval() const -//---------------------------------------- -{ - MPT_TRACE(); - Util::lock_guard<Util::mutex> lock(m_StreamPositionMutex); - return m_CurrentUpdateInterval; -} - - SoundDevice::StreamPosition Base::GetStreamPosition() const //--------------------------------------------------------- { @@ -436,20 +412,25 @@ { return StreamPosition(); } - if(m_Settings.Samplerate <= 0) - { - return StreamPosition(); - } int64 frames = 0; if(InternalHasGetStreamPosition()) { frames = InternalGetStreamPositionFrames(); + } else if(InternalHasTimeInfo()) + { + const uint64 now = SourceGetReferenceClockNowNanoseconds(); + const SoundDevice::TimeInfo timeInfo = GetTimeInfo(); + frames = Util::Round<int64>( + timeInfo.SyncPointStreamFrames + ( + static_cast<double>(static_cast<int64>(now - timeInfo.SyncPointSystemTimestamp)) * timeInfo.Speed * m_Settings.Samplerate * (1.0 / (1000.0 * 1000.0)) + ) + ); } else { Util::lock_guard<Util::mutex> lock(m_StreamPositionMutex); frames = m_StreamPositionOutputFrames; } - return StreamPosition(frames, StreamPositionFramesToSeconds(frames)); + return StreamPositionFromFrames(frames); } @@ -459,7 +440,7 @@ MPT_TRACE(); SoundDevice::Statistics result; result.InstantaneousLatency = m_Settings.Latency; - result.LastUpdateInterval = GetLastUpdateInterval(); + result.LastUpdateInterval = m_Settings.UpdateInterval; result.text = mpt::ustring(); return result; } Modified: trunk/OpenMPT/sounddev/SoundDevice.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDevice.h 2015-04-23 19:56:35 UTC (rev 4978) +++ trunk/OpenMPT/sounddev/SoundDevice.h 2015-04-24 15:21:18 UTC (rev 4979) @@ -37,27 +37,34 @@ }; +struct StreamPosition +{ + int64 Frames; // relative to Start() + double Seconds; // relative to Start() + StreamPosition() : Frames(0), Seconds(0.0) { } + StreamPosition(int64 frames, double seconds) : Frames(frames), Seconds(seconds) { } +}; + + struct TimeInfo { - int64 StreamFrames; // can actually be negative (e.g. when starting the stream) - uint64 SystemTimestamp; + + int64 SyncPointStreamFrames; + uint64 SyncPointSystemTimestamp; double Speed; + + SoundDevice::StreamPosition RenderStreamPositionBefore; + SoundDevice::StreamPosition RenderStreamPositionAfter; + // int64 chunkSize = After - Before + TimeInfo() - : StreamFrames(0) - , SystemTimestamp(0) + : SyncPointStreamFrames(0) + , SyncPointSystemTimestamp(0) , Speed(1.0) { return; } -}; - -struct StreamPosition -{ - int64 Frames; // relative to Start() - double Seconds; // relative to Start() - StreamPosition() : Frames(0), Seconds(0.0) { } - StreamPosition(int64 frames, double seconds) : Frames(frames), Seconds(seconds) { } }; @@ -77,7 +84,7 @@ virtual bool SoundSourceIsLockedByCurrentThread() const = 0; virtual void SoundSourceLock() = 0; virtual void SoundSourceRead(const SoundDevice::Settings &settings, const SoundDevice::Flags &flags, const SoundDevice::BufferAttributes &bufferAttributes, SoundDevice::TimeInfo timeInfo, std::size_t numFrames, void *buffer) = 0; - virtual void SoundSourceDone(const SoundDevice::Settings &settings, const SoundDevice::Flags &flags, const SoundDevice::BufferAttributes &bufferAttributes, SoundDevice::TimeInfo timeInfo, std::size_t numFrames, SoundDevice::StreamPosition streamPosition) = 0; + virtual void SoundSourceDone(const SoundDevice::Settings &settings, const SoundDevice::Flags &flags, const SoundDevice::BufferAttributes &bufferAttributes, SoundDevice::TimeInfo timeInfo) = 0; virtual void SoundSourceUnlock() = 0; public: class Guard @@ -588,9 +595,9 @@ SoundDevice::TimeInfo m_TimeInfo; + int64 m_StreamPositionRenderFrames; // only updated or read in audio CALLBACK or when device is stopped. requires no further locking + mutable Util::mutex m_StreamPositionMutex; - double m_CurrentUpdateInterval; - int64 m_StreamPositionRenderFrames; int64 m_StreamPositionOutputFrames; mpt::atomic_uint32_t m_RequestFlags; @@ -610,9 +617,9 @@ void SourceNotifyPostStop(); bool SourceIsLockedByCurrentThread() const; void SourceFillAudioBufferLocked(); - void SourceAudioPreRead(std::size_t numFrames); + void SourceAudioPreRead(std::size_t numFrames, std::size_t framesLatency); void SourceAudioRead(void *buffer, std::size_t numFrames); - void SourceAudioDone(std::size_t numFrames, std::size_t framesLatency); + void SourceAudioDone(); void RequestClose() { m_RequestFlags.fetch_or(RequestFlagClose); } void RequestReset() { m_RequestFlags.fetch_or(RequestFlagReset); } @@ -622,9 +629,9 @@ protected: - void UpdateTimeInfo(SoundDevice::TimeInfo timeInfo); + void SetTimeInfo(SoundDevice::TimeInfo timeInfo) { m_TimeInfo = timeInfo; } - double StreamPositionFramesToSeconds(int64 frames) const { return static_cast<double>(frames) / static_cast<double>(m_Settings.Samplerate); } + SoundDevice::StreamPosition StreamPositionFromFrames(int64 frames) const { return SoundDevice::StreamPosition(frames, static_cast<double>(frames) / static_cast<double>(m_Settings.Samplerate)); } virtual bool InternalHasTimeInfo() const { return false; } @@ -643,8 +650,6 @@ virtual SoundDevice::BufferAttributes InternalGetEffectiveBufferAttributes() const = 0; - double GetLastUpdateInterval() const; - protected: Base(SoundDevice::Info info); Modified: trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp 2015-04-23 19:56:35 UTC (rev 4978) +++ trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp 2015-04-24 15:21:18 UTC (rev 4979) @@ -879,7 +879,7 @@ } } else { - SourceAudioPreRead(countChunk); + SourceAudioPreRead(countChunk, m_nAsioBufferLen); if(m_Settings.sampleFormat == SampleFormatFloat32) { SourceAudioRead(&m_SampleBufferFloat[0], countChunk); @@ -1008,7 +1008,7 @@ } if(!rendersilence) { - SourceAudioDone(countChunk, m_nAsioBufferLen); + SourceAudioDone(); } } @@ -1021,35 +1021,6 @@ } -bool CASIODevice::InternalHasGetStreamPosition() const -//---------------------------------------------------- -{ - MPT_TRACE(); - return m_Settings.UseHardwareTiming; -} - - -int64 CASIODevice::InternalGetStreamPositionFrames() const -//-------------------------------------------------------- -{ - MPT_TRACE(); - if(m_Settings.UseHardwareTiming) - { - const uint64 asioNow = SourceGetReferenceClockNowNanoseconds(); - SoundDevice::TimeInfo timeInfo = GetTimeInfo(); - int64 currentStreamPositionFrames = - Util::Round<int64>( - timeInfo.StreamFrames + ((double)((int64)(asioNow - timeInfo.SystemTimestamp)) * timeInfo.Speed * m_Settings.Samplerate / (1000.0 * 1000.0)) - ) - ; - return currentStreamPositionFrames; - } else - { - return SoundDevice::Base::InternalGetStreamPositionFrames(); - } -} - - SoundDevice::BufferAttributes CASIODevice::InternalGetEffectiveBufferAttributes() const //------------------------------------------------------------------------------------- { @@ -1061,12 +1032,13 @@ } -void CASIODevice::UpdateTimeInfo(AsioTimeInfo asioTimeInfo) -//--------------------------------------------------------- +void CASIODevice::ApplyAsioTimeInfo(AsioTimeInfo asioTimeInfo) +//------------------------------------------------------------ { MPT_TRACE(); if(m_Settings.UseHardwareTiming) { + SoundDevice::TimeInfo timeInfo; if((asioTimeInfo.flags & kSamplePositionValid) && (asioTimeInfo.flags & kSystemTimeValid)) { double speed = 1.0; @@ -1077,20 +1049,19 @@ { speed *= asioTimeInfo.sampleRate / m_Settings.Samplerate; } - SoundDevice::TimeInfo timeInfo; - timeInfo.StreamFrames = ((((uint64)asioTimeInfo.samplePosition.hi) << 32) | asioTimeInfo.samplePosition.lo) - m_StreamPositionOffset; - timeInfo.SystemTimestamp = (((uint64)asioTimeInfo.systemTime.hi) << 32) | asioTimeInfo.systemTime.lo; + timeInfo.SyncPointStreamFrames = ((((uint64)asioTimeInfo.samplePosition.hi) << 32) | asioTimeInfo.samplePosition.lo) - m_StreamPositionOffset; + timeInfo.SyncPointSystemTimestamp = (((uint64)asioTimeInfo.systemTime.hi) << 32) | asioTimeInfo.systemTime.lo; timeInfo.Speed = speed; - SoundDevice::Base::UpdateTimeInfo(timeInfo); } else { // spec violation or nothing provided at all, better to estimate this stuff ourselves const uint64 asioNow = SourceGetReferenceClockNowNanoseconds(); - SoundDevice::TimeInfo timeInfo; - timeInfo.StreamFrames = m_TotalFramesWritten + m_nAsioBufferLen - m_StreamPositionOffset; - timeInfo.SystemTimestamp = asioNow + Util::Round<int64>(m_BufferLatency * 1000.0 * 1000.0 * 1000.0); + timeInfo.SyncPointStreamFrames = m_TotalFramesWritten + m_nAsioBufferLen - m_StreamPositionOffset; + timeInfo.SyncPointSystemTimestamp = asioNow + Util::Round<int64>(m_BufferLatency * 1000.0 * 1000.0 * 1000.0); timeInfo.Speed = 1.0; - SoundDevice::Base::UpdateTimeInfo(timeInfo); } + timeInfo.RenderStreamPositionBefore = StreamPositionFromFrames(m_TotalFramesWritten - m_StreamPositionOffset); + timeInfo.RenderStreamPositionAfter = StreamPositionFromFrames(m_TotalFramesWritten - m_StreamPositionOffset + m_nAsioBufferLen); + SetTimeInfo(timeInfo); } } @@ -1128,14 +1099,13 @@ } if(m_Settings.UseHardwareTiming) { + AsioTimeInfo asioTimeInfo; + MemsetZero(asioTimeInfo); if(params) { - UpdateTimeInfo(params->timeInfo); + asioTimeInfo = params->timeInfo; } else { - AsioTimeInfo asioTimeInfo; - MemsetZero(asioTimeInfo); - UpdateTimeInfo(asioTimeInfo); try { ASIOSamples samplePosition; @@ -1166,8 +1136,8 @@ { // continue } - UpdateTimeInfo(asioTimeInfo); } + ApplyAsioTimeInfo(asioTimeInfo); } m_BufferIndex = doubleBufferIndex; bool rendersilence = (InterlockedExchangeAdd(&m_RenderSilence, 0) == 1); Modified: trunk/OpenMPT/sounddev/SoundDeviceASIO.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceASIO.h 2015-04-23 19:56:35 UTC (rev 4978) +++ trunk/OpenMPT/sounddev/SoundDeviceASIO.h 2015-04-24 15:21:18 UTC (rev 4979) @@ -83,7 +83,7 @@ mutable mpt::atomic_uint32_t m_DebugRealtimeThreadID; private: - void UpdateTimeInfo(AsioTimeInfo asioTimeInfo); + void ApplyAsioTimeInfo(AsioTimeInfo asioTimeInfo); static bool IsSampleTypeFloat(ASIOSampleType sampleType); static bool IsSampleTypeInt16(ASIOSampleType sampleType); @@ -134,8 +134,6 @@ bool IsDriverOpen() const { return (m_pAsioDrv != nullptr); } bool InternalHasTimeInfo() const; - bool InternalHasGetStreamPosition() const; - int64 InternalGetStreamPositionFrames() const; SoundDevice::BufferAttributes InternalGetEffectiveBufferAttributes() const; Modified: trunk/OpenMPT/sounddev/SoundDeviceDirectSound.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceDirectSound.cpp 2015-04-23 19:56:35 UTC (rev 4978) +++ trunk/OpenMPT/sounddev/SoundDeviceDirectSound.cpp 2015-04-24 15:21:18 UTC (rev 4979) @@ -77,7 +77,8 @@ , m_nDSoundBufferSize(0) , m_bMixRunning(FALSE) , m_dwWritePos(0) - , m_dwLatency(0) + , m_StatisticLatencyFrames(0) + , m_StatisticPeriodFrames(0) { return; } @@ -240,7 +241,6 @@ Close(); return false; } - /////////////////////////////////////////////////// // Create the secondary buffer dsbd.dwSize = sizeof(dsbd); dsbd.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; @@ -355,6 +355,8 @@ return; } + DWORD dwLatency = 0; + for(int refillCount = 0; refillCount < 2; ++refillCount) { // Refill the buffer at most twice so we actually sleep some time when CPU is overloaded. @@ -374,12 +376,12 @@ { // startup m_dwWritePos = dwWrite; - m_dwLatency = 0; + dwLatency = 0; } else { // running - m_dwLatency = (m_dwWritePos - dwPlay + m_nDSoundBufferSize) % m_nDSoundBufferSize; - m_dwLatency = (m_dwLatency + m_nDSoundBufferSize - 1) % m_nDSoundBufferSize + 1; + dwLatency = (m_dwWritePos - dwPlay + m_nDSoundBufferSize) % m_nDSoundBufferSize; + dwLatency = (dwLatency + m_nDSoundBufferSize - 1) % m_nDSoundBufferSize + 1; dwBytes = (dwPlay - m_dwWritePos + m_nDSoundBufferSize) % m_nDSoundBufferSize; dwBytes = Clamp(dwBytes, DWORD(0), m_nDSoundBufferSize/2); // limit refill amount to half the buffer size } @@ -414,7 +416,7 @@ return; } - SourceAudioPreRead(dwSize1/bytesPerFrame + dwSize2/bytesPerFrame); + SourceAudioPreRead(dwSize1/bytesPerFrame + dwSize2/bytesPerFrame, dwLatency/bytesPerFrame); SourceAudioRead(buf1, dwSize1/bytesPerFrame); SourceAudioRead(buf2, dwSize2/bytesPerFrame); @@ -462,7 +464,9 @@ m_bMixRunning = TRUE; } - SourceAudioDone(dwSize1/bytesPerFrame + dwSize2/bytesPerFrame, m_dwLatency/bytesPerFrame); + m_StatisticLatencyFrames.store(dwLatency/bytesPerFrame); + m_StatisticPeriodFrames.store(dwSize1/bytesPerFrame + dwSize2/bytesPerFrame); + SourceAudioDone(); if(dwBytes < m_nDSoundBufferSize/2) { @@ -492,8 +496,8 @@ { MPT_TRACE(); SoundDevice::Statistics result; - result.InstantaneousLatency = 1.0 * m_dwLatency / m_Settings.GetBytesPerSecond(); - result.LastUpdateInterval = GetLastUpdateInterval(); + result.InstantaneousLatency = 1.0 * m_StatisticLatencyFrames.load() / m_Settings.Samplerate; + result.LastUpdateInterval = 1.0 * m_StatisticPeriodFrames.load() / m_Settings.Samplerate; result.text = mpt::ustring(); return result; } Modified: trunk/OpenMPT/sounddev/SoundDeviceDirectSound.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceDirectSound.h 2015-04-23 19:56:35 UTC (rev 4978) +++ trunk/OpenMPT/sounddev/SoundDeviceDirectSound.h 2015-04-24 15:21:18 UTC (rev 4979) @@ -40,8 +40,10 @@ DWORD m_nDSoundBufferSize; BOOL m_bMixRunning; DWORD m_dwWritePos; - DWORD m_dwLatency; + mpt::atomic_uint32_t m_StatisticLatencyFrames; + mpt::atomic_uint32_t m_StatisticPeriodFrames; + public: CDSoundDevice(SoundDevice::Info info); ~CDSoundDevice(); Modified: trunk/OpenMPT/sounddev/SoundDevicePortAudio.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDevicePortAudio.cpp 2015-04-23 19:56:35 UTC (rev 4978) +++ trunk/OpenMPT/sounddev/SoundDevicePortAudio.cpp 2015-04-24 15:21:18 UTC (rev 4979) @@ -40,6 +40,7 @@ CPortaudioDevice::CPortaudioDevice(SoundDevice::Info info) //-------------------------------------------------------- : SoundDevice::Base(info) + , m_StatisticPeriodFrames(0) { m_HostApi = SndDevTypeToHostApi(info.id.GetType()); MemsetZero(m_StreamParameters); @@ -175,9 +176,10 @@ //---------------------------------------------- { if(m_CurrentFrameCount == 0) return; - SourceAudioPreRead(m_CurrentFrameCount); + SourceAudioPreRead(m_CurrentFrameCount, Util::Round<std::size_t>(m_CurrentRealLatency * m_StreamInfo->sampleRate)); SourceAudioRead(m_CurrentFrameBuffer, m_CurrentFrameCount); - SourceAudioDone(m_CurrentFrameCount, Util::Round<std::size_t>(m_CurrentRealLatency * m_StreamInfo->sampleRate)); + m_StatisticPeriodFrames.store(m_CurrentFrameCount); + SourceAudioDone(); } @@ -206,7 +208,7 @@ MPT_TRACE(); SoundDevice::Statistics result; result.InstantaneousLatency = m_CurrentRealLatency; - result.LastUpdateInterval = GetLastUpdateInterval(); + result.LastUpdateInterval = 1.0 * m_StatisticPeriodFrames / m_Settings.Samplerate; result.text = mpt::ustring(); return result; } Modified: trunk/OpenMPT/sounddev/SoundDevicePortAudio.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDevicePortAudio.h 2015-04-23 19:56:35 UTC (rev 4978) +++ trunk/OpenMPT/sounddev/SoundDevicePortAudio.h 2015-04-24 15:21:18 UTC (rev 4979) @@ -44,6 +44,7 @@ unsigned long m_CurrentFrameCount; double m_CurrentRealLatency; // seconds + mpt::atomic_uint32_t m_StatisticPeriodFrames; public: CPortaudioDevice(SoundDevice::Info info); Modified: trunk/OpenMPT/sounddev/SoundDeviceWaveout.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceWaveout.cpp 2015-04-23 19:56:35 UTC (rev 4978) +++ trunk/OpenMPT/sounddev/SoundDeviceWaveout.cpp 2015-04-24 15:21:18 UTC (rev 4979) @@ -259,9 +259,9 @@ ULONG nBytesWritten = 0; while(oldBuffersPending < m_nPreparedHeaders) { - SourceAudioPreRead(m_nWaveBufferSize / bytesPerFrame); + nLatency += m_nWaveBufferSize; + SourceAudioPreRead(m_nWaveBufferSize / bytesPerFrame, nLatency / bytesPerFrame); SourceAudioRead(m_WaveBuffers[m_nWriteBuffer].lpData, m_nWaveBufferSize / bytesPerFrame); - nLatency += m_nWaveBufferSize; nBytesWritten += m_nWaveBufferSize; m_WaveBuffers[m_nWriteBuffer].dwBufferLength = m_nWaveBufferSize; InterlockedIncrement(&m_nBuffersPending); @@ -269,7 +269,7 @@ waveOutWrite(m_hWaveOut, &m_WaveBuffers[m_nWriteBuffer], sizeof(WAVEHDR)); m_nWriteBuffer++; m_nWriteBuffer %= m_nPreparedHeaders; - SourceAudioDone(m_nWaveBufferSize / bytesPerFrame, nLatency / bytesPerFrame); + SourceAudioDone(); } if(m_JustStarted) @@ -338,7 +338,7 @@ MPT_TRACE(); SoundDevice::Statistics result; result.InstantaneousLatency = InterlockedExchangeAdd(&m_nBuffersPending, 0) * m_nWaveBufferSize * 1.0 / m_Settings.GetBytesPerSecond(); - result.LastUpdateInterval = GetLastUpdateInterval(); + result.LastUpdateInterval = 1.0 * m_nWaveBufferSize / m_Settings.GetBytesPerSecond(); result.text = mpt::ustring(); return result; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |