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

github.com/mpc-hc/sanear.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Marsev <alex.marsev@gmail.com>2015-08-08 20:58:10 +0300
committerAlex Marsev <alex.marsev@gmail.com>2015-08-08 20:58:10 +0300
commita424d59c574751a746168cf1500bd161f026b2a4 (patch)
treedaa8b138459f281f1f88f1c9a7a0b9082f7a79a4
parent7ac3794b6e119a977e4a0ec8f5a6b39b10250084 (diff)
parent8afb5197935386ebee8b8c7380190041c3caaa82 (diff)
Merge master
-rw-r--r--changelog.txt4
-rw-r--r--dll/src/sanear-dll/Entry.cpp19
-rw-r--r--dll/src/sanear-dll/OuterFilter.cpp3
-rw-r--r--dll/src/sanear-dll/sanear.rc10
-rwxr-xr-xsrc/DspDither.cpp12
-rwxr-xr-xsrc/DspDither.h1
-rw-r--r--src/MyFilter.cpp52
-rw-r--r--src/MyFilter.h4
-rw-r--r--src/MyPropertyPage.cpp105
-rw-r--r--src/MyPropertyPage.h16
10 files changed, 167 insertions, 59 deletions
diff --git a/changelog.txt b/changelog.txt
index 4847bdc..3a57105 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,6 +1,10 @@
Sanear, a robust DirectShow audio renderer
==========================================
+v0.3 - 2015/08/08
+* Bugfixing release
+* Improves status page compatibility with certain players
+
v0.2 - 2015/08/02
* Bugfixing release
* Fixes audible noise in dithering
diff --git a/dll/src/sanear-dll/Entry.cpp b/dll/src/sanear-dll/Entry.cpp
index 9cabd03..9167b20 100644
--- a/dll/src/sanear-dll/Entry.cpp
+++ b/dll/src/sanear-dll/Entry.cpp
@@ -1,14 +1,17 @@
#include "pch.h"
#include "OuterFilter.h"
+#include "../../../src/MyPropertyPage.h"
namespace
{
// {DF557071-C9FD-433A-9627-81E0D3640ED9}
const GUID filterGuid = {0xdf557071, 0xc9fd, 0x433a, {0x96, 0x27, 0x81, 0xe0, 0xd3, 0x64, 0xe, 0xd9}};
-
const WCHAR filterName[] = L"Sanear Audio Renderer";
+ const GUID statusPageGuid = __uuidof(SaneAudioRenderer::MyPropertyPage);
+ const WCHAR statusPageName[] = L"Sanear Status Page";
+
const AMOVIESETUP_MEDIATYPE pinTypes[] = {
{&MEDIATYPE_Audio, &CLSID_NULL},
};
@@ -23,9 +26,11 @@ namespace
}
CUnknown* WINAPI CreateFilterInstance(LPUNKNOWN, HRESULT*);
+CUnknown* WINAPI CreateStatusPageInstance(LPUNKNOWN, HRESULT*);
CFactoryTemplate g_Templates[] = {
{filterName, &filterGuid, CreateFilterInstance},
+ {statusPageName, &statusPageGuid, CreateStatusPageInstance},
};
int g_cTemplates = _countof(g_Templates);
@@ -106,6 +111,18 @@ CUnknown* WINAPI CreateFilterInstance(IUnknown* pUnknown, HRESULT* pResult)
return pFilter;
}
+CUnknown* WINAPI CreateStatusPageInstance(IUnknown* pUnknown, HRESULT* pResult)
+{
+ CheckPointer(pResult, nullptr);
+
+ auto pFilter = new(std::nothrow) SaneAudioRenderer::MyPropertyPage();
+
+ if (!pFilter)
+ *pResult = E_OUTOFMEMORY;
+
+ return pFilter;
+}
+
STDAPI DllRegisterServer()
{
if (!IsWindowsVistaOrGreater())
diff --git a/dll/src/sanear-dll/OuterFilter.cpp b/dll/src/sanear-dll/OuterFilter.cpp
index 084e869..fdd6b73 100644
--- a/dll/src/sanear-dll/OuterFilter.cpp
+++ b/dll/src/sanear-dll/OuterFilter.cpp
@@ -56,6 +56,9 @@ namespace SaneAudioRenderer
if (riid == IID_IUnknown)
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
+ if (riid == IID_ISpecifyPropertyPages)
+ return m_innerFilter->QueryInterface(__uuidof(ISpecifyPropertyPages2), ppv);
+
return m_innerFilter->QueryInterface(riid, ppv);
}
diff --git a/dll/src/sanear-dll/sanear.rc b/dll/src/sanear-dll/sanear.rc
index fa267f1..cfc6778 100644
--- a/dll/src/sanear-dll/sanear.rc
+++ b/dll/src/sanear-dll/sanear.rc
@@ -60,8 +60,8 @@ IDI_ICON1 ICON "sanear.ico"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,0,0
- PRODUCTVERSION 0,2,0,0
+ FILEVERSION 0,3,0,0
+ PRODUCTVERSION 0,3,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -76,10 +76,10 @@ BEGIN
BEGIN
BLOCK "080904b0"
BEGIN
- VALUE "FileDescription", "Robust DirectShow audio renderer"
- VALUE "FileVersion", "0.2.0.0"
+ VALUE "FileDescription", "Sanear, a robust DirectShow audio renderer"
+ VALUE "FileVersion", "0.3.0.0"
VALUE "ProductName", "Sanear Audio Renderer"
- VALUE "ProductVersion", "0.2.0.0"
+ VALUE "ProductVersion", "0.3.0.0"
END
END
BLOCK "VarFileInfo"
diff --git a/src/DspDither.cpp b/src/DspDither.cpp
index c8682b0..7c9cbba 100755
--- a/src/DspDither.cpp
+++ b/src/DspDither.cpp
@@ -5,7 +5,8 @@ namespace SaneAudioRenderer
{
void DspDither::Initialize(DspFormat outputFormat)
{
- m_active = (outputFormat == DspFormat::Pcm16);
+ m_enabled = (outputFormat == DspFormat::Pcm16);
+ m_active = m_enabled;
for (size_t i = 0; i < 18; i++)
{
@@ -17,13 +18,18 @@ namespace SaneAudioRenderer
bool DspDither::Active()
{
- return m_active;
+ return m_enabled && m_active;
}
void DspDither::Process(DspChunk& chunk)
{
- if (!m_active || chunk.IsEmpty() || chunk.GetFormatSize() <= DspFormatSize(DspFormat::Pcm16))
+ if (!m_enabled || chunk.IsEmpty() || chunk.GetFormatSize() <= DspFormatSize(DspFormat::Pcm16))
+ {
+ m_active = false;
return;
+ }
+
+ m_active = true;
DspChunk::ToFloat(chunk);
diff --git a/src/DspDither.h b/src/DspDither.h
index 6fe5422..48f7294 100755
--- a/src/DspDither.h
+++ b/src/DspDither.h
@@ -24,6 +24,7 @@ namespace SaneAudioRenderer
private:
+ bool m_enabled = false;
bool m_active = false;
std::array<float, 18> m_previous;
std::array<std::minstd_rand, 18> m_generator;
diff --git a/src/MyFilter.cpp b/src/MyFilter.cpp
index 2a7bc67..ca6ab99 100644
--- a/src/MyFilter.cpp
+++ b/src/MyFilter.cpp
@@ -7,7 +7,6 @@
#include "MyClock.h"
#include "MyTestClock.h"
#include "MyPin.h"
-#include "MyPropertyPage.h"
namespace SaneAudioRenderer
{
@@ -69,8 +68,8 @@ namespace SaneAudioRenderer
if (riid == __uuidof(ISpecifyPropertyPages2))
return GetInterface(static_cast<ISpecifyPropertyPages2*>(this), ppv);
- if (riid == IID_ISpecifyPropertyPages)
- return GetInterface(static_cast<ISpecifyPropertyPages*>(this), ppv);
+ if (riid == __uuidof(IStatusPageData))
+ return GetInterface(static_cast<IStatusPageData*>(this), ppv);
return CBaseFilter::NonDelegatingQueryInterface(riid, ppv);
}
@@ -129,10 +128,18 @@ namespace SaneAudioRenderer
{
CheckPointer(pPages, E_POINTER);
- pPages->cElems = 1;
- pPages->pElems = (GUID*)CoTaskMemAlloc(sizeof(GUID));
- CheckPointer(pPages->pElems, E_OUTOFMEMORY);
- *pPages->pElems = __uuidof(MyPropertyPage);
+ if (m_pin->IsConnected())
+ {
+ pPages->cElems = 1;
+ pPages->pElems = (GUID*)CoTaskMemAlloc(sizeof(GUID));
+ CheckPointer(pPages->pElems, E_OUTOFMEMORY);
+ pPages->pElems[0] = __uuidof(MyPropertyPage);
+ }
+ else
+ {
+ pPages->cElems = 0;
+ pPages->pElems = nullptr;
+ }
return S_OK;
}
@@ -146,6 +153,21 @@ namespace SaneAudioRenderer
MyPropertyPage* pPage;
+ pPage = new(std::nothrow) MyPropertyPage();
+
+ CheckPointer(pPage, E_OUTOFMEMORY);
+
+ pPage->AddRef();
+
+ HRESULT result = pPage->QueryInterface(IID_PPV_ARGS(ppPage));
+
+ pPage->Release();
+
+ return result;
+ }
+
+ STDMETHODIMP MyFilter::GetPageData(std::vector<char>& data)
+ {
try
{
CAutoLock rendererLock(m_renderer.get());
@@ -153,23 +175,17 @@ namespace SaneAudioRenderer
auto inputFormat = m_renderer->GetInputFormat();
auto audioDevice = m_renderer->GetAudioDevice();
- pPage = new MyPropertyPage(inputFormat, audioDevice,
- m_renderer->GetActiveProcessors(),
- m_renderer->OnExternalClock(),
- m_renderer->IsLive());
+ data = MyPropertyPage::CreateDialogData(inputFormat, audioDevice,
+ m_renderer->GetActiveProcessors(),
+ m_renderer->OnExternalClock(),
+ m_renderer->IsLive());
}
catch (std::bad_alloc&)
{
return E_OUTOFMEMORY;
}
- pPage->AddRef();
-
- HRESULT result = pPage->QueryInterface(IID_PPV_ARGS(ppPage));
-
- pPage->Release();
-
- return result;
+ return S_OK;
}
template <FILTER_STATE NewState, typename PinFunction>
diff --git a/src/MyFilter.h b/src/MyFilter.h
index a4a92aa..f377ded 100644
--- a/src/MyFilter.h
+++ b/src/MyFilter.h
@@ -1,6 +1,7 @@
#pragma once
#include "Interfaces.h"
+#include "MyPropertyPage.h"
namespace SaneAudioRenderer
{
@@ -13,6 +14,7 @@ namespace SaneAudioRenderer
: public CCritSec
, public CBaseFilter
, public ISpecifyPropertyPages2
+ , public IStatusPageData
{
public:
@@ -40,6 +42,8 @@ namespace SaneAudioRenderer
STDMETHODIMP GetPages(CAUUID* pPages) override;
STDMETHODIMP CreatePage(const GUID& guid, IPropertyPage** ppPage) override;
+ STDMETHODIMP GetPageData(std::vector<char>& data) override;
+
private:
template <FILTER_STATE NewState, typename PinFunction>
diff --git a/src/MyPropertyPage.cpp b/src/MyPropertyPage.cpp
index 129019b..6574c64 100644
--- a/src/MyPropertyPage.cpp
+++ b/src/MyPropertyPage.cpp
@@ -27,7 +27,7 @@ namespace SaneAudioRenderer
Write(out, (void*)str.c_str(), sizeof(wchar_t) * (str.length() + 1));
}
- void WriteDialogHeader(std::vector<char>& out, const std::wstring& font, WORD fontSize)
+ void WriteDialogHeader(std::vector<char>& out, const std::wstring& font, WORD fontSize, short w, short h)
{
assert(out.empty());
@@ -36,8 +36,8 @@ namespace SaneAudioRenderer
Write<WORD>(out, 0);
Write<short>(out, 0);
Write<short>(out, 0);
- Write<short>(out, 0);
- Write<short>(out, 0);
+ Write<short>(out, w);
+ Write<short>(out, h);
Write<WORD>(out, 0);
Write<WORD>(out, 0);
WriteString(out, L"");
@@ -123,9 +123,8 @@ namespace SaneAudioRenderer
}
}
- MyPropertyPage::MyPropertyPage(SharedWaveFormat inputFormat, const AudioDevice* pDevice,
- std::vector<std::wstring> processors, bool externalClock, bool live)
- : CUnknown(L"SaneAudioRenderer::MyPropertyPage", nullptr)
+ std::vector<char> MyPropertyPage::CreateDialogData(SharedWaveFormat inputFormat, const AudioDevice* pDevice,
+ std::vector<std::wstring> processors, bool externalClock, bool live)
{
std::wstring adapterField = (pDevice && pDevice->GetAdapterName()) ? *pDevice->GetAdapterName() : L"-";
@@ -169,28 +168,38 @@ namespace SaneAudioRenderer
if (processorsField.empty())
processorsField = L"-";
- WriteDialogHeader(m_dialogData, L"MS Shell Dlg", 8);
- WriteDialogItem(m_dialogData, BS_GROUPBOX, 0x0080FFFF, 5, 5, 210, 150, L"Renderer Status");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 20, 60, 8, L"Adapter:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 20, 130, 8, adapterField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 32, 60, 8, L"Endpoint:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 32, 130, 8, endpointField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 44, 60, 8, L"Exclusive:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 44, 130, 8, exclusiveField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 56, 60, 8, L"Buffer:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 56, 130, 8, bufferField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 68, 60, 8, L"Bitstreaming:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 68, 130, 8, bitstreamingField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 80, 60, 8, L"Slaving:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 80, 130, 8, slavingField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 92, 60, 8, L"Format:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 92, 130, 8, formatField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 104, 60, 8, L"Channels:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 104, 130, 8, channelsField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 116, 60, 8, L"Rate:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 116, 130, 8, rateField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 128, 60, 8, L"Processors:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 128, 130, 24, processorsField);
+ std::vector<char> dialogData;
+
+ WriteDialogHeader(dialogData, L"MS Shell Dlg", 8, 220, 160);
+ WriteDialogItem(dialogData, BS_GROUPBOX, 0x0080FFFF, 5, 5, 210, 150, L"Renderer Status");
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 20, 60, 8, L"Adapter:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 20, 130, 8, adapterField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 32, 60, 8, L"Endpoint:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 32, 130, 8, endpointField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 44, 60, 8, L"Exclusive:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 44, 130, 8, exclusiveField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 56, 60, 8, L"Buffer:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 56, 130, 8, bufferField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 68, 60, 8, L"Bitstreaming:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 68, 130, 8, bitstreamingField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 80, 60, 8, L"Slaving:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 80, 130, 8, slavingField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 92, 60, 8, L"Format:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 92, 130, 8, formatField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 104, 60, 8, L"Channels:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 104, 130, 8, channelsField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 116, 60, 8, L"Rate:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 116, 130, 8, rateField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 128, 60, 8, L"Processors:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 128, 130, 24, processorsField);
+
+ return dialogData;
+ }
+
+ MyPropertyPage::MyPropertyPage()
+ : CUnknown(L"SaneAudioRenderer::MyPropertyPage", nullptr)
+ {
+ m_dialogData = CreateDialogData(nullptr, nullptr, {}, false, false);
}
STDMETHODIMP MyPropertyPage::NonDelegatingQueryInterface(REFIID riid, void** ppv)
@@ -215,9 +224,17 @@ namespace SaneAudioRenderer
{
CheckPointer(pRect, E_POINTER);
+ if (m_hWindow)
+ return E_UNEXPECTED;
+
m_hWindow = CreateDialogIndirect(GetModuleHandle(nullptr), (LPCDLGTEMPLATE)m_dialogData.data(), hParent, nullptr);
- return (m_hWindow != NULL) ? S_OK : E_UNEXPECTED;
+ if (!m_hWindow)
+ return E_OUTOFMEMORY;
+
+ Move(pRect);
+
+ return S_OK;
}
STDMETHODIMP MyPropertyPage::Deactivate()
@@ -243,6 +260,36 @@ namespace SaneAudioRenderer
pPageInfo->pszHelpFile = nullptr;
pPageInfo->dwHelpContext = 0;
+ // This is how GetDialogSize() from DirectShow Base Classes does it.
+ HWND hWindow = CreateDialogIndirect(GetModuleHandle(nullptr), (LPCDLGTEMPLATE)m_dialogData.data(), GetDesktopWindow(), nullptr);
+ if (hWindow)
+ {
+ RECT rect;
+ if (GetWindowRect(hWindow, &rect))
+ {
+ pPageInfo->size.cx = rect.right - rect.left;
+ pPageInfo->size.cy = rect.bottom - rect.top;
+ }
+
+ DestroyWindow(hWindow);
+ }
+
+ return S_OK;
+ }
+
+ STDMETHODIMP MyPropertyPage::SetObjects(ULONG nObjects, IUnknown** ppUnk)
+ {
+ if (nObjects != 1)
+ return E_UNEXPECTED;
+
+ CheckPointer(ppUnk, E_POINTER);
+ CheckPointer(ppUnk[0], E_POINTER);
+
+ IStatusPageDataPtr data;
+ ReturnIfFailed(ppUnk[0]->QueryInterface(IID_PPV_ARGS(&data)));
+
+ ReturnIfFailed(data->GetPageData(m_dialogData));
+
return S_OK;
}
diff --git a/src/MyPropertyPage.h b/src/MyPropertyPage.h
index 7b39414..53ef9c6 100644
--- a/src/MyPropertyPage.h
+++ b/src/MyPropertyPage.h
@@ -4,6 +4,14 @@ namespace SaneAudioRenderer
{
class AudioDevice;
+ // NOTE: This is internal interface and shouldn't be used outside of Sanear.
+ struct __declspec(uuid("361657BC-CC1E-420A-BE7B-21C34E3D9F76"))
+ IStatusPageData : IUnknown
+ {
+ STDMETHOD(GetPageData)(std::vector<char>& data) = 0;
+ };
+ _COM_SMARTPTR_TYPEDEF(IStatusPageData, __uuidof(IStatusPageData));
+
class _declspec(uuid("7EEEDEC8-8B8E-4220-AF12-08BC0CE844F0"))
MyPropertyPage final
: public CUnknown
@@ -11,8 +19,10 @@ namespace SaneAudioRenderer
{
public:
- MyPropertyPage(SharedWaveFormat inputFormat, const AudioDevice* device,
- std::vector<std::wstring> processors, bool externalClock, bool live);
+ static std::vector<char> CreateDialogData(SharedWaveFormat inputFormat, const AudioDevice* device,
+ std::vector<std::wstring> processors, bool externalClock, bool live);
+
+ MyPropertyPage();
MyPropertyPage(const MyPropertyPage&) = delete;
MyPropertyPage& operator=(const MyPropertyPage&) = delete;
@@ -24,7 +34,7 @@ namespace SaneAudioRenderer
STDMETHODIMP Activate(HWND hParent, LPCRECT pRect, BOOL bModal) override;
STDMETHODIMP Deactivate() override;
STDMETHODIMP GetPageInfo(PROPPAGEINFO* pPageInfo) override;
- STDMETHODIMP SetObjects(ULONG, IUnknown**) override { return S_OK; }
+ STDMETHODIMP SetObjects(ULONG nObjects, IUnknown** ppUnk) override;
STDMETHODIMP Show(UINT cmdShow) override;
STDMETHODIMP Move(LPCRECT pRect) override;
STDMETHODIMP IsPageDirty() override { return S_FALSE; }