From: <man...@us...> - 2013-11-15 06:27:36
|
Revision: 3226 http://sourceforge.net/p/modplug/code/3226 Author: manxorist Date: 2013-11-15 06:27:22 +0000 (Fri, 15 Nov 2013) Log Message: ----------- [Ref] sounddev: Cleanup and reorder the ISoundDevice interface so that the class definition is almost readable as documentation. [Ref] sounddev: Return time values as double seconds instead of float milliseconds. [Ref] sounddev: Cleanup sound device opening in CMainFrame and provide slithly better error messages. Modified Paths: -------------- trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Mpdlgs.cpp 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 trunk/OpenMPT/sounddev/SoundDeviceWaveout.h Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2013-11-15 06:27:22 UTC (rev 3226) @@ -747,9 +747,25 @@ } -bool CMainFrame::audioTryOpeningDevice() -//-------------------------------------- +bool CMainFrame::IsAudioDeviceOpen() const +//---------------------------------------- { + return gpSoundDevice && gpSoundDevice->IsOpen(); +} + + +bool CMainFrame::audioOpenDevice() +//-------------------------------- +{ + if(IsAudioDeviceOpen()) + { + return true; + } + if(!TrackerSettings::Instance().GetMixerSettings().IsValid()) + { + Reporting::Error("Unable to open sound device: Invalid mixer settings."); + return false; + } const SoundDeviceID deviceID = TrackerSettings::Instance().m_nWaveDevice; if(gpSoundDevice && (gpSoundDevice->GetDeviceID() != deviceID)) { @@ -762,48 +778,24 @@ } if(!gpSoundDevice) { + Reporting::Error("Unable to open sound device: Could not find sound device."); return false; } gpSoundDevice->SetMessageReceiver(this); gpSoundDevice->SetSource(this); if(!gpSoundDevice->Open(TrackerSettings::Instance().GetSoundDeviceSettings())) { + Reporting::Error("Unable to open sound device: Could not open sound device."); return false; } - return true; -} - - -bool CMainFrame::IsAudioDeviceOpen() const -//---------------------------------------- -{ - return gpSoundDevice && gpSoundDevice->IsOpen(); -} - - -bool CMainFrame::audioOpenDevice() -//-------------------------------- -{ - if(IsAudioDeviceOpen()) + SampleFormat actualSampleFormat = gpSoundDevice->GetActualSampleFormat(); + if(!actualSampleFormat.IsValid()) { - return true; + Reporting::Error("Unable to open sound device: Unknown sample format."); + return false; } - if(TrackerSettings::Instance().GetMixerSettings().IsValid()) - { - if(audioTryOpeningDevice()) - { - SampleFormat actualSampleFormat = gpSoundDevice->GetActualSampleFormat(); - if(actualSampleFormat.IsValid()) - { - TrackerSettings::Instance().m_SampleFormat = actualSampleFormat; - // Device is ready - return true; - } - } - } - // Display error message box - Reporting::Error("Unable to open sound device!"); - return false; + TrackerSettings::Instance().m_SampleFormat = actualSampleFormat; + return true; } Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2013-11-15 06:27:22 UTC (rev 3226) @@ -335,7 +335,6 @@ // from ISoundMessageReceiver void AudioMessage(const std::string &str); - bool audioTryOpeningDevice(); bool audioOpenDevice(); bool audioReopenDevice(); void audioCloseDevice(); Modified: trunk/OpenMPT/mptrack/Mpdlgs.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mpdlgs.cpp 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/mptrack/Mpdlgs.cpp 2013-11-15 06:27:22 UTC (rev 3226) @@ -545,10 +545,10 @@ { CHAR s[256]; _snprintf(s, 255, "Buffers: %d\r\nUpdate interval: %4.1f ms\r\nLatency: %4.1f ms\r\nCurrent Latency: %4.1f ms", - pMainFrm->gpSoundDevice->GetNumBuffers(), - (float)pMainFrm->gpSoundDevice->GetRealUpdateIntervalMS(), - (float)pMainFrm->gpSoundDevice->GetRealLatencyMS(), - (float)pMainFrm->gpSoundDevice->GetCurrentRealLatencyMS() + pMainFrm->gpSoundDevice->GetRealNumBuffers(), + (float)(pMainFrm->gpSoundDevice->GetRealUpdateInterval() * 1000.0f), + (float)(pMainFrm->gpSoundDevice->GetRealLatency() * 1000.0f), + (float)(pMainFrm->gpSoundDevice->GetCurrentRealLatency() * 1000.0f) ); m_EditStatistics.SetWindowText(s); } else Modified: trunk/OpenMPT/sounddev/SoundDevice.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDevice.cpp 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/sounddev/SoundDevice.cpp 2013-11-15 06:27:22 UTC (rev 3226) @@ -39,8 +39,9 @@ , m_InternalID(internalID) { - m_RealLatencyMS = static_cast<float>(m_Settings.LatencyMS); - m_RealUpdateIntervalMS = static_cast<float>(m_Settings.UpdateIntervalMS); + m_RealLatency = m_Settings.LatencyMS / 1000.0; + m_RealUpdateInterval = m_Settings.UpdateIntervalMS / 1000.0; + m_RealNumBuffers = 0; m_IsPlaying = false; m_StreamPositionRenderFrames = 0; @@ -109,8 +110,9 @@ if(m_Settings.LatencyMS > SNDDEV_MAXLATENCY_MS) m_Settings.LatencyMS = SNDDEV_MAXLATENCY_MS; if(m_Settings.UpdateIntervalMS < SNDDEV_MINUPDATEINTERVAL_MS) m_Settings.UpdateIntervalMS = SNDDEV_MINUPDATEINTERVAL_MS; if(m_Settings.UpdateIntervalMS > SNDDEV_MAXUPDATEINTERVAL_MS) m_Settings.UpdateIntervalMS = SNDDEV_MAXUPDATEINTERVAL_MS; - m_RealLatencyMS = static_cast<float>(m_Settings.LatencyMS); - m_RealUpdateIntervalMS = static_cast<float>(m_Settings.UpdateIntervalMS); + m_RealLatency = m_Settings.LatencyMS / 1000.0; + m_RealUpdateInterval = m_Settings.UpdateIntervalMS / 1000.0; + m_RealNumBuffers = 0; return InternalOpen(); } @@ -525,7 +527,7 @@ { CPriorityBooster priorityBooster(*this, m_SoundDevice.m_Settings.BoostThreadPriority); - CPeriodicWaker periodicWaker(*this, 0.001 * m_SoundDevice.GetRealUpdateIntervalMS()); + CPeriodicWaker periodicWaker(*this, m_SoundDevice.GetRealUpdateInterval()); m_SoundDevice.StartFromSoundThread(); Modified: trunk/OpenMPT/sounddev/SoundDevice.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDevice.h 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/sounddev/SoundDevice.h 2013-11-15 06:27:22 UTC (rev 3226) @@ -219,15 +219,18 @@ const SoundDeviceID m_ID; + std::wstring m_InternalID; + protected: - std::wstring m_InternalID; - SoundDeviceSettings m_Settings; - float m_RealLatencyMS; - float m_RealUpdateIntervalMS; +private: + double m_RealLatency; + double m_RealUpdateInterval; + int m_RealNumBuffers; + bool m_IsPlaying; mutable Util::mutex m_StreamPositionMutex; @@ -235,20 +238,46 @@ int64 m_StreamPositionOutputFrames; protected: + virtual void FillAudioBuffer() = 0; + void SourceFillAudioBufferLocked(); void SourceAudioRead(void *buffer, std::size_t numFrames); void SourceAudioDone(std::size_t numFrames, int32 framesLatency); + void AudioSendMessage(const std::string &str); +protected: + + bool FillWaveFormatExtensible(WAVEFORMATEXTENSIBLE &WaveFormat); + + void UpdateLatencyInfo(double latency, double updateInterval, int numBuffers) + { + m_RealLatency = latency; + m_RealUpdateInterval = updateInterval; + m_RealNumBuffers = numBuffers; + } + + virtual bool InternalHasGetStreamPosition() const { return false; } + virtual int64 InternalGetStreamPositionFrames() const { return 0; } + + virtual bool InternalIsOpen() const = 0; + + virtual bool InternalOpen() = 0; + virtual void InternalStart() = 0; + virtual void InternalStop() = 0; + virtual bool InternalClose() = 0; + public: + ISoundDevice(SoundDeviceID id, const std::wstring &internalID); virtual ~ISoundDevice(); + void SetSource(ISoundSource *source) { m_Source = source; } ISoundSource *GetSource() const { return m_Source; } void SetMessageReceiver(ISoundMessageReceiver *receiver) { m_MessageReceiver = receiver; } ISoundMessageReceiver *GetMessageReceiver() const { return m_MessageReceiver; } -public: + SoundDeviceID GetDeviceID() const { return m_ID; } SoundDeviceType GetDeviceType() const { return m_ID.GetType(); } SoundDeviceIndex GetDeviceIndex() const { return m_ID.GetIndex(); } @@ -256,32 +285,24 @@ virtual SoundDeviceCaps GetDeviceCaps(const std::vector<uint32> &baseSampleRates); -public: - float GetRealLatencyMS() const { return m_RealLatencyMS; } - float GetRealUpdateIntervalMS() const { return m_RealUpdateIntervalMS; } + bool Open(const SoundDeviceSettings &settings); + bool Close(); + void Start(); + void Stop(); + + bool IsOpen() const { return InternalIsOpen(); } bool IsPlaying() const { return m_IsPlaying; } -protected: - bool FillWaveFormatExtensible(WAVEFORMATEXTENSIBLE &WaveFormat); + SampleFormat GetActualSampleFormat() { return IsOpen() ? m_Settings.sampleFormat : SampleFormatInvalid; } -protected: - virtual bool InternalOpen() = 0; - virtual void InternalStart() = 0; - virtual void InternalStop() = 0; - virtual bool InternalClose() = 0; - virtual bool InternalHasGetStreamPosition() const { return false; } - virtual int64 InternalGetStreamPositionFrames() const { return 0; } + double GetRealLatency() const { return m_RealLatency; } // seconds + double GetRealUpdateInterval() const { return m_RealUpdateInterval; } // seconds + int GetRealNumBuffers() const { return m_RealNumBuffers; } -public: - bool Open(const SoundDeviceSettings &settings); - bool Close(); - void Start(); - void Stop(); + virtual double GetCurrentRealLatency() const { return GetRealLatency(); } + int64 GetStreamPositionFrames() const; - SampleFormat GetActualSampleFormat() { return IsOpen() ? m_Settings.sampleFormat : SampleFormatInvalid; } - virtual bool IsOpen() const = 0; - virtual UINT GetNumBuffers() { return 0; } - virtual float GetCurrentRealLatencyMS() { return GetRealLatencyMS(); } + }; Modified: trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp 2013-11-15 06:27:22 UTC (rev 3226) @@ -270,8 +270,10 @@ } m_nAsioBufferLen = n; } - m_RealLatencyMS = m_nAsioBufferLen * 2 * 1000.0f / m_Settings.Samplerate; - m_RealUpdateIntervalMS = m_nAsioBufferLen * 1000.0f / m_Settings.Samplerate; + UpdateLatencyInfo( + m_nAsioBufferLen * 2.0 / m_Settings.Samplerate, + m_nAsioBufferLen * 1.0 / m_Settings.Samplerate, + 2); #ifdef ASIO_LOG Log(" Using buffersize=%d samples\n", m_nAsioBufferLen); #endif Modified: trunk/OpenMPT/sounddev/SoundDeviceASIO.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceASIO.h 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/sounddev/SoundDeviceASIO.h 2013-11-15 06:27:22 UTC (rev 3226) @@ -61,9 +61,7 @@ void FillAudioBuffer(); void InternalStart(); void InternalStop(); - bool IsOpen() const { return (m_pAsioDrv != nullptr); } - UINT GetNumBuffers() { return 2; } - float GetCurrentRealLatencyMS() { return m_nAsioBufferLen * 2 * 1000.0f / m_Settings.Samplerate; } + bool InternalIsOpen() const { return (m_pAsioDrv != nullptr); } SoundDeviceCaps GetDeviceCaps(const std::vector<uint32> &baseSampleRates); Modified: trunk/OpenMPT/sounddev/SoundDeviceDirectSound.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceDirectSound.cpp 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/sounddev/SoundDeviceDirectSound.cpp 2013-11-15 06:27:22 UTC (rev 3226) @@ -251,8 +251,10 @@ m_pMixBuffer->GetStatus(&dwStat); if (dwStat & DSBSTATUS_BUFFERLOST) m_pMixBuffer->Restore(); } - m_RealLatencyMS = m_nDSoundBufferSize * 1000.0f / m_Settings.GetBytesPerSecond(); - m_RealUpdateIntervalMS = CLAMP(static_cast<float>(m_Settings.UpdateIntervalMS), 1.0f, m_nDSoundBufferSize * 1000.0f / ( 2.0f * m_Settings.GetBytesPerSecond() ) ); + UpdateLatencyInfo( + m_nDSoundBufferSize * 1.0 / m_Settings.GetBytesPerSecond(), + std::min(m_Settings.UpdateIntervalMS / 1000.0, m_nDSoundBufferSize / (2.0 * m_Settings.GetBytesPerSecond())), + 1); m_dwWritePos = 0xFFFFFFFF; return true; } Modified: trunk/OpenMPT/sounddev/SoundDeviceDirectSound.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceDirectSound.h 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/sounddev/SoundDeviceDirectSound.h 2013-11-15 06:27:22 UTC (rev 3226) @@ -45,9 +45,8 @@ void FillAudioBuffer(); void StartFromSoundThread(); void StopFromSoundThread(); - bool IsOpen() const { return (m_pMixBuffer != NULL); } - UINT GetNumBuffers() { return 1; } // meaning 1 ring buffer - float GetCurrentRealLatencyMS() { return m_dwLatency * 1000.0f / m_Settings.GetBytesPerSecond(); } + bool InternalIsOpen() const { return (m_pMixBuffer != NULL); } + double GetCurrentRealLatency() const { return 1.0 * m_dwLatency / m_Settings.GetBytesPerSecond(); } SoundDeviceCaps GetDeviceCaps(const std::vector<uint32> &baseSampleRates); protected: Modified: trunk/OpenMPT/sounddev/SoundDevicePortAudio.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDevicePortAudio.cpp 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/sounddev/SoundDevicePortAudio.cpp 2013-11-15 06:27:22 UTC (rev 3226) @@ -34,7 +34,7 @@ MemsetZero(m_StreamParameters); m_Stream = 0; m_CurrentFrameCount = 0; - m_CurrentRealLatencyMS = 0.0f; + m_CurrentRealLatency = 0.0; } @@ -89,8 +89,10 @@ m_Stream = 0; return false; } - m_RealLatencyMS = static_cast<float>(Pa_GetStreamInfo(m_Stream)->outputLatency) * 1000.0f; - m_RealUpdateIntervalMS = static_cast<float>(m_Settings.UpdateIntervalMS); + UpdateLatencyInfo( + Pa_GetStreamInfo(m_Stream)->outputLatency, + m_Settings.UpdateIntervalMS / 1000.0, + 1); return true; } @@ -102,7 +104,10 @@ { Pa_AbortStream(m_Stream); Pa_CloseStream(m_Stream); - if(Pa_GetDeviceInfo(m_StreamParameters.device)->hostApi == Pa_HostApiTypeIdToHostApiIndex(paWDMKS)) Pa_Sleep((long)(m_RealLatencyMS*2)); // wait for broken wdm drivers not closing the stream immediatly + if(Pa_GetDeviceInfo(m_StreamParameters.device)->hostApi == Pa_HostApiTypeIdToHostApiIndex(paWDMKS)) + { + Pa_Sleep((long)(GetRealLatency() * 2.0 * 1000.0)); // wait for broken wdm drivers not closing the stream immediatly + } MemsetZero(m_StreamParameters); m_Stream = 0; m_CurrentFrameCount = 0; @@ -131,7 +136,7 @@ { if(m_CurrentFrameCount == 0) return; SourceAudioRead(m_CurrentFrameBuffer, m_CurrentFrameCount); - SourceAudioDone(m_CurrentFrameCount, static_cast<ULONG>(m_CurrentRealLatencyMS * Pa_GetStreamInfo(m_Stream)->sampleRate / 1000.0f)); + SourceAudioDone(m_CurrentFrameCount, static_cast<ULONG>(m_CurrentRealLatency * Pa_GetStreamInfo(m_Stream)->sampleRate)); } @@ -143,10 +148,10 @@ } -float CPortaudioDevice::GetCurrentRealLatencyMS() -//----------------------------------------------- +double CPortaudioDevice::GetCurrentRealLatency() const +//---------------------------------------------------- { - return m_CurrentRealLatencyMS; + return m_CurrentRealLatency; } @@ -201,10 +206,10 @@ { // For WDM-KS, timeInfo->outputBufferDacTime seems to contain bogus values. // Work-around it by using the slightly less accurate per-stream latency estimation. - m_CurrentRealLatencyMS = static_cast<float>( Pa_GetStreamInfo(m_Stream)->outputLatency * 1000.0 ); + m_CurrentRealLatency = Pa_GetStreamInfo(m_Stream)->outputLatency; } else { - m_CurrentRealLatencyMS = static_cast<float>( timeInfo->outputBufferDacTime - timeInfo->currentTime ) * 1000.0f; + m_CurrentRealLatency = timeInfo->outputBufferDacTime - timeInfo->currentTime; } m_CurrentFrameBuffer = output; m_CurrentFrameCount = frameCount; Modified: trunk/OpenMPT/sounddev/SoundDevicePortAudio.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDevicePortAudio.h 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/sounddev/SoundDevicePortAudio.h 2013-11-15 06:27:22 UTC (rev 3226) @@ -36,7 +36,7 @@ void * m_CurrentFrameBuffer; unsigned long m_CurrentFrameCount; - float m_CurrentRealLatencyMS; + double m_CurrentRealLatency; // seconds public: CPortaudioDevice(SoundDeviceID id, const std::wstring &internalID); @@ -48,9 +48,8 @@ void FillAudioBuffer(); void InternalStart(); void InternalStop(); - bool IsOpen() const { return m_Stream ? true : false; } - UINT GetNumBuffers() { return 1; } - float GetCurrentRealLatencyMS(); + bool InternalIsOpen() const { return m_Stream ? true : false; } + double GetCurrentRealLatency() const; bool InternalHasGetStreamPosition() const { return false; } int64 InternalGetStreamPositionFrames() const; SoundDeviceCaps GetDeviceCaps(const std::vector<uint32> &baseSampleRates); Modified: trunk/OpenMPT/sounddev/SoundDeviceWaveout.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceWaveout.cpp 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/sounddev/SoundDeviceWaveout.cpp 2013-11-15 06:27:22 UTC (rev 3226) @@ -93,8 +93,10 @@ Close(); return false; } - m_RealLatencyMS = m_nWaveBufferSize * m_nPreparedHeaders * 1000.0f / m_Settings.GetBytesPerSecond(); - m_RealUpdateIntervalMS = m_nWaveBufferSize * 1000.0f / m_Settings.GetBytesPerSecond(); + UpdateLatencyInfo( + m_nWaveBufferSize * m_nPreparedHeaders * 1.0 / m_Settings.GetBytesPerSecond(), + m_nWaveBufferSize * 1.0 / m_Settings.GetBytesPerSecond(), + m_nPreparedHeaders); m_nBuffersPending = 0; m_nWriteBuffer = 0; return true; Modified: trunk/OpenMPT/sounddev/SoundDeviceWaveout.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceWaveout.h 2013-11-14 23:10:53 UTC (rev 3225) +++ trunk/OpenMPT/sounddev/SoundDeviceWaveout.h 2013-11-15 06:27:22 UTC (rev 3226) @@ -30,7 +30,7 @@ bool m_JustStarted; ULONG m_nPreparedHeaders; ULONG m_nWriteBuffer; - LONG m_nBuffersPending; + mutable LONG m_nBuffersPending; std::vector<WAVEHDR> m_WaveBuffers; std::vector<std::vector<char> > m_WaveBuffersData; @@ -44,9 +44,8 @@ void FillAudioBuffer(); void StartFromSoundThread(); void StopFromSoundThread(); - bool IsOpen() const { return (m_hWaveOut != NULL); } - UINT GetNumBuffers() { return m_nPreparedHeaders; } - float GetCurrentRealLatencyMS() { return InterlockedExchangeAdd(&m_nBuffersPending, 0) * m_nWaveBufferSize * 1000.0f / m_Settings.GetBytesPerSecond(); } + bool InternalIsOpen() const { return (m_hWaveOut != NULL); } + double GetCurrentRealLatency() const { return InterlockedExchangeAdd(&m_nBuffersPending, 0) * m_nWaveBufferSize * 1.0 / m_Settings.GetBytesPerSecond(); } bool InternalHasGetStreamPosition() const { return true; } int64 InternalGetStreamPositionFrames() const; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |