diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/DSP/dsp_sps/dxi | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/DSP/dsp_sps/dxi')
30 files changed, 5132 insertions, 0 deletions
diff --git a/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.cpp b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.cpp new file mode 100644 index 00000000..f2ebc687 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.cpp @@ -0,0 +1,283 @@ +// AudioPlugIn.cpp: implementation of the CAudioPlugIn class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "AudioPlugIn.h" + +// Note: see AudioPlugIn.h to redefine PROCESS_IN_PLACE +#if PROCESS_IN_PLACE +#pragma message("***** Compiling an IN-PLACE audio plug-in *****") +#else +#pragma message("***** Compiling an NON-IN-PLACE audio plug-in *****") +#endif + +#include "resource.h" +#include <commctrl.h> + +char g_path[MAX_PATH]; + +#define SPS_CONFIGDLG_IMPL +#define SPS_CONFIGDLG_ON_WM_CLOSE { ShowWindow(hwndDlg,SW_HIDE); /*g_config.visible=0;*/ } +//#define SPS_CONFIGDLG_HIDEABLE_EDITOR 0 +#include "../sps_common.h" +#include "../sps_configdlg.h" + +////////////////////////////////////////////////////////////////////// +// Ctors + +CAudioPlugIn::CAudioPlugIn( HRESULT* phr ) +{ + // TODO: put all initialization code in Initialize(), below. +} + +CAudioPlugIn::~CAudioPlugIn() +{ + SPS_quitapp(); +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugIn::Initialize() +{ + SPS_initapp(); + strcpy(g_path,"c:\\progra~1\\winamp\\plugins\\dsp_sps"); //FUCKO + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugIn::IsValidInputFormat( const WAVEFORMATEX* pwfx ) const +{ + // The plug-in base class will have already validated pwfx to ensure that + // it is 16-bit PCM or 32-bit float, 1 or 2 channels. + + // TODO: Add any additional checks here, such as sample rate, etc. + + // By default, only 32-bit float buffers are supported. + if (WAVE_FORMAT_IEEE_FLOAT != pwfx->wFormatTag) + return VFW_E_TYPE_NOT_ACCEPTED; + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugIn::IsValidOutputFormat( const WAVEFORMATEX* pwfx ) const +{ + // The plug-in base class will have already validated pwfx to ensure that + // it is 16-bit PCM or 32-bit float, 1 or 2 channels. + + // TODO: Add any additional checks here, such as sample rate, etc. + + // By default, only 32-bit float buffers are supported. + if (WAVE_FORMAT_IEEE_FLOAT != pwfx->wFormatTag) + return VFW_E_TYPE_NOT_ACCEPTED; + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugIn::IsValidTransform( const WAVEFORMATEX* pwfxIn, const WAVEFORMATEX* pwfxOut ) const +{ + // The plug-in base class will have already validated pwfxIn/pwfxOut to ensure that + // it is 16-bit PCM or 32-bit float, 1 or 2 channels, and that both have the same + // sample rate. + + // TODO: Add any additional checks here, such as sample rate, etc. + + // By default, only 32-bit float buffers are supported. + if (WAVE_FORMAT_IEEE_FLOAT != pwfxIn->wFormatTag) + return VFW_E_TYPE_NOT_ACCEPTED; + if (WAVE_FORMAT_IEEE_FLOAT != pwfxOut->wFormatTag) + return VFW_E_TYPE_NOT_ACCEPTED; + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugIn::SuggestOutputFormat( WAVEFORMATEX* pwfx ) const +{ + // The plug-in base class will have already validated pwfx to ensure that + // it is 16-bit PCM or 32-bit float, 1 or 2 channels, and that both have the same + // sample rate. + // TODO: Add any additional checks here, such as sample rate, etc. + + // pwfx is initially set to the input format. If your plug-in doesn't need + // to change the output format, simply return S_OK. + // TODO: change pwfx if necessary. + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugIn::Process( LONGLONG llSampAudioTimestamp, + AudioBuffer* pbufIn, + AudioBuffer* pbufOut ) +{ + BOOL const bGenerateTail = (NULL == pbufIn); + BOOL const bIsInPlace = (pbufIn == pbufOut); + + // Note about deferred zero filling: + // + // AudioBuffer will automatically take advantage of IDeferZeroFill, + // if the host app supports it. To avoid unnecessary and wasteful buffer + // fills, always check the 'bZero' flag in AudioBuffer before calling + // the GetPointer() method. This is because calling GetPointer() will + // trigger a zero-fill if the underlying data buffer was marked as "defer + // zero fill." + // + // Similarly, to allow downstream filters to benefit from deferred + // zero filling, be sure to set the 'bZero' flag in an AudioBuffer, if + // your DSP code is producing a completely silent buffer. + + if (bGenerateTail) + { + // TODO: Add code to generate a tail if required by your plug-in. + // Return S_OK if more effect tail data remains. Return S_FALSE + // if no more tail data remains. + + // Default implementation generates no tail + return S_FALSE; + } + + // TODO: Put your DSP code here + float *in=pbufIn->GetPointer(); + float *out=pbufOut->GetPointer(); + int of=(int)pbufIn->lOffset; + int size=(int)pbufIn->pms->GetSize(); + int nbsamp=size/sizeof(float); + +/* // If we're bypassed, copy input to output without processing + float fEnabled = GetParamValue( PARAM_ENABLE ); + if (fEnabled < 0.5f) + { + memcpy (out, in, pbufIn->cSamp * m_wfxIn.nBlockAlign ); + return S_OK; + }*/ + + + const WAVEFORMATEX *inpformat=GetInputFormat(); + int nch=inpformat->nChannels; + int srate=inpformat->nSamplesPerSec; + + if(0) + { + char tmp[512]; + int size2=(int)pbufOut->pms->GetSize(); + wsprintf(tmp,"%d %d %d %d %d %d\n",of,size,size2,nbsamp,nch,srate); + OutputDebugString(tmp); + } + + memcpy(out,in,size); + extern SPSEffectContext *g_fucko_ctx; + SPS_process_samples(g_fucko_ctx, + (void *)out, nbsamp/nch, 1, 32, nch, srate, + nbsamp, nbsamp); + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugIn::AllocateResources() +{ + // TODO: add code to here to prepare the for the start of streaming + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugIn::FreeResources() +{ + // TODO: add code to here to clean up after streaming + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +int CAudioPlugIn::PersistGetSize() const +{ + int const cb + = sizeof(DWORD) // # of persisted parameters + + NUM_PARAMS * (sizeof(DWORD) + sizeof(float)); // (index,value), for each parameter + + return cb; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugIn::PersistLoad( IStream* pStream ) +{ + ULONG cb = 0; + HRESULT hr = S_OK; + + // Get the number of persisted parameters + DWORD cParams = 0; + hr = pStream->Read( &cParams, sizeof(cParams), &cb ); + if (FAILED( hr ) || cb != sizeof(cParams)) + return E_FAIL; + + // Restore each parameter + for (DWORD ix = 0; ix < cParams; ix++) + { + // Get the parameter index + DWORD dwParam = 0; + hr = pStream->Read( &dwParam, sizeof(dwParam), &cb ); + if (FAILED( hr ) || cb != sizeof(dwParam)) + return E_FAIL; + + // Get the parameter value + float fValue = 0; + hr = pStream->Read( &fValue, sizeof(fValue), &cb ); + if (FAILED( hr ) || cb != sizeof(fValue)) + return E_FAIL; + + // Set the parameter value + if (m_pMediaParams) + m_pMediaParams->SetParam( dwParam, fValue ); + } + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugIn::PersistSave( IStream* pStream ) +{ + ULONG cb = 0; + HRESULT hr = S_OK; + + // Put the number of persisted parameters + DWORD cParams = NUM_PARAMS; + hr = pStream->Write( &cParams, sizeof(cParams), &cb ); + if (FAILED( hr ) || cb != sizeof(cParams)) + return E_FAIL; + + // Save each parameter + for (DWORD dwParam = 0; dwParam < cParams; dwParam++) + { + float fValue = 0; + + // Get the parameter value + if (m_pMediaParams) + m_pMediaParams->GetParam( dwParam, &fValue ); + + // Write the parameter index + hr = pStream->Write( &dwParam, sizeof(dwParam), &cb ); + if (FAILED( hr ) || cb != sizeof(dwParam)) + return E_FAIL; + + // Write the parameter value + hr = pStream->Write( &fValue, sizeof(fValue), &cb ); + if (FAILED( hr ) || cb != sizeof(fValue)) + return E_FAIL; + } + + return S_OK; +} diff --git a/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.def b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.def new file mode 100644 index 00000000..aa233f15 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.def @@ -0,0 +1,7 @@ +LIBRARY AudioPlugIn.dll +DESCRIPTION 'AudioPlugIn DXi' +EXPORTS + DllGetClassObject PRIVATE + DllCanUnloadNow PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE diff --git a/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.dep b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.dep new file mode 100644 index 00000000..50ef98b0 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.dep @@ -0,0 +1,69 @@ +# Microsoft Developer Studio Generated Dependency File, included by AudioPlugIn.mak + +.\AudioPlugIn.cpp : \ + ".\AudioPlugIn.h"\ + ".\include\CakeMedParam.h"\ + ".\include\DeferZeroFill.h"\ + ".\include\DXi.h"\ + ".\MediaParams.h"\ + ".\ParamEnvelope.h"\ + ".\Parameters.h"\ + ".\StdAfx.h"\ + + +.\AudioPlugIn.rc : \ + ".\res\AudioPlugIn.rc2"\ + + +.\AudioPlugInPropPage.cpp : \ + ".\AudioPlugInPropPage.h"\ + ".\include\CakeMedParam.h"\ + ".\Parameters.h"\ + ".\StdAfx.h"\ + + +.\Filter.cpp : \ + ".\AudioPlugIn.h"\ + ".\AudioPlugInPropPage.h"\ + ".\Filter.h"\ + ".\include\CakeMedParam.h"\ + ".\include\DeferZeroFill.h"\ + ".\include\DXi.h"\ + ".\MediaParams.h"\ + ".\ParamEnvelope.h"\ + ".\Parameters.h"\ + ".\PlugInGUIDs.h"\ + ".\StdAfx.h"\ + + +.\MediaParams.cpp : \ + ".\AudioPlugIn.h"\ + ".\include\CakeMedParam.h"\ + ".\include\CakeMedParam_i.c"\ + ".\include\DeferZeroFill.h"\ + ".\include\DXi.h"\ + ".\MediaParams.h"\ + ".\ParamEnvelope.h"\ + ".\Parameters.h"\ + ".\StdAfx.h"\ + + +.\ParamEnvelope.cpp : \ + ".\AudioPlugIn.h"\ + ".\include\CakeMedParam.h"\ + ".\include\DeferZeroFill.h"\ + ".\include\DXi.h"\ + ".\MediaParams.h"\ + ".\ParamEnvelope.h"\ + ".\Parameters.h"\ + ".\StdAfx.h"\ + + +.\PlugInApp.cpp : \ + ".\PlugInApp.h"\ + ".\StdAfx.h"\ + + +.\StdAfx.cpp : \ + ".\StdAfx.h"\ + diff --git a/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.dsp b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.dsp new file mode 100644 index 00000000..e35a6a76 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.dsp @@ -0,0 +1,271 @@ +# Microsoft Developer Studio Project File - Name="AudioPlugIn" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=AudioPlugIn - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AudioPlugIn.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AudioPlugIn.mak" CFG="AudioPlugIn - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AudioPlugIn - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "AudioPlugIn - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "AudioPlugIn - Win32 Release" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I "include" /I "..\..\dshow\include" /I "..\..\dshow\dshow" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_MBCS" /D "_USRDLL" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib ole32.lib oleaut32.lib DMOGUIDS.LIB winmm.lib comdlg32.lib /nologo /entry:"DllEntryPoint@12" /subsystem:windows /dll /machine:I386 /nodefaultlib:"libcmt" /nodefaultlib:"libcmtd" /libpath:"../../dshow" /opt:nowin98 +# SUBTRACT LINK32 /pdb:none +# Begin Custom Build - Custom Build Steps +OutDir=.\Release +TargetName=AudioPlugIn +InputPath=.\Release\AudioPlugIn.dll +SOURCE="$(InputPath)" + +"custom.bld" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + regsvr32.exe /s $(OutDir)\$(TargetName).DLL + echo >custom.bld + +# End Custom Build + +!ELSEIF "$(CFG)" == "AudioPlugIn - Win32 Debug" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /I "include" /I "..\..\dshow\include" /I "..\..\dshow\dshow" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib ole32.lib oleaut32.lib DMOGUIDS.LIB winmm.lib comdlg32.lib /nologo /entry:"DllEntryPoint@12" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libcmt" /nodefaultlib:"libcmtd" /pdbtype:sept /libpath:"../../dshow" +# Begin Custom Build - Custom Build Steps +OutDir=.\Debug +TargetName=AudioPlugIn +InputPath=.\Debug\AudioPlugIn.dll +SOURCE="$(InputPath)" + +"custom.bld" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + regsvr32.exe /s $(OutDir)\$(TargetName).DLL + echo >custom.bld + +# End Custom Build + +!ENDIF + +# Begin Target + +# Name "AudioPlugIn - Win32 Release" +# Name "AudioPlugIn - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Group "dx shit" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\AudioPlugIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\AudioPlugIn.def +# End Source File +# Begin Source File + +SOURCE=.\AudioPlugIn.rc +# End Source File +# Begin Source File + +SOURCE=.\AudioPlugInPropPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\Filter.cpp +# End Source File +# Begin Source File + +SOURCE=.\MediaParams.cpp +# End Source File +# Begin Source File + +SOURCE=.\ParamEnvelope.cpp +# End Source File +# Begin Source File + +SOURCE=.\PlugInApp.cpp +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# End Group +# Begin Group "ns-eel" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="..\..\ns-eel\megabuf.c" +# End Source File +# Begin Source File + +SOURCE="..\..\ns-eel\ns-eel-addfuncs.h" +# End Source File +# Begin Source File + +SOURCE="..\..\ns-eel\ns-eel-int.h" +# End Source File +# Begin Source File + +SOURCE="..\..\ns-eel\ns-eel.h" +# End Source File +# Begin Source File + +SOURCE="..\..\ns-eel\nseel-caltab.c" +# End Source File +# Begin Source File + +SOURCE="..\..\ns-eel\nseel-cfunc.c" +# End Source File +# Begin Source File + +SOURCE="..\..\ns-eel\nseel-compiler.c" +# End Source File +# Begin Source File + +SOURCE="..\..\ns-eel\nseel-eval.c" +# End Source File +# Begin Source File + +SOURCE="..\..\ns-eel\nseel-lextab.c" +# End Source File +# Begin Source File + +SOURCE="..\..\ns-eel\nseel-yylex.c" +# End Source File +# End Group +# Begin Group "sps" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\sps_common.cpp +# End Source File +# End Group +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\AudioPlugIn.h +# End Source File +# Begin Source File + +SOURCE=.\AudioPlugInPropPage.h +# End Source File +# Begin Source File + +SOURCE=.\include\DXi.h +# End Source File +# Begin Source File + +SOURCE=.\Filter.h +# End Source File +# Begin Source File + +SOURCE=.\MediaParams.h +# End Source File +# Begin Source File + +SOURCE=.\ParamEnvelope.h +# End Source File +# Begin Source File + +SOURCE=.\Parameters.h +# End Source File +# Begin Source File + +SOURCE=.\PlugInApp.h +# End Source File +# Begin Source File + +SOURCE=.\PlugInGUIDs.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\res\AudioPlugIn.rc2 +# End Source File +# End Group +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# End Target +# End Project diff --git a/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.dsw b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.dsw new file mode 100644 index 00000000..c697ed2e --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AudioPlugIn"=.\AudioPlugIn.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.h b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.h new file mode 100644 index 00000000..14446d14 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.h @@ -0,0 +1,47 @@ +// AudioPlugIn.h: interface for the CAudioPlugIn class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_AUDIOPLUGIN_H__D9177ACC_DFF4_4C13_8FB9_F949C35BFEF0__INCLUDED_) +#define AFX_AUDIOPLUGIN_H__D9177ACC_DFF4_4C13_8FB9_F949C35BFEF0__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +struct DXiEvent; +struct MfxEvent; + +#include "DXi.h" + +// TODO: #define PROCESS_IN_PLACE to FALSE if necessary, i.e., for plug-ins +// which convert mono to stereo. +#define PROCESS_IN_PLACE (TRUE) + +class CAudioPlugIn : + public CDXi +{ +public: + CAudioPlugIn( HRESULT* phr ); + virtual ~CAudioPlugIn(); + + HRESULT Initialize(); + + HRESULT IsValidInputFormat( const WAVEFORMATEX* pwfx ) const; + HRESULT IsValidOutputFormat( const WAVEFORMATEX* pwfx ) const; + HRESULT IsValidTransform( const WAVEFORMATEX* pwfxIn, const WAVEFORMATEX* pwfxOut ) const; + HRESULT SuggestOutputFormat( WAVEFORMATEX* pwfx ) const; + + HRESULT Process( LONGLONG llSampAudioTimestamp, + AudioBuffer* pbufIn, + AudioBuffer* pbufOut ); + + HRESULT AllocateResources(); + HRESULT FreeResources(); + + int PersistGetSize() const; + HRESULT PersistLoad( IStream* pStream ); + HRESULT PersistSave( IStream* pStream ); +}; + +#endif // !defined(AFX_AUDIOPLUGIN_H__D9177ACC_DFF4_4C13_8FB9_F949C35BFEF0__INCLUDED_) diff --git a/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.mak b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.mak new file mode 100644 index 00000000..09d2403e --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.mak @@ -0,0 +1,312 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on AudioPlugIn.dsp +!IF "$(CFG)" == "" +CFG=AudioPlugIn - Win32 Debug +!MESSAGE No configuration specified. Defaulting to AudioPlugIn - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "AudioPlugIn - Win32 Release" && "$(CFG)" != "AudioPlugIn - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AudioPlugIn.mak" CFG="AudioPlugIn - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AudioPlugIn - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "AudioPlugIn - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "AudioPlugIn - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +ALL : "$(OUTDIR)\AudioPlugIn.dll" ".\custom.bld" + + +CLEAN : + -@erase "$(INTDIR)\AudioPlugIn.obj" + -@erase "$(INTDIR)\AudioPlugIn.pch" + -@erase "$(INTDIR)\AudioPlugIn.res" + -@erase "$(INTDIR)\AudioPlugInPropPage.obj" + -@erase "$(INTDIR)\Filter.obj" + -@erase "$(INTDIR)\MediaParams.obj" + -@erase "$(INTDIR)\ParamEnvelope.obj" + -@erase "$(INTDIR)\PlugInApp.obj" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(OUTDIR)\AudioPlugIn.dll" + -@erase "$(OUTDIR)\AudioPlugIn.exp" + -@erase "$(OUTDIR)\AudioPlugIn.lib" + -@erase "custom.bld" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "." /I "include" /I "$(MSSDK)\include" /I "$(MSSDK)\Samples\Multimedia\DirectShow\BaseClasses" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_MBCS" /D "_USRDLL" /Fp"$(INTDIR)\AudioPlugIn.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\AudioPlugIn.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\AudioPlugIn.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib advapi32.lib ole32.lib oleaut32.lib \build\sdks\dxmedia\lib\DMOGUIDS.LIB winmm.lib /nologo /entry:"DllEntryPoint@12" /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\AudioPlugIn.pdb" /machine:I386 /nodefaultlib:"libcmt" /nodefaultlib:"libcmtd" /def:".\AudioPlugIn.def" /out:"$(OUTDIR)\AudioPlugIn.dll" /implib:"$(OUTDIR)\AudioPlugIn.lib" +DEF_FILE= \ + ".\AudioPlugIn.def" +LINK32_OBJS= \ + "$(INTDIR)\AudioPlugIn.obj" \ + "$(INTDIR)\AudioPlugInPropPage.obj" \ + "$(INTDIR)\Filter.obj" \ + "$(INTDIR)\MediaParams.obj" \ + "$(INTDIR)\ParamEnvelope.obj" \ + "$(INTDIR)\PlugInApp.obj" \ + "$(INTDIR)\StdAfx.obj" \ + "$(INTDIR)\AudioPlugIn.res" + +"$(OUTDIR)\AudioPlugIn.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +OutDir=.\Release +TargetName=AudioPlugIn +InputPath=.\Release\AudioPlugIn.dll +SOURCE="$(InputPath)" + +".\custom.bld" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + <<tempfile.bat + @echo off + regsvr32.exe /s $(OutDir)\$(TargetName).DLL + echo >custom.bld +<< + + +!ELSEIF "$(CFG)" == "AudioPlugIn - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +ALL : "$(OUTDIR)\AudioPlugIn.dll" ".\custom.bld" + + +CLEAN : + -@erase "$(INTDIR)\AudioPlugIn.obj" + -@erase "$(INTDIR)\AudioPlugIn.pch" + -@erase "$(INTDIR)\AudioPlugIn.res" + -@erase "$(INTDIR)\AudioPlugInPropPage.obj" + -@erase "$(INTDIR)\Filter.obj" + -@erase "$(INTDIR)\MediaParams.obj" + -@erase "$(INTDIR)\ParamEnvelope.obj" + -@erase "$(INTDIR)\PlugInApp.obj" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(OUTDIR)\AudioPlugIn.dll" + -@erase "$(OUTDIR)\AudioPlugIn.exp" + -@erase "$(OUTDIR)\AudioPlugIn.ilk" + -@erase "$(OUTDIR)\AudioPlugIn.lib" + -@erase "$(OUTDIR)\AudioPlugIn.pdb" + -@erase "custom.bld" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /I "include" /I "$(MSSDK)\include" /I "$(MSSDK)\Samples\Multimedia\DirectShow\BaseClasses" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_MBCS" /D "_USRDLL" /Fp"$(INTDIR)\AudioPlugIn.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\AudioPlugIn.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\AudioPlugIn.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib advapi32.lib ole32.lib oleaut32.lib \build\sdks\dxmedia\lib\DMOGUIDS.LIB winmm.lib /nologo /entry:"DllEntryPoint@12" /subsystem:windows /dll /incremental:yes /pdb:"$(OUTDIR)\AudioPlugIn.pdb" /debug /machine:I386 /nodefaultlib:"libcmt" /nodefaultlib:"libcmtd" /def:".\AudioPlugIn.def" /out:"$(OUTDIR)\AudioPlugIn.dll" /implib:"$(OUTDIR)\AudioPlugIn.lib" /pdbtype:sept +DEF_FILE= \ + ".\AudioPlugIn.def" +LINK32_OBJS= \ + "$(INTDIR)\AudioPlugIn.obj" \ + "$(INTDIR)\AudioPlugInPropPage.obj" \ + "$(INTDIR)\Filter.obj" \ + "$(INTDIR)\MediaParams.obj" \ + "$(INTDIR)\ParamEnvelope.obj" \ + "$(INTDIR)\PlugInApp.obj" \ + "$(INTDIR)\StdAfx.obj" \ + "$(INTDIR)\AudioPlugIn.res" + +"$(OUTDIR)\AudioPlugIn.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +OutDir=.\Debug +TargetName=AudioPlugIn +InputPath=.\Debug\AudioPlugIn.dll +SOURCE="$(InputPath)" + +".\custom.bld" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + <<tempfile.bat + @echo off + regsvr32.exe /s $(OutDir)\$(TargetName).DLL + echo >custom.bld +<< + + +!ENDIF + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("AudioPlugIn.dep") +!INCLUDE "AudioPlugIn.dep" +!ELSE +!MESSAGE Warning: cannot find "AudioPlugIn.dep" +!ENDIF +!ENDIF + + +!IF "$(CFG)" == "AudioPlugIn - Win32 Release" || "$(CFG)" == "AudioPlugIn - Win32 Debug" +SOURCE=.\AudioPlugIn.cpp + +"$(INTDIR)\AudioPlugIn.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\AudioPlugIn.pch" + + +SOURCE=.\AudioPlugIn.rc + +"$(INTDIR)\AudioPlugIn.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +SOURCE=.\AudioPlugInPropPage.cpp + +"$(INTDIR)\AudioPlugInPropPage.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\AudioPlugIn.pch" + + +SOURCE=.\Filter.cpp + +"$(INTDIR)\Filter.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\AudioPlugIn.pch" + + +SOURCE=.\MediaParams.cpp + +"$(INTDIR)\MediaParams.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\AudioPlugIn.pch" + + +SOURCE=.\ParamEnvelope.cpp + +"$(INTDIR)\ParamEnvelope.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\AudioPlugIn.pch" + + +SOURCE=.\PlugInApp.cpp + +"$(INTDIR)\PlugInApp.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\AudioPlugIn.pch" + + +SOURCE=.\StdAfx.cpp + +!IF "$(CFG)" == "AudioPlugIn - Win32 Release" + +CPP_SWITCHES=/nologo /MD /W3 /GX /O2 /I "." /I "include" /I "$(MSSDK)\include" /I "$(MSSDK)\Samples\Multimedia\DirectShow\BaseClasses" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_MBCS" /D "_USRDLL" /Fp"$(INTDIR)\AudioPlugIn.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\AudioPlugIn.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "AudioPlugIn - Win32 Debug" + +CPP_SWITCHES=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /I "include" /I "$(MSSDK)\include" /I "$(MSSDK)\Samples\Multimedia\DirectShow\BaseClasses" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_MBCS" /D "_USRDLL" /Fp"$(INTDIR)\AudioPlugIn.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\AudioPlugIn.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + + +!ENDIF + diff --git a/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.rc b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.rc new file mode 100644 index 00000000..38ba0bd7 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.rc @@ -0,0 +1,202 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include <windows.h> + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include <windows.h>\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 9, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif\r\n" + "#include ""res\\AudioPlugIn.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#endif\0" +END + +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "\0" + VALUE "FileDescription", "AudioPlugIn DLL\0" + VALUE "FileVersion", "1, 0, 0, 1\0" + VALUE "InternalName", "AudioPlugIn\0" + VALUE "LegalCopyright", "Copyright © 1997\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "AudioPlugIn.DLL\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "AudioPlugIn Dynamic Link Library\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOGEX 0, 0, 343, 222 +STYLE DS_CONTROL | DS_CENTER | WS_CHILD +EXSTYLE WS_EX_TOOLWINDOW +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS | + TBS_VERT | WS_TABSTOP,11,70,11,116 + CONTROL "Slider1",IDC_SLIDER2,"msctls_trackbar32",TBS_AUTOTICKS | + TBS_VERT | WS_TABSTOP,51,70,11,116 + CONTROL "Slider1",IDC_SLIDER3,"msctls_trackbar32",TBS_AUTOTICKS | + TBS_VERT | WS_TABSTOP,91,70,11,116 + EDITTEXT IDC_SLIDER1_LABEL2,24,74,26,13,ES_AUTOHSCROLL + EDITTEXT IDC_SLIDER1_LABEL3,24,170,26,13,ES_AUTOHSCROLL + EDITTEXT IDC_SLIDER1_LABEL1,12,189,38,13,ES_AUTOHSCROLL + EDITTEXT IDC_SLIDER2_LABEL2,64,74,26,13,ES_AUTOHSCROLL + EDITTEXT IDC_SLIDER2_LABEL3,64,170,26,13,ES_AUTOHSCROLL + EDITTEXT IDC_SLIDER2_LABEL1,52,189,38,13,ES_AUTOHSCROLL + EDITTEXT IDC_SLIDER3_LABEL2,104,74,26,13,ES_AUTOHSCROLL + EDITTEXT IDC_SLIDER3_LABEL3,104,170,26,13,ES_AUTOHSCROLL + EDITTEXT IDC_SLIDER3_LABEL1,92,189,38,13,ES_AUTOHSCROLL + PUSHBUTTON "Save",IDC_SAVE,185,4,50,14 + PUSHBUTTON "Help",IDC_SHOWHELP,289,4,50,14 + EDITTEXT IDC_INIT,183,32,155,43,ES_MULTILINE | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL + EDITTEXT IDC_ONSLIDERCHANGE,183,87,155,41,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | + WS_VSCROLL + EDITTEXT IDC_PERSAMPLE,183,141,155,80,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | + WS_VSCROLL + GROUPBOX "Signal Processing Controls",IDC_STATIC,3,61,176,159 + LTEXT "Initialization/format change:",IDC_STATIC,183,22,88,8 + LTEXT "Per sample (or sample-pair):",IDC_STATIC,183,131,87,8 + LTEXT "Slider change/initialization:",IDC_STATIC,183,77,85,8 + LTEXT "",IDC_PRESET,3,32,175,10,SS_SUNKEN + LTEXT "Current preset:",IDC_STATIC,3,21,47,8 + PUSHBUTTON "Load",IDC_LOAD,3,4,41,14 + PUSHBUTTON "New",IDC_NEW,50,4,41,14 + PUSHBUTTON "",IDC_EDIT,133,4,46,14 + CONTROL "Enable processing",IDC_BYPASS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,3,47,74,10 + CONTROL "Slider1",IDC_SLIDER4,"msctls_trackbar32",TBS_AUTOTICKS | + TBS_VERT | WS_TABSTOP,130,70,11,116 + EDITTEXT IDC_SLIDER4_LABEL2,144,74,26,13,ES_AUTOHSCROLL + EDITTEXT IDC_SLIDER4_LABEL3,144,170,26,13,ES_AUTOHSCROLL + EDITTEXT IDC_SLIDER4_LABEL1,132,189,38,13,ES_AUTOHSCROLL + PUSHBUTTON "Trigger 1",IDC_TRIGGER1,12,204,38,11 + PUSHBUTTON "Trigger 2",IDC_TRIGGER2,52,204,38,11 + PUSHBUTTON "Trigger 3",IDC_TRIGGER3,92,204,38,11 + PUSHBUTTON "Trigger 4",IDC_TRIGGER4,132,204,38,11 +END + +IDD_EVAL_HELP DIALOG DISCARDABLE 0, 0, 311, 231 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "SPS Expression Help" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "Close",IDOK,7,210,50,14 + EDITTEXT IDC_EDIT1,12,25,286,177,ES_MULTILINE | ES_READONLY | + WS_VSCROLL + CONTROL "Tab1",IDC_TAB1,"SysTabControl32",0x0,7,7,297,200 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_NAME_PLUGIN "Nullsoft SPS DX plugin" + IDS_DESC_PLUGIN "SPS" + IDS_SETTINGS "Settings" + IDS_HELPFILE_PLUGIN "AudioPlugIn.hlp" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif +#include "res\AudioPlugIn.rc2" // non-Microsoft Visual C++ edited resources +#endif +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugInPropPage.cpp b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugInPropPage.cpp new file mode 100644 index 00000000..5fbf0bd8 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugInPropPage.cpp @@ -0,0 +1,326 @@ +// AudioPlugInPropPage.cpp : implementation file +// + +#include "stdafx.h" +#include "resource.h" +#include "AudioPlugInPropPage.h" + +#include <MedParam.h> +#include "CakeMedParam.h" +#include "Parameters.h" + +///////////////////////////////////////////////////////////////////////////// +// CAudioPlugInPropPage property page + +extern HMODULE g_hInst; + +SPSEffectContext *g_fucko_ctx; + +CAudioPlugInPropPage::CAudioPlugInPropPage( IUnknown* pUnk, HRESULT* phr ) : + CUnknown( "AudioPlugInPropPage", pUnk ), + m_hWnd( NULL ), + m_pMediaParams( NULL ), + m_pUICallback( NULL ), + m_pPageSite( NULL ), + m_bDirty( FALSE ) +{ + SPS_initcontext(&m_ctx); //FUCKO + g_fucko_ctx=&m_ctx; +} + +///////////////////////////////////////////////////////////////////////////// + +CUnknown * WINAPI CAudioPlugInPropPage::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr) +{ + return new CAudioPlugInPropPage( lpunk, phr ); +} + +///////////////////////////////////////////////////////////////////////////// + +CAudioPlugInPropPage::~CAudioPlugInPropPage() +{ + if (m_pMediaParams) + m_pMediaParams->Release(); + m_pMediaParams = NULL; + + if (m_pUICallback) + m_pUICallback->Release(); + m_pUICallback = NULL; +} + +///////////////////////////////////////////////////////////////////////////// +// CUnknown + +HRESULT CAudioPlugInPropPage::NonDelegatingQueryInterface( REFIID riid, void** ppv ) +{ + if (IID_IUnknown == riid) + return GetInterface( (IUnknown*)this, ppv ); + else if (IID_IPropertyPage == riid) + return GetInterface( (IPropertyPage*)this, ppv ); + else + { + *ppv = NULL; + return E_NOINTERFACE; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// IPropertyPage + +HRESULT CAudioPlugInPropPage::GetPageInfo( LPPROPPAGEINFO pPageInfo ) +{ + IMalloc* pIMalloc; + if (FAILED( CoGetMalloc( MEMCTX_TASK, &pIMalloc ) )) + return E_FAIL; + + pPageInfo->pszTitle = (LPOLESTR)pIMalloc->Alloc( 256 ); + + pIMalloc->Release(); + + if (!pPageInfo->pszTitle) + return E_OUTOFMEMORY; + + static const char szTitle[] = "AudioPlugIn"; + mbstowcs( pPageInfo->pszTitle, szTitle, strlen( szTitle ) ); + + pPageInfo->size.cx = 100; + pPageInfo->size.cy = 100; + pPageInfo->pszDocString = NULL; + pPageInfo->pszHelpFile = NULL; + pPageInfo->dwHelpContext= 0; + + // Create the property page in order to determine its size + HWND const hWnd = ::CreateDialogParam( g_hInst, MAKEINTRESOURCE( IDD_DIALOG1 ), GetDesktopWindow(), (DLGPROC)StaticDialogProc, 0 ); + if (hWnd) + { + // Get the dialog size and destroy the window + RECT rc; + GetWindowRect( hWnd, &rc ); + pPageInfo->size.cx = rc.right - rc.left; + pPageInfo->size.cy = rc.bottom - rc.top; + DestroyWindow( hWnd ); + } + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugInPropPage::SetObjects( ULONG cObjects, LPUNKNOWN* ppUnk ) +{ + // Release old interfaces + if (m_pMediaParams) + m_pMediaParams->Release(); + m_pMediaParams = NULL; + if (m_pUICallback) + m_pUICallback->Release(); + m_pUICallback = NULL; + + // Look for a new IFilter + ULONG cObj = 0; + for (ULONG i = 0; i < cObjects; ++i) + { + if (S_OK == ppUnk[i]->QueryInterface( IID_IMediaParams, (void**)&m_pMediaParams )) + { + ppUnk[i]->QueryInterface( IID_IMediaParamsUICallback, (void**)&m_pUICallback ); + break; + } + } + + // Update controls if we've got a new object and we're activated + if (m_pMediaParams && ::IsWindow( m_hWnd )) + UpdateControls(); + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +extern BOOL CALLBACK SPS_configWindowProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam); + +BOOL CALLBACK CAudioPlugInPropPage::StaticDialogProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ +#if 0 + CAudioPlugInPropPage* pPage; + + if (WM_INITDIALOG == uMsg) + { + SetWindowLong( hwnd, DWL_USER, lParam ); + pPage = reinterpret_cast<CAudioPlugInPropPage*>(lParam); + if (!pPage) + return TRUE; + } + + pPage = reinterpret_cast<CAudioPlugInPropPage*>(GetWindowLong( hwnd, DWL_USER )); + if (!pPage) + return TRUE; + + return pPage->DialogProc( hwnd, uMsg, wParam, lParam ); +#endif + return SPS_configWindowProc(hwnd, uMsg, wParam,lParam); +} + +//////////////////////////////////////////////////////////////////////////////// + +BOOL CAudioPlugInPropPage::DialogProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + //return SPS_configWindowProc(hwnd, uMsg, wParam,lParam); + return 0; + +/* switch( uMsg ) + { + case WM_INITDIALOG: + m_hWnd = hwnd; + break; + + default: + return FALSE; + } + + return TRUE;*/ +} + +//////////////////////////////////////////////////////////////////////////////// + +void CAudioPlugInPropPage::UpdateControls() +{ + // TODO: update all UI elements to reflect new control state +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugInPropPage::Activate( HWND hwndParent, LPCRECT pRect, BOOL fModal ) +{ + if (!pRect) + return E_POINTER; + if (NULL != m_hWnd) + return E_UNEXPECTED; // already active! + + m_hWnd = CreateDialogParam( g_hInst, MAKEINTRESOURCE( IDD_DIALOG1 ), hwndParent, (DLGPROC)StaticDialogProc, (LPARAM)&m_ctx ); + if (!m_hWnd) + return E_OUTOFMEMORY; + + // Refresh the property page controls + UpdateControls(); + + // Move page into position and show it + Move( pRect ); + Show( SW_SHOWNORMAL ); + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugInPropPage::Move( LPCRECT pRect ) +{ + if (!pRect) + return E_POINTER; + if (NULL == m_hWnd) + E_UNEXPECTED; + + MoveWindow( m_hWnd, pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top, TRUE ); + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugInPropPage::Show( UINT nCmdShow ) +{ + if (NULL == m_hWnd) + E_UNEXPECTED; + // Ignore wrong show flags + if (nCmdShow != SW_SHOW && nCmdShow != SW_SHOWNORMAL && nCmdShow != SW_HIDE) + return E_INVALIDARG; + + ShowWindow( m_hWnd, nCmdShow ); + + if (SW_SHOWNORMAL == nCmdShow || SW_SHOW == nCmdShow) + { + // TODO: set the focus to which control needs it + } + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugInPropPage::Deactivate() +{ + if (NULL == m_hWnd) + return E_UNEXPECTED; + + DestroyWindow( m_hWnd ); + m_hWnd = NULL; + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugInPropPage::SetPageSite( LPPROPERTYPAGESITE pPageSite ) +{ + if (pPageSite) + { + if (m_pPageSite) + return E_UNEXPECTED; + m_pPageSite = pPageSite; + m_pPageSite->AddRef(); + } + else + { + if (m_pPageSite == NULL) + return E_UNEXPECTED; + m_pPageSite->Release(); + m_pPageSite = NULL; + } + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugInPropPage::Apply() +{ + // Take no action except clearing the dirty flag. + // So that the property page may be used in realtime, all user interface + // changes are immediately passed to the filter. I.e. there is no Cancel. + m_bDirty = FALSE; + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugInPropPage::IsPageDirty( void ) +{ + return m_bDirty ? S_OK : S_FALSE; +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugInPropPage::Help( LPCWSTR lpszHelpDir ) +{ + // Get location of DLL + char szDLL[ _MAX_PATH ]; + if (0 == ::GetModuleFileName( g_hInst, szDLL, sizeof szDLL )) + return E_FAIL; + + // Convert to location of .HLP file + char szHelp[ _MAX_PATH ]; + ::strncpy( szHelp, szDLL, ::strlen( szDLL ) - 3 ); + ::strcat( szHelp, "HLP" ); + + // Call help + if (::WinHelp( m_hWnd, szHelp, HELP_CONTENTS, NULL )) + return S_OK; + + return E_FAIL; +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CAudioPlugInPropPage::TranslateAccelerator( LPMSG lpMsg ) +{ + return E_NOTIMPL; +} + +///////////////////////////////////////////////////////////////////////////// diff --git a/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugInPropPage.h b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugInPropPage.h new file mode 100644 index 00000000..10485990 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/AudioPlugInPropPage.h @@ -0,0 +1,68 @@ +#ifndef _PLUGIN_PROP_PAGE_H_ +#define _PLUGIN_PROP_PAGE_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "../sps_common.h" + +struct IMediaParams; +struct IMediaParamsUICallback; + +///////////////////////////////////////////////////////////////////////////// +// CAudioPlugInPropPage dialog + +class CAudioPlugInPropPage : + public CUnknown, + public IPropertyPage +{ +// Construction +public: + CAudioPlugInPropPage( IUnknown* pUnk, HRESULT* phr ); + virtual ~CAudioPlugInPropPage(); + + // CUnknown + DECLARE_IUNKNOWN; + STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv); + + // *** IPropertyPage methods *** + STDMETHODIMP_(HRESULT) SetPageSite(LPPROPERTYPAGESITE pPageSite); + STDMETHODIMP_(HRESULT) Activate(HWND hwndParent, LPCRECT prect, BOOL fModal); + STDMETHODIMP_(HRESULT) Deactivate(void); + STDMETHODIMP_(HRESULT) GetPageInfo(LPPROPPAGEINFO pPageInfo); + STDMETHODIMP_(HRESULT) SetObjects(ULONG cObjects, LPUNKNOWN *ppUnk); + STDMETHODIMP_(HRESULT) Show(UINT nCmdShow); + STDMETHODIMP_(HRESULT) Move(LPCRECT prect); + STDMETHODIMP_(HRESULT) IsPageDirty(void); + STDMETHODIMP_(HRESULT) Apply(void); + STDMETHODIMP_(HRESULT) Help(LPCWSTR lpszHelpDir); + STDMETHODIMP_(HRESULT) TranslateAccelerator(LPMSG lpMsg); + +public: + + static CUnknown * WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT *phr); + +// Implementation +protected: + + void UpdateControls(); + BOOL DialogProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + + static BOOL CALLBACK StaticDialogProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + +private: + + HWND m_hWnd; + BOOL m_bDirty; + IPropertyPageSite* m_pPageSite; + IMediaParams* m_pMediaParams; + IMediaParamsUICallback* m_pUICallback; + + SPSEffectContext m_ctx; +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // _PLUGIN_PROP_PAGE_H_ diff --git a/Src/Plugins/DSP/dsp_sps/dxi/Filter.cpp b/Src/Plugins/DSP/dsp_sps/dxi/Filter.cpp new file mode 100644 index 00000000..35fef3a7 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/Filter.cpp @@ -0,0 +1,1139 @@ +// Filter.cpp : implementation file +// + +#include "stdafx.h" +#include "resource.h" +#include <mediaerr.h> +#include <initguid.h> +#include <DeferZeroFill.h> +#include <malloc.h> +#include "Filter.h" +#include "AudioPlugInPropPage.h" + +#ifdef _DEBUG +#pragma comment(lib, "strmbasd.lib") +#pragma comment(lib, "asynbased.lib") +#else +#pragma comment(lib, "strmbase.lib") +#endif + +#include "PlugInGUIDs.h" + +#define PLUGTITLE L"Nullsoft SPS Plug-In" + +///////////////////////////////////////////////////////////////////////////// +// Setup data + +static AMOVIESETUP_MEDIATYPE sudPinTypes = +{ + &MEDIATYPE_Audio, // Major CLSID + &MEDIASUBTYPE_NULL // Minor type +}; + +static AMOVIESETUP_PIN psudPins[] = +{ + { L"Input", // Pin's string name + FALSE, // Is it rendered + FALSE, // Is it an output + FALSE, // Allowed none + FALSE, // Allowed many + &CLSID_NULL, // Connects to filter + L"Output", // Connects to pin + 1, // Number of types + &sudPinTypes }, // Pin information + { L"Output", // Pin's string name + FALSE, // Is it rendered + TRUE, // Is it an output + FALSE, // Allowed none + FALSE, // Allowed many + &CLSID_NULL, // Connects to filter + L"Input", // Connects to pin + 1, // Number of types + &sudPinTypes } // Pin information +}; + +static AMOVIESETUP_FILTER sudFilter = +{ + &CLSID_Filter, // CLSID of filter + PLUGTITLE, // Filter's name + MERIT_DO_NOT_USE, // Filter merit + 2, // Number of pins + psudPins // Pin information +}; + +///////////////////////////////////////////////////////////////////////////// + +CFactoryTemplate g_Templates[ 2 ] = +{ + { PLUGTITLE + , &CLSID_Filter + , CFilter::CreateInstance + , NULL + , &sudFilter } + , + { L"AudioPlugIn Properties" + , &CLSID_FilterPropPage + , CAudioPlugInPropPage::CreateInstance + , NULL + , NULL } +}; + +int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); + +//-------------------------------------------------------------------------------- +// Helper function to notify the graph about pin changes + +static void notifyGraphChanged( IFilterGraph* pGraph ) +{ + if (pGraph) + { + IMediaEventSink* pSink = NULL; + if (S_OK == pGraph->QueryInterface( IID_IMediaEventSink, (void**)&pSink )) + { + pSink->Notify( EC_GRAPH_CHANGED, 0, 0 ); + pSink->Release(); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// CFilter +//////////////////////////////////////////////////////////////////////////////// + +//-------------------------------------------------------------------------------- +// Ctor + +CFilter::CFilter( TCHAR* pName, LPUNKNOWN pUnk, HRESULT* phr ) : + CBaseFilter( pName, pUnk, this, CLSID_Filter, phr ), + CPersistStream( pUnk, phr ), + CAudioPlugIn( phr ), + m_pinInput( NAME("Input"), this, phr, L"Input" ), + m_pinOutput( NAME("Output"), this, phr, L"Output" ), + m_llSamplePosition( 0 ) +{ + if (SUCCEEDED( *phr )) + { + // Create our DirectX automation helper object + *phr = CMediaParams::Create( &m_pMediaParams, (IUnknown*)(IBaseFilter*)this ); + } + + if (SUCCEEDED( *phr )) + { + // Initialize the plug-in + *phr = Initialize(); + } +} + + +//------------------------------------------------------------------------------ +// Factory-style construction + +CUnknown * WINAPI CFilter::CreateInstance( LPUNKNOWN pUnk, HRESULT* phr ) +{ + return new CFilter( NAME("Filter"), pUnk, phr ); +} + + +//-------------------------------------------------------------------------------- +// Expose setup data for registration + +LPAMOVIESETUP_FILTER CFilter::GetSetupData() +{ + return &sudFilter; +} + + +//-------------------------------------------------------------------------------- +// Expose other interfaces to the world + +STDMETHODIMP CFilter::NonDelegatingQueryInterface( REFIID riid, void** ppv ) +{ + if (riid == IID_IDispatch) + return GetInterface((IDispatch*)this, ppv); + else if (riid == IID_ISpecifyPropertyPages) + return GetInterface((ISpecifyPropertyPages*)this, ppv); + else if (riid == IID_IPersistStream) + return GetInterface((IPersistStream*)this, ppv); + else if (NULL != m_pMediaParams) + { + if (riid == IID_IMediaParams) + return GetInterface((IMediaParams*)m_pMediaParams, ppv); + else if (riid == IID_IMediaParamInfo) + return GetInterface((IMediaParamInfo*)m_pMediaParams, ppv); + else if (riid == IID_IMediaParamsSetUICallback) + return GetInterface((IMediaParamsSetUICallback*)m_pMediaParams, ppv); + else if (riid == IID_IMediaParamsUICallback) + return GetInterface((IMediaParamsUICallback*)m_pMediaParams, ppv); + } + + return CBaseFilter::NonDelegatingQueryInterface(riid, ppv); +} + + +//-------------------------------------------------------------------------------- +// CFilter dtor + +CFilter::~CFilter() +{ + if (m_pMediaParams) + m_pMediaParams->Release(), m_pMediaParams = NULL; +} + + +//-------------------------------------------------------------------------------- +// Get the total number of pins in our filter + +int CFilter::GetPinCount() +{ + return 2; +} + + +//-------------------------------------------------------------------------------- +// Get the Nth pin from our filter (CBaseFilter pure virtual override) +// Pin 0 is the input pin and all others are output pins + +CBasePin* CFilter::GetPin( int n ) +{ + if (0 == n) + return &m_pinInput; + else if (1 == n) + return &m_pinOutput; + else + return NULL; +} + + +//-------------------------------------------------------------------------------- +// Helper for checking media types + +HRESULT CFilter::CheckMediaType( PIN_DIRECTION pinDir, const CMediaType* pmt ) +{ + if (NULL == pmt) + return E_POINTER; + + // Must be audio + if (pmt->majortype != MEDIATYPE_Audio) + return VFW_E_TYPE_NOT_ACCEPTED; + + // Must not be compressed + if (pmt->bTemporalCompression) + return VFW_E_TYPE_NOT_ACCEPTED; + + // Must be WAVEFORMATEX + if (pmt->cbFormat < sizeof(WAVEFORMATEX)) + return VFW_E_TYPE_NOT_ACCEPTED; + + WAVEFORMATEX* pwfx = reinterpret_cast<WAVEFORMATEX*>( pmt->Format() ); + + // Must be 16-bit PCM or 32-bit float + BOOL const bInt16 = + (WAVE_FORMAT_PCM == pwfx->wFormatTag && 16 == pwfx->wBitsPerSample) || + (WAVE_FORMAT_EXTENSIBLE == pwfx->wFormatTag && 16 == pwfx->wBitsPerSample); + BOOL const bFloat32 = + (WAVE_FORMAT_IEEE_FLOAT == pwfx->wFormatTag && 32 == pwfx->wBitsPerSample); + if (!bInt16 && !bFloat32) + return VFW_E_TYPE_NOT_ACCEPTED; + + // Must be mono or stereo + if (1 != pwfx->nChannels && 2 != pwfx->nChannels) + return VFW_E_TYPE_NOT_ACCEPTED; + + // Let the plug-in decide the rest + if (PINDIR_INPUT == pinDir) + return IsValidInputFormat( pwfx ); + else + return IsValidOutputFormat( pwfx ); +} + + +//-------------------------------------------------------------------------------- +// CheckTransform + +HRESULT CFilter::CheckTransform( const CMediaType* pmtIn, const CMediaType* pmtOut ) +{ + if (NULL == pmtIn) + return E_POINTER; + if (NULL == pmtOut) + return E_POINTER; + + // Make sure input/output types are valid + HRESULT hr = S_OK; + hr = CheckMediaType( PINDIR_INPUT, pmtIn ); + if (FAILED( hr )) + return hr; + hr = CheckMediaType( PINDIR_OUTPUT, pmtOut ); + if (FAILED( hr )) + return hr; + + // Make sure sample rates are the same + WAVEFORMATEX* pwfxIn = reinterpret_cast<WAVEFORMATEX*>( pmtIn->Format() ); + WAVEFORMATEX* pwfxOut = reinterpret_cast<WAVEFORMATEX*>( pmtOut->Format() ); + if (pwfxIn->nSamplesPerSec != pwfxOut->nSamplesPerSec) + return VFW_E_TYPE_NOT_ACCEPTED; + + // Let the plug-in decide for sure + return IsValidTransform( pwfxIn, pwfxOut ); +} + + +//-------------------------------------------------------------------------------- +// GetMediaType + +HRESULT CFilter::GetMediaType( int iPosition, CMediaType* pmt ) +{ + if (!m_pinInput.IsConnected()) + return E_UNEXPECTED; + + if (iPosition < 0) + return E_INVALIDARG; + + if (iPosition > 0) + return VFW_S_NO_MORE_ITEMS; + + // Get pointers to input/ouput formats + WAVEFORMATEX* pwfxIn = reinterpret_cast<WAVEFORMATEX*>( m_pinInput.CurrentMediaType().Format() ); + if (NULL == pwfxIn) + return E_FAIL; + WAVEFORMATEX* pwfxOut = reinterpret_cast<WAVEFORMATEX*>( pmt->Format() ); + if (NULL == pwfxOut) + return E_FAIL; + + // Assume output format is the same as input format + *pwfxOut = *pwfxIn; + + // let the plug-in suggest something different + return SuggestOutputFormat( pwfxOut ); +} + + +//-------------------------------------------------------------------------------- +// SetMediaType + +HRESULT CFilter::SetMediaType( PIN_DIRECTION pindir, const CMediaType* pmt ) +{ + CAutoLock autoLock(m_pLock); + HRESULT hr = NOERROR; + + // Make sure it's a valid audio type + hr = CheckMediaType( pindir, pmt ); + if (S_OK != hr) + return hr; + + if (PINDIR_INPUT == pindir) + m_wfxIn = *reinterpret_cast<WAVEFORMATEX*>( pmt->Format() ); + else if (PINDIR_OUTPUT == pindir) + m_wfxOut = *reinterpret_cast<WAVEFORMATEX*>( pmt->Format() ); + + m_pMediaParams->SetSampleRate( m_wfxIn.nSamplesPerSec ); + + return NOERROR; +} + + +//-------------------------------------------------------------------------------- +// Run: Overriden to handle no input connections, and to notify the plug-in + +STDMETHODIMP CFilter::Run( REFERENCE_TIME tStart ) +{ + CAutoLock cObjectLock(m_pLock); + + CBaseFilter::Run( tStart ); + if (!m_pinInput.IsConnected()) + m_pinInput.EndOfStream(); + + return NOERROR; +} + + +//-------------------------------------------------------------------------------- +// Pause: Overriden to handle no input connections, and to notify the plug-in + +STDMETHODIMP CFilter::Pause() +{ + CAutoLock cObjectLock(m_pLock); + + if (State_Paused == m_State) + return S_OK; // nothing to do + + BOOL const bPreRoll = (State_Stopped == m_State); + + // Set this to something in case we never see a media sample timestamp + m_llSamplePosition = 0; + + // Let the base-class do the real pausing + HRESULT hr = CBaseFilter::Pause(); + + // Deal with unexpected disconnect + if (!m_pinInput.IsConnected()) + m_pinInput.EndOfStream(); + + if (bPreRoll && SUCCEEDED( hr )) + hr = AllocateResources(); + + return hr; +} + + +//-------------------------------------------------------------------------------- +// Stop: Overriden to handle no input connections, and to notify the plug-in + +STDMETHODIMP CFilter::Stop() +{ + CAutoLock cObjectLock(m_pLock); + + if (State_Stopped == m_State) + return S_OK; // nothing to do + + // Let the base-class do the real stopping + HRESULT hr = CBaseFilter::Stop(); + if (SUCCEEDED( hr )) + hr = FreeResources(); + + return hr; +} + + +//-------------------------------------------------------------------------------- +// Initialize an AudioBuffer and IMediaSample for an output pin. + +HRESULT CFilter::getOutputBuffer( CFilterOutputPin* pOutputPin, + AudioBuffer* pbufOut, + REFERENCE_TIME* prtStart, + BOOL bSyncPoint, BOOL bDiscontinuity, BOOL bPreroll ) +{ + if (NULL == pOutputPin) + return E_POINTER; + if (NULL == pbufOut) + return E_POINTER; + if (!pOutputPin->IsConnected()) + return E_UNEXPECTED; + + // Ask our output pin to allocate an output media sample + HRESULT hr = pOutputPin->GetDeliveryBuffer( &pbufOut->pms, NULL, NULL, 0 ); + if (FAILED( hr )) + return hr; + + // Set media sample properties + pbufOut->pms->SetTime( prtStart, NULL ); + pbufOut->pms->SetSyncPoint( bSyncPoint ); + pbufOut->pms->SetDiscontinuity( bDiscontinuity ); + pbufOut->pms->SetPreroll( bPreroll ); + + // Set the output size + pbufOut->cSamp = pbufOut->pms->GetSize() / m_wfxOut.nBlockAlign; + pbufOut->lOffset = 0; + + // Tag the output buffer as being all zeros + pbufOut->SetZerofill( TRUE ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------- +// Deliver results and cleanup + +HRESULT CFilter::deliverOutputBuffer( CFilterOutputPin* pOutputPin, + AudioBuffer* pbufOut, + HRESULT hrProcess, BOOL bCleanup ) +{ + if (NULL == pbufOut) + return E_POINTER; + if (NULL == pbufOut->pms) + return E_POINTER; + if (!pOutputPin->IsConnected()) + return E_UNEXPECTED; + + HRESULT hr = S_OK; + + // Deliver only if we need to + if (S_OK == hrProcess) + { + if (pbufOut->GetZerofill()) + { + // If the output buffer support IDeferZeroFill, there is nothing more + // that we need to do to zerofill it: the zerofill will occur when some + // downstream filter attempts to get the media sample's buffer pointer. + // buffer fill if possible. + IDeferZeroFill* pdzf = NULL; + if (S_OK == pbufOut->pms->QueryInterface( IID_IDeferZeroFill, (void**)&pdzf )) + { + pdzf->Release(); + } + else + { + // AudioBuffer::GetPointer will handle any zerofill for us. + pbufOut->GetPointer(); + } + } + + // Set the final output sample size + hr = pbufOut->pms->SetActualDataLength( pbufOut->cSamp * m_wfxOut.nBlockAlign ); + if (SUCCEEDED( hr )) + { + // Tell the current output pin to deliver this sample + hr = pOutputPin->Deliver( pbufOut->pms ); + } + } + else if (S_FALSE == hrProcess) + { + hr = pOutputPin->DeliverEndOfStream(); + } + + // Release the media sample once we're done with it + if (bCleanup) + { + pbufOut->pms->Release(); + pbufOut->pms = NULL; + } + + return hr; +} + + +//-------------------------------------------------------------------------------- +// ISpecifyPropertyPages + +STDMETHODIMP CFilter::GetPages(CAUUID *pPages) +{ + if (NULL == pPages) + return E_POINTER; + + pPages->cElems = 1; + pPages->pElems= (GUID*) CoTaskMemAlloc( sizeof(GUID) ); + + if (pPages->pElems==NULL) + return E_OUTOFMEMORY; + + pPages->pElems[0] = CLSID_FilterPropPage; + + return NOERROR; +} + + +//-------------------------------------------------------------------------------- +// CPersistStream + +STDMETHODIMP CFilter::GetClassID(CLSID* pClsid) +{ + if (NULL == pClsid) + return E_POINTER; + *pClsid = CLSID_Filter; + return NOERROR; +} + +int CFilter::SizeMax() +{ + return PersistGetSize(); +} + +HRESULT CFilter::WriteToStream(IStream* pStream) +{ + CAutoLock cObjectLock(m_pLock); + + return PersistSave( pStream ); +} + +HRESULT CFilter::ReadFromStream(IStream* pStream) +{ + CAutoLock cObjectLock(m_pLock); + + return PersistLoad( pStream ); +} + + +//-------------------------------------------------------------------------------- +// IDispatch is exposed only so MFC's COlePropertyPage can connect; ever single +// method is not implemented. + +HRESULT CFilter::GetTypeInfoCount( UINT* ) +{ + return E_NOTIMPL; +} + +HRESULT CFilter::GetTypeInfo( UINT, LCID, ITypeInfo** ) +{ + return E_NOTIMPL; +} + +HRESULT CFilter::GetIDsOfNames( REFIID, OLECHAR**, UINT, LCID, DISPID* ) +{ + return E_NOTIMPL; +} + +HRESULT CFilter::Invoke( DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT* ) +{ + return E_NOTIMPL; +} + + +////////////////////////////////////////////////////////////////////////////////// +// CFilterInputPin +////////////////////////////////////////////////////////////////////////////////// + +//-------------------------------------------------------------------------------- +// Ctor + +CFilterInputPin::CFilterInputPin( TCHAR* pObjDesc, CFilter* pFilter, HRESULT* phr, LPCWSTR pPinName ) : + CBaseInputPin( pObjDesc, pFilter, pFilter, phr, pPinName ), + m_pFilter( pFilter ), + m_bInsideCheckMediaType( FALSE ) +{ + ASSERT( pFilter ); +} + + +//-------------------------------------------------------------------------------- +// CheckMediaType + +HRESULT CFilterInputPin::CheckMediaType( const CMediaType* pmt ) +{ + CAutoLock autoLock(m_pLock); + HRESULT hr = NOERROR; + + // If we are already inside checkmedia type for this pin, return NOERROR. + // It is possble to hookup two of the these filters and some other filter + // like the video effects sample to get into this situation. If we don't + // detect this situation, we will carry on looping till we blow the stack. + + if (m_bInsideCheckMediaType) + return NOERROR; + + m_bInsideCheckMediaType = TRUE; + + // See if the wave format is supported + hr = m_pFilter->CheckMediaType( PINDIR_INPUT, pmt ); + if (S_OK != hr) + { + m_bInsideCheckMediaType = FALSE; + return hr; + } + + // Make sure the output pin agrees on the type + if (m_pFilter->m_pinOutput.IsConnected()) + { + // See if we can transform from input to the current output type + const CMediaType& mtOut = m_pFilter->m_pinOutput.CurrentMediaType(); + hr = m_pFilter->CheckTransform( pmt, &mtOut ); + if (FAILED( hr )) + { + m_bInsideCheckMediaType = FALSE; + return VFW_E_TYPE_NOT_ACCEPTED; + } + } + + // Either all the downstream pins have accepted or there are none. + m_bInsideCheckMediaType = FALSE; + return NOERROR; +} + + +//-------------------------------------------------------------------------------- +// Set the media type for this connection + +HRESULT CFilterInputPin::SetMediaType( const CMediaType* pmtIn ) +{ + // Set the base class media type (should always succeed) + HRESULT hr = CBaseInputPin::SetMediaType( pmtIn ); + ASSERT( SUCCEEDED( hr ) ); + + // Check the transform can be done (should always succeed) + hr = m_pFilter->CheckMediaType( PINDIR_INPUT, pmtIn ); + ASSERT( SUCCEEDED( hr ) ); + + return m_pFilter->SetMediaType( PINDIR_INPUT, pmtIn ); +} + + +//-------------------------------------------------------------------------------- +// CompleteConnect: Negotiate possible reconnection if types don't match + +HRESULT CFilterInputPin::CompleteConnect( IPin* pRecievePin ) +{ + HRESULT hr = S_OK; + + const CMediaType& mtIn = m_pFilter->m_pinInput.CurrentMediaType(); + + if (m_pFilter->m_pinOutput.IsConnected()) + { + const CMediaType& mtOut = m_pFilter->m_pinOutput.CurrentMediaType(); + hr = m_pFilter->CheckTransform( &mtIn, &mtOut ); + if (FAILED( hr )) + { + if (NULL == m_pFilter->m_pGraph) + hr = VFW_E_NOT_IN_GRAPH; + else + hr = m_pFilter->m_pGraph->Reconnect( &m_pFilter->m_pinOutput ); + } + } + + return hr; +} + + +//-------------------------------------------------------------------------------- +// Receive: override to send message to all downstream pins + +HRESULT CFilterInputPin::Receive( IMediaSample* pms ) +{ + CAutoLock autoLock(m_pLock); + HRESULT hr = NOERROR; + + ASSERT( pms ); + + // Grab the time stamp on discontinuity samples. We'll synthesize + // time stamps for all the rest. + REFERENCE_TIME rtStart = 0; + REFERENCE_TIME* prtStart = NULL; + if (S_OK == pms->IsDiscontinuity()) + { + REFERENCE_TIME rtEnd; + HRESULT hrGetTime = pms->GetTime( &rtStart, &rtEnd ); + if (S_OK == hrGetTime || VFW_S_NO_STOP_TIME == hrGetTime) + { + m_pFilter->m_llSamplePosition = (rtStart * m_pFilter->m_wfxIn.nSamplesPerSec) / UNITS; + prtStart = &rtStart; + } + } + + // Determine the total number of samples to be processed + long const cSampTotal = pms->GetActualDataLength() / m_pFilter->m_wfxIn.nBlockAlign; + + // Set up an input AudioBuffer + AudioBuffer bufIn; + bufIn.cSamp = cSampTotal; + bufIn.pms = pms; + + // Check to see if the input buffer is defer zero fill + IDeferZeroFill* pdzf = NULL; + if (S_OK == pms->QueryInterface( IID_IDeferZeroFill, (void**)&pdzf )) + { + bufIn.SetZerofill( pdzf->get_NeedsZerofill() ); + pdzf->Release(); + } + else + bufIn.SetZerofill( FALSE ); + + // Determine the set of decimation points for processing + long const lFs = m_pFilter->m_wfxIn.nSamplesPerSec; + int const cbSampIn = m_pFilter->m_wfxIn.nBlockAlign; + int const cbSampOut = m_pFilter->m_wfxOut.nBlockAlign; + std::vector<LONGLONG> samplePos; + hr = m_pFilter->m_pMediaParams->GetDecimationTimes( m_pFilter->m_llSamplePosition, m_pFilter->m_llSamplePosition + bufIn.cSamp, &samplePos ); + if (FAILED( hr )) + return hr; + + AudioBuffer* pbufOut; + +#if PROCESS_IN_PLACE + + // Make sure we don't double-release the shared media sample + bufIn.pms->AddRef(); + + // Point to the same input buffer + pbufOut = &bufIn; + +#else // !PROCESS_IN_PLACE + + AudioBuffer bufOut; + + // Get a brand new output buffer + hr = m_pFilter->getOutputBuffer( &m_pFilter->m_pinOutput, &bufOut, prtStart, + S_OK == pms->IsSyncPoint(), + S_OK == pms->IsDiscontinuity(), + S_OK == pms->IsPreroll() ); + if (FAILED( hr )) + return hr; + + // Set output buffer size = input buffer size + bufOut.cSamp = cSampTotal; + + // Point to this brand new output buffer + pbufOut = &bufOut; + +#endif // PROCESS_IN_PLACE + + HRESULT hrProcess = S_OK; + LONGLONG llPrevPos = m_pFilter->m_llSamplePosition; + LONGLONG llCurrPos = llPrevPos; + long cSampDone = 0; + for (std::vector<LONGLONG>::iterator it = samplePos.begin(); it != samplePos.end(); it++) + { + // Get the next "landmark", i.e., the next point in time where either a + // shape starts or ends, or where we periodically decimate. + llCurrPos = *it; + + // Position all automation parameters + hr = m_pFilter->m_pMediaParams->UpdateValuesForSample( llPrevPos ); + if (FAILED( hr )) + return hr; + + // Don't process if we haven't changed position + if (llCurrPos == llPrevPos) + continue; + + // Determine the number of samples processed in this iteration + long const cSampIter = long( min( llCurrPos - llPrevPos, cSampTotal - cSampDone ) ); + if (0 == cSampIter) + continue; // nothing to do this iteration + + // Set the buffer sizes and offsets + bufIn.cSamp = cSampIter; + +#if !PROCESS_IN_PLACE + pbufOut->cSamp = bufIn.cSamp; +#endif + + // Process the audio + hrProcess = m_pFilter->Process( llPrevPos, &bufIn, pbufOut ); + if (FAILED( hrProcess )) + break; + + // Update buffer offsets + bufIn.lOffset += (cSampIter * cbSampIn); + ASSERT( bufIn.lOffset <= (cSampTotal * cbSampIn) ); + +#if !PROCESS_IN_PLACE + pbufOut->lOffset += (cSampIter * cbSampOut); + ASSERT( pbufOut->lOffset <= (cSampTotal * cbSampOut) ); +#endif + + // On to the next... + llPrevPos = llCurrPos; + cSampDone += cSampIter; + } + + // Process the final buffer + if (SUCCEEDED( hrProcess ) && cSampDone < cSampTotal) + { + // Position all automation parameters + hr = m_pFilter->m_pMediaParams->UpdateValuesForSample( llPrevPos ); + if (FAILED( hr )) + return hr; + + // Set the final buffer size + bufIn.cSamp = cSampTotal - cSampDone; + +#if !PROCESS_IN_PLACE + pbufOut->cSamp = bufIn.cSamp; +#endif + + // Process the audio + hrProcess = m_pFilter->Process( llPrevPos, &bufIn, pbufOut ); + } + + // Deliver results and cleanup + pbufOut->lOffset = 0; + pbufOut->cSamp = cSampTotal; + hr = m_pFilter->deliverOutputBuffer( &m_pFilter->m_pinOutput, pbufOut, hrProcess, TRUE ); + + // Propagate any failures in processing + if (FAILED( hrProcess )) + hr = hrProcess; + + // Update our position + m_pFilter->m_llSamplePosition += cSampTotal; + + return NOERROR; +} + + +//-------------------------------------------------------------------------------- +// EndOfStream: override to send message to all downstream pins + +HRESULT CFilterInputPin::EndOfStream() +{ + CAutoLock autoLock(m_pLock); + HRESULT hr = NOERROR; + + // Get an output buffer + AudioBuffer bufOut; + hr = m_pFilter->getOutputBuffer( &m_pFilter->m_pinOutput, &bufOut, + NULL, FALSE, FALSE, FALSE ); + if (FAILED( hr )) + return hr; + + int const cSamp = bufOut.cSamp; + + // Deliver buffers until the entire flush is complete + for (;;) + { + // Process the audio + HRESULT hrProcess = m_pFilter->Process( m_pFilter->m_llSamplePosition, NULL, &bufOut ); + + // Deliver results, but don't cleanup yet + hr = m_pFilter->deliverOutputBuffer( &m_pFilter->m_pinOutput, &bufOut, hrProcess, FALSE ); + + // Propagate any failures in processing + if (FAILED( hrProcess )) + hr = hrProcess; + + // Stop at end-of-stream or failure + if (S_FALSE == hrProcess || FAILED( hr )) + break; + + // Update our position + m_pFilter->m_llSamplePosition += cSamp; + } + + // Clean up output buffer memory + m_pFilter->deliverOutputBuffer( &m_pFilter->m_pinOutput, &bufOut, S_FALSE, TRUE ); + + return hr; +} + + +//-------------------------------------------------------------------------------- +// BeginFlush: override to send message to all downstream pins + +HRESULT CFilterInputPin::BeginFlush() +{ + CAutoLock autoLock(m_pLock); + HRESULT hr = NOERROR; + + if (m_pFilter->m_pinOutput.IsConnected()) + { + hr = m_pFilter->m_pinOutput.DeliverBeginFlush(); + if (FAILED( hr )) + return hr; + } + + return CBaseInputPin::BeginFlush(); +} + + +//-------------------------------------------------------------------------------- +// EndFlush: override to send message to all downstream pins + +HRESULT CFilterInputPin::EndFlush() +{ + CAutoLock autoLock(m_pLock); + HRESULT hr = NOERROR; + + if (m_pFilter->m_pinOutput.IsConnected()) + { + hr = m_pFilter->m_pinOutput.DeliverEndFlush(); + if (FAILED( hr )) + return hr; + } + + return CBaseInputPin::EndFlush(); +} + + +//-------------------------------------------------------------------------------- +// NewSegment: override to send message to all downstream pins + +HRESULT CFilterInputPin::NewSegment( REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate ) +{ + CAutoLock autoLock(m_pLock); + HRESULT hr = NOERROR; + + if (m_pFilter->m_pinOutput.IsConnected()) + { + hr = m_pFilter->m_pinOutput.DeliverNewSegment( tStart, tStop, dRate ); + if (FAILED( hr )) + return hr; + } + + return CBaseInputPin::NewSegment( tStart, tStop, dRate ); +} + + + +////////////////////////////////////////////////////////////////////////////////// +// CFilterOutputPin +////////////////////////////////////////////////////////////////////////////////// + +DWORD CFilterOutputPin::m_idNext = 1; + +//-------------------------------------------------------------------------------- +// Ctor + +CFilterOutputPin::CFilterOutputPin( TCHAR* pObjDesc, + CFilter* pFilter, + HRESULT* phr, + LPCWSTR pPinName ) : + CBaseOutputPin( pObjDesc, pFilter, pFilter, phr, pPinName ), + m_pFilter( pFilter ), + m_bInsideCheckMediaType( FALSE ), + m_id( 0 ), + m_pPosition( NULL ) +{ + m_id = m_idNext; + m_idNext++; +} + +CFilterOutputPin::~CFilterOutputPin() +{ + if (m_pPosition) + m_pPosition->Release(); + m_pPosition = NULL; +} + + +//-------------------------------------------------------------------------------- +// NonDelegatingQueryInterface - Overriden to expose IMediaPosition and +// IMediaSeeking control interfaces + +STDMETHODIMP CFilterOutputPin::NonDelegatingQueryInterface( REFIID riid, void**ppv ) +{ + CheckPointer( ppv, E_POINTER ); + ValidateReadWritePtr( ppv, sizeof(PVOID) ); + *ppv = NULL; + + if (riid == IID_IMediaPosition || riid == IID_IMediaSeeking) + { + // Create the interface now if we haven't yet + if (m_pPosition == NULL) + { + HRESULT hr = CreatePosPassThru( GetOwner(), FALSE, &m_pFilter->m_pinInput, &m_pPosition ); + if (FAILED( hr )) + return hr; + } + return m_pPosition->QueryInterface( riid, ppv ); + } + else + return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv); +} + + +//-------------------------------------------------------------------------------- +// DecideBufferSize +// +// Determine allocator properties for our output pin. +// This has to be present to override the PURE virtual class base function + +HRESULT CFilterOutputPin::DecideBufferSize( IMemAllocator* pAllocator, + ALLOCATOR_PROPERTIES* pProp ) +{ + HRESULT hr = S_OK; + + // Get properties from the input pin, if possible + if (m_pFilter->m_pinInput.IsConnected()) + { + IMemAllocator* pAlloc = NULL; + if (SUCCEEDED( m_pFilter->m_pinInput.GetAllocator( &pAlloc ) )) + { + pAlloc->GetProperties( pProp ); + pAlloc->Release(); + } + + // Ask for a larger buffer size if necessary + if (1 == m_pFilter->m_wfxIn.nChannels && 2 == m_pFilter->m_wfxOut.nChannels) + pProp->cbBuffer *= 2; + } + + // Set the allocator's properties + ALLOCATOR_PROPERTIES propActual; + hr = pAllocator->SetProperties( pProp, &propActual ); + if (SUCCEEDED( hr )) + *pProp = propActual; + + return hr; +} + + +//-------------------------------------------------------------------------------- +// EnumMediaTypes + +STDMETHODIMP CFilterOutputPin::EnumMediaTypes( IEnumMediaTypes** ppEnum ) +{ + CAutoLock autoLock(m_pLock); + ASSERT( ppEnum ); + + // Make sure that we are connected + if (!m_pFilter->m_pinInput.IsConnected()) + return VFW_E_NOT_CONNECTED; + + // We will simply return the enumerator of our input pin's peer + return m_pFilter->m_pinInput.m_Connected->EnumMediaTypes(ppEnum); +} + + +//-------------------------------------------------------------------------------- +// CheckMediaType + +HRESULT CFilterOutputPin::CheckMediaType( const CMediaType* pmt ) +{ + CAutoLock autoLock(m_pLock); + + // If we are already inside checkmedia type for this pin, return NOERROR + // It is possble to hookup two of these filters and some other filter + // like the video effects sample to get into this situation. If we + // do not detect this, we will loop till we blow the stack + + if (m_bInsideCheckMediaType) + return NOERROR; + + m_bInsideCheckMediaType = TRUE; + + HRESULT hr = NOERROR; + + // See if the wave format is supported + hr = m_pFilter->CheckMediaType( PINDIR_OUTPUT, pmt ); + if (S_OK != hr) + { + m_bInsideCheckMediaType = FALSE; + return hr; + } + + // The input needs to have been connected first + if (!m_pFilter->m_pinInput.IsConnected()) + { + m_bInsideCheckMediaType = FALSE; + return VFW_E_NOT_CONNECTED; + } + + // Make sure we can transform from one type to the other + const CMediaType& mtIn = m_pFilter->m_pinInput.CurrentMediaType(); + hr = m_pFilter->CheckTransform( &mtIn, pmt ); + if (FAILED( hr )) + { + m_bInsideCheckMediaType = FALSE; + return VFW_E_TYPE_NOT_ACCEPTED; + } + + m_bInsideCheckMediaType = FALSE; + return NOERROR; +} + + +//-------------------------------------------------------------------------------- +// GetMediaType - get the media type supported by this pin + +HRESULT CFilterOutputPin::GetMediaType( int iPosition, CMediaType* pmt ) +{ + // We don't have any media types if our input is not connected + if (m_pFilter->m_pinInput.IsConnected()) + { + return m_pFilter->GetMediaType( iPosition, pmt ); + } + else + { + return VFW_S_NO_MORE_ITEMS; + } +} + + +//-------------------------------------------------------------------------------- +// SetMediaType + +HRESULT CFilterOutputPin::SetMediaType( const CMediaType* pmt ) +{ + CAutoLock autoLock(m_pLock); + + // Make sure that we have an input connected + if (!m_pFilter->m_pinInput.IsConnected()) + return VFW_E_NOT_CONNECTED; + + // Make sure that the base class likes it + HRESULT hr = CBaseOutputPin::SetMediaType( pmt ); + if (FAILED( hr )) + return hr; + + // Make sure the plug-in likes it + return m_pFilter->SetMediaType( PINDIR_OUTPUT, pmt ); +} diff --git a/Src/Plugins/DSP/dsp_sps/dxi/Filter.h b/Src/Plugins/DSP/dsp_sps/dxi/Filter.h new file mode 100644 index 00000000..a101742b --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/Filter.h @@ -0,0 +1,176 @@ +#ifndef _FILTER_H_ +#define _FILTER_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "DXi.h" +#include "AudioPlugIn.h" + +class CFilter; +class CFilterOutputPin; +class CFilterInputPin; + +//-------------------------------------------------------------------------------- + +class CFilterInputPin : public CBaseInputPin +{ + friend class CFilter; + friend class CFilterOutputPin; + +public: + // Ctor + CFilterInputPin( TCHAR* pObjDesc, CFilter* pFilter, HRESULT* phr, LPCWSTR pPinName ); + + // Check that we can support this output type + HRESULT CheckMediaType( const CMediaType* pmtIn ); + + // Set the connection media type + HRESULT SetMediaType( const CMediaType* pmt ); + + // Negotiate possible reconnection if types don't match + HRESULT CompleteConnect( IPin* pRecievePin ); + + // What is our media type? + CMediaType& CurrentMediaType() { return m_mt; }; + + // Pass through calls downstream + STDMETHODIMP EndOfStream(); + STDMETHODIMP BeginFlush(); + STDMETHODIMP EndFlush(); + STDMETHODIMP NewSegment( REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate ); + + // Handles the next block of data from the stream + STDMETHODIMP Receive( IMediaSample *pms ); + +// Implementation +private: + CFilter* m_pFilter; // the filter which owns us + BOOL m_bInsideCheckMediaType; // re-entrancy control +}; + +//-------------------------------------------------------------------------------- + +class CFilterOutputPin : public CBaseOutputPin +{ + friend class CFilter; + friend class CFilterInputPin; + +public: + + // Ctors + CFilterOutputPin( TCHAR* pObjDesc, CFilter* pFilter, HRESULT* phr, LPCWSTR pPinName ); + virtual ~CFilterOutputPin(); + + DECLARE_IUNKNOWN; + + // Override to expose IMediaPosition + STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); + + // Override to enumerate media types + STDMETHODIMP EnumMediaTypes( IEnumMediaTypes** ppEnum ); + + // Check that we can support an output type + HRESULT CheckMediaType( const CMediaType* pmt ); + HRESULT SetMediaType( const CMediaType* pmt ); + HRESULT GetMediaType( int iPosition, CMediaType* pmt ); + + // What is our media type? + CMediaType& CurrentMediaType() { return m_mt; }; + + // Negotiation to use our input pins allocator + HRESULT DecideBufferSize( IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProp ); + + // Get the unique identifier for this output pin + DWORD GetId() const { return m_id; } + +// Implementation +private: + CFilter* m_pFilter; // the filter which owns us + BOOL m_bInsideCheckMediaType; // re-entrancy control + DWORD m_id; // unique identifier + IUnknown* m_pPosition; + + static DWORD m_idNext; +}; + +//-------------------------------------------------------------------------------- + +class CFilter : + public CAudioPlugIn, + + public CBaseFilter, + public ISpecifyPropertyPages, + public IDispatch, + public CPersistStream +{ + friend class CFilterInputPin; + friend class CFilterOutputPin; + +public: + + // Ctors + CFilter( TCHAR *pName, LPUNKNOWN pUnk, HRESULT* phr ); + ~CFilter(); + + // Function needed for the class factory + static CUnknown * WINAPI CreateInstance( LPUNKNOWN pUnk, HRESULT* phr ); + + DECLARE_IUNKNOWN; + + STDMETHODIMP NonDelegatingQueryInterface( REFIID riid, void** ppv ); + + LPAMOVIESETUP_FILTER GetSetupData(); + + // CBaseFilter pure virtual overrides + CBasePin* GetPin( int n ); + int GetPinCount(); + + // Overrides to deal with not having input connections + STDMETHODIMP Run( REFERENCE_TIME tStart ); + STDMETHODIMP Pause(); + STDMETHODIMP Stop(); + + // Helpers for media type checking + HRESULT CheckMediaType( PIN_DIRECTION direction, const CMediaType* pmt ); + HRESULT CheckTransform( const CMediaType* pmtIn, const CMediaType* pmtOut ); + HRESULT GetMediaType( int iPosition, CMediaType* pmt ); + HRESULT SetMediaType( PIN_DIRECTION direction, const CMediaType* pmt ); + + // ISpecifyPropertyPages + STDMETHODIMP GetPages( CAUUID* pPages ); + + // CPersistStream + STDMETHODIMP GetClassID(CLSID* pClsid); + int SizeMax(); + HRESULT WriteToStream(IStream* pStream); + HRESULT ReadFromStream(IStream* pStream); + + // IDispatch + STDMETHODIMP GetTypeInfoCount( UINT* ); + STDMETHODIMP GetTypeInfo( UINT, LCID, ITypeInfo** ); + STDMETHODIMP GetIDsOfNames( REFIID, OLECHAR**, UINT, LCID, DISPID* ); + STDMETHODIMP Invoke( DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT* ); + +// Implementation +private: + + HRESULT getOutputBuffer( CFilterOutputPin* pPin, + AudioBuffer* pbufOut, + REFERENCE_TIME* prtStart, + BOOL bSyncPoint, BOOL bDiscontuity, BOOL bPreroll ); + HRESULT deliverOutputBuffer( CFilterOutputPin* pPin, + AudioBuffer* abufOut, + HRESULT hrProcess, BOOL bCleanup ); + + HRESULT audioPortsChangeBegin( int nNewPinCount ); + HRESULT audioPortsChangeEnd( int nNewPinCount ); + + CFilterInputPin m_pinInput; + CFilterOutputPin m_pinOutput; + IMemAllocator* m_pAllocator; + LONGLONG m_llSamplePosition; +}; + +#endif // _FILTER_H_ diff --git a/Src/Plugins/DSP/dsp_sps/dxi/MediaParams.cpp b/Src/Plugins/DSP/dsp_sps/dxi/MediaParams.cpp new file mode 100644 index 00000000..43fc4743 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/MediaParams.cpp @@ -0,0 +1,465 @@ +// MediaParams.cpp: implementation of the CMediaParams class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "AudioPlugIn.h" +#include "MediaParams.h" +#include "ParamEnvelope.h" + +#include "CakeMedParam_i.c" + +#define DEFINE_PARAM_INFO +#include "Parameters.h" + +////////////////////////////////////////////////////////////////////// +// Ctors + +CMediaParams::CMediaParams( IUnknown* pUnkOuter ) : m_pUnkOuter(pUnkOuter) +{ + m_pCallback = NULL; + m_cRef = 0; + m_aEnv = NULL; + m_dDecimationInterval = 20.0 / 1000.0; // 20 msec + m_lFs = 44100; +} + +CMediaParams::~CMediaParams() +{ + ASSERT( 0 == m_cRef ); + if (m_pCallback) + m_pCallback->Release(); + m_pCallback = NULL; + m_pUnkOuter = NULL; + + delete [] m_aEnv; + m_aEnv = NULL; +} + + +////////////////////////////////////////////////////////////////////// +// Factory-style construction + +HRESULT CMediaParams::Create( CMediaParams** ppObj, IUnknown* pUnkOuter ) +{ + if (NULL == ppObj) + return E_POINTER; + if (NULL == pUnkOuter) + return E_POINTER; + + // Construct the CMediaParams object + CMediaParams* pNew = new CMediaParams( pUnkOuter ); + if (NULL == pNew) + return E_OUTOFMEMORY; + + // Construct and initialize its parameters + pNew->m_aEnv = new CParamEnvelope [ NUM_PARAMS ]; + if (NULL == pNew->m_aEnv) + return E_OUTOFMEMORY; + for (ULONG ix = 0; ix < NUM_PARAMS; ++ix) + pNew->m_aEnv[ ix ].SetParamInfo( m_aParamInfo[ ix ] ); + + pNew->AddRef(); + *ppObj = pNew; + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////////////// +// Given a sample range, fills pTimes with sample positions where we need +// to recompute one or more automated parameter values. Positions are always +// added periodically at the decimation interval; positions are also added +// for every segment boundary among all of the parameters. + +HRESULT CMediaParams::GetDecimationTimes( LONGLONG llSampStart, + LONGLONG llSampEnd, + std::vector<LONGLONG>* pTimes ) +{ + LONGLONG const llInterval = static_cast<LONGLONG>( GetDecimationInterval() * GetSampleRate() ); + double const dSamplesPerRefTime = static_cast<double>( GetSampleRate() ) / UNITS; + REFERENCE_TIME const rtStart = REFERENCE_TIME( llSampStart / dSamplesPerRefTime + 0.5 ); + + // Make an worst-case guess at how many decimation points we'll need + ULONG uPoints = 0; + for (DWORD dwParam = 0; dwParam < NUM_AUTOMATED_PARAMS; dwParam++) + { + const CParamEnvelope& env = m_aEnv[ dwParam ]; + uPoints += env.GetCount() * 2; + } + + // If there is no automation, then there is no need to decimate + if (0 == uPoints) + return S_OK; + + // Account for points that are added due to periodic decimation + uPoints += ULONG( ((llSampEnd - llSampStart) / llInterval) + 1 ); + + // Reserve some memory for landmark points + pTimes->reserve( uPoints ); + + // Add periodic landmarks at the decimation interval + LONGLONG llSamp = (llSampStart / llInterval) * llInterval; + if (llSamp < llSampStart) + llSamp += llInterval; + while (llSamp < llSampEnd) + { + pTimes->push_back( llSamp ); + llSamp += llInterval; + } + + // Add landmarks for each shape boundary + for (dwParam = 0; dwParam < NUM_AUTOMATED_PARAMS; dwParam++) + { + const CParamEnvelope& env = m_aEnv[ dwParam ]; + unsigned const nCount = env.GetCount(); + + // Add each shape endpoint that falls in our time range + for (unsigned ix = 0; ix < nCount; ix++) + { + const MP_ENVELOPE_SEGMENT& seg = env.GetAt( ix ); + LONGLONG const llEnvStart = static_cast<LONGLONG>( seg.rtStart * dSamplesPerRefTime + 0.5 ); + LONGLONG const llEnvEnd = static_cast<LONGLONG>( seg.rtEnd * dSamplesPerRefTime + 0.5 ); + if (llSampStart <= llEnvStart && llEnvStart < llSampEnd) + pTimes->push_back( llEnvStart ); + if (llSampStart <= llEnvEnd && llEnvEnd < llSampEnd) + pTimes->push_back( llEnvEnd ); + } + } + + // Sort result + std::sort( pTimes->begin(), pTimes->end() ); + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// Set the current position among all parameters, updating current envelope +// value and deltas. This method is called repeatedly by the streaming code, +// to update parameter values as they evolve along the duration of the envelope. + +HRESULT CMediaParams::UpdateValuesForSample( LONGLONG llSamp ) +{ + double const dSamplesPerRefTime = static_cast<double>( GetSampleRate() ) / UNITS; + REFERENCE_TIME const rt = REFERENCE_TIME( llSamp / dSamplesPerRefTime + 0.5 ); + + HRESULT hr = S_OK; + for (DWORD dwParam = 0; dwParam < NUM_AUTOMATED_PARAMS; dwParam++) + { + hr = m_aEnv[ dwParam ].UpdateValuesForRefTime( rt, GetSampleRate() ); + if (FAILED( hr )) + break; + } + + return hr; +} + + +//////////////////////////////////////////////////////////////////////////////// +// IUnknown + +HRESULT CMediaParams::QueryInterface( REFIID riid, void** ppv ) +{ + if (NULL == ppv) + return E_POINTER; + + if (riid == IID_IUnknown) + { + *ppv = static_cast<IUnknown*>( static_cast<IMediaParams*>( this ) ); + m_pUnkOuter->AddRef(); + return S_OK; + } + else + { + return m_pUnkOuter->QueryInterface( riid, ppv ); + } +} + +ULONG CMediaParams::AddRef() +{ + return InterlockedIncrement( &m_cRef ); +} + +ULONG CMediaParams::Release() +{ + ASSERT( m_cRef > 0 ); + ULONG ul = InterlockedDecrement( &m_cRef ); + if (0 == ul) + { + delete this; + return 0; + } + else + return ul; +} + + +//////////////////////////////////////////////////////////////////////////////// +// IMediaParams + +HRESULT CMediaParams::GetParam(ULONG dwParamIndex, FLOAT* pValue) +{ + if (dwParamIndex >= NUM_PARAMS) + return E_INVALIDARG; + if (NULL == pValue) + return E_POINTER; + + return m_aEnv[ dwParamIndex ].GetParam( pValue ); +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CMediaParams::SetParam(ULONG dwParamIndex, FLOAT value) +{ + if (dwParamIndex >= NUM_PARAMS) + return E_INVALIDARG; + + return m_aEnv[ dwParamIndex ].SetParam( value ); +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CMediaParams::AddEnvelope(ULONG dwParamIndex, ULONG cSegments, MP_ENVELOPE_SEGMENT* pmpes) +{ + if (dwParamIndex >= NUM_AUTOMATED_PARAMS && dwParamIndex != DWORD_ALLPARAMS) + return E_INVALIDARG; + if (0 == cSegments) + return S_OK; + if (IsBadReadPtr( pmpes, cSegments * sizeof(MP_ENVELOPE_SEGMENT) )) + return E_POINTER; + + double const dSamplesPerRefTime = static_cast<double>( GetSampleRate() ) / UNITS; + + if (dwParamIndex == DWORD_ALLPARAMS) + { + for (ULONG ix = 0; ix < NUM_AUTOMATED_PARAMS; ix++) + { + HRESULT hr = m_aEnv[ ix ].AddEnvelope( cSegments, pmpes, dSamplesPerRefTime ); + if (FAILED( hr )) + return hr; + } + return S_OK; + } + else + { + return m_aEnv[ dwParamIndex ].AddEnvelope( cSegments, pmpes, dSamplesPerRefTime ); + } +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CMediaParams::FlushEnvelope(ULONG dwParamIndex, REFERENCE_TIME rtStart, REFERENCE_TIME rtEnd) +{ + if (dwParamIndex >= NUM_AUTOMATED_PARAMS && dwParamIndex != DWORD_ALLPARAMS) + return E_INVALIDARG; + if (rtStart > rtEnd) + return E_INVALIDARG; + + double const dSamplesPerRefTime = static_cast<double>( GetSampleRate() ) / UNITS; + + if (dwParamIndex == DWORD_ALLPARAMS) + { + for (ULONG ix = 0; ix < NUM_AUTOMATED_PARAMS; ix++) + { + HRESULT hr = m_aEnv[ ix ].FlushEnvelope( rtStart, rtEnd, dSamplesPerRefTime ); + if (FAILED( hr )) + return hr; + } + return S_OK; + } + else + { + HRESULT hr = m_aEnv[ dwParamIndex ].FlushEnvelope( rtStart, rtEnd, dSamplesPerRefTime ); + if (FAILED( hr )) + return hr; + } + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CMediaParams::SetTimeFormat(GUID guidTimeFormat, ULONG mpTimeData) +{ + if (guidTimeFormat != GUID_TIME_REFERENCE) + return E_INVALIDARG; + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////////////// +// IMediaParamInfo + +HRESULT CMediaParams::GetParamCount(ULONG* pdwParams) +{ + if (NULL == pdwParams) + return E_POINTER; + + *pdwParams = NUM_AUTOMATED_PARAMS; + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CMediaParams::GetParamInfo(ULONG dwParamIndex, MP_PARAMINFO* pInfo) +{ + if (dwParamIndex >= NUM_AUTOMATED_PARAMS) + return E_INVALIDARG; + if (IsBadWritePtr( pInfo, sizeof(MP_PARAMINFO) )) + return E_POINTER; + + *pInfo = m_aParamInfo[ dwParamIndex ].mppi; + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CMediaParams::GetParamText(ULONG dwParamIndex, WCHAR** ppwchText) +{ + if (dwParamIndex >= NUM_AUTOMATED_PARAMS) + return E_INVALIDARG; + if (NULL == ppwchText) + return E_POINTER; + + const ParamInfo& info = m_aParamInfo[ dwParamIndex ]; + const MP_PARAMINFO& mppi = info.mppi; + + // Count up lengths of label and unit strings, plus null terminators + int cch = wcslen(mppi.szLabel) + wcslen(mppi.szUnitText) + 3; + + // Add in length of the enum. text if any was supplied + if (NULL != info.pwszEnumText) + cch += wcslen(info.pwszEnumText) + 1; + + // Allocate memory for the returned string + *ppwchText = (WCHAR*)CoTaskMemAlloc( sizeof(WCHAR) * cch ); + if (NULL == *ppwchText) + return E_OUTOFMEMORY; + + // Text format is "Name\0Units\0Enum1\0Enum2\0...EnumN\0\0" + WCHAR* pwsz = *ppwchText; + + // [1] Copy in the name + wcscpy( pwsz, mppi.szLabel ); + pwsz += wcslen(mppi.szLabel) + 1; + + // [2] Copy in the units + wcscpy( pwsz, mppi.szUnitText ); + pwsz += wcslen(mppi.szUnitText) + 1; + + // [3] Copy in the enum. text, if any was supplied + if (NULL != info.pwszEnumText) + { + wcscpy( pwsz, info.pwszEnumText ); + + // Replace commas with nulls, to conform to DX8 string format spec + while (*pwsz) + { + if (*pwsz == L',') + *pwsz = 0; + pwsz++; + } + } + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CMediaParams::GetNumTimeFormats(ULONG* pdwNumTimeFormats) +{ + if (NULL == pdwNumTimeFormats) + return E_POINTER; + *pdwNumTimeFormats = 1; + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CMediaParams::GetSupportedTimeFormat(ULONG dwFormatIndex, GUID* pguidTimeFormat) +{ + if (NULL == pguidTimeFormat) + return E_POINTER; + if (0 != dwFormatIndex) + return E_INVALIDARG; + *pguidTimeFormat = GUID_TIME_REFERENCE; + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT CMediaParams::GetCurrentTimeFormat(GUID* pguidTimeFormat, ULONG*) +{ + if (NULL == pguidTimeFormat) + return E_POINTER; + *pguidTimeFormat = GUID_TIME_REFERENCE; + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////////////// +// IMediaParamsSetUICallback + +HRESULT CMediaParams::SetUICallback(IMediaParamsUICallback* pICallback) +{ + if (pICallback) + pICallback->AddRef(); + if (m_pCallback) + m_pCallback->Release(); + m_pCallback = pICallback; + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////////////// +// IMediaParamsUICallback + +HRESULT CMediaParams::ParamsBeginCapture(DWORD *aIndex, DWORD cPoints) +{ + HRESULT hr = S_OK; + + // Inform each parameter that capture has begun + for (DWORD ix = 0; ix < cPoints; ix++) + m_aEnv[ aIndex[ ix ] ].BeginCapture(); + + if (m_pCallback) + hr = m_pCallback->ParamsBeginCapture( aIndex, cPoints ); + + return hr; +} + +HRESULT CMediaParams::ParamsChanged(DWORD *aIndex, DWORD cPoints, MP_DATA *paData) +{ + HRESULT hr = S_OK; + + // Send the parameter change to each parameter + for (DWORD ix = 0; ix < cPoints; ix++) + { + hr = SetParam( aIndex[ ix ], paData[ ix ] ); + if (FAILED( hr )) + return hr; + } + + // Send the parameter change to our callback + if (m_pCallback) + hr = m_pCallback->ParamsChanged( aIndex, cPoints, paData ); + + return hr; +} + +HRESULT CMediaParams::ParamsEndCapture(DWORD *aIndex, DWORD cPoints) +{ + HRESULT hr = S_OK; + + // Inform each parameter that capture has ended + for (DWORD ix = 0; ix < cPoints; ix++) + m_aEnv[ aIndex[ ix ] ].EndCapture(); + + if (m_pCallback) + hr = m_pCallback->ParamsEndCapture( aIndex, cPoints ); + + return hr; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/Src/Plugins/DSP/dsp_sps/dxi/MediaParams.h b/Src/Plugins/DSP/dsp_sps/dxi/MediaParams.h new file mode 100644 index 00000000..947399f6 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/MediaParams.h @@ -0,0 +1,99 @@ +// MediaParams.h: interface for the CMediaParams class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MEDIAPARAMS_H__3DB99F00_3887_4C35_BBA8_C47835777A69__INCLUDED_) +#define AFX_MEDIAPARAMS_H__3DB99F00_3887_4C35_BBA8_C47835777A69__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include <MedParam.h> // DX8 automation +#include "CakeMedParam.h" // DX8 automation + +#include "ParamEnvelope.h" +#include "Parameters.h" + +//////////////////////////////////////////////////////////////////////////////// + +class CMediaParams : + public IMediaParams, + public IMediaParamInfo, + public IMediaParamsSetUICallback, + public IMediaParamsUICallback +{ +public: + + static HRESULT Create( CMediaParams** ppObj, IUnknown* pUnkOuter ); + +public: + + // IUnknown + STDMETHOD(QueryInterface)( REFIID riid, void** ppv ); + STDMETHODIMP_(ULONG) AddRef(); + STDMETHODIMP_(ULONG) Release(); + + // IMediaParams + STDMETHOD(GetParam)(ULONG dwParamIndex, FLOAT* pValue); + STDMETHOD(SetParam)(ULONG dwParamIndex, FLOAT value); + STDMETHOD(AddEnvelope)(ULONG dwParamIndex, ULONG cSegments, MP_ENVELOPE_SEGMENT* pEnvelopeSegments); + STDMETHOD(FlushEnvelope)(ULONG dwParamIndex, REFERENCE_TIME refTimeStart, REFERENCE_TIME refTimeEnd); + STDMETHOD(SetTimeFormat)(GUID guidTimeFormat, ULONG mpTimeData); + + // IMediaParamInfo + STDMETHOD(GetParamCount)(ULONG* pdwParams); + STDMETHOD(GetParamInfo)(ULONG dwParamIndex, MP_PARAMINFO* pInfo); + STDMETHOD(GetParamText)(ULONG dwParamIndex, WCHAR** ppwchText); + STDMETHOD(GetNumTimeFormats)(ULONG* pdwNumTimeFormats); + STDMETHOD(GetSupportedTimeFormat)(ULONG dwFormatIndex, GUID* pguidTimeFormat); + STDMETHOD(GetCurrentTimeFormat)(GUID* pguidTimeFormat, ULONG* pTimeData); + + // IMediaParamsSetUICallback + STDMETHOD(SetUICallback)(IMediaParamsUICallback* pICallback); + + // IMediaParamsUICallback + STDMETHOD(ParamsBeginCapture)(DWORD *aIndex, DWORD cPoints); + STDMETHOD(ParamsChanged)(DWORD *aIndex, DWORD cPoints, MP_DATA *paData); + STDMETHOD(ParamsEndCapture)(DWORD *aIndex, DWORD cPoints); + + // Helpers for setting the current sample rate + void SetSampleRate( long lFs ) { m_lFs = lFs; } + long GetSampleRate() const { return m_lFs; } + + // Helpers to decimate shapes into smaller chunks + HRESULT GetDecimationTimes( LONGLONG llSampStart, LONGLONG llSampEnd, std::vector<LONGLONG>* pTimes ); + void SetDecimationInterval( double d ) { m_dDecimationInterval = d; } + double GetDecimationInterval() const { return m_dDecimationInterval; } + + // Set our position among all parameter segments, updating current values, and + // flushing any out-of-date segments. + HRESULT UpdateValuesForSample( LONGLONG llSamp ); + + // Get the envelope for a given parameter + const CParamEnvelope& GetParamEnvelope( DWORD ix ) + { + ASSERT( ix >= 0 && ix < NUM_PARAMS ); + return m_aEnv[ ix ]; + } + +private: + + IUnknown* m_pUnkOuter; + IMediaParamsUICallback* m_pCallback; + LONG m_cRef; + CParamEnvelope* m_aEnv; + double m_dDecimationInterval; + long m_lFs; + +private: + + static const ParamInfo m_aParamInfo[ NUM_PARAMS ]; + +private: + + CMediaParams( IUnknown* pUnkOuter ); + virtual ~CMediaParams(); +}; + +#endif // !defined(AFX_MEDIAPARAMS_H__3DB99F00_3887_4C35_BBA8_C47835777A69__INCLUDED_) diff --git a/Src/Plugins/DSP/dsp_sps/dxi/ParamEnvelope.cpp b/Src/Plugins/DSP/dsp_sps/dxi/ParamEnvelope.cpp new file mode 100644 index 00000000..923496bb --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/ParamEnvelope.cpp @@ -0,0 +1,403 @@ +// ParamEnvelope.cpp: implementation of the CParamEnvelope class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "AudioPlugIn.h" +#include "ParamEnvelope.h" + +#include <math.h> + +//////////////////////////////////////////////////////////////////////////////// +// ParamInfo +//////////////////////////////////////////////////////////////////////////////// + +float ParamInfo::MapToInternal( float fValue ) const +{ + // Convert a user-supplied parameter value to one that is for internal + // use by the plug-in's processing code. + + if (MPT_FLOAT == mppi.mpType) + { + // Map floats to the internal range, using a linear mapping + double dDelta = (fValue - mppi.mpdMinValue) / (mppi.mpdMaxValue - mppi.mpdMinValue); + return float( fInternalMin + dDelta * (fInternalMax - fInternalMin) ); + } + else if (MPT_BOOL == mppi.mpType) + { + // Map booleans to 0.0 or 1.0 + return float( (fValue < 0.5) ? MPBOOL_FALSE : MPBOOL_TRUE ); + } + else // (MPT_ENUM == mppi.mpType || MPT_INT == mppi.mpType) + { + // Map integers to the internal range, using a linear mapping, and then + // round to the nearest value. + double dDelta = (fValue - mppi.mpdMinValue) / (mppi.mpdMaxValue - mppi.mpdMinValue); + double dMapped = fInternalMin + dDelta * (fInternalMax - fInternalMin); + return static_cast<float>( floor( dMapped + 0.5 ) ); + } +} + +//////////////////////////////////////////////////////////////////////////////// + +float ParamInfo::MapToExternal( float fValue ) const +{ + // Convert an internal processing value to value in the user's input range + + if (MPT_FLOAT == mppi.mpType) + { + // Map floats to the external range, using a linear mapping + double dDelta = (fValue - fInternalMin) / (fInternalMax - fInternalMin); + return float( mppi.mpdMinValue + dDelta * (mppi.mpdMaxValue - mppi.mpdMinValue) ); + } + else if (MPT_BOOL == mppi.mpType) + { + // Booleans are already in a suitable range; no mapping required. + return fValue; + } + else // (MPT_ENUM == mppi.mpType || MPT_INT == mppi.mpType) + { + // Map integers to the external range, using a linear mapping + double dDelta = (fValue - fInternalMin) / (fInternalMax - fInternalMin); + return float( mppi.mpdMinValue + dDelta * (mppi.mpdMaxValue - mppi.mpdMinValue) ); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// CParamEnvelope +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------ +// Ctors + +CParamEnvelope::CParamEnvelope() : + m_bOverride( FALSE ), + m_bCaptured( FALSE ), + m_fOverrideValue( 0 ), + m_fEnvelopeValue( 0 ), + m_dEnvelopeDelta1( 0 ), + m_dEnvelopeDelta2( 0 ), + m_bValidDeltas( TRUE ), + m_rtRendered( 0 ) +{ +} + +CParamEnvelope::~CParamEnvelope() +{ +} + + +//---------------------------------------------------------------------------- +// Phase 2 of construction + +void CParamEnvelope::SetParamInfo( const ParamInfo& info ) +{ + m_info = info; + m_fEnvelopeValue = m_info.MapToInternal( m_info.mppi.mpdNeutralValue ); + cleanup(); +} + + +//---------------------------------------------------------------------------- +// Find the index for data on or after rt + +int CParamEnvelope::IndexForRefTime( REFERENCE_TIME rt ) const +{ + CAutoLock lock( const_cast<CParamEnvelope*>( this ) ); + + int const nLength = GetCount(); + + // Fail gracefully if the list is empty + if (0 == nLength) + return -1; + + // Special case for position after the last segment + if (rt >= m_envSegs[ nLength - 1 ].rtEnd) + return nLength - 1; + + int ixMin = 0; + int ixMax = nLength; + int ix = ( ixMin + ixMax ) / 2; + + // Binary search for the shape which starts on or before the given time + do + { + REFERENCE_TIME rtShape = m_envSegs[ ix ].rtStart; + + // We've made an exact match + if (rtShape == rt) + return ix; + + // No match was found, so update search indices + else if (rt < rtShape) + ixMax = ix; + else if (rt > rtShape) + ixMin = ix; + ix = (ixMin + ixMax) / 2; + } + while (ix != ixMin); + + // The search may have left us at a shape after the desired time, so + // scan back if necessary + while (ix >= 0 && m_envSegs[ ix ].rtStart > rt) + --ix; + + return ix; +} + + +//------------------------------------------------------------------------------ +// Set the current position, updating current envelope value and deltas. This +// method is called repeatedly by the streaming code, to update parameter values +// as they evolve along the duration of the envelope. + +HRESULT CParamEnvelope::UpdateValuesForRefTime( REFERENCE_TIME rt, long lSampleRate ) +{ + CAutoLock lock( this ); + + int const nLength = GetCount(); + if (0 == nLength) + return S_OK; // nothing to do + + int const ix = IndexForRefTime( rt ); + const MP_ENVELOPE_SEGMENT* pmpseg = (ix < 0 || ix >= nLength) ? NULL : &m_envSegs[ ix ]; + + // Assume deltas are valid. We'll make them invalid if we encounter a SIN curve. + m_bValidDeltas = TRUE; + + if (NULL == pmpseg || rt < pmpseg->rtStart || rt > pmpseg->rtEnd) + { + // The seek position is between 2 segments, so do not modify the current envelope + // value. The envelope will either latch the previous value, or continue to obey + // any intervening override value, until we hit the next segment boundary. + if (NULL != pmpseg) + m_fEnvelopeValue = m_info.MapToInternal( pmpseg->valEnd ); + m_dEnvelopeDelta1 = m_dEnvelopeDelta2 = 0; + } + else + { + // We're dealing with point directly over a shape. Stop any override value. + stopOverride(); + + // Compute the time delta between this vector and the next, as value + // between 0..1. We use to interpolate between points. + double dx = double(pmpseg->rtEnd - pmpseg->rtStart) / UNITS; + double y0 = m_info.MapToInternal( pmpseg->valStart ); + double y1 = m_info.MapToInternal( pmpseg->valEnd ); + double dy = y1 - y0; + double x = (double(rt - pmpseg->rtStart) / UNITS) / dx; + + // Convert dx to units per sample, before computing deltas + dx = dx * lSampleRate; + + // Interpolate between times + if (MP_CURVE_JUMP == pmpseg->iCurve) + { + m_dEnvelopeDelta2 = 0; + m_dEnvelopeDelta1 = 0; + m_fEnvelopeValue = static_cast<float>( y0 ); + } + else if (MP_CURVE_LINEAR == pmpseg->iCurve) + { + m_dEnvelopeDelta2 = 0; + m_dEnvelopeDelta1 = dy / dx; + m_fEnvelopeValue = static_cast<float>( y0 + dy * x ); + } + else if (MP_CURVE_SQUARE == pmpseg->iCurve || MP_CURVE_INVSQUARE == pmpseg->iCurve) + { + double A; + double B; + if (MP_CURVE_SQUARE == pmpseg->iCurve) + { + A = y0; + B = dy; + } + else + { + x = x - 1; + A = y1; + B = -dy; + } + + m_dEnvelopeDelta2 = 2.0 * B / (dx * dx); + m_dEnvelopeDelta1 = (B / dx) * (2.0 * x + (1.0 / dx)); + m_fEnvelopeValue = static_cast<float>( A + B * x * x ); + } + else if (MP_CURVE_SINE) + { + static const double dPI = 3.14159265358979323846264338327950288419716939937510; + double dTheta = dPI * (x - 0.5); + m_bValidDeltas = FALSE; + m_fEnvelopeValue = float( dy * ( sin( dTheta ) + 0.5 ) ); + } + } + + // Keep track of the latest time rendered so far + m_rtRendered = max( m_rtRendered, rt ); + + return S_OK; +} + + +//------------------------------------------------------------------------------ +// If the list is empty, make sure we get an override value. + +void CParamEnvelope::cleanup() +{ + if (0 == GetCount() && !IsOverrideActive()) + { + m_fOverrideValue = m_fEnvelopeValue; + m_bOverride = TRUE; + } +} + + +//--------------------------------------------------------------------------- +// Set the value of our parameter, overriding any segment in effect. + +HRESULT CParamEnvelope::SetParam( float fValue ) +{ + m_bOverride = TRUE; + m_fOverrideValue = m_info.MapToInternal( fValue ); + m_fEnvelopeValue = m_fOverrideValue; + m_dEnvelopeDelta1 = m_dEnvelopeDelta2 = 0; + return S_OK; +} + + +//------------------------------------------------------------------------------ +// Get the value of the parameter, either overriden on an a segment + +HRESULT CParamEnvelope::GetParam( float* pfValue ) +{ + if (NULL == pfValue) + return E_POINTER; + *pfValue = m_info.MapToExternal( GetCurrentValue() ); + return S_OK; +} + + +//------------------------------------------------------------------------------ +// Add segments to this envelope + +static bool compareEnvSeg( const MP_ENVELOPE_SEGMENT& a, const MP_ENVELOPE_SEGMENT& b ) +{ + return a.rtStart < b.rtStart; +} + +static bool operator==( const MP_ENVELOPE_SEGMENT& a, const MP_ENVELOPE_SEGMENT& b ) +{ + return 0 == memicmp( &a, &b, sizeof(MP_ENVELOPE_SEGMENT) ); +} + +HRESULT CParamEnvelope::AddEnvelope( DWORD cSegments, MP_ENVELOPE_SEGMENT* pmpes, double dSamplesPerRefTime ) +{ + CAutoLock lock( this ); + + // Make room for what we are going to add + m_envSegs.reserve( m_envSegs.size() + cSegments ); + + // Add each segment, noting which one is earliest in time + REFERENCE_TIME rtMin = _I64_MAX; + for (int ix = 0; ix < cSegments; ix++) + { + // Round reference times to sample boundaries + MP_ENVELOPE_SEGMENT mpes = pmpes[ ix ]; + mpes.rtStart = REFERENCE_TIME(mpes.rtStart * dSamplesPerRefTime) / dSamplesPerRefTime + 0.5; + mpes.rtEnd = REFERENCE_TIME(mpes.rtEnd * dSamplesPerRefTime) / dSamplesPerRefTime + 0.5; + m_envSegs.push_back( pmpes[ ix ] ); + if (mpes.rtStart < rtMin) + rtMin = mpes.rtStart; + } + + // Flush all segments prior to the first newly added one + ix = IndexForRefTime( rtMin ); + if (ix > 0 && rtMin < m_rtRendered) + m_envSegs.erase( m_envSegs.begin(), m_envSegs.begin() + ix ); + + // Sort them + std::sort( m_envSegs.begin(), m_envSegs.end(), compareEnvSeg ); + + // Remove duplicates + EnvelopeSegs::iterator it = m_envSegs.begin(); + while (it != m_envSegs.end()) + { + EnvelopeSegs::iterator itBegin = it + 1; + EnvelopeSegs::iterator itEnd = itBegin; + while (itEnd != m_envSegs.end() && *itEnd == *it) + itEnd++; + if (itEnd != itBegin) + it = m_envSegs.erase( itBegin, itEnd ); + else + it++; + + } + + return S_OK; +} + + +//------------------------------------------------------------------------------ +// Flush segments within the specified time range. The rules for flushing are +// described as follows in the documentation for IMediaParams: +// +// If the time span specified by refTimeStart and refTimeEnd overlaps an envelope +// segment, the entire segment is flushed. On the other hand, if it falls on +// the boundary of an envelope segment, the entire segment is retained. Thus: +// +// [] If the start time falls inside an envelope segment, the segment is flushed. +// [] If the end time falls inside an envelope segment, the segment is flushed. +// [] If the start time equals the end time of an envelope segment, the segment is retained. +// [] If the end time equals the start time of an envelope segment, the segment is retained. + +HRESULT CParamEnvelope::FlushEnvelope( REFERENCE_TIME rtStart, REFERENCE_TIME rtEnd, double dSamplesPerRefTime ) +{ + CAutoLock lock( this ); + + // Round reference times to sample boundaries + if (rtStart != _I64_MIN && rtStart != _I64_MAX) + rtStart = REFERENCE_TIME( REFERENCE_TIME(rtStart / dSamplesPerRefTime) * dSamplesPerRefTime + 0.5 ); + if (rtEnd != _I64_MIN && rtEnd != _I64_MAX) + rtEnd = REFERENCE_TIME( REFERENCE_TIME(rtEnd / dSamplesPerRefTime) * dSamplesPerRefTime + 0.5 ); + + EnvelopeSegs::iterator it = m_envSegs.begin(); + while (it != m_envSegs.end()) + { + if (!(rtStart >= it->rtEnd || rtEnd <= it->rtStart)) + it = m_envSegs.erase( it ); + else + it++; + } + + // Once envelopes get thrown away, we need to redetermine our max render time + m_rtRendered = 0; + + cleanup(); + + return S_OK; +} + + +//------------------------------------------------------------------------------ +// The parameter pcSegments passes values both ways. The caller needs to pass in the +// size of the segment array. GetEnvelope() then uses pcSegments to return the number +// of segments it has placed in the array. + +HRESULT CParamEnvelope::GetEnvelope( DWORD *pcSegments, MP_ENVELOPE_SEGMENT *pmpes ) +{ + CAutoLock lock( this ); + + ASSERT( pcSegments ); + + DWORD ix = 0; + for (EnvelopeSegs::iterator it = m_envSegs.begin(); + it != m_envSegs.end() && ix < *pcSegments; + it++, ix++) + { + pmpes[ ix ] = *it; + } + + *pcSegments = ix; + + return S_OK; +} diff --git a/Src/Plugins/DSP/dsp_sps/dxi/ParamEnvelope.h b/Src/Plugins/DSP/dsp_sps/dxi/ParamEnvelope.h new file mode 100644 index 00000000..56bff5d5 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/ParamEnvelope.h @@ -0,0 +1,124 @@ +// ParamEnvelope.h: interface for the CParamEnvelope class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_PARAMENVELOPE_H__F04D0178_4674_45AF_9F7A_5C8206DE4CF6__INCLUDED_) +#define AFX_PARAMENVELOPE_H__F04D0178_4674_45AF_9F7A_5C8206DE4CF6__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +//////////////////////////////////////////////////////////////////////////////// + +typedef std::vector<MP_ENVELOPE_SEGMENT> EnvelopeSegs; + +//////////////////////////////////////////////////////////////////////////////// + +struct ParamInfo +{ + MP_PARAMINFO mppi; // external parameter info, as presented to the user + float fInternalMin; // minimum value used by internal processing code + float fInternalMax; // maximum value used by internal processing code + const WCHAR* pwszEnumText; // text for enumerations + + float MapToInternal( float fValue ) const; + float MapToExternal( float fValue ) const; +}; + +//////////////////////////////////////////////////////////////////////////////// + +class CParamEnvelope : public CCritSec +{ +public: + CParamEnvelope(); + virtual ~CParamEnvelope(); + +// Attributes +public: + + unsigned GetCount() const + { + return m_envSegs.size(); + } + + const MP_ENVELOPE_SEGMENT& GetAt( unsigned ix ) const + { + return m_envSegs[ ix ]; + } + + // Tell the envelope about the parameter being controlled + void SetParamInfo( const ParamInfo& info ); + + // These methods are called by CMediaParams to manipulate segments in an envelope + HRESULT AddEnvelope( DWORD cSegments, MP_ENVELOPE_SEGMENT* pEnvelopeSegments, double dSamplesPerRefTime ); + HRESULT FlushEnvelope( REFERENCE_TIME refTimeStart, REFERENCE_TIME refTimeEnd, double dSamplesPerRefTime ); + HRESULT GetEnvelope( DWORD* cSegments, MP_ENVELOPE_SEGMENT* pEnvelopeSegments ); + HRESULT SetParam( float fValue ); + HRESULT GetParam( float* pfValue ); + + // Manage UI capture and release + void BeginCapture() { m_bCaptured = TRUE; } + void EndCapture() { m_bCaptured = FALSE; } + + // Set the current position, updating current envelope value and deltas + HRESULT UpdateValuesForRefTime( REFERENCE_TIME rt, long lSampleRate ); + + // Check if automation envelopes have been overriden with a specific value + BOOL IsOverrideActive() const { return m_bOverride || m_bCaptured; } + + // Get the current automation data point + float GetCurrentValue() const + { + if (IsOverrideActive()) + return m_fOverrideValue; + else + return m_fEnvelopeValue; + } + + // Get the current automation deltas (for per-sample rendering) + HRESULT GetCurrentDeltas( double* pdDelta1, double* pdDelta2 ) const + { + if (!m_bValidDeltas) + return E_FAIL; + *pdDelta1 = m_dEnvelopeDelta1; + *pdDelta2 = m_dEnvelopeDelta2; + return S_OK; + } + + int IndexForRefTime( REFERENCE_TIME rt ) const; + +private: + + // Stop overriding data + void stopOverride() + { + if (IsOverrideActive() && GetCount() > 0) + m_bOverride = FALSE; + } + + // Make sure the automation track is in a state suitable for playback + void cleanup(); + +private: + + ParamInfo m_info; // information about this parameter + EnvelopeSegs m_envSegs; // the list of envelope segments + float m_fEnvelopeValue; // our evolving dynamic value + double m_dEnvelopeDelta1; // 1st delta of current envelope (w.r.t. seconds) + double m_dEnvelopeDelta2; // 2nd delta of current envelope (w.r.t. seconds) + BOOL m_bValidDeltas; // TRUE when deltas can be used (e.g. except for sin) + BOOL m_bOverride; // TRUE while automation point value is overridden + BOOL m_bCaptured; // TRUE while the captured by the UI + float m_fOverrideValue; // our override value + REFERENCE_TIME m_rtRendered; // latest time rendered so far + +private: + + CParamEnvelope( const CParamEnvelope& ); + CParamEnvelope& operator=( const CParamEnvelope& ); +}; + +//////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(AFX_PARAMENVELOPE_H__F04D0178_4674_45AF_9F7A_5C8206DE4CF6__INCLUDED_) diff --git a/Src/Plugins/DSP/dsp_sps/dxi/Parameters.h b/Src/Plugins/DSP/dsp_sps/dxi/Parameters.h new file mode 100644 index 00000000..f0bbfb3c --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/Parameters.h @@ -0,0 +1,47 @@ +// Declarations of automated parameters used by the plug-in + +//////////////////////////////////////////////////////////////////////////////// +#ifndef DEFINE_PARAM_INFO +//////////////////////////////////////////////////////////////////////////////// + +enum +{ + PARAM_ENABLE, + + // TODO: Add new automated parameter IDs here + + NUM_AUTOMATED_PARAMS, + + // TODO: Add new internal parameter IDs here. Make sure to assign the + // first value to NUM_AUTOMATED_PARAMS, i.e., + // + // _PARAM_INTERNAL1 = NUM_AUTOMATED_PARAMS, + // _PARAM_INTERNAL2, + // ... + + NUM_PARAMS +}; + +//////////////////////////////////////////////////////////////////////////////// +#else +//////////////////////////////////////////////////////////////////////////////// + +#define MP_NONE (0) +#define MP_JUMP (MP_CURVE_JUMP) +#define MP_LINES (MP_CURVE_JUMP|MP_CURVE_LINEAR) +#define MP_QUADS (MP_CURVE_JUMP|MP_CURVE_LINEAR|MP_CURVE_SQUARE|MP_CURVE_INVSQUARE) +#define MP_ALL (MP_CURVE_JUMP|MP_CURVE_LINEAR|MP_CURVE_SQUARE|MP_CURVE_INVSQUARE|MP_CURVE_SINE) + +const ParamInfo CMediaParams::m_aParamInfo[ NUM_PARAMS ] = +{ +// MP_TYPE MP_CAPS min max def units label int.min int.max "Enum1,Enum2,.." +// ------- ------- --- --- --- ----- ----- ------- ------- --------------- +{ MPT_BOOL, MP_QUADS, 0, 1, 1, L"", L"Enabled", 0, 1, NULL }, + +// TODO: Add entries for additional parameters here + +}; + +//////////////////////////////////////////////////////////////////////////////// +#endif // DEFINE_PARAM_INFO +//////////////////////////////////////////////////////////////////////////////// diff --git a/Src/Plugins/DSP/dsp_sps/dxi/PlugInApp.cpp b/Src/Plugins/DSP/dsp_sps/dxi/PlugInApp.cpp new file mode 100644 index 00000000..be1fdfbf --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/PlugInApp.cpp @@ -0,0 +1,192 @@ +// PlugInApp.cpp : Defines the initialization routines for the DLL. +// + +#include "stdafx.h" +#include "PlugInApp.h" + +//////////////////////////////////////////////////////////////////////////////// + +extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID); + +BOOL WINAPI DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pv) +{ + return DllEntryPoint( hInstance, ulReason, pv ); +} + +//////////////////////////////////////////////////////////////////////////////// + +LONG recursiveDeleteKey( HKEY hKeyParent, // Parent of key to delete + const char* lpszKeyChild ) // Key to delete +{ + // Open the child. + HKEY hKeyChild ; + LONG lRes = RegOpenKeyEx( hKeyParent, lpszKeyChild, 0, KEY_ALL_ACCESS, &hKeyChild ); + if (lRes != ERROR_SUCCESS) + { + return lRes; + } + + // Enumerate all of the decendents of this child. + FILETIME time; + char szBuffer[ 256 ]; + DWORD dwSize = 256; + while (RegEnumKeyEx( hKeyChild, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time ) == S_OK) + { + // Delete the decendents of this child. + lRes = recursiveDeleteKey( hKeyChild, szBuffer ); + if (lRes != ERROR_SUCCESS) + { + // Cleanup before exiting. + RegCloseKey( hKeyChild ); + return lRes; + } + dwSize = 256; + } + + // Close the child. + RegCloseKey( hKeyChild ); + + // Delete this child. + return RegDeleteKey( hKeyParent, lpszKeyChild ); +} + +//////////////////////////////////////////////////////////////////////////////// + +static const char* s_pszReg = "CakewalkPlugIns\\"; + +extern CFactoryTemplate g_Templates[]; +extern int g_cTemplates; + +//////////////////////////////////////////////////////////////////////////////// + +STDAPI DllRegisterServer() +{ + HKEY hKey = 0; + char sz[ _MAX_PATH ]; + OLECHAR wsz[ _MAX_PATH ]; + char szCLSID[ 64 ]; + ITypeLib* pTypeLib = 0; + int i = 0; + HRESULT hr = E_FAIL; + + // Do DirectShow registration + hr = AMovieDllRegisterServer2( TRUE ); + if (FAILED( hr )) + goto DONE; + + // Get our full pathname, converting to multibyte + GetModuleFileName( g_hInst, sz, sizeof sz ); + if (0 == MultiByteToWideChar( CP_ACP, 0, sz, _MAX_PATH, wsz, _MAX_PATH )) + goto DONE; + + // Iterate over all exported CLSIDs + for (i = 0; i < g_cTemplates; i++) + { + CFactoryTemplate* pT = &g_Templates[ i ]; + + if (NULL != pT->m_pAMovieSetup_Filter) + { + // For backwards compatability, instantiate all servers and get hold of + // IAMovieSetup (if implemented) and call IAMovieSetup.Register() method + if (NULL != pT->m_lpfnNew) + { + IAMovieSetup* pSetup = 0; + if (SUCCEEDED( CoCreateInstance( *(pT->m_ClsID), 0, CLSCTX_INPROC_SERVER, + IID_IAMovieSetup, (void**)&pSetup ) )) + { + pSetup->Register(); + pSetup->Release(); + } + } + + // Convert the CLSID to an ANSI string + StringFromGUID2( *(pT->m_ClsID), wsz, sizeof wsz ); + if (0 == WideCharToMultiByte( CP_ACP, 0, wsz, -1, szCLSID, sizeof szCLSID, NULL, NULL )) + goto DONE; + + // Add {...} to HKEY_CLASSES_ROOT\<s_pszReg> + strcpy( sz, s_pszReg ); + strcat( sz, szCLSID ); + if (ERROR_SUCCESS != RegCreateKey( HKEY_CLASSES_ROOT, sz, &hKey )) + goto DONE; + + // {...}\Description = <description text> + if (0 == WideCharToMultiByte( CP_ACP, 0, pT->m_Name, -1, sz, sizeof sz, NULL, NULL )) + goto DONE; + RegSetValueEx( hKey, "Description", 0, REG_SZ, (BYTE*)sz, strlen(sz) ); + + // Written for backwards compatability with SONAR 1.x and Pro Audio: + // {...}\HelpFilePath = "" + // {...}\HelpFileTopic = "" + *sz = 0; + RegSetValueEx( hKey, "HelpFilePath", 0, REG_SZ, (BYTE*)sz, 1 ); + RegSetValueEx( hKey, "HelpFileTopic", 0, REG_SZ, (BYTE*)sz, 1 ); + + RegCloseKey( hKey ); + hKey = 0; + } + } + + hr = S_OK; + +DONE: + + + if (hKey) + RegCloseKey( hKey ); + + return hr; +} + +//////////////////////////////////////////////////////////////////////////////// + +STDAPI DllUnregisterServer() +{ + char sz[ _MAX_PATH ]; + OLECHAR wsz[ _MAX_PATH ]; + char szCLSID[ 64 ]; + int i = 0; + HRESULT hr = E_FAIL; + + // Do DirectShow unregistration + hr = AMovieDllRegisterServer2( FALSE ); + if (FAILED( hr )) + goto DONE; + + // Iterate over all exported CLSIDs + for (i = 0; i < g_cTemplates; i++) + { + CFactoryTemplate* pT = &g_Templates[ i ]; + + // For backwards compatability, instantiate all servers and get hold of + // IAMovieSetup (if implemented) and call IAMovieSetup.Register() method + if (NULL != pT->m_lpfnNew) + { + IAMovieSetup* pSetup = 0; + if (SUCCEEDED( CoCreateInstance( *(pT->m_ClsID), 0, CLSCTX_INPROC_SERVER, + IID_IAMovieSetup, (void**)&pSetup ) )) + { + pSetup->Unregister(); + pSetup->Release(); + } + } + + // Convert the CLSID to an ANSI string + StringFromGUID2( *(pT->m_ClsID), wsz, sizeof wsz ); + if (0 == WideCharToMultiByte( CP_ACP, 0, wsz, -1, szCLSID, sizeof szCLSID, NULL, NULL )) + goto DONE; + + // Delete HKEY_CLASSES_ROOT\<s_pszReg> + strcpy( sz, s_pszReg ); + strcat( sz, szCLSID ); + recursiveDeleteKey( HKEY_CLASSES_ROOT, sz ); + } + + hr = S_OK; + +DONE: + + return hr; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/Src/Plugins/DSP/dsp_sps/dxi/PlugInApp.h b/Src/Plugins/DSP/dsp_sps/dxi/PlugInApp.h new file mode 100644 index 00000000..f7215ed3 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/PlugInApp.h @@ -0,0 +1,8 @@ +// PlugInApp.h : main header file for PlugIn.ax +// + +#ifndef _PLUGIN_APP_H_ +#define _PLUGIN_APP_H_ +extern HMODULE g_hInst; + +#endif // _PLUGIN_APP_H_ diff --git a/Src/Plugins/DSP/dsp_sps/dxi/PlugInGUIDs.h b/Src/Plugins/DSP/dsp_sps/dxi/PlugInGUIDs.h new file mode 100644 index 00000000..9476b4ba --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/PlugInGUIDs.h @@ -0,0 +1,5 @@ +///////////////////////////////////////////////////////////////////////////// +// Classes exported by this plug-in + +const GUID CLSID_Filter = { 0x2d63acbe, 0x64bd, 0x4fd9, { 0xa0, 0x23, 0xe3, 0xa7, 0x60, 0xc9, 0x6a, 0x14 } }; +const GUID CLSID_FilterPropPage = { 0xbf23bd81, 0x6e22, 0x42ab, { 0x9d, 0xa4, 0xc7, 0x93, 0xdb, 0xfc, 0x6, 0x85 } }; diff --git a/Src/Plugins/DSP/dsp_sps/dxi/ReadMe.txt b/Src/Plugins/DSP/dsp_sps/dxi/ReadMe.txt new file mode 100644 index 00000000..516d83e2 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/ReadMe.txt @@ -0,0 +1,68 @@ +The Cakewalk DirectX Plug-In Wizard has created
+the following files for you:
+
+AudioPlugIn.h, AudioPlugIn.cpp:
+ CAudioPlugIn, the DirectX plug-in object.
+
+AudioPlugInPropPage.h, AudioPlugInPropPage.cpp:
+ CAudioPlugInPropPage, an class that implements the plug-in's
+ property page (IPropertyPage).
+
+AudioPlugIn.rc
+ This is a listing of all of the Microsoft Windows resources that the
+ program uses. It includes the icons, bitmaps, and cursors that are stored
+ in the RES subdirectory. This file can be directly edited in Microsoft
+ Developer Studio.
+
+res\AudioPlugIn.rc2
+ This file contains resources that are not edited by Microsoft
+ Developer Studio. You should place all resources not
+ editable by the resource editor in this file.
+
+AudioPlugIn.def
+ This file contains information about the DLL that must be
+ provided to run with Microsoft Windows. It defines parameters
+ such as the name and description of the DLL. It also exports
+ functions from the DLL.
+
+AudioPlugIn.clw
+ This file contains information used by ClassWizard to edit existing
+ classes or add new classes. ClassWizard also uses this file to store
+ information needed to create and edit message maps and dialog data
+ maps and to create prototype member functions.
+
+///////////////////////////////////////////////////////////
+Support files:
+
+AudioPlugInApp.h
+AudioPlugInApp.cpp:
+ Entry points for component registration and deregistration.
+
+MediaParams.h
+MediaParams.cpp:
+ CMediaParams, a helper class to implement all pertinent DirectX automation
+ intefaces, such as IMediaParams and IMediaParamsInfo.
+
+ParamEnvelope.h
+ParamEnvelope.cpp:
+ CParamEnvelope, a container for a single parameter's envelope, i.e., its
+ evolving shape over time. CMediaParams keeps a collection of these.
+
+///////////////////////////////////////////////////////////
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+ These files are used to build a precompiled header (PCH) file
+ named AudioPlugIn.pch and a precompiled types file named StdAfx.obj.
+
+Resource.h
+ This is the standard header file, which defines new resource IDs.
+ Microsoft Developer Studio reads and updates this file.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/Src/Plugins/DSP/dsp_sps/dxi/StdAfx.cpp b/Src/Plugins/DSP/dsp_sps/dxi/StdAfx.cpp new file mode 100644 index 00000000..52fe71a8 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/StdAfx.cpp @@ -0,0 +1,9 @@ +// stdafx.cpp : source file that includes just the standard includes +// DShowMFC.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// If the include file below cannot be opened, then you do not have DirectX 8 SDK installed, or do not +// have its headers in your configured include path. +#include <d3d8.h> diff --git a/Src/Plugins/DSP/dsp_sps/dxi/StdAfx.h b/Src/Plugins/DSP/dsp_sps/dxi/StdAfx.h new file mode 100644 index 00000000..7af62053 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/StdAfx.h @@ -0,0 +1,43 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__5BCD2B6C_0D14_4C1E_8269_E522431AE0DD__INCLUDED_) +#define AFX_STDAFX_H__5BCD2B6C_0D14_4C1E_8269_E522431AE0DD__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include <windows.h> +#include <windowsx.h> + +#ifdef _DEBUG +#define DEBUG // the DirectShow headers use this symbol +#endif + +#include <objbase.h> +#include <control.h> +#include <streams.h> +#include <pstream.h> + +#ifndef WAVE_FORMAT_IEEE_FLOAT + #define WAVE_FORMAT_IEEE_FLOAT (3) +#endif + +#pragma warning( disable: 4786 ) // identifier was trucated to '255' characters in the debug information + +#include <string> +#include <vector> +#include <algorithm> +using namespace std; + +#pragma warning( disable: 4355 ) // 'this' : used in base member initialization list + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__5BCD2B6C_0D14_4C1E_8269_E522431AE0DD__INCLUDED_) diff --git a/Src/Plugins/DSP/dsp_sps/dxi/dmoguids.lib b/Src/Plugins/DSP/dsp_sps/dxi/dmoguids.lib Binary files differnew file mode 100644 index 00000000..89039a8f --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/dmoguids.lib diff --git a/Src/Plugins/DSP/dsp_sps/dxi/include/CakeMedParam.h b/Src/Plugins/DSP/dsp_sps/dxi/include/CakeMedParam.h new file mode 100644 index 00000000..0ecf149a --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/include/CakeMedParam.h @@ -0,0 +1,461 @@ +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + +/* File created by MIDL compiler version 5.01.0164 */ +/* at Fri May 03 10:13:47 2002 + */ +/* Compiler settings for CakeMedParam.idl: + Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext + error checks: allocation ref bounds_check enum stub_data +*/ +//MIDL_FILE_HEADING( ) + + +/* verify that the <rpcndr.h> version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 440 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of <rpcndr.h> +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __CakeMedParam_h__ +#define __CakeMedParam_h__ + +#ifdef __cplusplus +extern "C"{ +#endif + +/* Forward Declarations */ + +#ifndef __IMediaParamsUICallback_FWD_DEFINED__ +#define __IMediaParamsUICallback_FWD_DEFINED__ +typedef interface IMediaParamsUICallback IMediaParamsUICallback; +#endif /* __IMediaParamsUICallback_FWD_DEFINED__ */ + + +#ifndef __IMediaParamsSetUICallback_FWD_DEFINED__ +#define __IMediaParamsSetUICallback_FWD_DEFINED__ +typedef interface IMediaParamsSetUICallback IMediaParamsSetUICallback; +#endif /* __IMediaParamsSetUICallback_FWD_DEFINED__ */ + + +#ifndef __IMediaParamsCapture_FWD_DEFINED__ +#define __IMediaParamsCapture_FWD_DEFINED__ +typedef interface IMediaParamsCapture IMediaParamsCapture; +#endif /* __IMediaParamsCapture_FWD_DEFINED__ */ + + +#ifndef __IMediaParamsUICallback_FWD_DEFINED__ +#define __IMediaParamsUICallback_FWD_DEFINED__ +typedef interface IMediaParamsUICallback IMediaParamsUICallback; +#endif /* __IMediaParamsUICallback_FWD_DEFINED__ */ + + +#ifndef __IMediaParamsSetUICallback_FWD_DEFINED__ +#define __IMediaParamsSetUICallback_FWD_DEFINED__ +typedef interface IMediaParamsSetUICallback IMediaParamsSetUICallback; +#endif /* __IMediaParamsSetUICallback_FWD_DEFINED__ */ + + +#ifndef __IMediaParamsCapture_FWD_DEFINED__ +#define __IMediaParamsCapture_FWD_DEFINED__ +typedef interface IMediaParamsCapture IMediaParamsCapture; +#endif /* __IMediaParamsCapture_FWD_DEFINED__ */ + + +void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t); +void __RPC_USER MIDL_user_free( void __RPC_FAR * ); + +#ifndef __IMediaParamsUICallback_INTERFACE_DEFINED__ +#define __IMediaParamsUICallback_INTERFACE_DEFINED__ + +/* interface IMediaParamsUICallback */ +/* [version][uuid][local][object] */ + + +EXTERN_C const IID IID_IMediaParamsUICallback; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("B8E0480A-E08D-4a5d-9228-248017032368") + IMediaParamsUICallback : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE ParamsBeginCapture( + /* [in] */ DWORD __RPC_FAR *aIndex, + /* [in] */ DWORD cPoints) = 0; + + virtual HRESULT STDMETHODCALLTYPE ParamsChanged( + /* [in] */ DWORD __RPC_FAR *aIndex, + /* [in] */ DWORD cPoints, + /* [in] */ MP_DATA __RPC_FAR *paData) = 0; + + virtual HRESULT STDMETHODCALLTYPE ParamsEndCapture( + /* [in] */ DWORD __RPC_FAR *aIndex, + /* [in] */ DWORD cPoints) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMediaParamsUICallbackVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( + IMediaParamsUICallback __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( + IMediaParamsUICallback __RPC_FAR * This); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( + IMediaParamsUICallback __RPC_FAR * This); + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ParamsBeginCapture )( + IMediaParamsUICallback __RPC_FAR * This, + /* [in] */ DWORD __RPC_FAR *aIndex, + /* [in] */ DWORD cPoints); + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ParamsChanged )( + IMediaParamsUICallback __RPC_FAR * This, + /* [in] */ DWORD __RPC_FAR *aIndex, + /* [in] */ DWORD cPoints, + /* [in] */ MP_DATA __RPC_FAR *paData); + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ParamsEndCapture )( + IMediaParamsUICallback __RPC_FAR * This, + /* [in] */ DWORD __RPC_FAR *aIndex, + /* [in] */ DWORD cPoints); + + END_INTERFACE + } IMediaParamsUICallbackVtbl; + + interface IMediaParamsUICallback + { + CONST_VTBL struct IMediaParamsUICallbackVtbl __RPC_FAR *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMediaParamsUICallback_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IMediaParamsUICallback_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IMediaParamsUICallback_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IMediaParamsUICallback_ParamsBeginCapture(This,aIndex,cPoints) \ + (This)->lpVtbl -> ParamsBeginCapture(This,aIndex,cPoints) + +#define IMediaParamsUICallback_ParamsChanged(This,aIndex,cPoints,paData) \ + (This)->lpVtbl -> ParamsChanged(This,aIndex,cPoints,paData) + +#define IMediaParamsUICallback_ParamsEndCapture(This,aIndex,cPoints) \ + (This)->lpVtbl -> ParamsEndCapture(This,aIndex,cPoints) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IMediaParamsUICallback_ParamsBeginCapture_Proxy( + IMediaParamsUICallback __RPC_FAR * This, + /* [in] */ DWORD __RPC_FAR *aIndex, + /* [in] */ DWORD cPoints); + + +void __RPC_STUB IMediaParamsUICallback_ParamsBeginCapture_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IMediaParamsUICallback_ParamsChanged_Proxy( + IMediaParamsUICallback __RPC_FAR * This, + /* [in] */ DWORD __RPC_FAR *aIndex, + /* [in] */ DWORD cPoints, + /* [in] */ MP_DATA __RPC_FAR *paData); + + +void __RPC_STUB IMediaParamsUICallback_ParamsChanged_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IMediaParamsUICallback_ParamsEndCapture_Proxy( + IMediaParamsUICallback __RPC_FAR * This, + /* [in] */ DWORD __RPC_FAR *aIndex, + /* [in] */ DWORD cPoints); + + +void __RPC_STUB IMediaParamsUICallback_ParamsEndCapture_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IMediaParamsUICallback_INTERFACE_DEFINED__ */ + + +#ifndef __IMediaParamsSetUICallback_INTERFACE_DEFINED__ +#define __IMediaParamsSetUICallback_INTERFACE_DEFINED__ + +/* interface IMediaParamsSetUICallback */ +/* [version][uuid][local][object] */ + + +EXTERN_C const IID IID_IMediaParamsSetUICallback; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("F5011136-C416-48b9-8C35-E7C5F9AA6FDF") + IMediaParamsSetUICallback : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetUICallback( + /* [in] */ IMediaParamsUICallback __RPC_FAR *pICallback) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMediaParamsSetUICallbackVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( + IMediaParamsSetUICallback __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( + IMediaParamsSetUICallback __RPC_FAR * This); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( + IMediaParamsSetUICallback __RPC_FAR * This); + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SetUICallback )( + IMediaParamsSetUICallback __RPC_FAR * This, + /* [in] */ IMediaParamsUICallback __RPC_FAR *pICallback); + + END_INTERFACE + } IMediaParamsSetUICallbackVtbl; + + interface IMediaParamsSetUICallback + { + CONST_VTBL struct IMediaParamsSetUICallbackVtbl __RPC_FAR *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMediaParamsSetUICallback_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IMediaParamsSetUICallback_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IMediaParamsSetUICallback_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IMediaParamsSetUICallback_SetUICallback(This,pICallback) \ + (This)->lpVtbl -> SetUICallback(This,pICallback) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IMediaParamsSetUICallback_SetUICallback_Proxy( + IMediaParamsSetUICallback __RPC_FAR * This, + /* [in] */ IMediaParamsUICallback __RPC_FAR *pICallback); + + +void __RPC_STUB IMediaParamsSetUICallback_SetUICallback_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IMediaParamsSetUICallback_INTERFACE_DEFINED__ */ + + +#ifndef __IMediaParamsCapture_INTERFACE_DEFINED__ +#define __IMediaParamsCapture_INTERFACE_DEFINED__ + +/* interface IMediaParamsCapture */ +/* [version][uuid][local][object] */ + + +EXTERN_C const IID IID_IMediaParamsCapture; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("970FED79-6DEB-4ec4-A6EE-F72C6BA545CC") + IMediaParamsCapture : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE ParamCapture( + /* [in] */ DWORD dwIndex, + /* [in] */ REFERENCE_TIME refTimeCapture, + /* [in] */ MP_FLAGS flags) = 0; + + virtual HRESULT STDMETHODCALLTYPE ParamRelease( + /* [in] */ DWORD dwIndex, + /* [in] */ REFERENCE_TIME refTimeRelease, + /* [in] */ MP_FLAGS flags) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMediaParamsCaptureVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( + IMediaParamsCapture __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( + IMediaParamsCapture __RPC_FAR * This); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( + IMediaParamsCapture __RPC_FAR * This); + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ParamCapture )( + IMediaParamsCapture __RPC_FAR * This, + /* [in] */ DWORD dwIndex, + /* [in] */ REFERENCE_TIME refTimeCapture, + /* [in] */ MP_FLAGS flags); + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ParamRelease )( + IMediaParamsCapture __RPC_FAR * This, + /* [in] */ DWORD dwIndex, + /* [in] */ REFERENCE_TIME refTimeRelease, + /* [in] */ MP_FLAGS flags); + + END_INTERFACE + } IMediaParamsCaptureVtbl; + + interface IMediaParamsCapture + { + CONST_VTBL struct IMediaParamsCaptureVtbl __RPC_FAR *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMediaParamsCapture_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IMediaParamsCapture_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IMediaParamsCapture_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IMediaParamsCapture_ParamCapture(This,dwIndex,refTimeCapture,flags) \ + (This)->lpVtbl -> ParamCapture(This,dwIndex,refTimeCapture,flags) + +#define IMediaParamsCapture_ParamRelease(This,dwIndex,refTimeRelease,flags) \ + (This)->lpVtbl -> ParamRelease(This,dwIndex,refTimeRelease,flags) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IMediaParamsCapture_ParamCapture_Proxy( + IMediaParamsCapture __RPC_FAR * This, + /* [in] */ DWORD dwIndex, + /* [in] */ REFERENCE_TIME refTimeCapture, + /* [in] */ MP_FLAGS flags); + + +void __RPC_STUB IMediaParamsCapture_ParamCapture_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IMediaParamsCapture_ParamRelease_Proxy( + IMediaParamsCapture __RPC_FAR * This, + /* [in] */ DWORD dwIndex, + /* [in] */ REFERENCE_TIME refTimeRelease, + /* [in] */ MP_FLAGS flags); + + +void __RPC_STUB IMediaParamsCapture_ParamRelease_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IMediaParamsCapture_INTERFACE_DEFINED__ */ + + + +#ifndef __CakeMedParam_LIBRARY_DEFINED__ +#define __CakeMedParam_LIBRARY_DEFINED__ + +/* library CakeMedParam */ +/* [helpstring][version][uuid] */ + + + + + +EXTERN_C const IID LIBID_CakeMedParam; +#endif /* __CakeMedParam_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Src/Plugins/DSP/dsp_sps/dxi/include/CakeMedParam_i.c b/Src/Plugins/DSP/dsp_sps/dxi/include/CakeMedParam_i.c new file mode 100644 index 00000000..a166776e --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/include/CakeMedParam_i.c @@ -0,0 +1,53 @@ +/* this file contains the actual definitions of */ +/* the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + +/* File created by MIDL compiler version 5.01.0164 */ +/* at Fri May 03 10:13:47 2002 + */ +/* Compiler settings for CakeMedParam.idl: + Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext + error checks: allocation ref bounds_check enum stub_data +*/ +//MIDL_FILE_HEADING( ) +#ifdef __cplusplus +extern "C"{ +#endif + + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +const IID IID_IMediaParamsUICallback = {0xB8E0480A,0xE08D,0x4a5d,{0x92,0x28,0x24,0x80,0x17,0x03,0x23,0x68}}; + + +const IID IID_IMediaParamsSetUICallback = {0xF5011136,0xC416,0x48b9,{0x8C,0x35,0xE7,0xC5,0xF9,0xAA,0x6F,0xDF}}; + + +const IID IID_IMediaParamsCapture = {0x970FED79,0x6DEB,0x4ec4,{0xA6,0xEE,0xF7,0x2C,0x6B,0xA5,0x45,0xCC}}; + + +const IID LIBID_CakeMedParam = {0xA8F8EF3E,0x4E39,0x49e2,{0x89,0xE7,0x3C,0x91,0x94,0x2C,0xC5,0x7B}}; + + +#ifdef __cplusplus +} +#endif + diff --git a/Src/Plugins/DSP/dsp_sps/dxi/include/DXi.h b/Src/Plugins/DSP/dsp_sps/dxi/include/DXi.h new file mode 100644 index 00000000..44ce0dd1 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/include/DXi.h @@ -0,0 +1,121 @@ +#ifndef _DXI_H_ +#define _DXI_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include <DeferZeroFill.h> + +// DirectX automation helper +#include "MediaParams.h" + +//////////////////////////////////////////////////////////////////////////////// + +struct AudioBuffer +{ + long cSamp; // number of samples in the buffer + long lOffset; // offset into the data to process + IMediaSample* pms; // the raw IMediaSample for this buffer + + AudioBuffer() : cSamp(0), lOffset(0), pms(NULL) {} + + //---------------------------------------------------------------------------- + // Get a pointer to the audio samples, zero-filling if necesssary + + float* GetPointer() + { + // Get the raw-pointer + BYTE* pb = NULL; + pms->GetPointer( &pb ); + + // We cannot defer the zero fill any longer! + if (bZero) + { + IDeferZeroFill* pdzf; + if (SUCCEEDED( pms->QueryInterface( IID_IDeferZeroFill, (void**)&pdzf ) )) + { + // IDeferZeroFill will have taken care of the zero-fill for us, by + // virtue of our calling IMediaSample::GetPointer. Nothing more to do. + pdzf->Release(); + } + else + { + // No IDeferZeroFill is available. We must zero-fill the hard way. + memset( pb, 0, cSamp * sizeof(float) ); + } + bZero = FALSE; + } + + return reinterpret_cast<float*>( pb + lOffset ); + } + + //---------------------------------------------------------------------------- + // Allow buffers to be tagged as being all zeroes, without actually filling + // any data until someone asks for the buffer pointer + + BOOL GetZerofill() const { return bZero; } + + void SetZerofill( BOOL bZerofill ) + { + bZero = bZerofill; + IDeferZeroFill* pdzf; + if (SUCCEEDED( pms->QueryInterface( IID_IDeferZeroFill, (void**)&pdzf ) )) + { + pdzf->put_NeedsZerofill( bZero ); + pdzf->Release(); + } + } + +private: + + BOOL bZero; +}; + + +//////////////////////////////////////////////////////////////////////////////// + +class CDXi : public CCritSec +{ +public: + + virtual HRESULT Initialize() = 0; + + virtual HRESULT IsValidInputFormat( const WAVEFORMATEX* pwfx ) const = 0; + virtual HRESULT IsValidOutputFormat( const WAVEFORMATEX* pwfx ) const = 0; + virtual HRESULT IsValidTransform( const WAVEFORMATEX* pwfxIn, const WAVEFORMATEX* pwfxOut ) const = 0; + virtual HRESULT SuggestOutputFormat( WAVEFORMATEX* pwfx ) const = 0; + + virtual const WAVEFORMATEX* GetInputFormat() const { return &m_wfxIn; } + virtual const WAVEFORMATEX* GetOutputFormat() const { return &m_wfxOut; } + + virtual HRESULT Process( LONGLONG llSampAudioTimestamp, + AudioBuffer* pbufIn, + AudioBuffer* pbufOut ) = 0; + + virtual HRESULT AllocateResources() = 0; + virtual HRESULT FreeResources() = 0; + + virtual int PersistGetSize() const = 0; + virtual HRESULT PersistLoad( IStream* pStream ) = 0; + virtual HRESULT PersistSave( IStream* pStream ) = 0; + +protected: + WAVEFORMATEX m_wfxIn; + WAVEFORMATEX m_wfxOut; + CMediaParams* m_pMediaParams; + + float GetParamValue( DWORD dwParam ) const + { + return m_pMediaParams->GetParamEnvelope( dwParam ).GetCurrentValue(); + } + + HRESULT GetParamDeltas( DWORD dwParam, double* pdDelta1, double* pdDelta2 ) const + { + return m_pMediaParams->GetParamEnvelope( dwParam ).GetCurrentDeltas( pdDelta1, pdDelta2 ); + } +}; + +//////////////////////////////////////////////////////////////////////////////// + +#endif //_DXI_H_ diff --git a/Src/Plugins/DSP/dsp_sps/dxi/include/DeferZeroFill.h b/Src/Plugins/DSP/dsp_sps/dxi/include/DeferZeroFill.h new file mode 100644 index 00000000..4aa13e8e --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/include/DeferZeroFill.h @@ -0,0 +1,33 @@ +// IDeferZeroFill interface exposed a custom memory allocator and media sample. +// +// Copyright (C) 1997- Cakewalk Music Software. All rights reserved. +// + +#ifndef _DEFERZEROFILL_H_ +#define _DEFERZEROFILL_H_ + +///////////////////////////////////////////////////////////////////////////// +// Clients that wish to create real copies of the GUID must first include INITGUID.H + +// {447DA113-4AC8-4833-849A-2BA285E1E52B} +DEFINE_GUID(IID_IDeferZeroFill, +0x447da113, 0x4ac8, 0x4833, 0x84, 0x9a, 0x2b, 0xa2, 0x85, 0xe1, 0xe5, 0x2b); + +#undef INTERFACE +#define INTERFACE IDeferZeroFill + +DECLARE_INTERFACE_( IDeferZeroFill, IUnknown ) +{ + // *** IUnknown methods *** + STDMETHOD_(HRESULT, QueryInterface)( THIS_ REFIID riid, LPVOID* ppvObj ) PURE; + STDMETHOD_(ULONG, AddRef)( THIS ) PURE; + STDMETHOD_(ULONG, Release)( THIS ) PURE; + + // *** IDeferZeroFill methods *** + STDMETHOD_(BOOL, get_NeedsZerofill)( THIS ) PURE; + STDMETHOD_(void, put_NeedsZerofill)( THIS_ BOOL bZero ) PURE; + STDMETHOD_(HRESULT, GetRawPointer)( THIS_ BYTE** ppBuffer ) PURE; +}; + +#endif // _DEFERZEROFILL_H_ + diff --git a/Src/Plugins/DSP/dsp_sps/dxi/res/AudioPlugIn.rc2 b/Src/Plugins/DSP/dsp_sps/dxi/res/AudioPlugIn.rc2 new file mode 100644 index 00000000..2f7a81fc --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/res/AudioPlugIn.rc2 @@ -0,0 +1,13 @@ +// +// MFCDELAY.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/Src/Plugins/DSP/dsp_sps/dxi/resource.h b/Src/Plugins/DSP/dsp_sps/dxi/resource.h new file mode 100644 index 00000000..a51c6904 --- /dev/null +++ b/Src/Plugins/DSP/dsp_sps/dxi/resource.h @@ -0,0 +1,59 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by AudioPlugIn.rc +// +#define IDS_NAME_PLUGIN 1 +#define IDS_DESC_PLUGIN 2 +#define IDS_SETTINGS 3 +#define IDS_HELPFILE_PLUGIN 4 +#define IDD_PROPPAGE 200 +#define IDC_STATIC -1 +#define IDD_DIALOG1 101 +#define IDD_EVAL_HELP 166 +#define IDC_SLIDER1 1000 +#define IDC_SLIDER1_LABEL 1001 +#define IDC_SLIDER1_LABEL1 1001 +#define IDC_SLIDER1_LABEL2 1002 +#define IDC_SLIDER1_LABEL3 1003 +#define IDC_SLIDER2 1004 +#define IDC_SLIDER2_LABEL1 1005 +#define IDC_SLIDER2_LABEL2 1006 +#define IDC_SLIDER2_LABEL3 1007 +#define IDC_SLIDER3 1008 +#define IDC_SLIDER3_LABEL1 1009 +#define IDC_SLIDER3_LABEL2 1010 +#define IDC_SLIDER3_LABEL3 1011 +#define IDC_SLIDER4 1012 +#define IDC_LOAD 1013 +#define IDC_EDIT 1014 +#define IDC_SAVE 1015 +#define IDC_BYPASS 1016 +#define IDC_NEW 1017 +#define IDC_PRESET 1018 +#define IDC_SHOWHELP 1019 +#define IDC_SLIDER4_LABEL2 1020 +#define IDC_SLIDER4_LABEL3 1021 +#define IDC_SLIDER4_LABEL1 1022 +#define IDC_TRIGGER1 1023 +#define IDC_TRIGGER2 1024 +#define IDC_TRIGGER3 1025 +#define IDC_TRIGGER4 1026 +#define IDC_EDIT1 1089 +#define IDC_PERSAMPLE 1090 +#define IDC_INIT 1092 +#define IDC_ONSLIDERCHANGE 1093 +#define IDC_TAB1 1203 +#define IDC_PRESETNAME -1 + + + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 201 +#define _APS_NEXT_COMMAND_VALUE 32768 +#define _APS_NEXT_CONTROL_VALUE 1100 +#define _APS_NEXT_SYMED_VALUE 5 +#endif +#endif |