Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/mpc-hc/PPageAudioRenderer.cpp')
-rw-r--r--src/mpc-hc/PPageAudioRenderer.cpp233
1 files changed, 233 insertions, 0 deletions
diff --git a/src/mpc-hc/PPageAudioRenderer.cpp b/src/mpc-hc/PPageAudioRenderer.cpp
new file mode 100644
index 000000000..a65839897
--- /dev/null
+++ b/src/mpc-hc/PPageAudioRenderer.cpp
@@ -0,0 +1,233 @@
+/*
+ * (C) 2015 see Authors.txt
+ *
+ * This file is part of MPC-HC.
+ *
+ * MPC-HC is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MPC-HC is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "stdafx.h"
+#include "PPageAudioRenderer.h"
+
+#include "mplayerc.h"
+#include "VersionInfo.h"
+
+#include <FunctionDiscoveryKeys_devpkey.h>
+#include <Mmdeviceapi.h>
+
+namespace
+{
+ std::vector<std::pair<CString, CString>> GetDevices()
+ {
+ std::vector<std::pair<CString, CString>> ret;
+
+ CComPtr<IMMDeviceEnumerator> enumerator;
+ CComPtr<IMMDeviceCollection> collection;
+ UINT count = 0;
+
+ if (SUCCEEDED(enumerator.CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER)) &&
+ SUCCEEDED(enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED, &collection)) &&
+ SUCCEEDED(collection->GetCount(&count))) {
+
+ for (UINT i = 0; i < count; i++) {
+ CComPtr<IMMDevice> device;
+ CComHeapPtr<WCHAR> id;
+ CComPtr<IPropertyStore> devicePropertyStore;
+ PROPVARIANT friendlyName;
+ PropVariantInit(&friendlyName);
+
+ if (SUCCEEDED(collection->Item(i, &device)) &&
+ SUCCEEDED(device->GetId(&id)) &&
+ SUCCEEDED(device->OpenPropertyStore(STGM_READ, &devicePropertyStore)) &&
+ SUCCEEDED(devicePropertyStore->GetValue(PKEY_Device_FriendlyName, &friendlyName))) {
+
+ ret.emplace_back(friendlyName.pwszVal, static_cast<LPWSTR>(id));
+ PropVariantClear(&friendlyName);
+ }
+ }
+ }
+
+ return ret;
+ }
+}
+
+CPPageAudioRenderer::CPPageAudioRenderer()
+ : CPPageBase(IDD, VersionInfo::IsLite() ? IDS_PPAGE_OUTPUT_AUD_INTERNAL_REND : IDD_PPAGEAUDIORENDERER)
+ , m_bExclusiveMode(FALSE)
+ , m_bAllowBitstreaming(TRUE)
+ , m_bCrossfeedEnabled(FALSE)
+{
+}
+
+void CPPageAudioRenderer::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Check(pDX, IDC_CHECK1, m_bExclusiveMode);
+ DDX_Check(pDX, IDC_CHECK2, m_bAllowBitstreaming);
+ DDX_Check(pDX, IDC_CHECK3, m_bCrossfeedEnabled);
+ DDX_Control(pDX, IDC_COMBO1, m_combo1);
+ DDX_Control(pDX, IDC_SLIDER1, m_slider1);
+ DDX_Control(pDX, IDC_SLIDER2, m_slider2);
+}
+
+BEGIN_MESSAGE_MAP(CPPageAudioRenderer, CPPageBase)
+ ON_WM_HSCROLL()
+ ON_UPDATE_COMMAND_UI(IDC_CHECK2, OnUpdateAllowBitstreamingCheckbox)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateCrossfeedGroup)
+ ON_BN_CLICKED(IDC_BUTTON1, OnCMoyButton)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateCrossfeedGroup)
+ ON_BN_CLICKED(IDC_BUTTON2, OnJMeierButton)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC1, OnUpdateCrossfeedGroup)
+ ON_UPDATE_COMMAND_UI(IDC_SLIDER1, OnUpdateCrossfeedGroup)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC2, OnUpdateCrossfeedCutoffLabel)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC3, OnUpdateCrossfeedGroup)
+ ON_UPDATE_COMMAND_UI(IDC_SLIDER2, OnUpdateCrossfeedGroup)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC4, OnUpdateCrossfeedLevelLabel)
+END_MESSAGE_MAP()
+
+BOOL CPPageAudioRenderer::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ const auto& s = AfxGetAppSettings();
+
+ CString defaultString;
+ defaultString.LoadString(IDS_PPAGE_OUTPUT_SYS_DEF);
+ m_combo1.AddString(defaultString);
+ m_deviceIds.emplace_back();
+ m_combo1.SetItemData(0, 0);
+
+ for (const auto& device : GetDevices()) {
+ int idx = m_combo1.AddString(device.first);
+ if (idx >= 0) {
+ m_deviceIds.emplace_back(device.second);
+ m_combo1.SetItemData(idx, m_deviceIds.size() - 1);
+ }
+ }
+
+ CComHeapPtr<WCHAR> pDeviceId;
+ if (SUCCEEDED(s.sanear->GetOuputDevice(&pDeviceId, &m_bExclusiveMode, nullptr))) {
+ if (!pDeviceId || pDeviceId[0] == '\0') {
+ m_combo1.SetCurSel(0);
+ } else {
+ for (size_t i = 0; i < m_deviceIds.size(); i++) {
+ if (m_deviceIds[i] == pDeviceId) {
+ for (int j = 0; j < m_combo1.GetCount(); j++) {
+ if (m_combo1.GetItemData(j) == i) {
+ m_combo1.SetCurSel(j);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ s.sanear->GetAllowBitstreaming(&m_bAllowBitstreaming);
+ s.sanear->GetCrossfeedEnabled(&m_bCrossfeedEnabled);
+
+ m_slider1.SetRangeMin(SaneAudioRenderer::ISettings::CROSSFEED_CUTOFF_FREQ_MIN);
+ m_slider1.SetRangeMax(SaneAudioRenderer::ISettings::CROSSFEED_CUTOFF_FREQ_MAX);
+ m_slider2.SetRangeMin(SaneAudioRenderer::ISettings::CROSSFEED_LEVEL_MIN);
+ m_slider2.SetRangeMax(SaneAudioRenderer::ISettings::CROSSFEED_LEVEL_MAX);
+
+ UINT32 crossfeedCuttoffFrequency;
+ UINT32 crossfeedLevel;
+ s.sanear->GetCrossfeedSettings(&crossfeedCuttoffFrequency, &crossfeedLevel);
+ m_slider1.SetPos(crossfeedCuttoffFrequency);
+ m_slider2.SetPos(crossfeedLevel);
+
+ UpdateData(FALSE);
+
+ return TRUE;
+}
+
+BOOL CPPageAudioRenderer::OnApply()
+{
+ if (!UpdateData(TRUE)) {
+ return FALSE;
+ }
+
+ const auto& s = AfxGetAppSettings();
+
+ CString deviceId;
+ DWORD_PTR idx = m_combo1.GetItemData(m_combo1.GetCurSel());
+ if (idx != CB_ERR) {
+ deviceId = m_deviceIds[idx];
+ }
+
+ UINT32 buffer;
+ s.sanear->GetOuputDevice(nullptr, nullptr, &buffer);
+ s.sanear->SetOuputDevice(deviceId, m_bExclusiveMode, buffer);
+
+ s.sanear->SetAllowBitstreaming(m_bAllowBitstreaming);
+ s.sanear->SetCrossfeedSettings(m_slider1.GetPos(), m_slider2.GetPos());
+ s.sanear->SetCrossfeedEnabled(m_bCrossfeedEnabled);
+
+ return __super::OnApply();
+}
+
+void CPPageAudioRenderer::OnCancel()
+{
+ __super::OnCancel();
+}
+
+void CPPageAudioRenderer::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ if (pScrollBar && (*pScrollBar == m_slider1 || *pScrollBar == m_slider2)) {
+ SetModified(TRUE);
+ }
+}
+
+void CPPageAudioRenderer::OnCMoyButton()
+{
+ m_slider1.SetPos(SaneAudioRenderer::ISettings::CROSSFEED_CUTOFF_FREQ_CMOY);
+ m_slider2.SetPos(SaneAudioRenderer::ISettings::CROSSFEED_LEVEL_CMOY);
+ SetModified(TRUE);
+}
+
+void CPPageAudioRenderer::OnJMeierButton()
+{
+ m_slider1.SetPos(SaneAudioRenderer::ISettings::CROSSFEED_CUTOFF_FREQ_JMEIER);
+ m_slider2.SetPos(SaneAudioRenderer::ISettings::CROSSFEED_LEVEL_JMEIER);
+ SetModified(TRUE);
+}
+
+void CPPageAudioRenderer::OnUpdateAllowBitstreamingCheckbox(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(IsDlgButtonChecked(IDC_CHECK1));
+}
+
+void CPPageAudioRenderer::OnUpdateCrossfeedGroup(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(IsDlgButtonChecked(IDC_CHECK3));
+}
+
+void CPPageAudioRenderer::OnUpdateCrossfeedCutoffLabel(CCmdUI* pCmdUI)
+{
+ OnUpdateCrossfeedGroup(pCmdUI);
+ CString label;
+ label.Format(_T("%d Hz"), m_slider1.GetPos());
+ pCmdUI->SetText(label);
+}
+
+void CPPageAudioRenderer::OnUpdateCrossfeedLevelLabel(CCmdUI* pCmdUI)
+{
+ OnUpdateCrossfeedGroup(pCmdUI);
+ int pos = m_slider2.GetPos();
+ CString label;
+ label.Format(_T("%d.%d dB"), pos / 10, pos % 10);
+ pCmdUI->SetText(label);
+}