From: <man...@us...> - 2014-09-24 07:33:36
|
Revision: 4306 http://sourceforge.net/p/modplug/code/4306 Author: manxorist Date: 2014-09-24 07:33:28 +0000 (Wed, 24 Sep 2014) Log Message: ----------- [Fix] ASIO: If the corresponding soundcard is currently unavailable, some ASIO drivers allow opening the driver and report zero input and output channels in that case. Other driver do not support loading the driver at all in that case. In both cases, OpenMPT will now disallow selecting the driver in the setup dialog and hide it until restartet or the sound devices get rescanned. This avoids confusion in particular for the case where 0 channels get reported, which until now had the chance of corrupting the channel mapping. Modified Paths: -------------- trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mpdlgs.cpp trunk/OpenMPT/sounddev/SoundDevice.cpp trunk/OpenMPT/sounddev/SoundDevice.h trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2014-09-24 07:28:15 UTC (rev 4305) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2014-09-24 07:33:28 UTC (rev 4306) @@ -836,7 +836,14 @@ SoundDevice::Settings deviceSettings = TrackerSettings::Instance().GetSoundDeviceSettings(deviceID); if(!gpSoundDevice->Open(deviceSettings)) { - Reporting::Error("Unable to open sound device: Could not open sound device."); + if(!gpSoundDevice->IsAvailable()) + { + theApp.GetSoundDevicesManager()->SetDeviceUnavailable(deviceID); + Reporting::Error("Unable to open sound device: Device not available."); + } else + { + Reporting::Error("Unable to open sound device: Could not open sound device."); + } return false; } SampleFormat actualSampleFormat = gpSoundDevice->GetActualSampleFormat(); Modified: trunk/OpenMPT/mptrack/Mpdlgs.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mpdlgs.cpp 2014-09-24 07:28:15 UTC (rev 4305) +++ trunk/OpenMPT/mptrack/Mpdlgs.cpp 2014-09-24 07:33:28 UTC (rev 4306) @@ -157,7 +157,21 @@ , m_CurrentDeviceDynamicCaps(theApp.GetSoundDevicesManager()->GetDeviceDynamicCaps(dev, TrackerSettings::Instance().GetSampleRates(), CMainFrame::GetMainFrame(), CMainFrame::GetMainFrame()->gpSoundDevice, true)) , m_Settings(TrackerSettings::Instance().GetSoundDeviceSettings(dev)) { - return; + if(theApp.GetSoundDevicesManager()->IsDeviceUnavailable(dev)) + { + Reporting::Information("Device not availble. Reverting to default device."); + // if the device is unavailable, use the default device + SoundDevice::ID newdev = theApp.GetSoundDevicesManager()->FindDeviceInfoBestMatch(std::wstring()).id; + if(newdev != dev) + { + Reporting::Information("Device not availble. Reverting to default device."); + SetDevice(newdev); + UpdateEverything(); + } else + { + Reporting::Warning("Device not availble."); + } + } } @@ -172,6 +186,20 @@ { m_Settings = TrackerSettings::Instance().GetSoundDeviceSettings(dev); } + if(theApp.GetSoundDevicesManager()->IsDeviceUnavailable(dev)) + { + // if the device is unavailable, use the default device + SoundDevice::ID newdev = theApp.GetSoundDevicesManager()->FindDeviceInfoBestMatch(std::wstring()).id; + if(newdev != dev) + { + Reporting::Information("Device not availble. Reverting to default device."); + SetDevice(newdev); + UpdateEverything(); + } else + { + Reporting::Warning("Device not availble."); + } + } } @@ -314,7 +342,12 @@ } } + if(theApp.GetSoundDevicesManager()->IsDeviceUnavailable(it->id)) { + continue; + } + + { CString name = mpt::ToCString(it->name); cbi.mask = CBEIF_IMAGE | CBEIF_LPARAM | CBEIF_TEXT | CBEIF_SELECTEDIMAGE | CBEIF_OVERLAY; cbi.iItem = iItem; Modified: trunk/OpenMPT/sounddev/SoundDevice.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDevice.cpp 2014-09-24 07:28:15 UTC (rev 4305) +++ trunk/OpenMPT/sounddev/SoundDevice.cpp 2014-09-24 07:33:28 UTC (rev 4306) @@ -148,6 +148,8 @@ , m_InternalID(internalID) { + m_DeviceUnavailableOnOpen = false; + m_BufferAttributes.Latency = m_Settings.Latency; m_BufferAttributes.UpdateInterval = m_Settings.UpdateInterval; m_BufferAttributes.NumBuffers = 0; @@ -264,6 +266,7 @@ m_Settings.ChannelMapping = SoundDevice::ChannelMapping(m_Settings.Channels); } m_Flags = SoundDevice::Flags(); + m_DeviceUnavailableOnOpen = false; m_BufferAttributes.Latency = m_Settings.Latency; m_BufferAttributes.UpdateInterval = m_Settings.UpdateInterval; m_BufferAttributes.NumBuffers = 0; @@ -451,7 +454,9 @@ //------------------------- { m_SoundDevices.clear(); + m_DeviceUnavailable.clear(); m_DeviceCaps.clear(); + m_DeviceDynamicCaps.clear(); #ifndef NO_PORTAUDIO SndDevPortaudioUnnitialize(); @@ -566,7 +571,7 @@ } if(identifier.empty()) { - return m_SoundDevices[0]; + return *begin(); } for(std::vector<SoundDevice::Info>::const_iterator it = begin(); it != end(); ++it) { @@ -643,6 +648,9 @@ if(dummy) { m_DeviceCaps[id] = dummy->GetDeviceCaps(); + } else + { + SetDeviceUnavailable(id); } delete dummy; } @@ -659,6 +667,10 @@ if(currentSoundDevice && FindDeviceInfo(id).IsValid() && (currentSoundDevice->GetDeviceID() == id) && (currentSoundDevice->GetDeviceInternalID() == FindDeviceInfo(id).internalID)) { m_DeviceDynamicCaps[id] = currentSoundDevice->GetDeviceDynamicCaps(baseSampleRates); + if(!currentSoundDevice->IsAvailable()) + { + SetDeviceUnavailable(id); + } } else { SoundDevice::IBase *dummy = CreateSoundDevice(id); @@ -666,6 +678,13 @@ { dummy->SetMessageReceiver(messageReceiver); m_DeviceDynamicCaps[id] = dummy->GetDeviceDynamicCaps(baseSampleRates); + if(!dummy->IsAvailable()) + { + SetDeviceUnavailable(id); + } + } else + { + SetDeviceUnavailable(id); } delete dummy; } Modified: trunk/OpenMPT/sounddev/SoundDevice.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDevice.h 2014-09-24 07:28:15 UTC (rev 4305) +++ trunk/OpenMPT/sounddev/SoundDevice.h 2014-09-24 07:33:28 UTC (rev 4306) @@ -438,6 +438,7 @@ virtual bool IsInited() const = 0; virtual bool IsOpen() const = 0; + virtual bool IsAvailable() const = 0; virtual bool IsPlaying() const = 0; virtual bool OnIdle() = 0; // return true if any work has been done @@ -485,6 +486,7 @@ SoundDevice::Settings m_Settings; SoundDevice::Flags m_Flags; + bool m_DeviceUnavailableOnOpen; private: @@ -572,6 +574,7 @@ bool IsInited() const { return m_Caps.Available; } bool IsOpen() const { return IsInited() && InternalIsOpen(); } + bool IsAvailable() const { return m_Caps.Available && !m_DeviceUnavailableOnOpen; } bool IsPlaying() const { return m_IsPlaying; } virtual bool OnIdle() { return false; } @@ -648,6 +651,7 @@ { private: std::vector<SoundDevice::Info> m_SoundDevices; + std::map<SoundDevice::ID, bool> m_DeviceUnavailable; std::map<SoundDevice::ID, SoundDevice::Caps> m_DeviceCaps; std::map<SoundDevice::ID, SoundDevice::DynamicCaps> m_DeviceDynamicCaps; @@ -669,6 +673,9 @@ bool OpenDriverSettings(SoundDevice::ID id, SoundDevice::IMessageReceiver *messageReceiver = nullptr, SoundDevice::IBase *currentSoundDevice = nullptr); + void SetDeviceUnavailable(SoundDevice::ID id) { m_DeviceUnavailable[id] = true; } + bool IsDeviceUnavailable(SoundDevice::ID id) { return m_DeviceUnavailable[id]; } + SoundDevice::Caps GetDeviceCaps(SoundDevice::ID id, SoundDevice::IBase *currentSoundDevice = nullptr); SoundDevice::DynamicCaps GetDeviceDynamicCaps(SoundDevice::ID id, const std::vector<uint32> &baseSampleRates, SoundDevice::IMessageReceiver *messageReceiver = nullptr, SoundDevice::IBase *currentSoundDevice = nullptr, bool update = false); Modified: trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp 2014-09-24 07:28:15 UTC (rev 4305) +++ trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp 2014-09-24 07:33:28 UTC (rev 4306) @@ -268,6 +268,11 @@ long outputChannels = 0; asioCall(getChannels(&inputChannels, &outputChannels)); Log(mpt::String::Print("ASIO: getChannels() => inputChannels=%1 outputChannel=%2", inputChannels, outputChannels)); + if(inputChannels <= 0 && outputChannels <= 0) + { + m_DeviceUnavailableOnOpen = true; + throw ASIOException("Device unavailble."); + } if(m_Settings.Channels > outputChannels) { throw ASIOException("Not enough output channels."); @@ -1350,6 +1355,7 @@ TemporaryASIODriverOpener opener(*this); if(!IsDriverOpen()) { + m_DeviceUnavailableOnOpen = true; return caps; } @@ -1386,6 +1392,10 @@ long inputChannels = 0; long outputChannels = 0; asioCall(getChannels(&inputChannels, &outputChannels)); + if(!((inputChannels > 0) || (outputChannels > 0))) + { + m_DeviceUnavailableOnOpen = true; + } for(long i = 0; i < outputChannels; ++i) { ASIOChannelInfo channelInfo; @@ -1408,7 +1418,6 @@ { // continue } - return caps; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |