--- /dev/null
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QOgg", "QOgg\QOgg.vcproj", "{C7FCC9CF-148D-4C37-B9C0-0EEAFB3B909E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QVorbis", "QVorbis\QVorbis.vcproj", "{88A9E896-687C-47CE-ABE9-8C2366702A24}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QTTA", "QTTA\QTTA.vcproj", "{48ADAB28-37BE-46F9-81D7-E5F68252F0AE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QDSAudio", "QDSAudio\QDSAudio.vcproj", "{537EF009-F6E6-40BE-A5B2-A3B99D0CEC62}"
+ ProjectSection(ProjectDependencies) = postProject
+ {48ADAB28-37BE-46F9-81D7-E5F68252F0AE} = {48ADAB28-37BE-46F9-81D7-E5F68252F0AE}
+ {88A9E896-687C-47CE-ABE9-8C2366702A24} = {88A9E896-687C-47CE-ABE9-8C2366702A24}
+ {C7FCC9CF-148D-4C37-B9C0-0EEAFB3B909E} = {C7FCC9CF-148D-4C37-B9C0-0EEAFB3B909E}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QDSPlayer", "QDSPlayer\QDSPlayer.vcproj", "{B4F85FC2-73B1-472B-9A92-FF004A3484F7}"
+ ProjectSection(ProjectDependencies) = postProject
+ {537EF009-F6E6-40BE-A5B2-A3B99D0CEC62} = {537EF009-F6E6-40BE-A5B2-A3B99D0CEC62}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C7FCC9CF-148D-4C37-B9C0-0EEAFB3B909E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C7FCC9CF-148D-4C37-B9C0-0EEAFB3B909E}.Debug|Win32.Build.0 = Debug|Win32
+ {C7FCC9CF-148D-4C37-B9C0-0EEAFB3B909E}.Release|Win32.ActiveCfg = Release|Win32
+ {C7FCC9CF-148D-4C37-B9C0-0EEAFB3B909E}.Release|Win32.Build.0 = Release|Win32
+ {88A9E896-687C-47CE-ABE9-8C2366702A24}.Debug|Win32.ActiveCfg = Debug|Win32
+ {88A9E896-687C-47CE-ABE9-8C2366702A24}.Debug|Win32.Build.0 = Debug|Win32
+ {88A9E896-687C-47CE-ABE9-8C2366702A24}.Release|Win32.ActiveCfg = Release|Win32
+ {88A9E896-687C-47CE-ABE9-8C2366702A24}.Release|Win32.Build.0 = Release|Win32
+ {48ADAB28-37BE-46F9-81D7-E5F68252F0AE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {48ADAB28-37BE-46F9-81D7-E5F68252F0AE}.Debug|Win32.Build.0 = Debug|Win32
+ {48ADAB28-37BE-46F9-81D7-E5F68252F0AE}.Release|Win32.ActiveCfg = Release|Win32
+ {48ADAB28-37BE-46F9-81D7-E5F68252F0AE}.Release|Win32.Build.0 = Release|Win32
+ {537EF009-F6E6-40BE-A5B2-A3B99D0CEC62}.Debug|Win32.ActiveCfg = Debug|Win32
+ {537EF009-F6E6-40BE-A5B2-A3B99D0CEC62}.Debug|Win32.Build.0 = Debug|Win32
+ {537EF009-F6E6-40BE-A5B2-A3B99D0CEC62}.Release|Win32.ActiveCfg = Release|Win32
+ {537EF009-F6E6-40BE-A5B2-A3B99D0CEC62}.Release|Win32.Build.0 = Release|Win32
+ {B4F85FC2-73B1-472B-9A92-FF004A3484F7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B4F85FC2-73B1-472B-9A92-FF004A3484F7}.Debug|Win32.Build.0 = Debug|Win32
+ {B4F85FC2-73B1-472B-9A92-FF004A3484F7}.Release|Win32.ActiveCfg = Release|Win32
+ {B4F85FC2-73B1-472B-9A92-FF004A3484F7}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
--- /dev/null
+// DllMain.cpp
+// 2009/08/21
+
+#include "StdAfx.h"
+
+HMODULE g_hDll;
+
+BOOL WINAPI DllMain(
+ HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved)
+{
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hinstDLL);
+ g_hDll = hinstDLL;
+ break;
+ }
+
+ return TRUE;
+}
+
--- /dev/null
+// QDSAudio.cpp
+// 2009/08/21
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "VorbisDecoder.h"
+
+#include "OggVorbis.h"
+#include "TTAReader.h"
+
+#include "QDSAudio.h"
+
+#include "QMediaType.h"
+#include "QPinEnum.h"
+
+#include "QWaveOutputer.h"
+
+#include "QReader.h"
+
+#include "QStreamer.h"
+
+#include "QPin.h"
+#include "QFilter.h"
+
+/* */
+
+#ifdef QDSAUDIO_BUILD_DLL
+
+// Module
+class Module : public ATL::CAtlDllModuleT<Module> {
+
+}; // Module
+
+Module _AtlModule;
+
+#endif
+
+/* */
+
+static HRESULT InitModule()
+{
+#ifdef QDSAUDIO_BUILD_DLL
+ static bool s_init = true;
+ if (s_init) {
+ if (!QV_Initialize()) {
+ return E_OUTOFMEMORY;
+ }
+ s_init = false;
+ }
+#endif
+
+ return S_OK;
+}
+
+/* */
+
+HRESULT QDSA_CreateOggVorbisDecoder(
+ LPCWSTR path,
+ IBaseFilter** ppFilter)
+{
+ HRESULT hRslt = InitModule();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ ATL::CComObject<QFilter>* filter = 0;
+ hRslt = ATL::CComObject<QFilter>::CreateInstance(&filter);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ hRslt = filter->OpenVorbis(path);
+ if (FAILED(hRslt)) {
+ delete filter;
+ return hRslt;
+ }
+
+ hRslt = filter->QueryInterface(ppFilter);
+ if (FAILED(hRslt)) {
+ delete filter;
+ return hRslt;
+ }
+
+ return S_OK;
+}
+
+/* */
+
+HRESULT QDSA_CreateOggVorbisDecoder_IStream(
+ IStream* p,
+ IBaseFilter** ppFilter)
+{
+ HRESULT hRslt = InitModule();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ ATL::CComObject<QFilter>* filter = 0;
+ hRslt = ATL::CComObject<QFilter>::CreateInstance(&filter);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ hRslt = filter->OpenVorbis(p);
+ if (FAILED(hRslt)) {
+ delete filter;
+ return hRslt;
+ }
+
+ hRslt = filter->QueryInterface(ppFilter);
+ if (FAILED(hRslt)) {
+ delete filter;
+ return hRslt;
+ }
+
+ return S_OK;
+}
+
+/* */
+
+HRESULT QDSA_CreateTTADecoder(
+ LPCWSTR path,
+ IBaseFilter** ppFilter)
+{
+ HRESULT hRslt = InitModule();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ ATL::CComObject<QFilter>* filter = 0;
+ hRslt = ATL::CComObject<QFilter>::CreateInstance(&filter);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ hRslt = filter->OpenTTA(path);
+ if (FAILED(hRslt)) {
+ delete filter;
+ return hRslt;
+ }
+
+ hRslt = filter->QueryInterface(ppFilter);
+ if (FAILED(hRslt)) {
+ delete filter;
+ return hRslt;
+ }
+
+ return S_OK;
+}
+
+/* */
+
+HRESULT QDSA_CreateTTADecoder_IStream(
+ IStream* p,
+ IBaseFilter** ppFilter)
+{
+ HRESULT hRslt = InitModule();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ ATL::CComObject<QFilter>* filter = 0;
+ hRslt = ATL::CComObject<QFilter>::CreateInstance(&filter);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ hRslt = filter->OpenTTA(p);
+ if (FAILED(hRslt)) {
+ delete filter;
+ return hRslt;
+ }
+
+ hRslt = filter->QueryInterface(ppFilter);
+ if (FAILED(hRslt)) {
+ delete filter;
+ return hRslt;
+ }
+
+ return S_OK;
+}
+
+/* */
+
+void QDSA_FreeMediaType(
+ AM_MEDIA_TYPE* mt)
+{
+ QMediaType::Free(mt);
+}
+
+/* */
+
--- /dev/null
+; QVorbis.def
+; 2009/08/21
+
+EXPORTS
+QDSA_CreateOggVorbisDecoder
+QDSA_CreateOggVorbisDecoder_IStream
+
+QDSA_CreateTTADecoder
+QDSA_CreateTTADecoder_IStream
+
+QDSA_FreeMediaType
+
--- /dev/null
+// QDSAudio.h
+// 2009/08/21
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* */
+
+HRESULT QDSA_CreateOggVorbisDecoder(
+ LPCWSTR path,
+ IBaseFilter** ppFilter);
+
+HRESULT QDSA_CreateOggVorbisDecoder_IStream(
+ IStream* p,
+ IBaseFilter** ppFilter);
+
+/* */
+
+HRESULT QDSA_CreateTTADecoder(
+ LPCWSTR path,
+ IBaseFilter** ppFilter);
+
+HRESULT QDSA_CreateTTADecoder_IStream(
+ IStream* p,
+ IBaseFilter** ppFilter);
+
+/* */
+
+void QDSA_FreeMediaType(
+ AM_MEDIA_TYPE* mt);
+
+/* */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
--- /dev/null
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="QDSAudio"
+ ProjectGUID="{537EF009-F6E6-40BE-A5B2-A3B99D0CEC62}"
+ RootNamespace="QDSAudio"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="../Bin/$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../Lib/QOgg;../../../Lib/QTTA;../../../Lib/QVorbis"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;QDSAUDIO_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ ModuleDefinitionFile="$(InputName).def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="../Bin/$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../../Lib/QOgg;../../../Lib/QTTA;../../../Lib/QVorbis"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;QDSAUDIO_EXPORTS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ ModuleDefinitionFile="$(InputName).def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="\83\\81[\83X \83t\83@\83C\83\8b"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\DllMain.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\QDSAudio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\StdAfx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="\83w\83b\83_\81[ \83t\83@\83C\83\8b"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\QDSAudio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\QFilter.h"
+ >
+ </File>
+ <File
+ RelativePath=".\QMediaType.h"
+ >
+ </File>
+ <File
+ RelativePath=".\QPin.h"
+ >
+ </File>
+ <File
+ RelativePath=".\QPinEnum.h"
+ >
+ </File>
+ <File
+ RelativePath=".\QReader.h"
+ >
+ </File>
+ <File
+ RelativePath=".\QStreamer.h"
+ >
+ </File>
+ <File
+ RelativePath=".\QWaveOutputer.h"
+ >
+ </File>
+ <File
+ RelativePath=".\StdAfx.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="\83\8a\83\\81[\83X \83t\83@\83C\83\8b"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+// QFilter.h
+// 2009/08/21
+
+#pragma once
+
+/* */
+
+// {B72ABE74-E35E-4ACA-AACD-4A7E13E7AA65}
+DEFINE_GUID(CLSID_QDSAudio,
+ 0xb72abe74, 0xe35e, 0x4aca, 0xaa, 0xcd, 0x4a, 0x7e, 0x13, 0xe7, 0xaa, 0x65);
+
+/* */
+
+// QFilter
+[ uuid("B72ABE74-E35E-4ACA-AACD-4A7E13E7AA65") ]
+class ATL_NO_VTABLE QFilter :
+ public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>,
+ public ATL::CComCoClass<QFilter, &CLSID_QDSAudio>,
+
+ public IBaseFilter,
+ public IMediaSeeking,
+ public IAMFilterMiscFlags,
+
+ public QPinHost {
+
+ ATL::CComCriticalSection m_cs;
+
+ ATL::CComPtr<IReferenceClock> m_Clock;
+
+ IFilterGraph* m_pFGraph; /* weak */
+
+ ATL::CStringW m_Name;
+
+ QReader* m_pReader;
+
+ QStreamer* m_pStreamer;
+
+ enum {
+ PID_Audio = 0,
+ PINS
+ };
+
+ IPin* m_Pins[PINS];
+
+ QPinAudio* m_pPinAudio;
+
+ FILTER_STATE m_state;
+
+ INT64 m_StartPos;
+
+public:
+
+ DECLARE_NOT_AGGREGATABLE(QFilter)
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(QFilter)
+ COM_INTERFACE_ENTRY(IPersist)
+ COM_INTERFACE_ENTRY(IMediaFilter)
+ COM_INTERFACE_ENTRY(IBaseFilter)
+ COM_INTERFACE_ENTRY(IMediaSeeking)
+ COM_INTERFACE_ENTRY(IAMFilterMiscFlags)
+ END_COM_MAP()
+
+public:
+
+ QFilter() :
+ m_pReader(0),
+ m_pStreamer(0),
+ m_pPinAudio(0),
+ m_state(State_Stopped),
+ m_StartPos(-1)
+ {
+ memset(m_Pins, 0, sizeof(m_Pins));
+ }
+
+ ~QFilter()
+ {
+ delete m_pReader;
+ }
+
+ HRESULT FinalConstruct()
+ {
+ ATLTRACE("QFilter::FinalConstruct()\n");
+
+ HRESULT hRslt = m_cs.Init();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ {
+ ATL::CComObject<QPinAudio>* pin = 0;
+ HRESULT hRslt = ATL::CComObject<QPinAudio>::CreateInstance(&pin);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ pin->Init(this, this, L"Audio");
+
+ hRslt = pin->QueryInterface(m_Pins + PID_Audio);
+ if (FAILED(hRslt)) {
+ delete pin;
+ return hRslt;
+ }
+
+ m_pPinAudio = pin;
+ }
+
+ return S_OK;
+ }
+
+ void FinalRelease()
+ {
+ ATLTRACE("QFilter::FinalRelease()\n");
+
+ for (INT32 i = 0; i < PINS; i++) {
+ if (m_Pins[i] != 0) {
+ m_Pins[i]->Release();
+ }
+ }
+
+ m_cs.Term();
+ }
+
+ /* */
+
+ HRESULT OpenVorbis(LPCWSTR path)
+ {
+ QVorbisReader* p = new QVorbisReader();
+ if (!p->Open(path)) {
+ delete p;
+ return VFW_E_NOT_FOUND;
+ }
+
+ m_pReader = p;
+
+ HRESULT hRslt = Setup();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ HRESULT OpenVorbis(IStream* p)
+ {
+ QVorbisReader* r = new QVorbisReader();
+ if (!r->Open(p)) {
+ delete r;
+ return VFW_E_NOT_FOUND;
+ }
+
+ m_pReader = r;
+
+ HRESULT hRslt = Setup();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ /* */
+
+ HRESULT OpenTTA(LPCWSTR path)
+ {
+ QTTAReader* p = new QTTAReader();
+ if (!p->Open(path)) {
+ delete p;
+ return VFW_E_NOT_FOUND;
+ }
+
+ m_pReader = p;
+
+ HRESULT hRslt = Setup();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ HRESULT OpenTTA(IStream* p)
+ {
+ QTTAReader* r = new QTTAReader();
+ if (!r->Open(p)) {
+ delete r;
+ return VFW_E_NOT_FOUND;
+ }
+
+ m_pReader = r;
+
+ HRESULT hRslt = Setup();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ /* */
+
+private:
+
+ /* */
+
+ HRESULT Setup()
+ {
+ QReader::Format fmt = m_pReader->GetFormat();
+
+ m_pPinAudio->SetupAudioFormat(
+ fmt.Channels,
+ fmt.SamplingRate);
+
+ return S_OK;
+ }
+
+ /* */
+
+public:
+
+ /* QPinHost */
+
+ virtual ATL::CComCriticalSection& FilterCSec()
+ {
+ return m_cs;
+ }
+
+ virtual bool IsRunning()
+ {
+ return (m_state != State_Stopped);
+ }
+
+ /* IPersist */
+
+ STDMETHOD(GetClassID)(
+ LPCLSID pClassID)
+ {
+ ATLTRACE("QFilter::GetClassID()\n");
+
+ if (pClassID == 0) {
+ return E_INVALIDARG;
+ }
+
+ *pClassID = __uuidof(QFilter);
+
+ return S_OK;
+ }
+
+ /* IMediaFilter */
+
+ STDMETHOD(Stop)(void)
+ {
+ ATLTRACE("QFilter::Stop()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ HRESULT hRslt = StopStreaming();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ m_state = State_Stopped;
+
+ return S_OK;
+ }
+
+ STDMETHOD(Pause)(void)
+ {
+ ATLTRACE("QFilter::Pause()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ HRESULT hRslt = StartStreaming();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ m_state = State_Paused;
+
+ return S_OK;
+ }
+
+ STDMETHOD(Run)(REFERENCE_TIME tStart)
+ {
+ ATLTRACE("QFilter::Run()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ HRESULT hRslt = StartStreaming();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ m_state = State_Running;
+
+ return S_OK;
+ }
+
+ STDMETHOD(GetState)(
+ DWORD /* dwMilliSecsTimeout */,
+ FILTER_STATE* State)
+ {
+ ATLTRACE("QFilter::GetState()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ if (State == 0) {
+ return E_INVALIDARG;
+ }
+
+ *State = m_state;
+
+ return S_OK;
+ }
+
+ STDMETHOD(SetSyncSource)(IReferenceClock* pClock)
+ {
+ ATLTRACE("QFilter::SetSyncSource()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ m_Clock = pClock;
+
+ return S_OK;
+ }
+
+ STDMETHOD(GetSyncSource)(IReferenceClock** pClock)
+ {
+ ATLTRACE("QFilter::GetSyncSource()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ if (pClock == 0) {
+ return E_INVALIDARG;
+ }
+
+ HRESULT hRslt = m_Clock.CopyTo(pClock);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ /* IBaseFilter */
+
+ STDMETHOD(EnumPins)(IEnumPins** ppEnum)
+ {
+ ATLTRACE("QFilter::EnumPins()\n");
+
+ if (ppEnum == 0) {
+ return E_INVALIDARG;
+ }
+
+ HRESULT hRslt = QEnumPins::Create(m_Pins, m_Pins + PINS, static_cast<IBaseFilter*>(this), ppEnum);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(FindPin)(
+ LPCWSTR Id,
+ IPin** ppPin)
+ {
+ ATLTRACE("QFilter::FindPin()\n");
+
+ if (Id == 0 || ppPin == 0) {
+ return E_INVALIDARG;
+ }
+
+ IPin* pin = 0;
+
+ if (wcscmp(Id, L"Audio") == 0) {
+ pin = m_Pins[PID_Audio];
+ }
+
+ *ppPin = pin;
+
+ if (pin == 0) {
+ return VFW_E_NOT_FOUND;
+ }
+
+ pin->AddRef();
+
+ return S_OK;
+ }
+
+ STDMETHOD(QueryFilterInfo)(
+ FILTER_INFO* pInfo)
+ {
+ ATLTRACE("QFilter::QueryFilterInfo()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ if (pInfo == 0) {
+ return E_INVALIDARG;
+ }
+
+ SIZE_T len = m_Name.GetLength();
+ if (len > MAX_FILTER_NAME - 1) {
+ len = MAX_FILTER_NAME - 1;
+ }
+ wcsncpy_s(pInfo->achName, MAX_FILTER_NAME, m_Name, len);
+
+ pInfo->pGraph = m_pFGraph;
+ if (m_pFGraph != 0) {
+ m_pFGraph->AddRef();
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(JoinFilterGraph)(
+ IFilterGraph* pGraph,
+ LPCWSTR pName)
+ {
+ ATLTRACE("QFilter::JoinFilterGraph()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ m_pFGraph = pGraph; /* weak */
+
+ if (pGraph != 0) {
+ if (pName != 0) {
+ m_Name = pName;
+ } else {
+ m_Name = L"QDSAudio";
+ }
+
+ } else {
+ m_Name.Empty();
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(QueryVendorInfo)(
+ LPWSTR* pVendorInfo)
+ {
+ ATLTRACE("QFilter::QueryVendorInfo()\n");
+
+ if (pVendorInfo == 0) {
+ return E_INVALIDARG;
+ }
+
+ LPCWSTR NAME = L"Project Quilla";
+
+ *pVendorInfo = static_cast<LPWSTR>(CoTaskMemAlloc((wcslen(NAME) + 1) * sizeof(WCHAR)));
+ if (*pVendorInfo == 0) {
+ return E_OUTOFMEMORY;
+ }
+
+ memcpy(*pVendorInfo, NAME, (wcslen(NAME) + 1) * sizeof(WCHAR));
+
+ return S_OK;
+ }
+
+ /* IMediaSeeking */
+
+ STDMETHOD(GetCapabilities)(
+ DWORD* pCapabilities)
+ {
+ if (pCapabilities == 0) {
+ return E_INVALIDARG;
+ }
+
+ *pCapabilities =
+ AM_SEEKING_CanSeekAbsolute |
+ AM_SEEKING_CanSeekForwards |
+ AM_SEEKING_CanSeekBackwards |
+ AM_SEEKING_CanGetDuration;
+
+ return S_OK;
+ }
+
+ STDMETHOD(CheckCapabilities)(
+ DWORD* pCapabilities)
+ {
+ if (pCapabilities == 0) {
+ return E_INVALIDARG;
+ }
+
+ DWORD c0 = *pCapabilities;
+
+ DWORD cap = 0;
+ GetCapabilities(&cap);
+
+ *pCapabilities &= cap;
+
+ if ((cap & c0) != cap) {
+ return S_FALSE;
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(IsFormatSupported)(
+ const GUID* pFormat)
+ {
+ if (pFormat == 0) {
+ return E_INVALIDARG;
+ }
+
+ if (*pFormat != TIME_FORMAT_MEDIA_TIME) {
+ return S_FALSE;
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(QueryPreferredFormat)(
+ GUID* pFormat)
+ {
+ if (pFormat == 0) {
+ return E_INVALIDARG;
+ }
+
+ *pFormat = TIME_FORMAT_MEDIA_TIME;
+
+ return S_OK;
+ }
+
+ STDMETHOD(GetTimeFormat)(
+ GUID* pFormat)
+ {
+ if (pFormat == 0) {
+ return E_INVALIDARG;
+ }
+
+ *pFormat = TIME_FORMAT_MEDIA_TIME;
+
+ return S_OK;
+ }
+
+ STDMETHOD(IsUsingTimeFormat)(
+ const GUID* pFormat)
+ {
+ if (pFormat == 0) {
+ return E_INVALIDARG;
+ }
+
+ if (*pFormat != TIME_FORMAT_MEDIA_TIME) {
+ return S_FALSE;
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(SetTimeFormat)(
+ const GUID* pFormat)
+ {
+ if (pFormat == 0) {
+ return E_INVALIDARG;
+ }
+
+ if (*pFormat != TIME_FORMAT_MEDIA_TIME) {
+ return E_INVALIDARG;
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(GetDuration)(
+ LONGLONG* pDuration)
+ {
+ if (pDuration == 0) {
+ return E_INVALIDARG;
+ }
+
+ if (m_pReader != 0) {
+ *pDuration = m_pReader->GetDuration();
+ } else {
+ *pDuration = 0;
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(GetStopPosition)(
+ LONGLONG* /* pStop */)
+ {
+ return E_NOTIMPL;
+ }
+
+ STDMETHOD(GetCurrentPosition)(
+ LONGLONG* /* pCurrent */)
+ {
+ return E_NOTIMPL;
+ }
+
+ STDMETHOD(ConvertTimeFormat)(
+ LONGLONG* /* pTarget*/,
+ const GUID* /* pTargetFormat */,
+ LONGLONG /* Source */,
+ const GUID* /* pSourceFormat */)
+ {
+ return E_NOTIMPL;
+ }
+
+ STDMETHOD(SetPositions)(
+ LONGLONG* pCurrent,
+ DWORD dwCurrentFlags,
+ LONGLONG* pStop,
+ DWORD dwStopFlags)
+ {
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ switch (dwCurrentFlags & AM_SEEKING_PositioningBitsMask) {
+ case AM_SEEKING_NoPositioning:
+ break;
+
+ case AM_SEEKING_AbsolutePositioning:
+ {
+ if (pCurrent == 0) {
+ return E_INVALIDARG;
+ }
+
+ INT64 pos = *pCurrent;
+
+ if (m_pStreamer != 0) {
+ m_pStreamer->BeginFlush();
+ m_pStreamer->RequestSeek(pos);
+ m_pStreamer->RequestStart();
+
+ } else {
+ m_StartPos = pos;
+ }
+
+ break;
+ }
+
+ default:
+ return E_INVALIDARG;
+ }
+
+ switch (dwStopFlags & AM_SEEKING_PositioningBitsMask) {
+ case AM_SEEKING_NoPositioning:
+ break;
+
+ default:
+ return E_INVALIDARG;
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(GetPositions)(
+ LONGLONG* /* pCurrent */,
+ LONGLONG* /* pStop */)
+ {
+ return E_NOTIMPL;
+ }
+
+ STDMETHOD(GetAvailable)(
+ LONGLONG* /* pEarliest */,
+ LONGLONG* /* pLatest */)
+ {
+ return E_NOTIMPL;
+ }
+
+ STDMETHOD(SetRate)(
+ double /* dRate */)
+ {
+ return E_NOTIMPL;
+ }
+
+ STDMETHOD(GetRate)(
+ double* /* pdRate */)
+ {
+ return E_NOTIMPL;
+ }
+
+ STDMETHOD(GetPreroll)(
+ LONGLONG* /* pllPreroll */)
+ {
+ return E_NOTIMPL;
+ }
+
+ /* IAMFilterMiscFlags */
+
+ STDMETHOD_(ULONG, GetMiscFlags)()
+ {
+ ATLTRACE("QFilter::GetMiscFlags()\n");
+
+ return AM_FILTER_MISC_FLAGS_IS_SOURCE;
+ }
+
+ /* */
+
+private:
+
+ /* */
+
+ HRESULT StartStreaming()
+ {
+ if (m_pStreamer == 0) {
+ m_pStreamer = new QStreamer(m_pReader);
+
+ HRESULT hRslt = m_pStreamer->Initialize();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ hRslt = m_pStreamer->SetupAudio(
+ m_pPinAudio->GetMemInputPin(),
+ m_pPinAudio->GetMemAllocator(),
+ m_pPinAudio->GetWaveHeader());
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ hRslt = m_pStreamer->Commit();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ hRslt = m_pStreamer->Create();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ if (m_StartPos != -1) {
+ m_pStreamer->RequestSeek(m_StartPos);
+ m_StartPos = -1;
+ }
+ }
+
+ m_pStreamer->RequestStart();
+
+ return S_OK;
+ }
+
+ HRESULT StopStreaming()
+ {
+ if (m_pStreamer != 0) {
+ HRESULT hRslt = m_pStreamer->Decommit();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ m_pStreamer->RequestQuit();
+
+ m_pStreamer->Uninitialize();
+
+ delete m_pStreamer;
+ m_pStreamer = 0;
+ }
+
+ return S_OK;
+ }
+
+ /* */
+
+}; // QFilter
+
+/* */
+
--- /dev/null
+// QMediaType.h
+// 2009/08/21
+
+#pragma once
+
+/* */
+
+// QMediaType
+struct QMediaType : public AM_MEDIA_TYPE {
+
+ QMediaType()
+ {
+ memset(this, 0, sizeof(QMediaType));
+ }
+
+ ~QMediaType()
+ {
+ SafeRelease();
+ }
+
+ void SafeRelease()
+ {
+ if (pUnk != 0) {
+ pUnk->Release();
+ pUnk = 0;
+ }
+
+ if (pbFormat != 0) {
+ CoTaskMemFree(pbFormat);
+ pbFormat = 0;
+ }
+
+ memset(this, 0, sizeof(QMediaType));
+ }
+
+ void Assign(const AM_MEDIA_TYPE* p)
+ {
+ SafeRelease();
+
+ if (p != 0) {
+ Copy(this, p);
+ }
+ }
+
+ static bool Copy(AM_MEDIA_TYPE* d, const AM_MEDIA_TYPE* p)
+ {
+ memcpy(d, p, sizeof(AM_MEDIA_TYPE));
+
+ if (p->pbFormat != 0) {
+ BYTE* pb = static_cast<BYTE*>(CoTaskMemAlloc(p->cbFormat));
+ if (pb == 0) {
+ return false;
+ }
+
+ memcpy(pb, p->pbFormat, p->cbFormat);
+
+ d->pbFormat = pb;
+ }
+
+ if (p->pUnk != 0) {
+ p->pUnk->Release();
+ }
+
+ return true;
+ }
+
+ static AM_MEDIA_TYPE* CopyFrom(const AM_MEDIA_TYPE* p)
+ {
+ if (p == 0) {
+ return 0;
+ }
+
+ AM_MEDIA_TYPE* d = static_cast<AM_MEDIA_TYPE*>(CoTaskMemAlloc(
+ sizeof(AM_MEDIA_TYPE)));
+ if (d == 0) {
+ return 0;
+ }
+
+ if (!Copy(d, p)) {
+ CoTaskMemFree(d);
+ return 0;
+ }
+
+ return d;
+ }
+
+ static void Free(AM_MEDIA_TYPE* p)
+ {
+ if (p == 0) {
+ return;
+ }
+
+ if (p->pUnk != 0) {
+ p->pUnk->Release();
+ }
+
+ if (p->pbFormat != 0) {
+ CoTaskMemFree(p->pbFormat);
+ }
+
+ CoTaskMemFree(p);
+ }
+
+ /* */
+
+ void SetFormat(const void* pv, SIZE_T cb)
+ {
+ if (pbFormat != 0) {
+ CoTaskMemFree(pbFormat);
+
+ pbFormat = 0;
+ cbFormat = 0;
+ }
+
+ BYTE* pb = static_cast<BYTE*>(CoTaskMemAlloc(cb));
+ if (pb == 0) {
+ return;
+ }
+
+ memcpy(pb, pv, cb);
+
+ cbFormat = cb;
+ pbFormat = pb;
+ }
+
+ void SetAudio(
+ INT32 channels,
+ INT32 samplingRate)
+ {
+ majortype = MEDIATYPE_Audio;
+ subtype = MEDIASUBTYPE_PCM;
+
+ bFixedSizeSamples = TRUE;
+ bTemporalCompression = FALSE;
+
+ formattype = FORMAT_WaveFormatEx;
+
+ lSampleSize = channels * 2 * samplingRate;
+
+ WAVEFORMATEX wfx = { 0 };
+
+ wfx.wFormatTag = WAVE_FORMAT_PCM;
+ wfx.nChannels = channels;
+ wfx.nSamplesPerSec = samplingRate;
+ wfx.nAvgBytesPerSec = channels * 2 * samplingRate;
+ wfx.nBlockAlign = channels * 2;
+ wfx.wBitsPerSample = 16;
+ wfx.cbSize = 0;
+
+ SetFormat(&wfx, sizeof(wfx));
+ }
+
+ /* */
+
+}; // QMediaType
+
+/* */
+
+// QEnumMediaTypes
+class ATL_NO_VTABLE QEnumMediaTypes :
+ public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>,
+
+ public IEnumMediaTypes {
+
+ ATL::CComCriticalSection m_cs;
+
+ AM_MEDIA_TYPE* m_pStart;
+ AM_MEDIA_TYPE* m_pEnd;
+
+ AM_MEDIA_TYPE* m_p;
+
+ ATL::CComPtr<IUnknown> m_Pin;
+
+public:
+
+ DECLARE_NOT_AGGREGATABLE(QEnumMediaTypes)
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(QEnumMediaTypes)
+ COM_INTERFACE_ENTRY(IEnumMediaTypes)
+ END_COM_MAP()
+
+public:
+
+ QEnumMediaTypes() : m_pStart(0), m_pEnd(0), m_p(0)
+ {
+ }
+
+ ~QEnumMediaTypes()
+ {
+ }
+
+ HRESULT FinalConstruct()
+ {
+ ATLTRACE("QEnumMediaTypes::FinalConstruct()\n");
+
+ HRESULT hRslt = m_cs.Init();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ void FinalRelease()
+ {
+ ATLTRACE("QEnumMediaTypes::FinalRelease()\n");
+
+ m_Pin.Release();
+ }
+
+ void Init(AM_MEDIA_TYPE* s, AM_MEDIA_TYPE* e, IUnknown* p)
+ {
+ m_pStart = s;
+ m_pEnd = e;
+
+ m_p = m_pStart;
+
+ m_Pin = p;
+ }
+
+ /* */
+
+ static HRESULT Create(AM_MEDIA_TYPE* s, AM_MEDIA_TYPE* e, IUnknown* p, IEnumMediaTypes** ppEnum)
+ {
+ if (ppEnum == 0) {
+ return E_INVALIDARG;
+ }
+
+ ATL::CComObject<QEnumMediaTypes>* obj = 0;
+
+ HRESULT hRslt = ATL::CComObject<QEnumMediaTypes>::CreateInstance(&obj);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ obj->Init(s, e, p);
+
+ hRslt = obj->QueryInterface(ppEnum);
+ if (FAILED(hRslt)) {
+ delete obj;
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ /* */
+
+ STDMETHOD(Next)(
+ ULONG cMediaTypes,
+ AM_MEDIA_TYPE** ppMediaTypes,
+ ULONG* pcFetched)
+ {
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ if (ppMediaTypes == 0) {
+ return E_INVALIDARG;
+ }
+
+ if (pcFetched == 0 && cMediaTypes != 1) {
+ return E_INVALIDARG;
+ }
+
+ if (pcFetched != 0) {
+ *pcFetched = 0;
+ }
+
+ ULONG i;
+ AM_MEDIA_TYPE** pp = ppMediaTypes;
+ for (i = 0; i < cMediaTypes && m_p < m_pEnd; i++, pp++, m_p++) {
+ AM_MEDIA_TYPE* mt = QMediaType::CopyFrom(m_p);
+ if (mt == 0) {
+ return E_OUTOFMEMORY;
+ }
+ *pp = mt;
+ }
+
+ if (pcFetched != 0) {
+ *pcFetched = i;
+ }
+
+ if (i == 0) {
+ return S_FALSE;
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(Skip)(
+ ULONG cMediaTypes)
+ {
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ m_p += cMediaTypes;
+
+ if (m_p > m_pEnd) {
+ m_p = m_pEnd;
+ }
+
+ return S_OK;
+ }
+
+
+ STDMETHOD(Reset)(void)
+ {
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ m_p = m_pStart;
+
+ return S_OK;
+ }
+
+ STDMETHOD(Clone)(
+ IEnumMediaTypes** ppEnum)
+ {
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ HRESULT hRslt = Create(m_pStart, m_pEnd, m_Pin, ppEnum);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ /* */
+
+}; // QEnumMediaTypes
+
+/* */
+
--- /dev/null
+// QPin.h
+// 2009/08/21
+
+#pragma once
+
+// QPinHost
+class QPinHost {
+
+public:
+
+ virtual ATL::CComCriticalSection& FilterCSec() = 0;
+
+ virtual bool IsRunning() = 0;
+
+}; /* QPinHost */
+
+// QPinAudio
+class ATL_NO_VTABLE QPinAudio :
+ public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>,
+ public IPin {
+
+ QPinHost* m_pHost;
+
+ IBaseFilter* m_pFilter; /* weak */
+
+ ATL::CStringW m_Id;
+
+ INT32 m_cMediaTypes;
+ QMediaType* m_MediaTypes;
+
+ ATL::CComPtr<IPin> m_ConnectedTo;
+
+ ATL::CComPtr<IMemInputPin> m_MemInputPin;
+ ATL::CComPtr<IMemAllocator> m_MemAllocator;
+
+ QMediaType m_ConnectionMediaType;
+
+ WAVEFORMATEX m_WaveHeader;
+
+public:
+
+ DECLARE_NOT_AGGREGATABLE(QPinAudio)
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(QPinAudio)
+ COM_INTERFACE_ENTRY(IPin)
+ END_COM_MAP()
+
+public:
+
+ QPinAudio() : m_pHost(0), m_pFilter(0), m_cMediaTypes(0), m_MediaTypes(0)
+ {
+ memset(&m_WaveHeader, 0, sizeof(m_WaveHeader));
+ }
+
+ ~QPinAudio()
+ {
+ delete[] m_MediaTypes;
+ }
+
+ void Init(
+ QPinHost* host,
+ IBaseFilter* p,
+ LPCWSTR id)
+ {
+ m_pHost = host;
+ m_pFilter = p;
+ m_Id = id;
+ }
+
+ /* */
+
+ HRESULT FinalConstruct()
+ {
+ ATLTRACE("QPinAudio::FinalConstruct()\n");
+
+ return S_OK;
+ }
+
+ void FinalRelease()
+ {
+ ATLTRACE("QPinAudio::FinalRelease()\n");
+ }
+
+ /* */
+
+ QMediaType* MediaTypes()
+ {
+ return m_MediaTypes;
+ }
+
+ void SetupMediaTypes(INT32 c)
+ {
+ m_cMediaTypes = c;
+ m_MediaTypes = new QMediaType[c];
+ }
+
+ /* */
+
+ IMemInputPin* GetMemInputPin()
+ {
+ return m_MemInputPin;
+ }
+
+ IMemAllocator* GetMemAllocator()
+ {
+ return m_MemAllocator;
+ }
+
+ /* */
+
+ void SetupAudioFormat(
+ INT32 channels,
+ INT32 samplingRate)
+ {
+ SetupMediaTypes(1);
+
+ QMediaType* mt = MediaTypes();
+
+ mt[0].SetAudio(channels, samplingRate);
+ }
+
+ const WAVEFORMATEX* GetWaveHeader()
+ {
+ return &m_WaveHeader;
+ }
+
+ /* */
+
+ HRESULT SetupAllocator(
+ IMemAllocator* alloc,
+ const AM_MEDIA_TYPE* target)
+ {
+ HRESULT hRslt = CheckAccept(target);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ ALLOCATOR_PROPERTIES rprop = { 0 };
+ ALLOCATOR_PROPERTIES aprop = { 0 };
+
+ rprop.cBuffers = 20;
+ rprop.cbBuffer = 2 * m_WaveHeader.nChannels * m_WaveHeader.nSamplesPerSec / 10;
+ rprop.cbAlign = 1;
+ rprop.cbPrefix = 0;
+
+ hRslt = alloc->SetProperties(
+ &rprop,
+ &aprop);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ HRESULT CheckAccept(
+ const AM_MEDIA_TYPE* pmt)
+ {
+ if (pmt->majortype != MEDIATYPE_Audio) {
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+
+ if (pmt->formattype == FORMAT_WaveFormatEx &&
+ pmt->cbFormat >= sizeof(WAVEFORMATEX) &&
+ pmt->pbFormat != 0) {
+
+ const WAVEFORMATEX* w = (const WAVEFORMATEX*)(pmt->pbFormat);
+
+ ATLTRACE("Wave: %d ch %d Hz\n", w->nChannels, w->nSamplesPerSec);
+
+ memcpy(&m_WaveHeader, w, sizeof(m_WaveHeader));
+
+ } else {
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+
+ return S_OK;
+ }
+
+ /* IPin */
+
+ STDMETHOD(Connect)(
+ IPin* pReceivePin,
+ const AM_MEDIA_TYPE* pmt)
+ {
+ ATLTRACE("QPinAudio::Connect()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_pHost->FilterCSec());
+
+ if (pReceivePin == 0) {
+ return E_INVALIDARG;
+ }
+
+ if (m_ConnectedTo != 0) {
+ return VFW_E_ALREADY_CONNECTED;
+ }
+
+ if (m_pHost->IsRunning()) {
+ return VFW_E_NOT_STOPPED;
+ }
+
+ const AM_MEDIA_TYPE* target = 0;
+
+ for (INT32 i = 0; i < m_cMediaTypes; i++) {
+ const AM_MEDIA_TYPE* mt = m_MediaTypes + i;
+
+ if (pmt != 0) {
+ if (mt->majortype != pmt->majortype ||
+ mt->subtype != pmt->subtype) {
+ continue;
+ }
+
+ if (pmt->formattype != GUID_NULL) {
+ if (mt->formattype != pmt->formattype) {
+ continue;
+ }
+
+ if (mt->cbFormat != pmt->cbFormat) {
+ continue;
+ }
+
+ if (memcmp(mt->pbFormat, pmt->pbFormat, mt->cbFormat) != 0) {
+ continue;
+ }
+ }
+ }
+
+ HRESULT hRslt = pReceivePin->QueryAccept(mt);
+ if (hRslt == S_OK) {
+ target = mt;
+ break;
+ }
+ }
+
+ if (target == 0) {
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+
+ HRESULT hRslt = pReceivePin->ReceiveConnection(
+ this,
+ target);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ m_ConnectionMediaType.SafeRelease();
+ hRslt = pReceivePin->ConnectionMediaType(&m_ConnectionMediaType);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ ATL::CComQIPtr<IMemInputPin> mem = pReceivePin;
+ if (mem == 0) {
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+
+ ATL::CComPtr<IMemAllocator> alloc;
+ hRslt = mem->GetAllocator(&alloc);
+ if (FAILED(hRslt)) {
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+
+ hRslt = SetupAllocator(
+ alloc,
+ target);
+ if (FAILED(hRslt)) {
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+
+ hRslt = mem->NotifyAllocator(alloc, FALSE);
+ if (FAILED(hRslt)) {
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+
+ m_MemInputPin = mem;
+ m_MemAllocator = alloc;
+
+ m_ConnectedTo = pReceivePin;
+
+ return S_OK;
+ }
+
+ STDMETHOD(ReceiveConnection)(
+ IPin* /* pConnector */,
+ const AM_MEDIA_TYPE* /* pmt */)
+ {
+ ATLTRACE("QPinAudio::ReceiveConnection()\n");
+
+ return E_NOTIMPL;
+ }
+
+ STDMETHOD(Disconnect)(void)
+ {
+ ATLTRACE("QPinAudio::Disconnect()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_pHost->FilterCSec());
+
+ if (m_pHost->IsRunning()) {
+ return VFW_E_NOT_STOPPED;
+ }
+
+ if (m_ConnectedTo == 0) {
+ return S_FALSE;
+ }
+
+ m_MemAllocator.Release();
+ m_MemInputPin. Release();
+
+ m_ConnectedTo.Release();
+
+ return S_OK;
+ }
+
+ STDMETHOD(ConnectedTo)(
+ IPin** pPin)
+ {
+ ATLTRACE("QPinAudio::ConnectedTo()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_pHost->FilterCSec());
+
+ if (m_ConnectedTo == 0) {
+ if (pPin != 0) {
+ *pPin = 0;
+ }
+
+ return VFW_E_NOT_CONNECTED;
+ }
+
+ if (pPin == 0) {
+ return E_INVALIDARG;
+ }
+
+ *pPin = m_ConnectedTo;
+
+ if (*pPin != 0) {
+ (*pPin)->AddRef();
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(ConnectionMediaType)(
+ AM_MEDIA_TYPE* pmt)
+ {
+ ATLTRACE("QPinAudio::ConnectionMediaType()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_pHost->FilterCSec());
+
+ if (pmt == 0) {
+ return E_INVALIDARG;
+ }
+
+ if (!QMediaType::Copy(pmt, &m_ConnectionMediaType)) {
+ return E_OUTOFMEMORY;
+ }
+
+ return S_OK;
+ }
+
+ /* */
+
+ STDMETHOD(QueryPinInfo)(
+ PIN_INFO* pInfo)
+ {
+ ATLTRACE("QPinAudio::QueryPinInfo()\n");
+
+ if (pInfo == 0) {
+ return E_INVALIDARG;
+ }
+
+ pInfo->pFilter = m_pFilter;
+ pInfo->dir = PINDIR_OUTPUT;
+
+ SIZE_T len = m_Id.GetLength();
+ if (len > 127) {
+ len = 127;
+ }
+ wcsncpy_s(pInfo->achName, 128, m_Id, len);
+
+ if (m_pFilter != 0) {
+ m_pFilter->AddRef();
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(QueryDirection)(
+ PIN_DIRECTION* pPinDir)
+ {
+ ATLTRACE("QPinAudio::QueryDirection()\n");
+
+ if (pPinDir == 0) {
+ return E_INVALIDARG;
+ }
+
+ *pPinDir = PINDIR_OUTPUT;
+
+ return S_OK;
+ }
+
+ STDMETHOD(QueryId)(
+ LPWSTR* Id)
+ {
+ ATLTRACE("QPinAudio::QueryId()\n");
+
+ if (Id == 0) {
+ return E_INVALIDARG;
+ }
+
+ LPCWSTR id = m_Id;
+ SIZE_T cb = (m_Id.GetLength() + 1) * sizeof(WCHAR);
+
+ *Id = static_cast<LPWSTR>(CoTaskMemAlloc(cb));
+ if (*Id == 0) {
+ return E_OUTOFMEMORY;
+ }
+
+ memcpy(*Id, id, cb);
+
+ return S_OK;
+ }
+
+ /* */
+
+ STDMETHOD(QueryAccept)(
+ const AM_MEDIA_TYPE* pmt)
+ {
+ ATLTRACE("QPinAudio::QueryAccept()\n");
+
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_pHost->FilterCSec());
+
+ if (pmt == 0) {
+ return E_INVALIDARG;
+ }
+
+ HRESULT hRslt = CheckAccept(pmt);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ m_ConnectionMediaType.Assign(pmt);
+
+ return S_OK;
+ }
+
+ STDMETHOD(EnumMediaTypes)(
+ IEnumMediaTypes** ppEnum)
+ {
+ ATLTRACE("QPinAudio::EnumMediaTypes()\n");
+
+ if (ppEnum == 0) {
+ return E_INVALIDARG;
+ }
+
+ HRESULT hRslt = QEnumMediaTypes::Create(m_MediaTypes, m_MediaTypes + m_cMediaTypes, this, ppEnum);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ /* */
+
+ STDMETHOD(QueryInternalConnections)(
+ IPin** apPin,
+ ULONG* nPin)
+ {
+ ATLTRACE("QPinAudio::QueryInternalConnections()\n");
+
+ if (apPin != 0 && nPin != 0) {
+ if (*nPin > 0) {
+ memset(apPin, 0, *nPin * sizeof(IPin*));
+ }
+ *nPin = 0;
+ }
+
+ return E_NOTIMPL;
+ }
+
+ /* */
+
+ STDMETHOD(EndOfStream)(void)
+ {
+ ATLTRACE("QPinAudio::EndOfStream()\n");
+
+ return E_NOTIMPL;
+ }
+
+ STDMETHOD(BeginFlush)(void)
+ {
+ ATLTRACE("QPinAudio::BeginFlush()\n");
+
+ return E_NOTIMPL;
+ }
+
+ STDMETHOD(EndFlush)(void)
+ {
+ ATLTRACE("QPinAudio::EndFlush()\n");
+
+ return E_NOTIMPL;
+ }
+
+ STDMETHOD(NewSegment)(
+ REFERENCE_TIME /* tStart */,
+ REFERENCE_TIME /* tStop */,
+ double /* dRate */)
+ {
+ ATLTRACE("QPinAudio::NewSegment()\n");
+
+ return E_NOTIMPL;
+ }
+
+ /* */
+
+}; // QPinAudio
+
--- /dev/null
+// QPinEnum.h
+// 2009/08/21
+
+#pragma once
+
+// QEnumPins
+class ATL_NO_VTABLE QEnumPins :
+ public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>,
+
+ public IEnumPins {
+
+ ATL::CComCriticalSection m_cs;
+
+ IPin** m_pStart;
+ IPin** m_pEnd;
+
+ IPin** m_p;
+
+ ATL::CComPtr<IUnknown> m_Filter;
+
+public:
+
+ DECLARE_NOT_AGGREGATABLE(QEnumPins)
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(QEnumPins)
+ COM_INTERFACE_ENTRY(IEnumPins)
+ END_COM_MAP()
+
+public:
+
+ QEnumPins() : m_pStart(0), m_pEnd(0), m_p(0)
+ {
+ }
+
+ ~QEnumPins()
+ {
+ }
+
+ HRESULT FinalConstruct()
+ {
+ ATLTRACE("QEnumPins::FinalConstruct()\n");
+
+ HRESULT hRslt = m_cs.Init();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ void FinalRelease()
+ {
+ ATLTRACE("QEnumPins::FinalRelease()\n");
+
+ m_Filter.Release();
+ }
+
+ void Init(IPin** s, IPin** e, IUnknown* p)
+ {
+ m_pStart = s;
+ m_pEnd = e;
+
+ m_p = m_pStart;
+
+ m_Filter = p;
+ }
+
+ /* */
+
+ static HRESULT Create(IPin** s, IPin** e, IUnknown* p, IEnumPins** ppEnum)
+ {
+ if (ppEnum == 0) {
+ return E_INVALIDARG;
+ }
+
+ ATL::CComObject<QEnumPins>* obj = 0;
+
+ HRESULT hRslt = ATL::CComObject<QEnumPins>::CreateInstance(&obj);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ obj->Init(s, e, p);
+
+ hRslt = obj->QueryInterface(ppEnum);
+ if (FAILED(hRslt)) {
+ delete obj;
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ /* */
+
+ STDMETHOD(Next)(
+ ULONG cPins,
+ IPin** ppPins,
+ ULONG* pcFetched)
+ {
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ if (ppPins == 0) {
+ return E_INVALIDARG;
+ }
+
+ if (pcFetched == 0 && cPins != 1) {
+ return E_INVALIDARG;
+ }
+
+ ULONG i;
+ IPin** pp = ppPins;
+ for (i = 0; i < cPins && m_p < m_pEnd; i++, pp++, m_p++) {
+ *pp = *m_p;
+ if (*pp != 0) {
+ (*pp)->AddRef();
+ }
+ }
+
+ if (pcFetched != 0) {
+ *pcFetched = i;
+ }
+
+ if (i == 0) {
+ return S_FALSE;
+ }
+
+ return S_OK;
+ }
+
+ STDMETHOD(Skip)(
+ ULONG cPins)
+ {
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ m_p += cPins;
+
+ if (m_p > m_pEnd) {
+ m_p = m_pEnd;
+ }
+
+ return S_OK;
+ }
+
+
+ STDMETHOD(Reset)(void)
+ {
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ m_p = m_pStart;
+
+ return S_OK;
+ }
+
+ STDMETHOD(Clone)(
+ IEnumPins** ppEnum)
+ {
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ HRESULT hRslt = Create(m_pStart, m_pEnd, m_Filter, ppEnum);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ /* */
+
+}; // QEnumPins
+
--- /dev/null
+// QReader.h
+// 2009/08/21
+
+#pragma once
+
+/* */
+
+// QReader
+class QReader {
+
+public:
+
+ struct Format {
+ INT32 SamplingRate;
+ INT32 Channels;
+ };
+
+ virtual ~QReader()
+ {
+ }
+
+ virtual Format GetFormat() = 0;
+
+ virtual INT64 GetDuration() = 0;
+
+ virtual bool Seek(INT64 pos) = 0;
+
+ virtual INT32 Read(
+ IMemAllocator* aalloc,
+ IMemInputPin* apin,
+ QWaveOutputer* aout) = 0;
+
+}; // QReader
+
+const INT64 RT_UNIT = 10*1000*1000;
+
+/* */
+
+// QVorbisReader
+class QVorbisReader : public QReader {
+
+ QOV_Reader_t* m_reader;
+
+ INT64 m_Position;
+
+ enum {
+ BUFFER_SIZE = 2048
+ };
+
+public:
+
+ QVorbisReader() : m_reader(0), m_Position(0)
+ {
+ }
+
+ virtual ~QVorbisReader()
+ {
+ QOV_ReleaseReader(m_reader);
+ }
+
+ bool Open(const WCHAR* path)
+ {
+ m_reader = QOV_CreateReader();
+ if (m_reader == 0) {
+ return false;
+ }
+
+ if (!QOV_OpenReader(m_reader, path)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ bool Open(IStream* p)
+ {
+ m_reader = QOV_CreateReader();
+ if (m_reader == 0) {
+ return false;
+ }
+
+ if (!QOV_OpenReader_IStream(m_reader, p)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /* */
+
+ virtual Format GetFormat()
+ {
+ const QOV_Format_t* fmt = QOV_GetFormat(m_reader);
+ Format f = { fmt->SamplingRate, fmt->Channels };
+ return f;
+ }
+
+ virtual INT64 GetDuration()
+ {
+ const QOV_Format_t* fmt = QOV_GetFormat(m_reader);
+ return (fmt->Duration * RT_UNIT) / fmt->SamplingRate;
+ }
+
+ /* */
+
+ virtual bool Seek(INT64 pos)
+ {
+ const QOV_Format_t* fmt = QOV_GetFormat(m_reader);
+ INT64 sample = (pos * fmt->SamplingRate) / RT_UNIT;
+
+ if (!QOV_Seek(m_reader, sample)) {
+ return false;
+ }
+
+ m_Position = 0;
+
+ return true;
+ }
+
+ virtual INT32 Read(
+ IMemAllocator* aalloc,
+ IMemInputPin* apin,
+ QWaveOutputer* aout)
+ {
+ INT16 buffer[BUFFER_SIZE * 2];
+
+ INT32 output = 0;
+ if (!QOV_Decode(m_reader, buffer, BUFFER_SIZE, &output)) {
+ return -1;
+ }
+ if (output == 0) {
+ return 0;
+ }
+
+ const QOV_Format_t* fmt = QOV_GetFormat(m_reader);
+
+ REFERENCE_TIME rts = (m_Position * RT_UNIT) / fmt->SamplingRate;
+
+ if (!aout->Output(
+ aalloc,
+ apin,
+ rts,
+ buffer,
+ output * fmt->Channels)) {
+ return -1;
+ }
+
+ m_Position += output;
+
+ return 1;
+ }
+
+}; // QVorbisReader
+
+/* */
+
+// QTTAReader
+class QTTAReader : public QReader {
+
+ QTTA_Reader_t* m_reader;
+
+ INT64 m_Position;
+
+ enum {
+ BUFFER_SIZE = 2048
+ };
+
+public:
+
+ QTTAReader() : m_reader(0), m_Position(0)
+ {
+ }
+
+ virtual ~QTTAReader()
+ {
+ QTTA_ReleaseReader(m_reader);
+ }
+
+ bool Open(const WCHAR* path)
+ {
+ m_reader = QTTA_CreateReader();
+ if (m_reader == 0) {
+ return false;
+ }
+
+ if (!QTTA_OpenReader(m_reader, path)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ bool Open(IStream* p)
+ {
+ m_reader = QTTA_CreateReader();
+ if (m_reader == 0) {
+ return false;
+ }
+
+ if (!QTTA_OpenReader_IStream(m_reader, p)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /* */
+
+ virtual Format GetFormat()
+ {
+ const QTTA_Format_t* fmt = QTTA_GetFormat(m_reader);
+ Format f = { fmt->SamplingRate, fmt->Channels };
+ return f;
+ }
+
+ virtual INT64 GetDuration()
+ {
+ const QTTA_Format_t* fmt = QTTA_GetFormat(m_reader);
+ return (fmt->Duration * RT_UNIT) / fmt->SamplingRate;
+ }
+
+ /* */
+
+ virtual bool Seek(INT64 pos)
+ {
+ const QTTA_Format_t* fmt = QTTA_GetFormat(m_reader);
+ INT64 sample = (pos * fmt->SamplingRate) / RT_UNIT;
+
+ if (!QTTA_Seek(m_reader, sample)) {
+ return false;
+ }
+
+ m_Position = 0;
+
+ return true;
+ }
+
+ virtual INT32 Read(
+ IMemAllocator* aalloc,
+ IMemInputPin* apin,
+ QWaveOutputer* aout)
+ {
+ INT16 buffer[BUFFER_SIZE * 2];
+
+ INT32 output = 0;
+ if (!QTTA_Decode(m_reader, buffer, BUFFER_SIZE, &output)) {
+ return -1;
+ }
+ if (output == 0) {
+ return 0;
+ }
+
+ const QTTA_Format_t* fmt = QTTA_GetFormat(m_reader);
+
+ REFERENCE_TIME rts = (m_Position * RT_UNIT) / fmt->SamplingRate;
+
+ if (!aout->Output(
+ aalloc,
+ apin,
+ rts,
+ buffer,
+ output * fmt->Channels)) {
+ return -1;
+ }
+
+ m_Position += output;
+
+ return 1;
+ }
+
+}; // QTTAReader
+
+/* */
+
--- /dev/null
+// QStreamer.h
+// 2009/08/21
+
+#pragma once
+
+/* */
+
+#ifndef STDCALL
+#define STDCALL __stdcall
+#endif
+
+/* */
+
+// QEvent
+class QEvent {
+
+ HANDLE m_hEvent;
+
+public:
+
+ QEvent() : m_hEvent(0)
+ {
+ }
+
+ ~QEvent()
+ {
+ Close();
+ }
+
+ operator HANDLE()
+ {
+ return m_hEvent;
+ }
+
+ HRESULT Create(bool init)
+ {
+ HANDLE h = CreateEventW(
+ 0,
+ TRUE,
+ init,
+ 0);
+ if (h == 0) {
+ DWORD error = GetLastError();
+ return HRESULT_FROM_WIN32(error);
+ }
+
+ m_hEvent = h;
+
+ return S_OK;
+ }
+
+ void Close()
+ {
+ if (m_hEvent != 0) {
+ CloseHandle(m_hEvent);
+ m_hEvent = 0;
+ }
+ }
+
+ void SetEvent()
+ {
+ ::SetEvent(m_hEvent);
+ }
+
+ void ResetEvent()
+ {
+ ::ResetEvent(m_hEvent);
+ }
+
+}; // QEvent
+
+/* */
+
+#define WM_STREAM_START (WM_USER + 100)
+
+// QStreamer
+class QStreamer {
+
+ QReader* m_pReader;
+
+ DWORD m_idThread;
+ HANDLE m_hThread;
+
+ QEvent m_Ready;
+
+ ATL::CComCriticalSection m_cs;
+
+ bool m_bSeek;
+ INT64 m_SeekPos;
+
+ ATL::CComPtr<IPin> m_AudioPin;
+ ATL::CComPtr<IMemInputPin> m_AudioInputPin;
+ ATL::CComPtr<IMemAllocator> m_AudioAllocator;
+
+ QWaveOutputer m_Outputer;
+
+public:
+
+ QStreamer(QReader* p) : m_pReader(p), m_idThread(0), m_hThread(0), m_bSeek(false), m_SeekPos(0)
+ {
+ }
+
+ ~QStreamer()
+ {
+ Uninitialize();
+ }
+
+ HRESULT Initialize()
+ {
+ HRESULT hRslt = m_Ready.Create(false);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ hRslt = m_cs.Init();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ void Uninitialize()
+ {
+ if (m_hThread != 0) {
+ Join();
+
+ CloseHandle(m_hThread);
+
+ m_idThread = 0;
+ m_hThread = 0;
+ }
+
+ m_Ready.Close();
+
+ m_cs.Term();
+ }
+
+ HRESULT Create()
+ {
+ unsigned tid = 0;
+ uintptr_t th = _beginthreadex(
+ 0,
+ 0,
+ ThreadProc,
+ this,
+ 0,
+ &tid);
+ if (th == 0) {
+ return E_OUTOFMEMORY;
+ }
+
+ HANDLE aEvents[2] = {
+ (HANDLE)th,
+ m_Ready
+ };
+
+ DWORD result = WaitForMultipleObjects(
+ sizeof(aEvents) / sizeof(aEvents[0]),
+ aEvents,
+ FALSE,
+ 60 * 1000);
+ if (result != WAIT_OBJECT_0 + 1) {
+ CloseHandle((HANDLE)th);
+ return E_FAIL;
+ }
+
+ m_idThread = (DWORD) tid;
+ m_hThread = (HANDLE)th;
+
+ return S_OK;
+ }
+
+ INT32 Join()
+ {
+ DWORD code = DWORD(-1);
+
+ if (m_hThread != 0) {
+ WaitForSingleObject(m_hThread, INFINITE);
+
+ GetExitCodeThread(m_hThread, &code);
+ }
+
+ return (INT32)code;
+ }
+
+ /* */
+
+ void RequestStart()
+ {
+ PostThreadMessageW(
+ m_idThread,
+ WM_STREAM_START,
+ 0,
+ 0);
+ }
+
+ void RequestQuit()
+ {
+ PostThreadMessageW(
+ m_idThread,
+ WM_QUIT,
+ 0,
+ 0);
+ }
+
+ /* */
+
+ HRESULT SetupAudio(
+ IMemInputPin* pin,
+ IMemAllocator* alloc,
+ const WAVEFORMATEX* w)
+ {
+ if (pin == 0) {
+ return S_OK;
+ }
+
+ ATL::CComQIPtr<IPin> vp(pin);
+ if (vp == 0) {
+ return E_NOINTERFACE;
+ }
+
+ m_AudioPin = vp;
+ m_AudioInputPin = pin;
+ m_AudioAllocator = alloc;
+
+ m_Outputer.Setup(
+ w->nChannels,
+ w->nSamplesPerSec);
+
+ return S_OK;
+ }
+
+ /* */
+
+ HRESULT Commit()
+ {
+ if (m_AudioAllocator != 0) {
+ HRESULT hRslt = m_AudioAllocator->Commit();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+ }
+
+ return S_OK;
+ }
+
+ HRESULT Decommit()
+ {
+ if (m_AudioAllocator != 0) {
+ HRESULT hRslt = m_AudioAllocator->Decommit();
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+ }
+
+ return S_OK;
+ }
+
+ /* */
+
+ HRESULT BeginFlush()
+ {
+ if (m_AudioPin != 0) {
+ m_AudioPin->BeginFlush();
+ }
+
+ return S_OK;
+ }
+
+ /* */
+
+ void RequestSeek(INT64 pos)
+ {
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ m_bSeek = true;
+ m_SeekPos = pos;
+ }
+
+ /* */
+
+private:
+
+ /* */
+
+ static void SetupThreadName(const char* p)
+ {
+ INT_PTR para[4];
+
+ para[0] = 0x1000;
+ para[1] = (INT_PTR)p;
+ para[2] = -1;
+ para[3] = 0;
+
+ __try {
+ RaiseException(
+ 0x406D1388,
+ 0,
+ sizeof(para) / sizeof(ULONG_PTR),
+ (const ULONG_PTR*)para);
+
+ } __except(EXCEPTION_CONTINUE_EXECUTION) {
+
+ }
+ }
+
+ static unsigned STDCALL ThreadProc(void* p)
+ {
+ QStreamer* pThis = static_cast<QStreamer*>(p);
+
+ unsigned code = pThis->OnThread();
+
+ return code;
+ }
+
+ unsigned OnThread()
+ {
+ SetupThreadName("QStreamer");
+
+ HRESULT hRslt = CoInitializeEx(0, COINIT_MULTITHREADED);
+ if (FAILED(hRslt)) {
+ return -1;
+ }
+
+ unsigned code = -1;
+
+ if (Init()) {
+ DoProcess();
+ code = 0;
+ }
+
+ Uninit();
+
+ CoUninitialize();
+
+ return code;
+ }
+
+ bool Init()
+ {
+ ATLTRACE("QStreamer::Init()\n");
+
+ // Prepare Windows Message Queue
+ {
+ MSG msg = { 0 };
+ BOOL fPeek = PeekMessageW(
+ &msg,
+ 0,
+ 0,
+ 0,
+ PM_NOREMOVE);
+ }
+
+ m_Ready.SetEvent();
+
+ return true;
+ }
+
+ void Uninit()
+ {
+ ATLTRACE("QStreamer::Uninit()\n");
+ }
+
+ void DoProcess()
+ {
+ for (; ; ) {
+ MSG msg = { 0 };
+
+ BOOL fPeek = PeekMessageW(
+ &msg,
+ 0,
+ 0,
+ 0,
+ PM_REMOVE);
+ if (fPeek) {
+ switch (msg.message) {
+ case WM_STREAM_START:
+ if (DoStreaming()) {
+ return;
+ }
+ break;
+
+ case WM_QUIT:
+ return;
+ }
+
+ } else {
+ WaitMessage();
+ }
+ }
+ }
+
+ bool DoStreaming()
+ {
+ ATLTRACE("QStreamer::DoStreaming() Start...\n");
+
+ for (; ; ) {
+ MSG msg = { 0 };
+
+ BOOL fPeek = PeekMessageW(
+ &msg,
+ 0,
+ 0,
+ 0,
+ PM_REMOVE);
+ if (fPeek) {
+ if (msg.message == WM_QUIT) {
+ m_Outputer.Flush();
+ return true;
+ }
+
+ } else {
+ {
+ ATL::CComCritSecLock<ATL::CComCriticalSection> lock(m_cs);
+
+ if (m_bSeek) {
+ m_bSeek = false;
+
+ m_Outputer.Flush();
+
+ if (!m_pReader->Seek(m_SeekPos)) {
+ ATLTRACE("QStreamer::DoStreaming() Seek ERROR!\n");
+ break;
+ }
+
+ if (m_AudioPin != 0) {
+ m_AudioPin->EndFlush();
+ }
+ }
+ }
+
+ INT32 code = m_pReader->Read(
+ m_AudioAllocator,
+ m_AudioInputPin,
+ &m_Outputer);
+ if (code < 0) {
+ ATLTRACE("QStreamer::DoStreaming() Read ERROR!\n");
+ break;
+ }
+ if (code == 0) {
+ break;
+ }
+ }
+ }
+
+ m_Outputer.EndOfStream(m_AudioInputPin);
+
+ if (m_AudioPin != 0) {
+ m_AudioPin->EndOfStream();
+ }
+
+ ATLTRACE("QStreamer::DoStreaming() Finished.\n");
+
+ return false;
+ }
+
+}; // QStreamer
+
--- /dev/null
+// QWaveOutputer.h
+// 2009/08/21
+
+#pragma once
+
+// QWaveOutputer
+class QWaveOutputer {
+
+ INT32 m_Channels;
+ INT32 m_SamplingRate;
+
+ ATL::CComPtr<IMediaSample> m_sample;
+
+ BYTE* m_pbSample;
+ DWORD m_cbSample;
+
+ DWORD m_cbFilled;
+
+ bool m_bDiscontinue;
+
+public:
+
+ QWaveOutputer() :
+ m_Channels(2), m_SamplingRate(44100),
+ m_pbSample(0), m_cbSample(0), m_cbFilled(0),
+ m_bDiscontinue(true)
+ {
+ }
+
+ ~QWaveOutputer()
+ {
+ }
+
+ void Setup(INT32 c, INT32 s)
+ {
+ m_Channels = c;
+ m_SamplingRate = s;
+ }
+
+ INT32 GetTime(INT32 s)
+ {
+ return s / m_SamplingRate;
+ }
+
+ INT32 GetSamples(INT32 c)
+ {
+ return c / m_Channels;
+ }
+
+ bool Output(
+ IMemAllocator* alloc,
+ IMemInputPin* pin,
+ REFERENCE_TIME rt,
+ const void* pv,
+ INT32 count)
+ {
+ if (alloc == 0 || pin == 0) {
+ return true;
+ }
+
+ REFERENCE_TIME ts = rt;
+
+ const BYTE* pb = static_cast<const BYTE*>(pv);
+
+ INT32 s = 0;
+
+ INT32 samples = count / m_Channels;
+
+ for (; ; ) {
+ if (m_sample != 0) {
+ INT32 cb = m_cbSample - m_cbFilled;
+ INT32 ss = cb / (2 * m_Channels);
+
+ INT32 s0 = samples - s;
+ if (s0 > ss) {
+ s0 = ss;
+ }
+
+ INT32 b0 = s0 * (2 * m_Channels);
+
+ memcpy(
+ m_pbSample + m_cbFilled,
+ pb,
+ b0);
+
+ m_cbFilled += b0;
+
+ pb += b0;
+ s += s0;
+
+ INT64 t = INT64(s0) * 10*1000*1000;
+ ts += t / m_SamplingRate;
+ }
+
+ INT32 s0 = samples - s;
+ if (s0 > 0 || m_cbFilled >= m_cbSample) {
+ if (!Deliver(pin)) {
+ return false;
+ }
+ }
+
+ if (s0 == 0) {
+ break;
+ }
+
+ if (!Allocate(
+ alloc,
+ ts)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool EndOfStream(IMemInputPin* pin)
+ {
+ if (pin == 0) {
+ return true;
+ }
+
+ if (!Deliver(pin)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ bool Flush()
+ {
+ if (m_sample != 0) {
+ m_sample.Release();
+
+ m_pbSample = 0;
+ m_cbSample = 0;
+ m_cbFilled = 0;
+ }
+
+ m_bDiscontinue = true;
+
+ return true;
+ }
+
+private:
+
+ bool Deliver(IMemInputPin* pin)
+ {
+ if (m_sample != 0) {
+ m_sample->SetActualDataLength(m_cbFilled);
+
+ HRESULT hRslt = pin->Receive(m_sample);
+ if (FAILED(hRslt)) {
+ return false;
+ }
+
+ m_sample.Release();
+
+ m_pbSample = 0;
+ m_cbSample = 0;
+ m_cbFilled = 0;
+ }
+
+ return true;
+ }
+
+ bool Allocate(
+ IMemAllocator* alloc,
+ REFERENCE_TIME rt)
+ {
+ HRESULT hRslt = alloc->GetBuffer(
+ &m_sample,
+ 0,
+ 0,
+ 0);
+ if (FAILED(hRslt)) {
+ return false;
+ }
+
+ BYTE* pb = 0;
+ m_sample->GetPointer(&pb);
+
+ INT32 cb = m_sample->GetSize();
+
+ m_pbSample = pb;
+ m_cbSample = cb;
+ m_cbFilled = 0;
+
+ if (m_bDiscontinue) {
+ m_bDiscontinue = false;
+
+ m_sample->SetTime(&rt, 0);
+
+ m_sample->SetDiscontinuity(TRUE);
+ }
+
+ return true;
+ }
+
+}; // QWaveOutputer
+
--- /dev/null
+// StdAfx.cpp
+// 2009/08/21
+
+#include "StdAfx.h"
+
--- /dev/null
+// StdAfx.h
+// 2009/08/21
+
+#pragma once
+
+#ifndef STRICT
+#define STRICT
+#endif
+
+#define _ATL_APARTMENT_THREADED
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
+#define _ATL_ALL_WARNINGS
+
+#include <atlbase.h>
+#include <atlcom.h>
+#include <atlfile.h>
+#include <atlcoll.h>
+#include <atlstr.h>
+
+#include <atlwin.h>
+
+#include <shlwapi.h>
+
+#include <dshow.h>
+#include <uuids.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef QDSAUDIO_EXPORTS
+#define QDSAUDIO_BUILD_DLL
+#pragma comment(lib, "strmiids.lib")
+#endif
+
--- /dev/null
+// Main.cpp
+// 2009/08/24
+
+#include "StdAfx.h"
+
+#include <crtdbg.h>
+
+/* */
+
+#include "MainDialog.h"
+
+/* */
+
+WTL::CAppModule _Module;
+
+/* */
+
+int DoProcess();
+
+/* */
+
+int WINAPI wWinMain(
+ HINSTANCE hInstance,
+ HINSTANCE /*hPrevInstance*/,
+ LPWSTR /*lpCmdLine*/,
+ int /*nCmdShow*/)
+{
+ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+ // _CrtSetBreakAlloc(1);
+
+ HRESULT hRslt = OleInitialize(0);
+ if (FAILED(hRslt)) {
+ return -1;
+ }
+
+ _Module.Init(0, hInstance);
+
+ int result = DoProcess();
+
+ _Module.Term();
+
+ OleUninitialize();
+
+ return result;
+}
+
+/* */
+
+static bool DoInitialize();
+static void DoUninitialize();
+static int DoMain();
+
+int DoProcess()
+{
+ int result = -1;
+
+ if (DoInitialize()) {
+ result = DoMain();
+ }
+
+ DoUninitialize();
+
+ return result;
+}
+
+/* */
+
+static bool DoInitialize()
+{
+ return true;
+}
+
+static void DoUninitialize()
+{
+}
+
+/* */
+
+static int DoMain()
+{
+ int result = -1;
+
+ WTL::CMessageLoop theLoop;
+ _Module.AddMessageLoop(&theLoop);
+
+ {
+ MainDialog dlg;
+
+ theLoop.AddMessageFilter(&dlg);
+
+ HWND hwnd = dlg.Create(0);
+ if (hwnd != 0) {
+ dlg.ShowWindow(SW_NORMAL);
+ dlg.UpdateWindow();
+
+ result = theLoop.Run();
+ }
+
+ theLoop.RemoveMessageFilter(&dlg);
+ }
+
+ _Module.RemoveMessageLoop();
+
+ return result;
+}
+
+/* */
+
--- /dev/null
+// MainDialog.h
+// 2009/08/24
+
+#pragma once
+
+#include "resource.h"
+
+#include "QDSAudio.h"
+
+// MainDialog
+class MainDialog :
+ public ATL::CDialogImpl<MainDialog>,
+ public WTL::CMessageFilter {
+
+ enum {
+ TID_TICK = 1,
+ TICK_TIMEOUT = 20
+ };
+
+ enum {
+ WM_EVENT_NOTIFY = WM_APP + 1
+ };
+
+ ATL::CComPtr<IGraphBuilder> m_FilterGraph;
+
+ ATL::CComPtr<IBaseFilter> m_Decoder;
+
+ DWORD m_dwCookie;
+
+public:
+
+ /* */
+
+ enum { IDD = IDD_MAIN };
+
+ /* */
+
+ MainDialog() : m_dwCookie(0)
+ {
+ }
+
+ ~MainDialog()
+ {
+ }
+
+ /* */
+
+ BEGIN_MSG_MAP_EX(MainDialog)
+ MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
+ MESSAGE_HANDLER(WM_COMMAND, OnCommand )
+
+ MSG_WM_DESTROY(OnDestroy)
+
+ MSG_WM_TIMER(OnTimer)
+
+ MESSAGE_HANDLER(WM_DROPFILES, OnDropFiles )
+ MESSAGE_HANDLER(WM_EVENT_NOTIFY, OnEventNotify)
+ END_MSG_MAP()
+
+ /* */
+
+ LRESULT OnInitDialog(
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam,
+ BOOL& bHandled)
+ {
+ SetWindowPos(
+ 0,
+ 0, 0,
+ 0, 0,
+ SWP_NOZORDER | SWP_NOSIZE);
+
+ SetDlgItemTextW(IDC_PATH, L"");
+ SetDlgItemTextW(IDC_AUDIO, L"");
+ SetDlgItemTextW(IDC_DURATION, L"");
+ SetDlgItemTextW(IDC_CURRENT, L"");
+
+ SetTimer(TID_TICK, TICK_TIMEOUT);
+
+ DragAcceptFiles(TRUE);
+
+ return TRUE;
+ }
+
+ LRESULT OnCommand(
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam,
+ BOOL& bHandled)
+ {
+ int id = LOWORD(wParam);
+ int code = HIWORD(wParam);
+
+ switch (id) {
+ case IDC_OPEN:
+ Open();
+ break;
+
+ case IDC_RUN:
+ Run();
+ break;
+
+ case IDC_PAUSE:
+ Pause();
+ break;
+
+ case IDC_RELEASE:
+ ReleaseFilterGraph();
+ SetDlgItemTextW(IDC_PATH, L"");
+ SetDlgItemTextW(IDC_AUDIO, L"");
+ SetDlgItemTextW(IDC_DURATION, L"");
+ SetDlgItemTextW(IDC_CURRENT, L"");
+ break;
+
+ case IDOK:
+ case IDCANCEL:
+ case IDCLOSE:
+ ReleaseFilterGraph();
+ DestroyWindow();
+ break;
+ }
+
+ return 0;
+ }
+
+ /* */
+
+ void OnDestroy()
+ {
+ PostQuitMessage(0);
+ }
+
+ /* */
+
+ void OnTimer(UINT_PTR nIDEvent)
+ {
+ if (nIDEvent == TID_TICK) {
+ OnTick();
+ }
+ }
+
+ /* */
+
+ virtual BOOL PreTranslateMessage(MSG* pMsg)
+ {
+ HWND hwnd = *this;
+
+ if (hwnd != 0) {
+ if (pMsg->message == WM_KEYDOWN &&
+ ::GetParent(pMsg->hwnd) == hwnd) {
+ ATLTRACE("DOWN\n");
+ INT32 code = (INT32)pMsg->wParam;
+ if (code >= '0' && code <= '9') {
+ INT32 p = code - '0';
+ Seek(p);
+ return TRUE;
+ }
+ }
+
+ if (::IsDialogMessageW(hwnd, pMsg)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+ }
+
+ /* */
+
+ void OnTick()
+ {
+ if (m_FilterGraph != 0) {
+ ATL::CComQIPtr<IMediaSeeking> seek(m_FilterGraph);
+
+ INT64 pos = 0;
+ seek->GetCurrentPosition(&pos);
+
+ INT32 ds = (INT32)(pos / (1000*1000));
+ INT32 ss = ds / 10;
+
+ ATL::CStringW buf;
+ buf.Format(L"%d:%02d:%d", ss / 60, ss % 60, ds % 10);
+
+ SetDlgItemText(IDC_CURRENT, buf);
+ }
+ }
+
+ /* */
+
+private:
+
+ /* */
+
+ void ReleaseFilterGraph()
+ {
+ if (m_dwCookie != 0) {
+ RemoveFromRot(m_dwCookie);
+ m_dwCookie = 0;
+ }
+
+ if (m_FilterGraph != 0) {
+ ATL::CComQIPtr<IMediaControl> ctrl(m_FilterGraph);
+ ctrl->Stop();
+
+ ATL::CComQIPtr<IMediaEventEx> me(m_FilterGraph);
+ me->SetNotifyWindow(0, 0, 0);
+ }
+
+ m_Decoder.Release();
+
+ m_FilterGraph.Release();
+ }
+
+ /* */
+
+ void Open()
+ {
+ WTL::CFileDialog dlg(
+ TRUE,
+ L"ogg",
+ 0,
+ OFN_HIDEREADONLY,
+ L"Ogg Vorbis Files (*.ogg)\0*.ogg\0TTA Files (*.tta)\0*.tta\0All Files (*.*)\0*.*\0\0");
+
+ if (dlg.DoModal() == IDOK) {
+ ReleaseFilterGraph();
+ Prepare(dlg.m_szFileName);
+ }
+ }
+
+ /* */
+
+ void Prepare(LPCWSTR path)
+ {
+ if (m_FilterGraph != 0) {
+ return;
+ }
+
+ SetDlgItemTextW(IDC_PATH, path);
+ SetDlgItemTextW(IDC_AUDIO, L"");
+ SetDlgItemTextW(IDC_DURATION, L"");
+ SetDlgItemTextW(IDC_CURRENT, L"");
+
+ GetDlgItem(IDC_RUN) .EnableWindow(FALSE);
+ GetDlgItem(IDC_PAUSE).EnableWindow(FALSE);
+ GetDlgItem(IDC_RUN) .ShowWindow(SW_HIDE);
+ GetDlgItem(IDC_PAUSE).ShowWindow(SW_HIDE);
+
+ UpdateWindow();
+
+ WTL::CWaitCursor wait;
+
+ HRESULT hRslt = m_FilterGraph.CoCreateInstance(
+ CLSID_FilterGraph,
+ 0,
+ CLSCTX_INPROC_SERVER);
+ if (FAILED(hRslt)) {
+ return;
+ }
+
+ {
+ ATL::CComQIPtr<IMediaEventEx> me(m_FilterGraph);
+
+ HWND hwnd = *this;
+ hRslt = me->SetNotifyWindow(
+ (OAHWND)hwnd,
+ WM_EVENT_NOTIFY,
+ 0);
+ if (FAILED(hRslt)) {
+ return;
+ }
+ }
+
+ ATL::CComPtr<IBaseFilter> filter;
+
+ {
+ ATL::CComPtr<IStream> stm;
+ hRslt = SHCreateStreamOnFileW(
+ path,
+ STGM_READ,
+ &stm);
+ if (FAILED(hRslt)) {
+ return;
+ }
+
+ LPCWSTR ext = PathFindExtensionW(path);
+ if (ext != 0 && _wcsicmp(ext, L".ogg") == 0) {
+ hRslt = QDSA_CreateOggVorbisDecoder_IStream(
+ stm,
+ &filter);
+ if (FAILED(hRslt)) {
+ return;
+ }
+ } else if (ext != 0 && _wcsicmp(ext, L".tta") == 0) {
+ hRslt = QDSA_CreateTTADecoder_IStream(
+ stm,
+ &filter);
+ if (FAILED(hRslt)) {
+ return;
+ }
+ }
+ }
+
+ if (filter == 0) {
+ return;
+ }
+
+ hRslt = m_FilterGraph->AddFilter(
+ filter,
+ L"QDSAudio");
+ if (FAILED(hRslt)) {
+ return;
+ }
+
+ m_Decoder = filter;
+
+ /* Audio */
+
+ {
+ ATL::CComPtr<IPin> pin;
+ hRslt = filter->FindPin(L"Audio", &pin);
+ if (FAILED(hRslt)) {
+ return;
+ }
+
+ ATL::CComPtr<IEnumMediaTypes> em;
+ hRslt = pin->EnumMediaTypes(&em);
+ if (FAILED(hRslt)) {
+ return;
+ }
+
+ bool b = false;
+
+ while (!b) {
+ AM_MEDIA_TYPE* mt = 0;
+ ULONG c = 0;
+ hRslt = em->Next(1, &mt, &c);
+ if (FAILED(hRslt)) {
+ return;
+ }
+ if (mt == 0) {
+ break;
+ }
+
+ if (mt->formattype == FORMAT_WaveFormatEx &&
+ mt->pbFormat != 0 &&
+ mt->cbFormat >= sizeof(WAVEFORMATEX)) {
+
+ WAVEFORMATEX* w = (WAVEFORMATEX*)(mt->pbFormat);
+
+ ATL::CStringW buf;
+ buf.Format(L"A: %d ch %d Hz", w->nChannels, w->nSamplesPerSec);
+ SetDlgItemTextW(IDC_AUDIO, buf);
+
+ b = true;
+ }
+
+ QDSA_FreeMediaType(mt);
+ }
+
+ if (b) {
+ ATL::CComPtr<IBaseFilter> rend;
+ hRslt = rend.CoCreateInstance(
+ CLSID_DSoundRender,
+ 0,
+ CLSCTX_INPROC_SERVER);
+ if (FAILED(hRslt)) {
+ return;
+ }
+
+ hRslt = m_FilterGraph->AddFilter(
+ rend,
+ L"A-Renderer");
+ if (FAILED(hRslt)) {
+ return;
+ }
+
+ ATL::CComPtr<IEnumPins> e;
+ hRslt = rend->EnumPins(&e);
+ if (FAILED(hRslt)) {
+ return;
+ }
+
+ ATL::CComPtr<IPin> ip;
+ ULONG c = 0;
+ hRslt = e->Next(1, &ip, &c);
+ if (FAILED(hRslt)) {
+ return;
+ }
+
+ hRslt = m_FilterGraph->ConnectDirect(
+ pin,
+ ip,
+ 0);
+ if (FAILED(hRslt)) {
+ ATLTRACE("ERROR ConnectDirect (A).\n");
+ return;
+ }
+
+ } else {
+ SetDlgItemTextW(IDC_AUDIO, L"NO Audio");
+ }
+ }
+
+ /* */
+
+ {
+ ATL::CComQIPtr<IMediaSeeking> seek(m_FilterGraph);
+ if (seek != 0) {
+ INT64 duration = 0;
+ seek->GetDuration(&duration);
+
+ INT32 ds = (INT32)(duration / (1000*1000));
+ INT32 ss = ds / 10;
+
+ ATL::CStringW buf;
+ buf.Format(L"%d:%02d:%d", ss / 60, ss % 60, ds % 10);
+
+ SetDlgItemText(IDC_DURATION, buf);
+ }
+ }
+
+ /* */
+
+#ifdef _DEBUG
+ AddToRot(m_FilterGraph, &m_dwCookie);
+#endif
+
+ /* */
+
+ GetDlgItem(IDC_RUN) .ShowWindow(SW_NORMAL);
+ GetDlgItem(IDC_PAUSE).ShowWindow(SW_NORMAL);
+ GetDlgItem(IDC_RUN) .EnableWindow(TRUE);
+ GetDlgItem(IDC_PAUSE).EnableWindow(TRUE);
+ }
+
+ /* */
+
+ void Run()
+ {
+ if (m_FilterGraph == 0) {
+ return;
+ }
+
+ ATL::CComQIPtr<IMediaControl> ctrl(m_FilterGraph);
+ ctrl->Run();
+ }
+
+ void Pause()
+ {
+ if (m_FilterGraph == 0) {
+ return;
+ }
+
+ ATL::CComQIPtr<IMediaControl> ctrl(m_FilterGraph);
+ ctrl->Pause();
+ }
+
+ /* */
+
+ void Seek(INT32 p)
+ {
+ if (m_FilterGraph != 0) {
+ ATL::CComQIPtr<IMediaSeeking> seek(m_FilterGraph);
+ if (seek != 0) {
+ INT64 duration = 0;
+ seek->GetDuration(&duration);
+
+ INT64 pos = p * (duration / 10);
+ seek->SetPositions(
+ &pos,
+ AM_SEEKING_AbsolutePositioning,
+ 0,
+ AM_SEEKING_NoPositioning);
+ }
+ }
+ }
+
+ /* */
+
+ LRESULT OnDropFiles(
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam,
+ BOOL& bHandled)
+ {
+ HDROP hDrop = (HDROP)wParam;
+
+ UINT c = DragQueryFileW(hDrop, (UINT)-1, 0, 0);
+ if (c > 0) {
+ WCHAR path[MAX_PATH];
+ DragQueryFileW(hDrop, 0, path, MAX_PATH);
+
+ ReleaseFilterGraph();
+ Prepare(path);
+ }
+
+ DragFinish(hDrop);
+
+ return 0;
+ }
+
+ /* */
+
+ LRESULT OnEventNotify(
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam,
+ BOOL& bHandled)
+ {
+ if (m_FilterGraph == 0) {
+ return 0;
+ }
+
+ ATL::CComQIPtr<IMediaEvent> me(m_FilterGraph);
+ if (me != 0) {
+ LONG lEventCode = 0;
+
+ LONG_PTR lParam1 = 0;
+ LONG_PTR lParam2 = 0;
+
+ HRESULT hRslt = me->GetEvent(
+ &lEventCode,
+ &lParam1,
+ &lParam2,
+ 0);
+ if (SUCCEEDED(hRslt)) {
+ if (lEventCode == EC_COMPLETE) {
+ ATLTRACE("EC_COMPLETE\n");
+
+ ATL::CComQIPtr<IMediaControl> ctrl(m_FilterGraph);
+ ctrl->Stop();
+ }
+
+ me->FreeEventParams(
+ lEventCode,
+ lParam1,
+ lParam2);
+ }
+ }
+
+ return 0;
+ }
+
+ /* */
+
+ static HRESULT AddToRot(IUnknown* pUnkGraph, DWORD* pdwRegister)
+ {
+ ATL::CComPtr<IRunningObjectTable> rot;
+ HRESULT hRslt = GetRunningObjectTable(0, &rot);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ WCHAR name[256];
+ swprintf_s(name, 256, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
+
+ ATL::CComPtr<IMoniker> moniker;
+ hRslt = CreateItemMoniker(L"!", name, &moniker);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ hRslt = rot->Register(
+ ROTFLAGS_REGISTRATIONKEEPSALIVE,
+ pUnkGraph,
+ moniker,
+ pdwRegister);
+ if (FAILED(hRslt)) {
+ return hRslt;
+ }
+
+ return S_OK;
+ }
+
+ static void RemoveFromRot(DWORD dwRegister)
+ {
+ ATL::CComPtr<IRunningObjectTable> rot;
+ HRESULT hRslt = GetRunningObjectTable(0, &rot);
+ if (FAILED(hRslt)) {
+ return;
+ }
+
+ rot->Revoke(dwRegister);
+ }
+
+ /* */
+
+}; // MainDialog
+
+/* */
+
--- /dev/null
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// \93ú\96{\8cê resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
+#ifdef _WIN32
+LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
+#pragma code_page(932)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_MAIN DIALOGEX 0, 0, 240, 62
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "QDSPlayer"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "PATH",IDC_PATH,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | SS_PATHELLIPSIS | WS_GROUP,7,7,160,8
+ PUSHBUTTON "Open...",IDC_OPEN,183,7,50,14
+ LTEXT "AUDIO",IDC_AUDIO,7,25,120,8
+ LTEXT "CURRENT",IDC_CURRENT,150,25,32,8
+ LTEXT "DURATION",IDC_DURATION,197,25,36,8
+ PUSHBUTTON "Run",IDC_RUN,7,40,50,14
+ PUSHBUTTON "Pause",IDC_PAUSE,94,40,50,14
+ PUSHBUTTON "Release",IDC_RELEASE,183,40,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_MAIN, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 233
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 55
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // \93ú\96{\8cê resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
--- /dev/null
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="QDSPlayer"
+ ProjectGUID="{B4F85FC2-73B1-472B-9A92-FF004A3484F7}"
+ RootNamespace="QDSPlayer"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="../Bin/$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../WTL/include;../QDSAudio"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="../Bin/$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../../WTL/include;../QDSAudio"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="\83\\81[\83X \83t\83@\83C\83\8b"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\Main.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\StdAfx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="\83w\83b\83_\81[ \83t\83@\83C\83\8b"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\MainDialog.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\StdAfx.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="\83\8a\83\\81[\83X \83t\83@\83C\83\8b"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\QDSPlayer.rc"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+// StdAfx.cpp
+// 2009/08/24
+
+#include "StdAfx.h"
+
--- /dev/null
+// StdAfx.h
+// 2009/08/24
+
+#pragma once
+
+#ifndef STRICT
+#define STRICT
+#endif
+
+#ifndef WINVER
+#define WINVER 0x0501
+#endif
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
+
+#ifndef _WIN32_WINDOWS
+#define _WIN32_WINDOWS 0x0410
+#endif
+
+#ifndef _WIN32_IE
+#define _WIN32_IE 0x0600
+#endif
+
+#define _SECURE_ATL 1
+
+#define _ATL_APARTMENT_THREADED
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
+#define _ATL_ALL_WARNINGS
+
+#include <atlbase.h>
+#include <atlcom.h>
+#include <atlfile.h>
+#include <atlcoll.h>
+#include <atlstr.h>
+
+#include <atlwin.h>
+
+#define _WTL_NO_AUTOMATIC_NAMESPACE
+
+#include <atlapp.h>
+#include <atlctrls.h>
+#include <atlcrack.h>
+#include <atlmisc.h>
+#include <atlframe.h>
+#include <atlgdi.h>
+#include <atlddx.h>
+#include <atldlgs.h>
+#include <atlctrlx.h>
+
+/* */
+
+#include <mmsystem.h>
+#pragma comment(lib, "winmm.lib")
+
+#include <dshow.h>
+#pragma comment(lib, "strmiids.lib")
+
+#include <shlwapi.h>
+
+/* */
+
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
+
+/* */
+
--- /dev/null
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by QDSPlayer.rc
+//
+#define IDD_MAIN 101
+#define IDC_OPEN 1001
+#define IDC_RUN 1002
+#define IDC_PAUSE 1003
+#define IDC_RELEASE 1004
+#define IDC_PATH 1005
+#define IDC_AUDIO 1006
+#define IDC_AUDIO2 1007
+#define IDC_DURATION 1007
+#define IDC_CURRENT 1008
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1009
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
--- /dev/null
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="QOgg"
+ ProjectGUID="{C7FCC9CF-148D-4C37-B9C0-0EEAFB3B909E}"
+ RootNamespace="QOgg"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../Lib/QVorbis"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../../Lib/QVorbis"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="\83\\81[\83X \83t\83@\83C\83\8b"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\Lib\QOgg\OggReader.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QOgg\OggVorbis.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QOgg\OggVorbisReader.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QOgg\StdAfx.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QOgg\Utils.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="\83w\83b\83_\81[ \83t\83@\83C\83\8b"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\..\Lib\QOgg\MemoryAllocator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QOgg\OggReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QOgg\OggVorbis.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QOgg\OggVorbisReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QOgg\StdAfx.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QOgg\StreamReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QOgg\Utils.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="\83\8a\83\\81[\83X \83t\83@\83C\83\8b"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="QTTA"
+ ProjectGUID="{48ADAB28-37BE-46F9-81D7-E5F68252F0AE}"
+ RootNamespace="QTTA"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="\83\\81[\83X \83t\83@\83C\83\8b"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\Lib\QTTA\StdAfx.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QTTA\TTADecoder.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QTTA\TTAReader.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="\83w\83b\83_\81[ \83t\83@\83C\83\8b"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\..\Lib\QTTA\StdAfx.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QTTA\TTADecoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QTTA\TTAReader.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="\83\8a\83\\81[\83X \83t\83@\83C\83\8b"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="QVorbis"
+ ProjectGUID="{88A9E896-687C-47CE-ABE9-8C2366702A24}"
+ RootNamespace="QVorbis"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="\83\\81[\83X \83t\83@\83C\83\8b"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\BitDecoder.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\DecoderContext.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\DecoderSetup.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\Floor1Decoder.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\FrameDecoder.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\HuffmanDecoder.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\MemoryPool.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\ResidueDecoder.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\SamplesChecker.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\StdAfx.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\TransformDecoder.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\TransformIMDCT.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\TransformIMDCT_SSE2.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\VorbisDecoder.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="\83w\83b\83_\81[ \83t\83@\83C\83\8b"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\BitDecoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\DecoderContext.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\DecoderSetup.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\Floor1Decoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\FrameConverter.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\FrameDecoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\HuffmanDecoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\MemoryPool.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\ResidueDecoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\SamplesChecker.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\StdAfx.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\TransformDecoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\TransformIMDCT.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\VorbisDecoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\Lib\QVorbis\VorbisTest.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="\83\8a\83\\81[\83X \83t\83@\83C\83\8b"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>