From: <man...@us...> - 2015-02-09 17:56:37
|
Revision: 4745 http://sourceforge.net/p/modplug/code/4745 Author: manxorist Date: 2015-02-09 17:56:30 +0000 (Mon, 09 Feb 2015) Log Message: ----------- [Ref] sounddev: Split class SoundDevice::Manager into separate SoundDeviceManager.* files. Modified Paths: -------------- trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mpdlgs.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/sounddev/SoundDevice.cpp trunk/OpenMPT/sounddev/SoundDevice.h Added Paths: ----------- trunk/OpenMPT/sounddev/SoundDeviceManager.cpp trunk/OpenMPT/sounddev/SoundDeviceManager.h Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2015-02-08 14:06:34 UTC (rev 4744) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2015-02-09 17:56:30 UTC (rev 4745) @@ -12,6 +12,7 @@ #include "mptrack.h" #include "MainFrm.h" #include "../sounddev/SoundDevice.h" +#include "../sounddev/SoundDeviceManager.h" #include "../soundlib/AudioReadTarget.h" #include "moddoc.h" #include "childfrm.h" Modified: trunk/OpenMPT/mptrack/Mpdlgs.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mpdlgs.cpp 2015-02-08 14:06:34 UTC (rev 4744) +++ trunk/OpenMPT/mptrack/Mpdlgs.cpp 2015-02-09 17:56:30 UTC (rev 4745) @@ -16,9 +16,10 @@ #include "mpdlgs.h" #include "moptions.h" #include "moddoc.h" -#include "../sounddev/SoundDevice.h" #include "mpdlgs.h" #include "../common/StringFixer.h" +#include "../sounddev/SoundDevice.h" +#include "../sounddev/SoundDeviceManager.h" OPENMPT_NAMESPACE_BEGIN Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2015-02-08 14:06:34 UTC (rev 4744) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2015-02-09 17:56:30 UTC (rev 4745) @@ -32,6 +32,7 @@ #include "PNG.h" #include "../common/ComponentManager.h" #include "WelcomeDialog.h" +#include "../sounddev/SoundDeviceManager.h" // rewbs.memLeak #define _CRTDBG_MAP_ALLOC Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp 2015-02-08 14:06:34 UTC (rev 4744) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp 2015-02-09 17:56:30 UTC (rev 4745) @@ -14,6 +14,7 @@ #include "Moddoc.h" #include "Mainfrm.h" #include "../sounddev/SoundDevice.h" +#include "../sounddev/SoundDeviceManager.h" #include "../common/version.h" #include "UpdateCheck.h" #include "Mpdlgs.h" Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2015-02-08 14:06:34 UTC (rev 4744) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2015-02-09 17:56:30 UTC (rev 4745) @@ -768,6 +768,10 @@ > </File> <File + RelativePath="..\sounddev\SoundDeviceManager.cpp" + > + </File> + <File RelativePath="..\sounddev\SoundDeviceASIO.cpp" > </File> @@ -1510,6 +1514,10 @@ > </File> <File + RelativePath="..\sounddev\SoundDeviceManager.h" + > + </File> + <File RelativePath="..\sounddev\SoundDeviceASIO.h" > </File> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2015-02-08 14:06:34 UTC (rev 4744) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2015-02-09 17:56:30 UTC (rev 4745) @@ -740,6 +740,7 @@ <ClCompile Include="..\sounddev\SoundDevice.cpp" /> <ClCompile Include="..\sounddev\SoundDeviceASIO.cpp" /> <ClCompile Include="..\sounddev\SoundDeviceDirectSound.cpp" /> + <ClCompile Include="..\sounddev\SoundDeviceManager.cpp" /> <ClCompile Include="..\sounddev\SoundDevicePortAudio.cpp" /> <ClCompile Include="..\sounddev\SoundDeviceThread.cpp" /> <ClCompile Include="..\sounddev\SoundDeviceWaveout.cpp" /> @@ -967,6 +968,7 @@ <ClInclude Include="..\sounddev\SoundDevice.h" /> <ClInclude Include="..\sounddev\SoundDeviceASIO.h" /> <ClInclude Include="..\sounddev\SoundDeviceDirectSound.h" /> + <ClInclude Include="..\sounddev\SoundDeviceManager.h" /> <ClInclude Include="..\sounddev\SoundDevicePortAudio.h" /> <ClInclude Include="..\sounddev\SoundDeviceThread.h" /> <ClInclude Include="..\sounddev\SoundDeviceWaveout.h" /> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2015-02-08 14:06:34 UTC (rev 4744) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2015-02-09 17:56:30 UTC (rev 4745) @@ -544,6 +544,9 @@ <ClCompile Include="PatternFont.cpp"> <Filter>Source Files\mptrack</Filter> </ClCompile> + <ClCompile Include="..\sounddev\SoundDeviceManager.cpp"> + <Filter>Source Files\sounddev</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\soundlib\Loaders.h"> @@ -1065,6 +1068,9 @@ <ClInclude Include="PatternFont.h"> <Filter>Header Files\mptrack</Filter> </ClInclude> + <ClInclude Include="..\sounddev\SoundDeviceManager.h"> + <Filter>Header Files\sounddev</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="res\bitmap1.bmp"> Modified: trunk/OpenMPT/sounddev/SoundDevice.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDevice.cpp 2015-02-08 14:06:34 UTC (rev 4744) +++ trunk/OpenMPT/sounddev/SoundDevice.cpp 2015-02-09 17:56:30 UTC (rev 4745) @@ -16,13 +16,6 @@ #include "../common/misc_util.h" #include "../common/StringFixer.h" -#include "SoundDeviceASIO.h" -#include "SoundDeviceDirectSound.h" -#include "SoundDevicePortAudio.h" -#include "SoundDeviceWaveout.h" - -#include <algorithm> - #include <mmreg.h> @@ -459,337 +452,6 @@ } -/////////////////////////////////////////////////////////////////////////////////////// -// -// Global Functions -// - - -void Manager::ReEnumerate(SoundDevice::TypesSet enabledTypes) -//----------------------------------------------------------- -{ - m_SoundDevices.clear(); - m_DeviceUnavailable.clear(); - m_DeviceCaps.clear(); - m_DeviceDynamicCaps.clear(); - -#ifndef NO_PORTAUDIO - if(IsComponentAvailable(m_PortAudio)) - { - m_PortAudio->ReInit(); - } -#endif // NO_PORTAUDIO - - if(enabledTypes[SoundDevice::TypeWAVEOUT]) - { - const std::vector<SoundDevice::Info> infos = CWaveDevice::EnumerateDevices(); - m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); - } -#ifndef NO_ASIO - if(enabledTypes[SoundDevice::TypeASIO]) - { - const std::vector<SoundDevice::Info> infos = CASIODevice::EnumerateDevices(); - m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); - } -#endif // NO_ASIO -#ifndef NO_PORTAUDIO - if(IsComponentAvailable(m_PortAudio) && enabledTypes[SoundDevice::TypePORTAUDIO_WASAPI]) - { - const std::vector<SoundDevice::Info> infos = CPortaudioDevice::EnumerateDevices(TypePORTAUDIO_WASAPI); - m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); - } - if(IsComponentAvailable(m_PortAudio) && enabledTypes[SoundDevice::TypePORTAUDIO_WDMKS]) - { - const std::vector<SoundDevice::Info> infos = CPortaudioDevice::EnumerateDevices(TypePORTAUDIO_WDMKS); - m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); - } -#endif // NO_PORTAUDIO - - // kind of deprecated by now -#ifndef NO_DSOUND - if(enabledTypes[SoundDevice::TypeDSOUND]) - { - const std::vector<SoundDevice::Info> infos = CDSoundDevice::EnumerateDevices(); - m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); - } -#endif // NO_DSOUND - - // duplicate devices, only used if [Sound Settings]MorePortaudio=1 -#ifndef NO_PORTAUDIO - if(IsComponentAvailable(m_PortAudio) && enabledTypes[SoundDevice::TypePORTAUDIO_WMME]) - { - const std::vector<SoundDevice::Info> infos = CPortaudioDevice::EnumerateDevices(TypePORTAUDIO_WMME); - m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); - } - if(IsComponentAvailable(m_PortAudio) && enabledTypes[SoundDevice::TypePORTAUDIO_ASIO]) - { - const std::vector<SoundDevice::Info> infos = CPortaudioDevice::EnumerateDevices(TypePORTAUDIO_ASIO); - m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); - } - if(IsComponentAvailable(m_PortAudio) && enabledTypes[SoundDevice::TypePORTAUDIO_DS]) - { - const std::vector<SoundDevice::Info> infos = CPortaudioDevice::EnumerateDevices(TypePORTAUDIO_DS); - m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); - } -#endif // NO_PORTAUDIO - -} - - -SoundDevice::Info Manager::FindDeviceInfo(SoundDevice::ID id) const -//----------------------------------------------------------------- -{ - for(std::vector<SoundDevice::Info>::const_iterator it = begin(); it != end(); ++it) - { - if(it->id == id) - { - return *it; - } - } - return SoundDevice::Info(); -} - - -SoundDevice::Info Manager::FindDeviceInfo(SoundDevice::Identifier identifier) const -//--------------------------------------------------------------------------------- -{ - if(m_SoundDevices.empty()) - { - return SoundDevice::Info(); - } - if(identifier.empty()) - { - return m_SoundDevices[0]; - } - for(std::vector<SoundDevice::Info>::const_iterator it = begin(); it != end(); ++it) - { - if(it->GetIdentifier() == identifier) - { - return *it; - } - } - return SoundDevice::Info(); -} - - -SoundDevice::Type ParseType(const SoundDevice::Identifier &identifier) -//-------------------------------------------------------------------- -{ - for(int i = 0; i < TypeNUM_DEVTYPES; ++i) - { - const mpt::ustring api = SoundDevice::TypeToString(static_cast<SoundDevice::Type>(i)); - if(identifier.find(api) == 0) - { - return static_cast<SoundDevice::Type>(i); - } - } - return TypeINVALID; -} - - -SoundDevice::Info Manager::FindDeviceInfoBestMatch(SoundDevice::Identifier identifier, bool preferSameType) -//--------------------------------------------------------------------------------------------------------- -{ - if(m_SoundDevices.empty()) - { - return SoundDevice::Info(); - } - if(identifier.empty()) - { - return *begin(); - } - for(std::vector<SoundDevice::Info>::const_iterator it = begin(); it != end(); ++it) - { - if((it->GetIdentifier() == identifier) && !IsDeviceUnavailable(it->GetIdentifier())) - { // exact match - return *it; - } - } - const SoundDevice::Type type = ParseType(identifier); - switch(type) - { - case TypePORTAUDIO_WASAPI: - // WASAPI devices might change names if a different connector jack is used. - // In order to avoid defaulting to wave mapper in that case, - // just find the first WASAPI device. - for(std::vector<SoundDevice::Info>::const_iterator it = begin(); it != end(); ++it) - { - if((it->id.GetType() == TypePORTAUDIO_WASAPI) && !IsDeviceUnavailable(it->GetIdentifier())) - { - return *it; - } - } - // default to first device - return *begin(); - break; - case TypeWAVEOUT: - case TypeDSOUND: - case TypePORTAUDIO_WMME: - case TypePORTAUDIO_DS: - case TypeASIO: - case TypePORTAUDIO_WDMKS: - case TypePORTAUDIO_ASIO: - if(preferSameType) - { - for(std::vector<SoundDevice::Info>::const_iterator it = begin(); it != end(); ++it) - { - if((it->id.GetType() == type) && !IsDeviceUnavailable(it->GetIdentifier())) - { - return *it; - } - } - } else - { - // default to first device - return *begin(); - } - break; - } - // invalid - return SoundDevice::Info(); -} - - -bool Manager::OpenDriverSettings(SoundDevice::Identifier identifier, SoundDevice::IMessageReceiver *messageReceiver, SoundDevice::IBase *currentSoundDevice) -//---------------------------------------------------------------------------------------------------------------------------------------------------------- -{ - bool result = false; - if(currentSoundDevice && FindDeviceInfo(identifier).IsValid() && (currentSoundDevice->GetDeviceInfo().GetIdentifier() == identifier)) - { - result = currentSoundDevice->OpenDriverSettings(); - } else - { - SoundDevice::IBase *dummy = CreateSoundDevice(identifier); - if(dummy) - { - dummy->SetMessageReceiver(messageReceiver); - result = dummy->OpenDriverSettings(); - } - delete dummy; - } - return result; -} - - -SoundDevice::Caps Manager::GetDeviceCaps(SoundDevice::Identifier identifier, SoundDevice::IBase *currentSoundDevice) -//------------------------------------------------------------------------------------------------------------------ -{ - if(m_DeviceCaps.find(identifier) == m_DeviceCaps.end()) - { - if(currentSoundDevice && FindDeviceInfo(identifier).IsValid() && (currentSoundDevice->GetDeviceInfo().GetIdentifier() == identifier)) - { - m_DeviceCaps[identifier] = currentSoundDevice->GetDeviceCaps(); - } else - { - SoundDevice::IBase *dummy = CreateSoundDevice(identifier); - if(dummy) - { - m_DeviceCaps[identifier] = dummy->GetDeviceCaps(); - } else - { - SetDeviceUnavailable(identifier); - } - delete dummy; - } - } - return m_DeviceCaps[identifier]; -} - - -SoundDevice::DynamicCaps Manager::GetDeviceDynamicCaps(SoundDevice::Identifier identifier, const std::vector<uint32> &baseSampleRates, SoundDevice::IMessageReceiver *messageReceiver, SoundDevice::IBase *currentSoundDevice, bool update) -//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -{ - if((m_DeviceDynamicCaps.find(identifier) == m_DeviceDynamicCaps.end()) || update) - { - if(currentSoundDevice && FindDeviceInfo(identifier).IsValid() && (currentSoundDevice->GetDeviceInfo().GetIdentifier() == identifier)) - { - m_DeviceDynamicCaps[identifier] = currentSoundDevice->GetDeviceDynamicCaps(baseSampleRates); - if(!currentSoundDevice->IsAvailable()) - { - SetDeviceUnavailable(identifier); - } - } else - { - SoundDevice::IBase *dummy = CreateSoundDevice(identifier); - if(dummy) - { - dummy->SetMessageReceiver(messageReceiver); - m_DeviceDynamicCaps[identifier] = dummy->GetDeviceDynamicCaps(baseSampleRates); - if(!dummy->IsAvailable()) - { - SetDeviceUnavailable(identifier); - } - } else - { - SetDeviceUnavailable(identifier); - } - delete dummy; - } - } - return m_DeviceDynamicCaps[identifier]; -} - - -SoundDevice::IBase * Manager::CreateSoundDevice(SoundDevice::Identifier identifier) -//--------------------------------------------------------------------------------- -{ - const SoundDevice::Info info = FindDeviceInfo(identifier); - if(!info.IsValid()) - { - return nullptr; - } - SoundDevice::IBase *result = nullptr; - switch(info.id.GetType()) - { - case TypeWAVEOUT: result = new CWaveDevice(info); break; -#ifndef NO_DSOUND - case TypeDSOUND: result = new CDSoundDevice(info); break; -#endif // NO_DSOUND -#ifndef NO_ASIO - case TypeASIO: result = new CASIODevice(info); break; -#endif // NO_ASIO -#ifndef NO_PORTAUDIO - case TypePORTAUDIO_WASAPI: - case TypePORTAUDIO_WDMKS: - case TypePORTAUDIO_WMME: - case TypePORTAUDIO_DS: - case TypePORTAUDIO_ASIO: - if(IsComponentAvailable(m_PortAudio)) - { - result = new CPortaudioDevice(info); - } - break; -#endif // NO_PORTAUDIO - } - if(!result) - { - return nullptr; - } - if(!result->Init()) - { - delete result; - result = nullptr; - return nullptr; - } - m_DeviceCaps[identifier] = result->GetDeviceCaps(); // update cached caps - return result; -} - - -Manager::Manager(SoundDevice::TypesSet enabledTypes) -//-------------------------------------------------- -{ - ReEnumerate(enabledTypes); -} - - -Manager::~Manager() -//----------------- -{ - return; -} - - } // namespace SoundDevice Modified: trunk/OpenMPT/sounddev/SoundDevice.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDevice.h 2015-02-08 14:06:34 UTC (rev 4744) +++ trunk/OpenMPT/sounddev/SoundDevice.h 2015-02-09 17:56:30 UTC (rev 4745) @@ -15,7 +15,6 @@ #include "../common/misc_util.h" #include "../common/FlagSet.h" #include "../common/mptAtomic.h" -#include "../common/ComponentManager.h" #include "../soundlib/SampleFormat.h" #include <bitset> @@ -647,53 +646,6 @@ }; -class ComponentPortAudio; - - -//=========== -class Manager -//=========== -{ -private: - -#ifndef NO_PORTAUDIO - ComponentHandle<ComponentPortAudio> m_PortAudio; -#endif // NO_PORTAUDIO - - std::vector<SoundDevice::Info> m_SoundDevices; - std::map<SoundDevice::Identifier, bool> m_DeviceUnavailable; - std::map<SoundDevice::Identifier, SoundDevice::Caps> m_DeviceCaps; - std::map<SoundDevice::Identifier, SoundDevice::DynamicCaps> m_DeviceDynamicCaps; - -public: - Manager(SoundDevice::TypesSet enabledTypes); - ~Manager(); - -public: - - void ReEnumerate(SoundDevice::TypesSet enabledTypes); - - std::vector<SoundDevice::Info>::const_iterator begin() const { return m_SoundDevices.begin(); } - std::vector<SoundDevice::Info>::const_iterator end() const { return m_SoundDevices.end(); } - const std::vector<SoundDevice::Info> & GetDeviceInfos() const { return m_SoundDevices; } - - SoundDevice::Info FindDeviceInfo(SoundDevice::ID id) const; - SoundDevice::Info FindDeviceInfo(SoundDevice::Identifier identifier) const; - SoundDevice::Info FindDeviceInfoBestMatch(SoundDevice::Identifier identifier, bool preferSameType); - - bool OpenDriverSettings(SoundDevice::Identifier identifier, SoundDevice::IMessageReceiver *messageReceiver = nullptr, SoundDevice::IBase *currentSoundDevice = nullptr); - - void SetDeviceUnavailable(SoundDevice::Identifier identifier) { m_DeviceUnavailable[identifier] = true; } - bool IsDeviceUnavailable(SoundDevice::Identifier identifier) { return m_DeviceUnavailable[identifier]; } - - SoundDevice::Caps GetDeviceCaps(SoundDevice::Identifier identifier, SoundDevice::IBase *currentSoundDevice = nullptr); - SoundDevice::DynamicCaps GetDeviceDynamicCaps(SoundDevice::Identifier identifier, const std::vector<uint32> &baseSampleRates, SoundDevice::IMessageReceiver *messageReceiver = nullptr, SoundDevice::IBase *currentSoundDevice = nullptr, bool update = false); - - SoundDevice::IBase * CreateSoundDevice(SoundDevice::Identifier identifier); - -}; - - } // namespace SoundDevice Copied: trunk/OpenMPT/sounddev/SoundDeviceManager.cpp (from rev 4744, trunk/OpenMPT/sounddev/SoundDevice.cpp) =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceManager.cpp (rev 0) +++ trunk/OpenMPT/sounddev/SoundDeviceManager.cpp 2015-02-09 17:56:30 UTC (rev 4745) @@ -0,0 +1,363 @@ +/* + * SoundDeviceManager.cpp + * ---------------------- + * Purpose: Sound device manager class. + * Notes : (currently none) + * Authors: Olivier Lapicque + * OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#include "stdafx.h" + +#include "SoundDeviceManager.h" +#include "SoundDevice.h" + +#include "SoundDeviceASIO.h" +#include "SoundDeviceDirectSound.h" +#include "SoundDevicePortAudio.h" +#include "SoundDeviceWaveout.h" + + +OPENMPT_NAMESPACE_BEGIN + + +namespace SoundDevice { + + +/////////////////////////////////////////////////////////////////////////////////////// +// +// Global Functions +// + + +void Manager::ReEnumerate(SoundDevice::TypesSet enabledTypes) +//----------------------------------------------------------- +{ + m_SoundDevices.clear(); + m_DeviceUnavailable.clear(); + m_DeviceCaps.clear(); + m_DeviceDynamicCaps.clear(); + +#ifndef NO_PORTAUDIO + if(IsComponentAvailable(m_PortAudio)) + { + m_PortAudio->ReInit(); + } +#endif // NO_PORTAUDIO + + if(enabledTypes[SoundDevice::TypeWAVEOUT]) + { + const std::vector<SoundDevice::Info> infos = CWaveDevice::EnumerateDevices(); + m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); + } +#ifndef NO_ASIO + if(enabledTypes[SoundDevice::TypeASIO]) + { + const std::vector<SoundDevice::Info> infos = CASIODevice::EnumerateDevices(); + m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); + } +#endif // NO_ASIO +#ifndef NO_PORTAUDIO + if(IsComponentAvailable(m_PortAudio) && enabledTypes[SoundDevice::TypePORTAUDIO_WASAPI]) + { + const std::vector<SoundDevice::Info> infos = CPortaudioDevice::EnumerateDevices(TypePORTAUDIO_WASAPI); + m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); + } + if(IsComponentAvailable(m_PortAudio) && enabledTypes[SoundDevice::TypePORTAUDIO_WDMKS]) + { + const std::vector<SoundDevice::Info> infos = CPortaudioDevice::EnumerateDevices(TypePORTAUDIO_WDMKS); + m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); + } +#endif // NO_PORTAUDIO + + // kind of deprecated by now +#ifndef NO_DSOUND + if(enabledTypes[SoundDevice::TypeDSOUND]) + { + const std::vector<SoundDevice::Info> infos = CDSoundDevice::EnumerateDevices(); + m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); + } +#endif // NO_DSOUND + + // duplicate devices, only used if [Sound Settings]MorePortaudio=1 +#ifndef NO_PORTAUDIO + if(IsComponentAvailable(m_PortAudio) && enabledTypes[SoundDevice::TypePORTAUDIO_WMME]) + { + const std::vector<SoundDevice::Info> infos = CPortaudioDevice::EnumerateDevices(TypePORTAUDIO_WMME); + m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); + } + if(IsComponentAvailable(m_PortAudio) && enabledTypes[SoundDevice::TypePORTAUDIO_ASIO]) + { + const std::vector<SoundDevice::Info> infos = CPortaudioDevice::EnumerateDevices(TypePORTAUDIO_ASIO); + m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); + } + if(IsComponentAvailable(m_PortAudio) && enabledTypes[SoundDevice::TypePORTAUDIO_DS]) + { + const std::vector<SoundDevice::Info> infos = CPortaudioDevice::EnumerateDevices(TypePORTAUDIO_DS); + m_SoundDevices.insert(m_SoundDevices.end(), infos.begin(), infos.end()); + } +#endif // NO_PORTAUDIO + +} + + +SoundDevice::Info Manager::FindDeviceInfo(SoundDevice::ID id) const +//----------------------------------------------------------------- +{ + for(std::vector<SoundDevice::Info>::const_iterator it = begin(); it != end(); ++it) + { + if(it->id == id) + { + return *it; + } + } + return SoundDevice::Info(); +} + + +SoundDevice::Info Manager::FindDeviceInfo(SoundDevice::Identifier identifier) const +//--------------------------------------------------------------------------------- +{ + if(m_SoundDevices.empty()) + { + return SoundDevice::Info(); + } + if(identifier.empty()) + { + return m_SoundDevices[0]; + } + for(std::vector<SoundDevice::Info>::const_iterator it = begin(); it != end(); ++it) + { + if(it->GetIdentifier() == identifier) + { + return *it; + } + } + return SoundDevice::Info(); +} + + +SoundDevice::Type ParseType(const SoundDevice::Identifier &identifier) +//-------------------------------------------------------------------- +{ + for(int i = 0; i < TypeNUM_DEVTYPES; ++i) + { + const mpt::ustring api = SoundDevice::TypeToString(static_cast<SoundDevice::Type>(i)); + if(identifier.find(api) == 0) + { + return static_cast<SoundDevice::Type>(i); + } + } + return TypeINVALID; +} + + +SoundDevice::Info Manager::FindDeviceInfoBestMatch(SoundDevice::Identifier identifier, bool preferSameType) +//--------------------------------------------------------------------------------------------------------- +{ + if(m_SoundDevices.empty()) + { + return SoundDevice::Info(); + } + if(identifier.empty()) + { + return *begin(); + } + for(std::vector<SoundDevice::Info>::const_iterator it = begin(); it != end(); ++it) + { + if((it->GetIdentifier() == identifier) && !IsDeviceUnavailable(it->GetIdentifier())) + { // exact match + return *it; + } + } + const SoundDevice::Type type = ParseType(identifier); + switch(type) + { + case TypePORTAUDIO_WASAPI: + // WASAPI devices might change names if a different connector jack is used. + // In order to avoid defaulting to wave mapper in that case, + // just find the first WASAPI device. + for(std::vector<SoundDevice::Info>::const_iterator it = begin(); it != end(); ++it) + { + if((it->id.GetType() == TypePORTAUDIO_WASAPI) && !IsDeviceUnavailable(it->GetIdentifier())) + { + return *it; + } + } + // default to first device + return *begin(); + break; + case TypeWAVEOUT: + case TypeDSOUND: + case TypePORTAUDIO_WMME: + case TypePORTAUDIO_DS: + case TypeASIO: + case TypePORTAUDIO_WDMKS: + case TypePORTAUDIO_ASIO: + if(preferSameType) + { + for(std::vector<SoundDevice::Info>::const_iterator it = begin(); it != end(); ++it) + { + if((it->id.GetType() == type) && !IsDeviceUnavailable(it->GetIdentifier())) + { + return *it; + } + } + } else + { + // default to first device + return *begin(); + } + break; + } + // invalid + return SoundDevice::Info(); +} + + +bool Manager::OpenDriverSettings(SoundDevice::Identifier identifier, SoundDevice::IMessageReceiver *messageReceiver, SoundDevice::IBase *currentSoundDevice) +//---------------------------------------------------------------------------------------------------------------------------------------------------------- +{ + bool result = false; + if(currentSoundDevice && FindDeviceInfo(identifier).IsValid() && (currentSoundDevice->GetDeviceInfo().GetIdentifier() == identifier)) + { + result = currentSoundDevice->OpenDriverSettings(); + } else + { + SoundDevice::IBase *dummy = CreateSoundDevice(identifier); + if(dummy) + { + dummy->SetMessageReceiver(messageReceiver); + result = dummy->OpenDriverSettings(); + } + delete dummy; + } + return result; +} + + +SoundDevice::Caps Manager::GetDeviceCaps(SoundDevice::Identifier identifier, SoundDevice::IBase *currentSoundDevice) +//------------------------------------------------------------------------------------------------------------------ +{ + if(m_DeviceCaps.find(identifier) == m_DeviceCaps.end()) + { + if(currentSoundDevice && FindDeviceInfo(identifier).IsValid() && (currentSoundDevice->GetDeviceInfo().GetIdentifier() == identifier)) + { + m_DeviceCaps[identifier] = currentSoundDevice->GetDeviceCaps(); + } else + { + SoundDevice::IBase *dummy = CreateSoundDevice(identifier); + if(dummy) + { + m_DeviceCaps[identifier] = dummy->GetDeviceCaps(); + } else + { + SetDeviceUnavailable(identifier); + } + delete dummy; + } + } + return m_DeviceCaps[identifier]; +} + + +SoundDevice::DynamicCaps Manager::GetDeviceDynamicCaps(SoundDevice::Identifier identifier, const std::vector<uint32> &baseSampleRates, SoundDevice::IMessageReceiver *messageReceiver, SoundDevice::IBase *currentSoundDevice, bool update) +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +{ + if((m_DeviceDynamicCaps.find(identifier) == m_DeviceDynamicCaps.end()) || update) + { + if(currentSoundDevice && FindDeviceInfo(identifier).IsValid() && (currentSoundDevice->GetDeviceInfo().GetIdentifier() == identifier)) + { + m_DeviceDynamicCaps[identifier] = currentSoundDevice->GetDeviceDynamicCaps(baseSampleRates); + if(!currentSoundDevice->IsAvailable()) + { + SetDeviceUnavailable(identifier); + } + } else + { + SoundDevice::IBase *dummy = CreateSoundDevice(identifier); + if(dummy) + { + dummy->SetMessageReceiver(messageReceiver); + m_DeviceDynamicCaps[identifier] = dummy->GetDeviceDynamicCaps(baseSampleRates); + if(!dummy->IsAvailable()) + { + SetDeviceUnavailable(identifier); + } + } else + { + SetDeviceUnavailable(identifier); + } + delete dummy; + } + } + return m_DeviceDynamicCaps[identifier]; +} + + +SoundDevice::IBase * Manager::CreateSoundDevice(SoundDevice::Identifier identifier) +//--------------------------------------------------------------------------------- +{ + const SoundDevice::Info info = FindDeviceInfo(identifier); + if(!info.IsValid()) + { + return nullptr; + } + SoundDevice::IBase *result = nullptr; + switch(info.id.GetType()) + { + case TypeWAVEOUT: result = new CWaveDevice(info); break; +#ifndef NO_DSOUND + case TypeDSOUND: result = new CDSoundDevice(info); break; +#endif // NO_DSOUND +#ifndef NO_ASIO + case TypeASIO: result = new CASIODevice(info); break; +#endif // NO_ASIO +#ifndef NO_PORTAUDIO + case TypePORTAUDIO_WASAPI: + case TypePORTAUDIO_WDMKS: + case TypePORTAUDIO_WMME: + case TypePORTAUDIO_DS: + case TypePORTAUDIO_ASIO: + if(IsComponentAvailable(m_PortAudio)) + { + result = new CPortaudioDevice(info); + } + break; +#endif // NO_PORTAUDIO + } + if(!result) + { + return nullptr; + } + if(!result->Init()) + { + delete result; + result = nullptr; + return nullptr; + } + m_DeviceCaps[identifier] = result->GetDeviceCaps(); // update cached caps + return result; +} + + +Manager::Manager(SoundDevice::TypesSet enabledTypes) +//-------------------------------------------------- +{ + ReEnumerate(enabledTypes); +} + + +Manager::~Manager() +//----------------- +{ + return; +} + + +} // namespace SoundDevice + + +OPENMPT_NAMESPACE_END Copied: trunk/OpenMPT/sounddev/SoundDeviceManager.h (from rev 4744, trunk/OpenMPT/sounddev/SoundDevice.h) =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceManager.h (rev 0) +++ trunk/OpenMPT/sounddev/SoundDeviceManager.h 2015-02-09 17:56:30 UTC (rev 4745) @@ -0,0 +1,75 @@ +/* + * SoundDeviceManager.h + * -------------------- + * Purpose: Sound device manager class. + * Notes : (currently none) + * Authors: Olivier Lapicque + * OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#pragma once + +#include "SoundDevice.h" + +#include "../common/ComponentManager.h" + + +OPENMPT_NAMESPACE_BEGIN + + +namespace SoundDevice { + + +class ComponentPortAudio; + + +//=========== +class Manager +//=========== +{ +private: + +#ifndef NO_PORTAUDIO + ComponentHandle<ComponentPortAudio> m_PortAudio; +#endif // NO_PORTAUDIO + + std::vector<SoundDevice::Info> m_SoundDevices; + std::map<SoundDevice::Identifier, bool> m_DeviceUnavailable; + std::map<SoundDevice::Identifier, SoundDevice::Caps> m_DeviceCaps; + std::map<SoundDevice::Identifier, SoundDevice::DynamicCaps> m_DeviceDynamicCaps; + +public: + Manager(SoundDevice::TypesSet enabledTypes); + ~Manager(); + +public: + + void ReEnumerate(SoundDevice::TypesSet enabledTypes); + + std::vector<SoundDevice::Info>::const_iterator begin() const { return m_SoundDevices.begin(); } + std::vector<SoundDevice::Info>::const_iterator end() const { return m_SoundDevices.end(); } + const std::vector<SoundDevice::Info> & GetDeviceInfos() const { return m_SoundDevices; } + + SoundDevice::Info FindDeviceInfo(SoundDevice::ID id) const; + SoundDevice::Info FindDeviceInfo(SoundDevice::Identifier identifier) const; + SoundDevice::Info FindDeviceInfoBestMatch(SoundDevice::Identifier identifier, bool preferSameType); + + bool OpenDriverSettings(SoundDevice::Identifier identifier, SoundDevice::IMessageReceiver *messageReceiver = nullptr, SoundDevice::IBase *currentSoundDevice = nullptr); + + void SetDeviceUnavailable(SoundDevice::Identifier identifier) { m_DeviceUnavailable[identifier] = true; } + bool IsDeviceUnavailable(SoundDevice::Identifier identifier) { return m_DeviceUnavailable[identifier]; } + + SoundDevice::Caps GetDeviceCaps(SoundDevice::Identifier identifier, SoundDevice::IBase *currentSoundDevice = nullptr); + SoundDevice::DynamicCaps GetDeviceDynamicCaps(SoundDevice::Identifier identifier, const std::vector<uint32> &baseSampleRates, SoundDevice::IMessageReceiver *messageReceiver = nullptr, SoundDevice::IBase *currentSoundDevice = nullptr, bool update = false); + + SoundDevice::IBase * CreateSoundDevice(SoundDevice::Identifier identifier); + +}; + + +} // namespace SoundDevice + + +OPENMPT_NAMESPACE_END This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |