From: <man...@us...> - 2013-11-18 16:03:06
|
Revision: 3261 http://sourceforge.net/p/modplug/code/3261 Author: manxorist Date: 2013-11-18 16:02:58 +0000 (Mon, 18 Nov 2013) Log Message: ----------- [Imp] sounddev: Allow selecting the base (first) channel to use with ASIO drivers. [Imp] sounddev: Get the channel names from ASIO drivers. (code mostly by Saga_Musix) [Imp] sounddev: Add a button to open the ASIO driver panel from the soundcard options dialog. (code mostly by Saga_Musix) [Fix] sounddev: Disable some soundcard options dialog controls that dont do anything for certain device types. Modified Paths: -------------- trunk/OpenMPT/mptrack/Mpdlgs.cpp trunk/OpenMPT/mptrack/Mpdlgs.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/sounddev/SoundDevice.cpp trunk/OpenMPT/sounddev/SoundDevice.h trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp trunk/OpenMPT/sounddev/SoundDeviceASIO.h Modified: trunk/OpenMPT/mptrack/Mpdlgs.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mpdlgs.cpp 2013-11-18 00:53:40 UTC (rev 3260) +++ trunk/OpenMPT/mptrack/Mpdlgs.cpp 2013-11-18 16:02:58 UTC (rev 3261) @@ -74,9 +74,11 @@ ON_CBN_SELCHANGE(IDC_COMBO4, OnSettingsChanged) ON_CBN_SELCHANGE(IDC_COMBO5, OnSettingsChanged) ON_CBN_SELCHANGE(IDC_COMBO6, OnSettingsChanged) + ON_CBN_SELCHANGE(IDC_COMBO9, OnSettingsChanged) ON_CBN_EDITCHANGE(IDC_COMBO2, OnSettingsChanged) ON_CBN_EDITCHANGE(IDC_COMBO_UPDATEINTERVAL, OnSettingsChanged) ON_COMMAND(IDC_BUTTON1, OnSoundCardRescan) + ON_COMMAND(IDC_BUTTON2, OnSoundCardDriverPanel) END_MESSAGE_MAP() @@ -92,6 +94,8 @@ DDX_Control(pDX, IDC_COMBO4, m_CbnPolyphony); DDX_Control(pDX, IDC_COMBO5, m_CbnChannels); DDX_Control(pDX, IDC_COMBO6, m_CbnSampleFormat); + DDX_Control(pDX, IDC_COMBO9, m_CbnBaseChannel); + DDX_Control(pDX, IDC_BUTTON2, m_BtnDriverPanel); DDX_Control(pDX, IDC_SLIDER1, m_SliderStereoSep); DDX_Control(pDX, IDC_SLIDER_PREAMP, m_SliderPreAmp); DDX_Control(pDX, IDC_EDIT_STATISTICS, m_EditStatistics); @@ -99,6 +103,24 @@ } +COptionsSoundcard::COptionsSoundcard(const SoundDeviceSettings &settings, SoundDeviceID sd) +//----------------------------------------------------------------------------------------- + : CPropertyPage(IDD_OPTIONS_SOUNDCARD) + , m_Settings(settings) +{ + m_PreAmpNoteShowed = false; + SetDevice(sd); +} + + +void COptionsSoundcard::SetDevice(SoundDeviceID dev) +//-------------------------------------------------- +{ + m_CurrentDeviceInfo = theApp.GetSoundDevicesManager()->FindDeviceInfo(dev) ? *(theApp.GetSoundDevicesManager()->FindDeviceInfo(dev)) : SoundDeviceInfo(); + m_CurrentDeviceCaps = theApp.GetSoundDevicesManager()->GetDeviceCaps(dev, TrackerSettings::Instance().GetSampleRates(), CMainFrame::GetMainFrame(), CMainFrame::GetMainFrame()->gpSoundDevice, true); +} + + void COptionsSoundcard::OnSoundCardRescan() //----------------------------------------- { @@ -133,7 +155,7 @@ CheckDlgButton(IDC_CHECK5, m_Settings.BoostThreadPriority ? MF_CHECKED : MF_UNCHECKED); // Sampling Rate - UpdateSampleRates(m_nSoundDevice); + UpdateSampleRates(); // Max Mixing Channels { @@ -261,31 +283,38 @@ _tcscpy(tmp, name); cbi.pszText = tmp; int pos = m_CbnDevice.InsertItem(&cbi); - if(cbi.lParam == m_nSoundDevice.GetIdRaw()) + if(cbi.lParam == m_CurrentDeviceInfo.id.GetIdRaw()) { m_CbnDevice.SetCurSel(pos); } iItem++; } } - UpdateControls(m_nSoundDevice); + UpdateControls(); } - UpdateChannels(m_nSoundDevice); - UpdateSampleFormat(m_nSoundDevice); + UpdateChannels(); + UpdateSampleFormat(); } -void COptionsSoundcard::UpdateChannels(SoundDeviceID dev) -//------------------------------------------------------- +void COptionsSoundcard::UpdateChannels() +//-------------------------------------- { - MPT_UNREFERENCED_PARAMETER(dev); CHAR s[128]; UINT n = 0; m_CbnChannels.ResetContent(); - for(UINT channels = 4; channels >= 1; channels /= 2) + UINT maxChannels = 0; + if(m_CurrentDeviceCaps.channelNames.size() > 0) { + maxChannels = std::min<std::size_t>(4, m_CurrentDeviceCaps.channelNames.size()); + } else + { + maxChannels = 4; + } + for(UINT channels = maxChannels; channels >= 1; channels /= 2) + { wsprintf(s, "%s", gszChnCfgNames[(channels+2)/2-1]); UINT ndx = m_CbnChannels.AddString(s); m_CbnChannels.SetItemData(ndx, channels); @@ -295,15 +324,37 @@ } } m_CbnChannels.SetCurSel(n); + if(m_CurrentDeviceInfo.id.GetType() == SNDDEV_ASIO) + { + m_CbnBaseChannel.ResetContent(); + m_CbnBaseChannel.EnableWindow(TRUE); + m_BtnDriverPanel.ShowWindow(SW_SHOW); + int sel = 0; + for(std::size_t channel = 0; channel < m_CurrentDeviceCaps.channelNames.size(); ++channel) + { + int ndx = m_CbnBaseChannel.AddString(mpt::ToCString(m_CurrentDeviceCaps.channelNames[channel])); + m_CbnBaseChannel.SetItemData(ndx, channel); + if(channel == m_Settings.BaseChannel) + { + sel = ndx; + } + } + m_CbnBaseChannel.SetCurSel(sel); + } else + { + m_CbnBaseChannel.ResetContent(); + m_CbnBaseChannel.EnableWindow(FALSE); + m_BtnDriverPanel.ShowWindow(SW_HIDE); + } } -void COptionsSoundcard::UpdateSampleFormat(SoundDeviceID dev) -//----------------------------------------------------------- +void COptionsSoundcard::UpdateSampleFormat() +//------------------------------------------ { UINT n = 0; m_CbnSampleFormat.ResetContent(); - const bool asio = dev.GetType() == SNDDEV_ASIO; + const bool asio = m_CurrentDeviceInfo.id.GetType() == SNDDEV_ASIO; if(asio) { m_Settings.sampleFormat = TrackerSettings::Instance().m_SampleFormat; @@ -400,25 +451,32 @@ //--------------------------------------- { int n = m_CbnDevice.GetCurSel(); - if (n >= 0) + if(n >= 0) { - SoundDeviceID dev = SoundDeviceID::FromIdRaw(m_CbnDevice.GetItemData(n)); - UpdateControls(dev); - UpdateSampleRates(dev); - UpdateChannels(dev); - UpdateSampleFormat(dev); + SetDevice(SoundDeviceID::FromIdRaw(m_CbnDevice.GetItemData(n))); + UpdateControls(); + UpdateSampleRates(); + UpdateChannels(); + UpdateSampleFormat(); OnSettingsChanged(); } } +void COptionsSoundcard::OnSoundCardDriverPanel() +//---------------------------------------------- +{ + theApp.GetSoundDevicesManager()->OpenDriverSettings(SoundDeviceID::FromIdRaw(m_CbnDevice.GetItemData(m_CbnDevice.GetCurSel())), CMainFrame::GetMainFrame(), CMainFrame::GetMainFrame()->gpSoundDevice); +} + + // Fill the dropdown box with a list of valid sample rates, depending on the selected sound device. -void COptionsSoundcard::UpdateSampleRates(SoundDeviceID dev) -//---------------------------------------------------------- +void COptionsSoundcard::UpdateSampleRates() +//----------------------------------------- { m_CbnMixingFreq.ResetContent(); - std::vector<uint32> samplerates = theApp.GetSoundDevicesManager()->GetDeviceCaps(dev, TrackerSettings::Instance().GetSampleRates(), CMainFrame::GetMainFrame(), CMainFrame::GetMainFrame()->gpSoundDevice).supportedSampleRates; + std::vector<uint32> samplerates = m_CurrentDeviceCaps.supportedSampleRates; if(samplerates.empty()) { @@ -442,10 +500,12 @@ } -void COptionsSoundcard::UpdateControls(SoundDeviceID dev) -//------------------------------------------------------- +void COptionsSoundcard::UpdateControls() +//-------------------------------------- { + const SoundDeviceID dev = m_CurrentDeviceInfo.id; GetDlgItem(IDC_CHECK4)->EnableWindow((dev.GetType() == SNDDEV_DSOUND || dev.GetType() == SNDDEV_PORTAUDIO_WASAPI) ? TRUE : FALSE); + GetDlgItem(IDC_CHECK5)->EnableWindow((dev.GetType() == SNDDEV_WAVEOUT || dev.GetType() == SNDDEV_DSOUND) ? TRUE : FALSE); GetDlgItem(IDC_STATIC_UPDATEINTERVAL)->EnableWindow((dev.GetType() == SNDDEV_ASIO) ? FALSE : TRUE); GetDlgItem(IDC_COMBO_UPDATEINTERVAL)->EnableWindow((dev.GetType() == SNDDEV_ASIO) ? FALSE : TRUE); if(dev.GetType() == SNDDEV_DSOUND) @@ -507,9 +567,10 @@ int n = m_CbnDevice.GetCurSel(); if(n >= 0) { - m_nSoundDevice = SoundDeviceID::FromIdRaw(m_CbnDevice.GetItemData(n)); + SetDevice(SoundDeviceID::FromIdRaw(m_CbnDevice.GetItemData(n))); } } + const SoundDeviceID dev = m_CurrentDeviceInfo.id; // Latency { CHAR s[32]; @@ -530,12 +591,22 @@ wsprintf(s, "%d ms", m_Settings.UpdateIntervalMS); m_CbnUpdateIntervalMS.SetWindowText(s); } - CMainFrame::GetMainFrame()->SetupSoundCard(m_Settings, m_nSoundDevice); - UpdateSampleFormat(m_nSoundDevice); + // Base Channel + { + if(m_CurrentDeviceInfo.id.GetType() == SNDDEV_ASIO) + { + m_Settings.BaseChannel = m_CbnBaseChannel.GetItemData(m_CbnBaseChannel.GetCurSel()); + } + } + CMainFrame::GetMainFrame()->SetupSoundCard(m_Settings, m_CurrentDeviceInfo.id); + SetDevice(m_CurrentDeviceInfo.id); // Poll changed ASIO channel names + UpdateSampleFormat(); + UpdateChannels(); UpdateStatistics(); CPropertyPage::OnOK(); } + void COptionsSoundcard::UpdateStatistics() //---------------------------------------- { Modified: trunk/OpenMPT/mptrack/Mpdlgs.h =================================================================== --- trunk/OpenMPT/mptrack/Mpdlgs.h 2013-11-18 00:53:40 UTC (rev 3260) +++ trunk/OpenMPT/mptrack/Mpdlgs.h 2013-11-18 16:02:58 UTC (rev 3261) @@ -21,24 +21,27 @@ CComboBoxEx m_CbnDevice; CComboBox m_CbnLatencyMS, m_CbnUpdateIntervalMS, m_CbnMixingFreq, m_CbnPolyphony, m_CbnChannels, m_CbnSampleFormat; CSliderCtrl m_SliderStereoSep, m_SliderPreAmp; + CComboBox m_CbnBaseChannel; CEdit m_EditStatistics; - CButton m_BtnRescan; + CButton m_BtnDriverPanel; SoundDeviceSettings m_Settings; - SoundDeviceID m_nSoundDevice; bool m_PreAmpNoteShowed; + void SetDevice(SoundDeviceID dev); + SoundDeviceInfo m_CurrentDeviceInfo; + SoundDeviceCaps m_CurrentDeviceCaps; + public: - COptionsSoundcard(const SoundDeviceSettings &settings, SoundDeviceID sd):CPropertyPage(IDD_OPTIONS_SOUNDCARD) - { m_Settings = settings; m_nSoundDevice = sd; m_PreAmpNoteShowed = false; } + COptionsSoundcard(const SoundDeviceSettings &settings, SoundDeviceID sd); void UpdateStatistics(); private: void UpdateEverything(); - void UpdateSampleRates(SoundDeviceID dev); - void UpdateChannels(SoundDeviceID dev); - void UpdateSampleFormat(SoundDeviceID dev); - void UpdateControls(SoundDeviceID dev); + void UpdateSampleRates(); + void UpdateChannels(); + void UpdateSampleFormat(); + void UpdateControls(); void SetPreAmpSliderPosition(); protected: @@ -52,6 +55,7 @@ afx_msg void OnHScroll(UINT, UINT, CScrollBar *); afx_msg void OnVScroll(UINT, UINT, CScrollBar *); afx_msg void OnSoundCardRescan(); + afx_msg void OnSoundCardDriverPanel(); DECLARE_MESSAGE_MAP() }; Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2013-11-18 00:53:40 UTC (rev 3260) +++ trunk/OpenMPT/mptrack/mptrack.rc 2013-11-18 16:02:58 UTC (rev 3261) @@ -1310,10 +1310,13 @@ COMBOBOX IDC_COMBO3,72,84,66,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO5,144,84,42,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO6,192,84,66,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Max. Polyphony:",IDC_STATIC,12,102,54,12,SS_CENTERIMAGE - COMBOBOX IDC_COMBO4,72,102,66,88,CBS_DROPDOWNLIST | WS_TABSTOP + LTEXT "Base channel:",IDC_STATIC,12,102,54,12,SS_CENTERIMAGE + COMBOBOX IDC_COMBO9,72,102,114,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Driver Panel",IDC_BUTTON2,192,102,66,12 GROUPBOX "",IDC_STATIC,6,126,258,90 - CONTROL "Soft Panning",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,138,78,12 + LTEXT "Max. Polyphony:",IDC_STATIC,12,138,54,12,SS_CENTERIMAGE + COMBOBOX IDC_COMBO4,72,138,66,88,CBS_DROPDOWNLIST | WS_TABSTOP + CONTROL "Soft Panning",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,138,78,12 LTEXT "Stereo Separation:",IDC_STATIC,12,157,62,8 LTEXT "100%",IDC_TEXT1,80,157,20,8 RTEXT "Low",IDC_STATIC,22,168,15,14,SS_CENTERIMAGE Modified: trunk/OpenMPT/sounddev/SoundDevice.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDevice.cpp 2013-11-18 00:53:40 UTC (rev 3260) +++ trunk/OpenMPT/sounddev/SoundDevice.cpp 2013-11-18 16:02:58 UTC (rev 3261) @@ -711,11 +711,32 @@ } -SoundDeviceCaps SoundDevicesManager::GetDeviceCaps(SoundDeviceID id, const std::vector<uint32> &baseSampleRates, ISoundMessageReceiver *messageReceiver, ISoundDevice *currentSoundDevice) -//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +bool SoundDevicesManager::OpenDriverSettings(SoundDeviceID id, ISoundMessageReceiver *messageReceiver, ISoundDevice *currentSoundDevice) +//-------------------------------------------------------------------------------------------------------------------------------------- { - if(m_DeviceCaps.find(id) == m_DeviceCaps.end()) + bool result = false; + if(currentSoundDevice && FindDeviceInfo(id) && (currentSoundDevice->GetDeviceID() == id) && (currentSoundDevice->GetDeviceInternalID() == FindDeviceInfo(id)->internalID)) { + result = currentSoundDevice->OpenDriverSettings(); + } else + { + ISoundDevice *dummy = CreateSoundDevice(id); + if(dummy) + { + dummy->SetMessageReceiver(messageReceiver); + result = dummy->OpenDriverSettings(); + } + delete dummy; + } + return result; +} + + +SoundDeviceCaps SoundDevicesManager::GetDeviceCaps(SoundDeviceID id, const std::vector<uint32> &baseSampleRates, ISoundMessageReceiver *messageReceiver, ISoundDevice *currentSoundDevice, bool update) +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +{ + if((m_DeviceCaps.find(id) == m_DeviceCaps.end()) || update) + { if(currentSoundDevice && FindDeviceInfo(id) && (currentSoundDevice->GetDeviceID() == id) && (currentSoundDevice->GetDeviceInternalID() == FindDeviceInfo(id)->internalID)) { m_DeviceCaps[id] = currentSoundDevice->GetDeviceCaps(baseSampleRates); Modified: trunk/OpenMPT/sounddev/SoundDevice.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDevice.h 2013-11-18 00:53:40 UTC (rev 3260) +++ trunk/OpenMPT/sounddev/SoundDevice.h 2013-11-18 16:02:58 UTC (rev 3261) @@ -198,6 +198,7 @@ { uint32 currentSampleRate; std::vector<uint32> supportedSampleRates; // Which samplerates are actually supported by the device. Currently only implemented properly for ASIO, DirectSound and PortAudio. + std::vector<std::wstring> channelNames; SoundDeviceCaps() : currentSampleRate(0) { @@ -317,6 +318,7 @@ int64 GetStreamPositionFrames() const; + virtual bool OpenDriverSettings() { return false; }; }; @@ -360,8 +362,10 @@ const SoundDeviceInfo * FindDeviceInfo(SoundDeviceID id) const; - SoundDeviceCaps GetDeviceCaps(SoundDeviceID id, const std::vector<uint32> &baseSampleRates, ISoundMessageReceiver *messageReceiver = nullptr, ISoundDevice *currentSoundDevice = nullptr); + bool OpenDriverSettings(SoundDeviceID id, ISoundMessageReceiver *messageReceiver = nullptr, ISoundDevice *currentSoundDevice = nullptr); + SoundDeviceCaps GetDeviceCaps(SoundDeviceID id, const std::vector<uint32> &baseSampleRates, ISoundMessageReceiver *messageReceiver = nullptr, ISoundDevice *currentSoundDevice = nullptr, bool update = false); + ISoundDevice * CreateSoundDevice(SoundDeviceID id); }; Modified: trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp 2013-11-18 00:53:40 UTC (rev 3260) +++ trunk/OpenMPT/sounddev/SoundDeviceASIO.cpp 2013-11-18 16:02:58 UTC (rev 3261) @@ -26,6 +26,32 @@ #include <algorithm> +// Helper class to temporarily open a device for a query. +class TemporaryASIODeviceOpener +{ +protected: + CASIODevice &device; + const bool wasOpen; + +public: + TemporaryASIODeviceOpener(CASIODevice &d) : device(d), wasOpen(d.IsOpen()) + { + if(!wasOpen) + { + device.OpenDevice(); + } + } + + ~TemporaryASIODeviceOpener() + { + if(!wasOpen) + { + device.CloseDevice(); + } + } +}; + + /////////////////////////////////////////////////////////////////////////////////////// // // ASIO Device implementation @@ -679,14 +705,10 @@ { SoundDeviceCaps caps; - const bool wasOpen = (m_pAsioDrv != NULL); - if(!wasOpen) + TemporaryASIODeviceOpener opener(*this); + if(!IsOpen()) { - OpenDevice(); - if(m_pAsioDrv == NULL) - { - return caps; - } + return caps; } ASIOSampleRate samplerate; @@ -703,14 +725,40 @@ caps.supportedSampleRates.push_back(baseSampleRates[i]); } } - - if(!wasOpen) + long inputChannels = 0; + long outputChannels = 0; + if(m_pAsioDrv->getChannels(&inputChannels, &outputChannels) == ASE_OK) { - CloseDevice(); + for(long i = 0; i < outputChannels; ++i) + { + ASIOChannelInfo channelInfo; + MemsetZero(channelInfo); + channelInfo.channel = i; + if(m_pAsioDrv->getChannelInfo(&channelInfo) == ASE_OK) + { + mpt::String::SetNullTerminator(channelInfo.name); + caps.channelNames.push_back(mpt::ToWide(mpt::CharsetLocale, channelInfo.name)); + } else + { + caps.channelNames.push_back(mpt::ToWString(i)); + } + } } return caps; } +bool CASIODevice::OpenDriverSettings() +//------------------------------------ +{ + TemporaryASIODeviceOpener opener(*this); + if(!IsOpen()) + { + return false; + } + return m_pAsioDrv->controlPanel() == ASE_OK; +} + + #endif // NO_ASIO Modified: trunk/OpenMPT/sounddev/SoundDeviceASIO.h =================================================================== --- trunk/OpenMPT/sounddev/SoundDeviceASIO.h 2013-11-18 00:53:40 UTC (rev 3260) +++ trunk/OpenMPT/sounddev/SoundDeviceASIO.h 2013-11-18 16:02:58 UTC (rev 3261) @@ -29,6 +29,8 @@ class CASIODevice: public ISoundDevice //==================================== { + friend class TemporaryASIODeviceOpener; + enum { ASIO_MAX_CHANNELS=4 }; enum { ASIO_BLOCK_LEN=1024 }; protected: @@ -61,6 +63,7 @@ bool InternalIsOpen() const { return (m_pAsioDrv != nullptr); } SoundDeviceCaps GetDeviceCaps(const std::vector<uint32> &baseSampleRates); + bool OpenDriverSettings(); public: static std::vector<SoundDeviceInfo> EnumerateDevices(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |