diff options
author | Alex Marsev <alex.marsev@gmail.com> | 2015-08-08 20:58:10 +0300 |
---|---|---|
committer | Alex Marsev <alex.marsev@gmail.com> | 2015-08-08 20:58:10 +0300 |
commit | a424d59c574751a746168cf1500bd161f026b2a4 (patch) | |
tree | daa8b138459f281f1f88f1c9a7a0b9082f7a79a4 | |
parent | 7ac3794b6e119a977e4a0ec8f5a6b39b10250084 (diff) | |
parent | 8afb5197935386ebee8b8c7380190041c3caaa82 (diff) |
Merge master
-rw-r--r-- | changelog.txt | 4 | ||||
-rw-r--r-- | dll/src/sanear-dll/Entry.cpp | 19 | ||||
-rw-r--r-- | dll/src/sanear-dll/OuterFilter.cpp | 3 | ||||
-rw-r--r-- | dll/src/sanear-dll/sanear.rc | 10 | ||||
-rwxr-xr-x | src/DspDither.cpp | 12 | ||||
-rwxr-xr-x | src/DspDither.h | 1 | ||||
-rw-r--r-- | src/MyFilter.cpp | 52 | ||||
-rw-r--r-- | src/MyFilter.h | 4 | ||||
-rw-r--r-- | src/MyPropertyPage.cpp | 105 | ||||
-rw-r--r-- | src/MyPropertyPage.h | 16 |
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; }
|