aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/DSP/dsp_sps
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/DSP/dsp_sps')
-rw-r--r--Src/Plugins/DSP/dsp_sps/api__dsp_sps.h9
-rw-r--r--Src/Plugins/DSP/dsp_sps/constant.binbin0 -> 247 bytes
-rw-r--r--Src/Plugins/DSP/dsp_sps/dsp_sps.cpp294
-rw-r--r--Src/Plugins/DSP/dsp_sps/dsp_sps.dsp250
-rw-r--r--Src/Plugins/DSP/dsp_sps/dsp_sps.dsw29
-rw-r--r--Src/Plugins/DSP/dsp_sps/dsp_sps.vcxproj346
-rw-r--r--Src/Plugins/DSP/dsp_sps/dsp_sps.vcxproj.filters92
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.cpp283
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.def7
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.dep69
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.dsp271
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.dsw29
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.h47
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.mak312
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/AudioPlugIn.rc202
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/AudioPlugInPropPage.cpp326
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/AudioPlugInPropPage.h68
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/Filter.cpp1139
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/Filter.h176
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/MediaParams.cpp465
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/MediaParams.h99
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/ParamEnvelope.cpp403
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/ParamEnvelope.h124
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/Parameters.h47
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/PlugInApp.cpp192
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/PlugInApp.h8
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/PlugInGUIDs.h5
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/ReadMe.txt68
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/StdAfx.cpp9
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/StdAfx.h43
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/dmoguids.libbin0 -> 22810 bytes
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/include/CakeMedParam.h461
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/include/CakeMedParam_i.c53
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/include/DXi.h121
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/include/DeferZeroFill.h33
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/res/AudioPlugIn.rc213
-rw-r--r--Src/Plugins/DSP/dsp_sps/dxi/resource.h59
-rw-r--r--Src/Plugins/DSP/dsp_sps/function.binbin0 -> 3130 bytes
-rw-r--r--Src/Plugins/DSP/dsp_sps/general.binbin0 -> 2574 bytes
-rw-r--r--Src/Plugins/DSP/dsp_sps/operator.binbin0 -> 699 bytes
-rw-r--r--Src/Plugins/DSP/dsp_sps/res.rc210
-rw-r--r--Src/Plugins/DSP/dsp_sps/resource.h70
-rw-r--r--Src/Plugins/DSP/dsp_sps/sps_common.cpp574
-rw-r--r--Src/Plugins/DSP/dsp_sps/sps_common.h63
-rw-r--r--Src/Plugins/DSP/dsp_sps/sps_configdlg.h476
-rw-r--r--Src/Plugins/DSP/dsp_sps/version.rc239
46 files changed, 7584 insertions, 0 deletions
diff --git a/Src/Plugins/DSP/dsp_sps/api__dsp_sps.h b/Src/Plugins/DSP/dsp_sps/api__dsp_sps.h
new file mode 100644
index 00000000..3aeb4332
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/api__dsp_sps.h
@@ -0,0 +1,9 @@
+#ifndef NULLSOFT_API_H
+#define NULLSOFT_API_H
+
+#include "api/service/api_service.h"
+#include "api/service/waServiceFactory.h"
+
+#include "../Agave/Language/api_language.h"
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/DSP/dsp_sps/constant.bin b/Src/Plugins/DSP/dsp_sps/constant.bin
new file mode 100644
index 00000000..f0efef8b
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/constant.bin
Binary files differ
diff --git a/Src/Plugins/DSP/dsp_sps/dsp_sps.cpp b/Src/Plugins/DSP/dsp_sps/dsp_sps.cpp
new file mode 100644
index 00000000..3c9323d8
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/dsp_sps.cpp
@@ -0,0 +1,294 @@
+#include <windows.h>
+#include <commctrl.h>
+#include "../winamp/dsp.h"
+#include "resource.h"
+#include "sps_common.h"
+#include "../winamp/wa_ipc.h"
+#include "../../General/gen_hotkeys/wa_hotkeys.h"
+#define SPS_HOTKEY_ID "dsp_sps sc"
+#include "sps_configdlg.h"
+
+//#define PLUGIN_NAME "Nullsoft Signal Processing Studio DSP v1.0b"
+#define PLUGIN_VERSION "v1.0b"
+
+ // config, winamp specific shit here:
+struct
+{
+ int showeditor; //def 0
+ int visible; //def 1
+} g_config;
+
+SPSEffectContext g_wacontext;
+HWND g_configwindow;
+HWND helpWnd;
+int helpWndOpenHack = 0;
+char *INI_FILE;
+static int loaded_once = 0;
+char g_path[MAX_PATH];
+
+// wasabi based services for localisation support
+api_service *WASABI_API_SVC = 0;
+api_language *WASABI_API_LNG = 0;
+HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
+
+// module getter.
+winampDSPModule *getModule(int which);
+
+void config(struct winampDSPModule *this_mod);
+int init(struct winampDSPModule *this_mod);
+void quit(struct winampDSPModule *this_mod);
+int modify_samples(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate);
+
+// Module header, includes version, description, and address of the module retriever function
+typedef struct
+{
+ int version; // DSP_HDRVER
+ char *description; // description of library
+ winampDSPModule* (*getModule)(int); // module retrieval function
+ int (*sf)(int);
+} winampDSPHeaderEx;
+
+static int sf(int v)
+{
+ int res;
+ res = v * (unsigned long)1103515245;
+ res += (unsigned long)13293;
+ res &= (unsigned long)0x7FFFFFFF;
+ res ^= v;
+ return res;
+}
+
+winampDSPHeaderEx hdr = { DSP_HDRVER+1, 0, getModule, sf };
+
+// first module
+winampDSPModule mod =
+{
+ 0,//"Signal Processing Studio",
+ NULL, // hwndParent
+ NULL, // hDllInstance
+ config,
+ init,
+ modify_samples,
+ quit
+};
+
+extern "C"
+{
+ static HINSTANCE GetMyInstance()
+ {
+ MEMORY_BASIC_INFORMATION mbi = {0};
+
+ if(VirtualQuery(GetMyInstance, &mbi, sizeof(mbi)))
+ return (HINSTANCE)mbi.AllocationBase;
+
+ return NULL;
+ }
+
+ __declspec( dllexport ) winampDSPHeaderEx *winampDSPGetHeader2(HWND hwndParent)
+ {
+ if(IsWindow(hwndParent))
+ {
+ if(!WASABI_API_LNG_HINST)
+ {
+ // loader so that we can get the localisation service api for use
+ WASABI_API_SVC = (api_service*)SendMessageW(hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+
+ if (WASABI_API_SVC == (api_service*)1)
+ WASABI_API_SVC = NULL;
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
+
+ if (sf)
+ WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
+
+ // need to have this initialised before we try to do anything with localisation features
+ WASABI_API_START_LANG(GetMyInstance(),DspSpsLangGUID);
+ }
+
+ static char szDescription[256];
+ if(!szDescription[0])
+ {
+ char temp[256];
+ wsprintfA(szDescription,"%s %s",WASABI_API_LNGSTRING_BUF(IDS_SPS_TITLE,temp,256), PLUGIN_VERSION );
+ hdr.description = szDescription;
+ }
+
+ static char szDescription2[256];
+ if(!szDescription2[0])
+ {
+ mod.description = WASABI_API_LNGSTRING_BUF(IDS_SPS_MODULE_TITLE,szDescription2,256);
+ }
+ }
+ return &hdr;
+ }
+}
+
+// getmodule routine from the main header. Returns NULL if an invalid module was requested,
+// otherwise returns either mod1 or mod2 depending on 'which'.
+winampDSPModule *getModule(int which)
+{
+ switch (which)
+ {
+ case 0: return &mod;
+ default:return NULL;
+ }
+}
+
+void config(struct winampDSPModule *this_mod)
+{
+ // show config
+ if (g_configwindow && IsWindow(g_configwindow))
+ {
+ g_config.visible=1;
+ ShowWindow(g_configwindow,SW_SHOW);
+ }
+}
+
+static void WriteInt(char *section, char *name,int value, char *fn)
+{
+ char str[128];
+ wsprintf(str,"%d",value);
+ WritePrivateProfileString(section,name,str,fn);
+}
+
+static char ghkStr[64];
+static genHotkeysAddStruct sps_ghas_showconfig = {
+ ghkStr,
+ 0,
+ WM_USER+0x80,
+ 0,
+ 0,
+ SPS_HOTKEY_ID,
+ 0,
+};
+static int m_genhotkeys_add_ipc;
+
+int init(struct winampDSPModule *this_mod)
+{
+ wsprintf(g_path,"%s\\dsp_sps",(char*)SendMessageW(this_mod->hwndParent,WM_WA_IPC,0,IPC_GETPLUGINDIRECTORY));
+ CreateDirectory(g_path,NULL);
+
+ // loader so that we can get the localisation service api for use
+ WASABI_API_SVC = (api_service*)SendMessageW(this_mod->hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+ if (WASABI_API_SVC == (api_service*)1)
+ WASABI_API_SVC = NULL;
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
+ if (sf)
+ WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
+
+ // need to have this initialised before we try to do anything with localisation features
+ WASABI_API_START_LANG(this_mod->hDllInstance,DspSpsLangGUID);
+
+ SPS_initapp();
+
+ SPS_initcontext(&g_wacontext);
+
+ /* read config */
+ INI_FILE = (char*)SendMessageW(this_mod->hwndParent,WM_WA_IPC,0,IPC_GETINIFILE);
+ g_config.showeditor=GetPrivateProfileInt("DSP_SPS","showeditor",0,INI_FILE);
+ g_config.visible=GetPrivateProfileInt("DSP_SPS","visible",1,INI_FILE);
+
+ g_wacontext.bypass=GetPrivateProfileInt("DSP_SPS","bypass",1,INI_FILE);
+ SPS_load_preset(&g_wacontext,INI_FILE,"DSP_SPS");
+ GetPrivateProfileString("DSP_SPS","last_preset","",g_wacontext.curpreset_name,sizeof(g_wacontext.curpreset_name),INI_FILE);
+
+ g_configwindow=WASABI_API_CREATEDIALOGPARAM(IDD_DIALOG1,this_mod->hwndParent,SPS_configWindowProc,(LPARAM)&g_wacontext);
+
+ // we are starting minimised so process as needed (keep our window hidden)
+ if(!loaded_once)
+ {
+ loaded_once = 1;
+ if (g_config.visible)
+ ShowWindow(g_configwindow,!GetPrivateProfileInt("Winamp","minimized",1,INI_FILE)?SW_SHOWNA:SW_SHOWMINNOACTIVE);
+ }
+ else{
+ if (g_config.visible)
+ ShowWindow(g_configwindow,SW_SHOWNA);
+ }
+
+ m_genhotkeys_add_ipc=SendMessageW(this_mod->hwndParent,WM_WA_IPC,(WPARAM)&"GenHotkeysAdd",IPC_REGISTER_WINAMP_IPCMESSAGE);
+
+ WASABI_API_LNGSTRING_BUF(IDS_SPS_SHOW_CONFIG,ghkStr,64);
+ sps_ghas_showconfig.flags &= ~HKF_DISABLED;
+ sps_ghas_showconfig.wnd = g_configwindow;
+
+ if (m_genhotkeys_add_ipc > 65536)
+ PostMessageW(this_mod->hwndParent,WM_WA_IPC,(WPARAM)&sps_ghas_showconfig,m_genhotkeys_add_ipc); //post so gen_hotkeys will catch it if not inited yet
+
+ return 0;
+}
+
+void quit(struct winampDSPModule *this_mod)
+{
+ if(IsWindow(helpWnd))
+ {
+ DestroyWindow(helpWnd);
+ helpWndOpenHack = 1;
+ }
+
+ helpWnd = 0;
+
+ if(IsWindow(g_configwindow))
+ {
+ DestroyWindow(g_configwindow);
+ }
+
+ g_configwindow=0;
+
+ /* write config */
+ WriteInt("DSP_SPS","showeditor",g_config.showeditor,INI_FILE);
+ WriteInt("DSP_SPS","visible",g_config.visible,INI_FILE);
+
+ WritePrivateProfileString("DSP_SPS","last_preset",g_wacontext.curpreset_name,INI_FILE);
+ WriteInt("DSP_SPS","bypass",g_wacontext.bypass,INI_FILE);
+ SPS_save_preset(&g_wacontext,INI_FILE,"DSP_SPS");
+
+ SPS_quitcontext(&g_wacontext);
+ SPS_quitapp();
+
+ sps_ghas_showconfig.flags |= HKF_DISABLED;
+ sps_ghas_showconfig.wnd=0;
+
+ if (m_genhotkeys_add_ipc > 65536)
+ {
+ DWORD d;
+ SendMessageTimeout(this_mod->hwndParent,WM_WA_IPC,(WPARAM)&sps_ghas_showconfig,m_genhotkeys_add_ipc,SMTO_BLOCK|SMTO_ABORTIFHUNG,500,&d);
+ }
+
+ // helps to work around a crash on close issue when the help dialog is open
+ if(helpWndOpenHack)
+ {
+ char buf[MAX_PATH];
+ GetModuleFileName(this_mod->hDllInstance, buf, MAX_PATH);
+ LoadLibrary(buf);
+ }
+}
+
+int modify_samples(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate)
+{
+ return SPS_process_samples(&g_wacontext,samples,numsamples,0,bps,nch,srate,numsamples*2,1);
+}
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID)
+{
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ {
+ DisableThreadLibraryCalls(hinstDLL);
+ }
+
+ return TRUE;
+}
+
+extern "C" __declspec( dllexport ) int winampUninstallPlugin(HINSTANCE hDllInst, HWND hwndDlg, int param)
+{
+ // force plugin to be uninstalled from a restart so that we can deal with the case of the help dialog being open
+ return helpWndOpenHack;
+}
+
+//////////// common dialog stuff
+
+#define SPS_CONFIGDLG_IMPL
+#define SPS_CONFIGDLG_ON_WM_CLOSE { ShowWindow(hwndDlg,SW_HIDE); g_config.visible=0; }
+#define SPS_CONFIGDLG_HIDEABLE_EDITOR g_config.showeditor
+#include "sps_configdlg.h" \ No newline at end of file
diff --git a/Src/Plugins/DSP/dsp_sps/dsp_sps.dsp b/Src/Plugins/DSP/dsp_sps/dsp_sps.dsp
new file mode 100644
index 00000000..3ae414e2
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/dsp_sps.dsp
@@ -0,0 +1,250 @@
+# Microsoft Developer Studio Project File - Name="dsp_sps" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=dsp_sps - 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 "dsp_sps.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 "dsp_sps.mak" CFG="dsp_sps - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "dsp_sps - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "dsp_sps - 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)" == "dsp_sps - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DSP_SPS_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../Wasabi" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DSP_SPS_EXPORTS" /D "NSEEL_LOOPFUNC_SUPPORT" /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"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x8000000" /entry:"DllMain" /dll /map /machine:I386 /out:"C:/progra~1/winamp/plugins/dsp_sps.dll" /opt:nowin98
+# SUBTRACT LINK32 /pdb:none /debug
+
+!ELSEIF "$(CFG)" == "dsp_sps - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DSP_SPS_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../Wasabi" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DSP_SPS_EXPORTS" /D "NSEEL_LOOPFUNC_SUPPORT" /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"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:/progra~1/winamp/plugins/dsp_sps.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "dsp_sps - Win32 Release"
+# Name "dsp_sps - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Group "eel"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE="..\ns-eel\megabuf.c"
+
+!IF "$(CFG)" == "dsp_sps - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "dsp_sps - Win32 Debug"
+
+!ENDIF
+
+# 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"
+
+!IF "$(CFG)" == "dsp_sps - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "dsp_sps - Win32 Debug"
+
+!ENDIF
+
+# 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 Source File
+
+SOURCE=.\dsp_sps.cpp
+
+!IF "$(CFG)" == "dsp_sps - Win32 Release"
+
+# SUBTRACT CPP /Z<none>
+
+!ELSEIF "$(CFG)" == "dsp_sps - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sps_common.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Group "Support Files"
+
+# PROP Default_Filter "*.h"
+# Begin Source File
+
+SOURCE=..\Winamp\api_language.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Wasabi\api\service\api_service.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Winamp\lang.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\gen_hotkeys\wa_hotkeys.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Winamp\wa_ipc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Wasabi\api\service\waservicefactory.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\api.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Winamp\DSP.H
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\sps_common.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\sps_configdlg.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=.\constant.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\function.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\general.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\operator.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\res.rc
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/Src/Plugins/DSP/dsp_sps/dsp_sps.dsw b/Src/Plugins/DSP/dsp_sps/dsp_sps.dsw
new file mode 100644
index 00000000..cf887680
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/dsp_sps.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "dsp_sps"=.\dsp_sps.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/Src/Plugins/DSP/dsp_sps/dsp_sps.vcxproj b/Src/Plugins/DSP/dsp_sps/dsp_sps.vcxproj
new file mode 100644
index 00000000..897568f0
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/dsp_sps.vcxproj
@@ -0,0 +1,346 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>17.0</VCProjectVersion>
+ <SccProjectName />
+ <SccLocalPath />
+ <ProjectGuid>{434C583B-DC45-400E-952F-D11755828553}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>17.0.32505.173</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnabled>false</VcpkgEnabled>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;DSP_SPS_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(IntDir)$(TargetName).tlb</TypeLibraryName>
+ <HeaderFileName />
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\</Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)*.dll ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;DSP_SPS_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>$(IntDir)$(TargetName).tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\</Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)*.dll ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;DSP_SPS_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <OptimizeReferences>true</OptimizeReferences>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(IntDir)$(TargetName).tlb</TypeLibraryName>
+ <HeaderFileName />
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\</Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)*.dll ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;DSP_SPS_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <OptimizeReferences>true</OptimizeReferences>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>$(IntDir)$(TargetName).tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\</Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)*.dll ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\ns-eel2\nseel-cfunc.c" />
+ <ClCompile Include="..\..\..\ns-eel2\nseel-compiler.c" />
+ <ClCompile Include="..\..\..\ns-eel2\nseel-eval.c" />
+ <ClCompile Include="..\..\..\ns-eel2\nseel-ram.c" />
+ <ClCompile Include="..\..\..\ns-eel2\y.tab.c" />
+ <ClCompile Include="dsp_sps.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DSP_SPS_EXPORTS;NSEEL_LOOPFUNC_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DSP_SPS_EXPORTS;NSEEL_LOOPFUNC_SUPPORT</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DSP_SPS_EXPORTS;NSEEL_LOOPFUNC_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DSP_SPS_EXPORTS;NSEEL_LOOPFUNC_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="sps_common.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DSP_SPS_EXPORTS;NSEEL_LOOPFUNC_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DSP_SPS_EXPORTS;NSEEL_LOOPFUNC_SUPPORT</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DSP_SPS_EXPORTS;NSEEL_LOOPFUNC_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DSP_SPS_EXPORTS;NSEEL_LOOPFUNC_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\ns-eel2\denormal.h" />
+ <ClInclude Include="..\..\..\ns-eel2\glue_x86.h" />
+ <ClInclude Include="..\..\..\ns-eel2\glue_x86_64.h" />
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel-addfuncs.h" />
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel-func-ref.h" />
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel-int.h" />
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel.h" />
+ <ClInclude Include="..\..\..\ns-eel2\wdlcstring.h" />
+ <ClInclude Include="..\..\..\ns-eel2\wdltypes.h" />
+ <ClInclude Include="..\..\..\ns-eel2\y.tab.h" />
+ <ClInclude Include="api__dsp_sps.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="sps_common.h" />
+ <ClInclude Include="sps_configdlg.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/DSP/dsp_sps/dsp_sps.vcxproj.filters b/Src/Plugins/DSP/dsp_sps/dsp_sps.vcxproj.filters
new file mode 100644
index 00000000..7f746be3
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/dsp_sps.vcxproj.filters
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{5493b195-56dc-432a-ae15-7e7d896e38bf}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{02e8ad96-519d-4f05-a8f7-7b6c37776a0e}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{0796236c-1cfe-4820-bfbf-fcc2167a1af2}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ <Filter Include="Source Files\ns-eel2">
+ <UniqueIdentifier>{67403946-6e24-444a-a76d-d03f25c59a93}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="dsp_sps.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="sps_common.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\ns-eel2\nseel-cfunc.c">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\ns-eel2\nseel-compiler.c">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\ns-eel2\nseel-eval.c">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\ns-eel2\nseel-ram.c">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\ns-eel2\y.tab.c">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="sps_common.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="sps_configdlg.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\denormal.h">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\glue_x86.h">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\glue_x86_64.h">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel.h">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel-addfuncs.h">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel-func-ref.h">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel-int.h">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\wdlcstring.h">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\wdltypes.h">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\y.tab.h">
+ <Filter>Source Files\ns-eel2</Filter>
+ </ClInclude>
+ <ClInclude Include="api__dsp_sps.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
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
new file mode 100644
index 00000000..89039a8f
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/dxi/dmoguids.lib
Binary files differ
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
diff --git a/Src/Plugins/DSP/dsp_sps/function.bin b/Src/Plugins/DSP/dsp_sps/function.bin
new file mode 100644
index 00000000..c9b369f0
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/function.bin
Binary files differ
diff --git a/Src/Plugins/DSP/dsp_sps/general.bin b/Src/Plugins/DSP/dsp_sps/general.bin
new file mode 100644
index 00000000..656d96cd
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/general.bin
Binary files differ
diff --git a/Src/Plugins/DSP/dsp_sps/operator.bin b/Src/Plugins/DSP/dsp_sps/operator.bin
new file mode 100644
index 00000000..feb40e1e
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/operator.bin
Binary files differ
diff --git a/Src/Plugins/DSP/dsp_sps/res.rc b/Src/Plugins/DSP/dsp_sps/res.rc
new file mode 100644
index 00000000..f815b4a2
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/res.rc
@@ -0,0 +1,210 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.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
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 343, 223
+STYLE DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+FONT 8, "MS Sans Serif"
+BEGIN
+ PUSHBUTTON "Load",IDC_LOAD,3,4,41,14
+ PUSHBUTTON "New",IDC_NEW,50,4,41,14
+ PUSHBUTTON "",IDC_EDIT,133,4,46,14
+ PUSHBUTTON "Save",IDC_SAVE,185,4,50,14
+ PUSHBUTTON "Help",IDC_SHOWHELP,289,4,50,14
+ LTEXT "Current preset:",IDC_STATIC,3,21,47,8
+ LTEXT "",IDC_PRESET,3,32,175,10,SS_SUNKEN
+ CONTROL "Enable processing",IDC_BYPASS,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,3,47,74,10
+ GROUPBOX "Signal Processing Controls",IDC_STATIC,3,61,176,159
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_VERT | WS_TABSTOP,11,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
+ PUSHBUTTON "Trigger 1",IDC_TRIGGER1,12,204,38,11
+ CONTROL "Slider1",IDC_SLIDER2,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_VERT | WS_TABSTOP,51,70,11,116
+ 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
+ PUSHBUTTON "Trigger 2",IDC_TRIGGER2,52,204,38,11
+ CONTROL "Slider1",IDC_SLIDER3,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_VERT | WS_TABSTOP,91,70,11,116
+ 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 "Trigger 3",IDC_TRIGGER3,92,204,38,11
+ 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 4",IDC_TRIGGER4,132,204,38,11
+ LTEXT "Initialization/format change:",IDC_STATIC,183,22,88,8
+ EDITTEXT IDC_INIT,183,32,155,43,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ LTEXT "Slider change/initialization:",IDC_STATIC,183,77,85,8
+ EDITTEXT IDC_ONSLIDERCHANGE,183,87,155,41,ES_MULTILINE |
+ ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN |
+ WS_VSCROLL
+ LTEXT "Per sample (or sample-pair):",IDC_STATIC,183,131,87,8
+ EDITTEXT IDC_PERSAMPLE,183,141,155,80,ES_MULTILINE |
+ ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN |
+ WS_VSCROLL
+END
+
+IDD_EVAL_HELP DIALOG DISCARDABLE 0, 0, 308, 226
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "SPS Expression Help"
+FONT 8, "MS Sans Serif"
+BEGIN
+ DEFPUSHBUTTON "Close",IDOK,4,209,50,13
+ EDITTEXT IDC_EDIT1,12,22,286,177,ES_MULTILINE | ES_READONLY |
+ WS_VSCROLL
+ CONTROL "Tab1",IDC_TAB1,"SysTabControl32",0x0,4,4,300,200
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_DIALOG1, DIALOG
+ BEGIN
+ LEFTMARGIN, 3
+ RIGHTMARGIN, 341
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 221
+ END
+
+ IDD_EVAL_HELP, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 304
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 222
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXT
+//
+
+IDR_GENERAL TEXT DISCARDABLE "general.bin"
+IDR_OPERATORS TEXT DISCARDABLE "operator.bin"
+IDR_FUNCTIONS TEXT DISCARDABLE "function.bin"
+IDR_CONSTANTS TEXT DISCARDABLE "constant.bin"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ 65535 "{4B567AEB-89CE-4881-9D7D-B31D7B65979A}"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_SPS_SHOW_CONFIG "SPS: Show Config"
+ IDS_SHOW_EDITOR "Show Editor"
+ IDS_HIDE_EDITOR "Hide Editor"
+ IDS_SAVE_PRESET "Save Preset"
+ IDS_SPS_PRESETS "SPS Presets"
+ IDS_ALL_FILES "All files"
+ IDS_GENERAL "General"
+ IDS_OPERATORS "Operators"
+ IDS_FUNCTIONS "Functions"
+ IDS_CONSTANTS "Constants"
+ IDS_LOAD_PRESET "Load Preset"
+ IDS_CLEAR_CURRENT_SETTINGS "Clear current SPS settings?"
+ IDS_CONFIRMATION "Confirmation"
+ IDS_SPS_TITLE "Nullsoft Signal Processing Studio DSP"
+ IDS_SPS_MODULE_TITLE "Signal Processing Studio"
+END
+
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/DSP/dsp_sps/resource.h b/Src/Plugins/DSP/dsp_sps/resource.h
new file mode 100644
index 00000000..8288d34b
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/resource.h
@@ -0,0 +1,70 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by res.rc
+//
+#define IDS_SPS_SHOW_CONFIG 1
+#define IDS_SHOW_EDITOR 2
+#define IDS_HIDE_EDITOR 3
+#define IDS_SAVE_PRESET 4
+#define IDS_SPS_PRESETS 5
+#define IDS_ALL_FILES 6
+#define IDS_GENERAL 7
+#define IDS_OPERATORS 8
+#define IDS_FUNCTIONS 9
+#define IDS_CONSTANTS 10
+#define IDS_LOAD_PRESET 11
+#define IDS_CLEAR_CURRENT_SETTINGS 12
+#define IDS_CONFIRMATION 13
+#define IDS_SPS_TITLE 14
+#define IDS_SPS_MODULE_TITLE 15
+#define IDD_DIALOG1 101
+#define IDR_GENERAL 102
+#define IDR_OPERATORS 103
+#define IDR_FUNCTIONS 104
+#define IDR_CONSTANTS 105
+#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 106
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1024
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/DSP/dsp_sps/sps_common.cpp b/Src/Plugins/DSP/dsp_sps/sps_common.cpp
new file mode 100644
index 00000000..1e8df30b
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/sps_common.cpp
@@ -0,0 +1,574 @@
+#include <windows.h>
+#include "resource.h"
+#include "..\..\..\winamp\dsp.h"
+#include "sps_common.h"
+
+void NSEEL_HOSTSTUB_EnterMutex() {}
+void NSEEL_HOSTSTUB_LeaveMutex() {}
+
+extern winampDSPModule mod;
+
+char *SPSHELP_gethelptext( int sel )
+{
+ int help_id[] = { IDR_GENERAL,IDR_OPERATORS,IDR_FUNCTIONS,IDR_CONSTANTS };
+ void *data = 0;
+
+ HRSRC rsrc = FindResource( WASABI_API_LNG_HINST, MAKEINTRESOURCE( help_id[ sel ] ), "TEXT" );
+ if ( rsrc )
+ {
+ HGLOBAL resourceHandle = LoadResource( WASABI_API_LNG_HINST, rsrc );
+ data = LockResource( resourceHandle );
+
+ return (char *) data;
+ }
+
+ return 0;
+}
+
+void SPS_initcontext( SPSEffectContext *ctx )
+{
+ memset( ctx, 0, sizeof( SPSEffectContext ) );
+ InitializeCriticalSection( &ctx->code_cs );
+ ctx->vm_ctx = NSEEL_VM_alloc();
+ ctx->code_needrecompile = 7;
+}
+
+void SPS_quitcontext( SPSEffectContext *ctx )
+{
+ if ( ctx->sample_buffer ) GlobalFree( ctx->sample_buffer );
+ ctx->sample_buffer_len = 0;
+ ctx->sample_buffer = NULL;
+
+ NSEEL_code_free( ctx->code[ 0 ] );
+ NSEEL_code_free( ctx->code[ 1 ] );
+ NSEEL_code_free( ctx->code[ 2 ] );
+ memset( &ctx->code, 0, sizeof( ctx->code ) );
+
+ //megabuf_cleanup( ctx->vm_ctx );
+ NSEEL_VM_free( ctx->vm_ctx );
+
+ ctx->vm_ctx = 0;
+ memset( &ctx->vars, 0, sizeof( ctx->vars ) );
+
+ DeleteCriticalSection( &ctx->code_cs );
+}
+
+static __inline int double2int( double v )
+{
+#if 0
+ return (int) v;
+#else
+ int a;
+ __asm
+ {
+ fld v;
+ fistp a;
+ }
+ return a;
+#endif
+}
+
+static __inline double int24todouble( unsigned char *int24 )
+{
+ unsigned int a = ( int24[ 0 ] ) | ( int24[ 1 ] << 8 ) | ( int24[ 2 ] << 16 );
+
+ if ( a & 0x800000 )
+ a |= 0xFF000000;
+ else
+ a &= 0xFFFFFF;
+
+ return (double) ( ( (signed int) a ) + 0.5 ) / 8388607.5;
+}
+
+static __inline void doubletoint24( double v, unsigned char *int24 )
+{
+ v = ( v * 8388607.5 ) - 0.5;
+ if ( v <= -8388608.0 )
+ {
+ int24[ 0 ] = int24[ 1 ] = 0; // 0x800000 is lowest possible value
+ int24[ 2 ] = 0x80;
+ }
+ else if ( v >= 8388607.0 )
+ {
+ int24[ 0 ] = int24[ 1 ] = 0xff; // 0x7fffff is highest possible value
+ int24[ 2 ] = 0x7f;
+ }
+ else
+ {
+ int a = (int) v;
+ int24[ 0 ] = a & 0xff;
+ int24[ 1 ] = ( a >> 8 ) & 0xff;
+ int24[ 2 ] = ( a >> 16 ) & 0xff;
+ }
+}
+
+int SPS_process_samples( SPSEffectContext *ctx,
+ void *samples, int numsamples,
+ int isfloat, int bps, int nch,
+ int srate, int maxout, int minout )
+{
+ // can only do 1 or 2ch for now
+ if ( nch != 1 && nch != 2 )
+ return numsamples;
+
+ int samplepair_size = ( bps / 8 ) * nch;
+ if ( ctx->bypass )
+ {
+ memset( ctx->triggers, 0, sizeof( ctx->triggers ) );
+
+ return numsamples;
+ }
+
+ if ( !samples || numsamples < 1 )
+ return numsamples;
+
+ int rlen = numsamples * samplepair_size;
+
+ if ( !ctx->sample_buffer || ctx->sample_buffer_len < rlen )
+ {
+ ctx->sample_buffer_len = rlen * 2;
+
+ if ( ctx->sample_buffer )
+ GlobalFree( ctx->sample_buffer );
+
+ ctx->sample_buffer = (void *) GlobalAlloc( GMEM_FIXED, ctx->sample_buffer_len );
+ }
+
+ if ( !ctx->sample_buffer )
+ return numsamples;
+
+ int needinit = ctx->last_nch != nch || ctx->last_srate != srate;
+ ctx->last_nch = nch;
+ ctx->last_srate = srate;
+
+ if ( ctx->code_needrecompile )
+ {
+ EnterCriticalSection( &ctx->code_cs );
+ if ( ctx->code_needrecompile & 1 )
+ {
+ //NSEEL_VM_resetvars( ctx->vm_ctx );
+ ctx->vars.spl0 = NSEEL_VM_regvar( ctx->vm_ctx, "spl0" );
+ ctx->vars.spl1 = NSEEL_VM_regvar( ctx->vm_ctx, "spl1" );
+ ctx->vars.skip = NSEEL_VM_regvar( ctx->vm_ctx, "skip" );
+ ctx->vars.repeat = NSEEL_VM_regvar( ctx->vm_ctx, "repeat" );
+ ctx->vars.nch = NSEEL_VM_regvar( ctx->vm_ctx, "nch" );
+ ctx->vars.srate = NSEEL_VM_regvar( ctx->vm_ctx, "srate" );
+ ctx->vars.sliders1 = NSEEL_VM_regvar( ctx->vm_ctx, "slider1" );
+ ctx->vars.sliders2 = NSEEL_VM_regvar( ctx->vm_ctx, "slider2" );
+ ctx->vars.sliders3 = NSEEL_VM_regvar( ctx->vm_ctx, "slider3" );
+ ctx->vars.sliders4 = NSEEL_VM_regvar( ctx->vm_ctx, "slider4" );
+ ctx->vars.trigger1 = NSEEL_VM_regvar( ctx->vm_ctx, "trig1" );
+ ctx->vars.trigger2 = NSEEL_VM_regvar( ctx->vm_ctx, "trig2" );
+ ctx->vars.trigger3 = NSEEL_VM_regvar( ctx->vm_ctx, "trig3" );
+ ctx->vars.trigger4 = NSEEL_VM_regvar( ctx->vm_ctx, "trig4" );
+
+ needinit = 1;
+ NSEEL_code_free( ctx->code[ 0 ] );
+ ctx->code[ 0 ] = NSEEL_code_compile( ctx->vm_ctx, ctx->curpreset.code_text[ 0 ], 0 );
+ }
+
+ if ( ctx->code_needrecompile & 2 )
+ {
+ NSEEL_code_free( ctx->code[ 1 ] );
+ ctx->code[ 1 ] = NSEEL_code_compile( ctx->vm_ctx, ctx->curpreset.code_text[ 1 ], 0 );
+#ifdef DEBUG
+ if ( !ctx->code[ 1 ] && NSEEL_code_getcodeerror( ctx->vm_ctx ) && *NSEEL_code_getcodeerror( ctx->vm_ctx ) )
+ OutputDebugString( NSEEL_code_getcodeerror( ctx->vm_ctx ) );
+#endif
+ }
+ if ( ctx->code_needrecompile & 4 )
+ {
+ NSEEL_code_free( ctx->code[ 2 ] );
+ ctx->code[ 2 ] = NSEEL_code_compile( ctx->vm_ctx, ctx->curpreset.code_text[ 2 ], 0 );
+ ctx->sliderchange = 1;
+ }
+ ctx->code_needrecompile = 0;
+ LeaveCriticalSection( &ctx->code_cs );
+ }
+
+ if ( !ctx->vars.spl0 )
+ return numsamples;
+
+ *( ctx->vars.nch ) = (double) nch;
+ *( ctx->vars.srate ) = (double) srate;
+
+ int slidech = ctx->sliderchange;
+ ctx->sliderchange = 0;
+
+ if ( ctx->triggers[ 0 ] )
+ {
+ ctx->triggers[ 0 ]--;
+ *( ctx->vars.trigger1 ) = 1.0;
+ }
+
+ if ( ctx->triggers[ 1 ] )
+ {
+ ctx->triggers[ 1 ]--;
+ *( ctx->vars.trigger2 ) = 1.0;
+ }
+
+ if ( ctx->triggers[ 2 ] )
+ {
+ ctx->triggers[ 2 ]--;
+ *( ctx->vars.trigger3 ) = 1.0;
+ }
+
+ if ( ctx->triggers[ 3 ] )
+ {
+ ctx->triggers[ 3 ]--;
+ *( ctx->vars.trigger4 ) = 1.0;
+ }
+
+ if ( needinit || slidech )
+ {
+ *( ctx->vars.sliders1 ) = (double) ctx->curpreset.sliderpos[ 0 ] / 1000.0;
+ *( ctx->vars.sliders2 ) = (double) ctx->curpreset.sliderpos[ 1 ] / 1000.0;
+ *( ctx->vars.sliders3 ) = (double) ctx->curpreset.sliderpos[ 2 ] / 1000.0;
+ *( ctx->vars.sliders4 ) = (double) ctx->curpreset.sliderpos[ 3 ] / 1000.0;
+ }
+
+ if ( needinit )
+ {
+ //megabuf_cleanup( ctx->vm_ctx );
+ NSEEL_code_execute( ctx->code[ 0 ] );
+ }
+
+ if ( needinit || slidech )
+ {
+ NSEEL_code_execute( ctx->code[ 2 ] );
+ }
+
+
+ if ( !maxout )
+ maxout = numsamples;
+
+ memcpy( ctx->sample_buffer, samples, rlen );
+ int x = 0;
+ int outpos = 0;
+
+ while ( x < numsamples && outpos < maxout )
+ {
+ *( ctx->vars.skip ) = 0;
+ *( ctx->vars.repeat ) = 0;
+
+ if ( isfloat )
+ {
+ if ( bps == 32 )
+ {
+ float *sbuf_float = (float *) ctx->sample_buffer;
+ if ( nch == 2 )
+ {
+ *( ctx->vars.spl0 ) = (double) sbuf_float[ x + x ];
+ *( ctx->vars.spl1 ) = (double) sbuf_float[ x + x + 1 ];
+ }
+ else
+ {
+ *( ctx->vars.spl1 ) =
+ *( ctx->vars.spl0 ) = (double) sbuf_float[ x ];
+ }
+ }
+ else if ( bps == 64 )
+ {
+ double *sbuf_dbl = (double *) ctx->sample_buffer;
+ if ( nch == 2 )
+ {
+ *( ctx->vars.spl0 ) = sbuf_dbl[ x + x ];
+ *( ctx->vars.spl1 ) = sbuf_dbl[ x + x + 1 ];
+ }
+ else
+ {
+ *( ctx->vars.spl1 ) =
+ *( ctx->vars.spl0 ) = sbuf_dbl[ x ];
+ }
+ }
+ else
+ {
+ *( ctx->vars.spl1 ) =
+ *( ctx->vars.spl0 ) = 0.0;
+ }
+ }
+ else
+ {
+ if ( bps == 16 )
+ {
+ short *sbuf_short = (short *) ctx->sample_buffer;
+ if ( nch == 2 )
+ {
+ *( ctx->vars.spl0 ) = ( sbuf_short[ x + x ] + 0.5 ) / 32767.5;
+ *( ctx->vars.spl1 ) = ( sbuf_short[ x + x + 1 ] + 0.5 ) / 32767.5;
+ }
+ else
+ {
+ *( ctx->vars.spl1 ) =
+ *( ctx->vars.spl0 ) = ( sbuf_short[ x ] + 0.5 ) / 32767.5;
+ }
+ }
+ else if ( bps == 8 )
+ {
+ unsigned char *sbuf_char = (unsigned char *) ctx->sample_buffer;
+ if ( nch == 2 )
+ {
+ *( ctx->vars.spl0 ) = ( sbuf_char[ x + x ] - 127.5 ) / 127.5;
+ *( ctx->vars.spl1 ) = ( sbuf_char[ x + x + 1 ] - 127.5 ) / 127.5;
+ }
+ else
+ {
+ *( ctx->vars.spl1 ) =
+ *( ctx->vars.spl0 ) = ( sbuf_char[ x ] - 127.5 ) / 127.5;
+ }
+ }
+ else if ( bps == 24 )
+ {
+ unsigned char *sbuf_char = (unsigned char *) ctx->sample_buffer;
+ if ( nch == 2 )
+ {
+ int x6 = ( x << 2 ) + x + x;
+ *( ctx->vars.spl0 ) = int24todouble( sbuf_char + x6 );
+ *( ctx->vars.spl1 ) = int24todouble( sbuf_char + x6 + 3 );
+ }
+ else
+ {
+ *( ctx->vars.spl1 ) =
+ *( ctx->vars.spl0 ) = int24todouble( sbuf_char + x + x + x );
+ }
+ }
+ else
+ {
+ // todo: 32 bit mode?
+ *( ctx->vars.spl1 ) =
+ *( ctx->vars.spl0 ) = 0.0;
+ }
+ }
+
+ NSEEL_code_execute( ctx->code[ 1 ] );
+
+ if ( *( ctx->vars.skip ) < 0.0001 || (/*samples out*/ outpos + /* samples left */ ( numsamples - x ) ) < minout )
+ {
+ if ( isfloat )
+ {
+ if ( bps == 32 )
+ {
+ float *samples_float = (float *) samples;
+ if ( nch == 2 )
+ {
+ samples_float[ outpos + outpos ] = (float) *ctx->vars.spl0;
+ samples_float[ outpos + outpos + 1 ] = (float) *ctx->vars.spl1;
+ }
+ else
+ {
+ samples_float[ outpos ] = (float) *ctx->vars.spl0;
+ }
+ }
+ else if ( bps == 64 )
+ {
+ double *samples_double = (double *) samples;
+ if ( nch == 2 )
+ {
+ samples_double[ outpos + outpos ] = *ctx->vars.spl0;
+ samples_double[ outpos + outpos + 1 ] = *ctx->vars.spl1;
+ }
+ else
+ {
+ samples_double[ outpos ] = *ctx->vars.spl0;
+ }
+ }
+ }
+ else
+ {
+ if ( bps == 16 )
+ {
+ short *samples_short = (short *) samples;
+ if ( nch == 2 )
+ {
+ double d = *( ctx->vars.spl0 ) * 32767.5 - 0.5;
+ if ( d <= -32768.0 )
+ samples_short[ outpos + outpos ] = -32768;
+ else if ( d >= 32767.0 )
+ samples_short[ outpos + outpos ] = 32767;
+ else
+ samples_short[ outpos + outpos ] = double2int( d );
+
+ d = *( ctx->vars.spl1 ) * 32767.5 - 0.5;
+ if ( d <= -32768.0 )
+ samples_short[ outpos + outpos + 1 ] = -32768;
+ else if ( d >= 32767.0 )
+ samples_short[ outpos + outpos + 1 ] = 32767;
+ else
+ samples_short[ outpos + outpos + 1 ] = double2int( d );
+ }
+ else
+ {
+ double d = *( ctx->vars.spl0 ) * 32767.5 - 0.5;
+ if ( d <= -32768.0 )
+ samples_short[ outpos ] = -32768;
+ else if ( d >= 32767.0 )
+ samples_short[ outpos ] = 32767;
+ else
+ samples_short[ outpos ] = double2int( d );
+ }
+ }
+ else if ( bps == 8 )
+ {
+ unsigned char *samples_char = (unsigned char *) samples;
+ if ( nch == 2 )
+ {
+ double d = *( ctx->vars.spl0 ) * 127.5 + 127.5;
+ if ( d <= 0.0 )
+ samples_char[ outpos + outpos ] = 0;
+ else if ( d >= 255.0 )
+ samples_char[ outpos + outpos ] = 255;
+ else
+ samples_char[ outpos + outpos ] = double2int( d );
+
+ d = *( ctx->vars.spl1 ) * 127.5 + 127.5;
+ if ( d <= 0.0 )
+ samples_char[ outpos + outpos + 1 ] = 0;
+ else if ( d >= 255.0 )
+ samples_char[ outpos + outpos + 1 ] = 255;
+ else
+ samples_char[ outpos + outpos + 1 ] = double2int( d );
+ }
+ else
+ {
+ double d = *( ctx->vars.spl0 ) * 127.5 + 127.5;
+ if ( d <= 0.0 )
+ samples_char[ outpos ] = 0;
+ else if ( d >= 255.0 )
+ samples_char[ outpos ] = 255;
+ else
+ samples_char[ outpos ] = double2int( d );
+ }
+ }
+ else if ( bps == 24 )
+ {
+ unsigned char *samples_char = (unsigned char *) samples;
+ if ( nch == 2 )
+ {
+ int op6 = outpos + outpos + ( outpos << 2 );
+ doubletoint24( *ctx->vars.spl0, samples_char + op6 );
+ doubletoint24( *ctx->vars.spl1, samples_char + op6 + 3 );
+ }
+ else
+ {
+ doubletoint24( *ctx->vars.spl0, samples_char + outpos + outpos + outpos );
+ }
+ }
+ else
+ {
+ memcpy( (char *) samples + outpos * samplepair_size, (char *) ctx->sample_buffer + x * samplepair_size,
+ samplepair_size );
+ // todo: 24/32 bit modes
+ }
+ }
+ outpos++;
+
+ if ( *( ctx->vars.repeat ) < 0.0001 )
+ x++;
+ }
+ else x++;
+ }
+
+ return outpos;
+}
+
+static void WriteInt( char *section, char *name, int value, char *fn )
+{
+ char str[ 128 ];
+ wsprintf( str, "%d", value );
+ WritePrivateProfileString( section, name, str, fn );
+}
+
+void SPS_save_preset( SPSEffectContext *ctx, char *filename, char *section )
+{
+ SPSPresetConfig *cfg = &ctx->curpreset;
+
+ WriteInt( section, "slider1", cfg->sliderpos[ 0 ], filename );
+ WriteInt( section, "slider2", cfg->sliderpos[ 1 ], filename );
+ WriteInt( section, "slider3", cfg->sliderpos[ 2 ], filename );
+ WriteInt( section, "slider4", cfg->sliderpos[ 3 ], filename );
+ int x;
+ for ( x = 0; x < 4; x++ )
+ {
+ int y;
+ for ( y = 0; y < 3; y++ )
+ {
+ char buf[ 64 ];
+ wsprintf( buf, "labels_%d_%d", x, y );
+ WritePrivateProfileString( section, buf, cfg->slider_labels[ x ][ y ], filename );
+ }
+ }
+
+ int s = strlen( cfg->code_text[ 0 ] );
+ WriteInt( section, "code0_size", s, filename );
+ WritePrivateProfileStruct( section, "code0_data", cfg->code_text[ 0 ], s, filename );
+ s = strlen( cfg->code_text[ 1 ] );
+ WriteInt( section, "code1_size", s, filename );
+ WritePrivateProfileStruct( section, "code1_data", cfg->code_text[ 1 ], s, filename );
+ s = strlen( cfg->code_text[ 2 ] );
+ WriteInt( section, "code2_size", s, filename );
+ WritePrivateProfileStruct( section, "code2_data", cfg->code_text[ 2 ], s, filename );
+}
+
+void SPS_load_preset( SPSEffectContext *ctx, char *filename, char *section )
+{
+ SPSPresetConfig *cfg = &ctx->curpreset;
+ EnterCriticalSection( &ctx->code_cs );
+ cfg->sliderpos[ 0 ] = GetPrivateProfileInt( section, "slider1", 0, filename );
+ cfg->sliderpos[ 1 ] = GetPrivateProfileInt( section, "slider2", 0, filename );
+ cfg->sliderpos[ 2 ] = GetPrivateProfileInt( section, "slider3", 0, filename );
+ cfg->sliderpos[ 3 ] = GetPrivateProfileInt( section, "slider4", 0, filename );
+ int x;
+ for ( x = 0; x < 4; x++ )
+ {
+ int y;
+ for ( y = 0; y < 3; y++ )
+ {
+ char buf[ 64 ];
+ wsprintf( buf, "labels_%d_%d", x, y );
+ GetPrivateProfileString( section, buf, "", cfg->slider_labels[ x ][ y ], MAX_LABEL_LEN, filename );
+ }
+ }
+
+ int s = GetPrivateProfileInt( section, "code0_size", 0, filename );
+ cfg->code_text[ 0 ][ 0 ] = 0;
+ if ( s > 0 && s < MAX_CODE_LEN - 1 )
+ {
+ if ( GetPrivateProfileStruct( section, "code0_data", cfg->code_text[ 0 ], s, filename ) )
+ cfg->code_text[ 0 ][ s ] = 0;
+ else
+ cfg->code_text[ 0 ][ 0 ] = 0;
+ }
+
+ s = GetPrivateProfileInt( section, "code1_size", 0, filename );
+ cfg->code_text[ 1 ][ 0 ] = 0;
+ if ( s > 0 && s < MAX_CODE_LEN - 1 )
+ {
+ if ( GetPrivateProfileStruct( section, "code1_data", cfg->code_text[ 1 ], s, filename ) )
+ cfg->code_text[ 1 ][ s ] = 0;
+ else
+ cfg->code_text[ 1 ][ 0 ] = 0;
+ }
+ s = GetPrivateProfileInt( section, "code2_size", 0, filename );
+ cfg->code_text[ 2 ][ 0 ] = 0;
+ if ( s > 0 && s < MAX_CODE_LEN - 1 )
+ {
+ if ( GetPrivateProfileStruct( section, "code2_data", cfg->code_text[ 2 ], s, filename ) )
+ cfg->code_text[ 2 ][ s ] = 0;
+ else
+ cfg->code_text[ 2 ][ 0 ] = 0;
+ }
+ ctx->code_needrecompile = 7;
+ lstrcpyn( ctx->curpreset_name, filename, sizeof( ctx->curpreset_name ) );
+ LeaveCriticalSection( &ctx->code_cs );
+}
+
+void SPS_initapp()
+{
+ NSEEL_init();
+ //NSEEL_addfunctionex( "megabuf", 1, (int) _asm_megabuf, (int) _asm_megabuf_end - (int) _asm_megabuf, megabuf_ppproc );
+}
+
+void SPS_quitapp()
+{
+ NSEEL_quit();
+} \ No newline at end of file
diff --git a/Src/Plugins/DSP/dsp_sps/sps_common.h b/Src/Plugins/DSP/dsp_sps/sps_common.h
new file mode 100644
index 00000000..2157ca42
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/sps_common.h
@@ -0,0 +1,63 @@
+#ifndef _SPS_COMMON_H_
+#define _SPS_COMMON_H_
+
+#if (_MSC_VER <= 1200)
+typedef int intptr_t;
+#endif
+
+#include "..\..\..\ns-eel2\ns-eel.h"
+#include "api__dsp_sps.h"
+
+#define MAX_CODE_LEN 32768
+#define MAX_LABEL_LEN 32
+
+char *SPSHELP_gethelptext(int sel);
+
+typedef struct
+{
+ char code_text[3][MAX_CODE_LEN];
+
+ char slider_labels[4][3][MAX_LABEL_LEN];
+ int sliderpos[4];
+} SPSPresetConfig;
+
+// someday we'll have multiple of these, stackable like :)
+typedef struct
+{
+ CRITICAL_SECTION code_cs;
+ int code_needrecompile; // &1 = init, &2 = per sample, &4=slider
+ NSEEL_VMCTX vm_ctx;
+ NSEEL_CODEHANDLE code[3];
+ void *sample_buffer;
+ int sample_buffer_len;
+ int last_nch, last_srate;
+ struct
+ {
+ double *spl0, *spl1;
+ double *skip;
+ double *repeat;
+ double *nch;
+ double *srate;
+ double *sliders1,*sliders2,*sliders3,*sliders4;
+ double *trigger1,*trigger2,*trigger3,*trigger4;
+ } vars;
+ int triggers[4];
+ int sliderchange;
+
+ int bypass; // def1
+ SPSPresetConfig curpreset;
+ char curpreset_name[2048];
+}
+SPSEffectContext;
+
+void SPS_initapp();
+void SPS_quitapp();
+void SPS_initcontext(SPSEffectContext *ctx);
+void SPS_quitcontext(SPSEffectContext *ctx);
+int SPS_process_samples(SPSEffectContext *ctx, void *samples,
+ int numsamples, int isfloat, int bps,
+ int nch, int srate, int maxout, int minout);
+void SPS_load_preset(SPSEffectContext *ctx, char *filename, char *section);
+void SPS_save_preset(SPSEffectContext *ctx, char *filename, char *section);
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/DSP/dsp_sps/sps_configdlg.h b/Src/Plugins/DSP/dsp_sps/sps_configdlg.h
new file mode 100644
index 00000000..b6e462a1
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/sps_configdlg.h
@@ -0,0 +1,476 @@
+#ifndef SPS_CONFIGDLG_IMPL
+
+BOOL CALLBACK SPS_configWindowProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+
+#else
+
+#ifdef SPS_CONFIGDLG_HIDEABLE_EDITOR
+static void showHideSliders(HWND hwndDlg, SPSEffectContext *ctx)
+{
+ int x;
+ x=(SPS_CONFIGDLG_HIDEABLE_EDITOR || ctx->curpreset.slider_labels[0][0][0])?SW_SHOWNA:SW_HIDE;
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER1),x);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER1_LABEL1),x);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER1_LABEL2),x);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER1_LABEL3),x);
+ x=(SPS_CONFIGDLG_HIDEABLE_EDITOR || ctx->curpreset.slider_labels[1][0][0])?SW_SHOWNA:SW_HIDE;
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER2),x);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER2_LABEL1),x);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER2_LABEL2),x);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER2_LABEL3),x);
+ x=(SPS_CONFIGDLG_HIDEABLE_EDITOR || ctx->curpreset.slider_labels[2][0][0])?SW_SHOWNA:SW_HIDE;
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER3),x);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER3_LABEL1),x);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER3_LABEL2),x);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER3_LABEL3),x);
+ x=(SPS_CONFIGDLG_HIDEABLE_EDITOR || ctx->curpreset.slider_labels[3][0][0])?SW_SHOWNA:SW_HIDE;
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER4),x);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER4_LABEL1),x);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER4_LABEL2),x);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_SLIDER4_LABEL3),x);
+}
+
+static void showHideEditor(HWND hwndDlg, int isInit)
+{
+ int en=0;
+ static int lw;
+ RECT r;
+ GetWindowRect(hwndDlg,&r);
+ if (isInit)
+ {
+ lw=r.right-r.left;
+ }
+ if (!SPS_CONFIGDLG_HIDEABLE_EDITOR)
+ {
+ SetDlgItemText(hwndDlg,IDC_EDIT,WASABI_API_LNGSTRING(IDS_SHOW_EDITOR));
+ RECT r2;
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_SAVE),&r2);
+ SetWindowPos(hwndDlg,NULL,0,0,r2.left-r.left,r.bottom-r.top,SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE);
+ }
+ else
+ {
+ if (!isInit)
+ {
+ SetWindowPos(hwndDlg,NULL,0,0,lw,r.bottom-r.top,SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE);
+ }
+ SetDlgItemText(hwndDlg,IDC_EDIT,WASABI_API_LNGSTRING(IDS_HIDE_EDITOR));
+ en=1;
+ }
+
+ UINT tab[] = {
+ IDC_SLIDER1_LABEL1,
+ IDC_SLIDER1_LABEL2,
+ IDC_SLIDER1_LABEL3,
+ IDC_SLIDER2_LABEL1,
+ IDC_SLIDER2_LABEL2,
+ IDC_SLIDER2_LABEL3,
+ IDC_SLIDER3_LABEL1,
+ IDC_SLIDER3_LABEL2,
+ IDC_SLIDER3_LABEL3,
+ IDC_SLIDER4_LABEL1,
+ IDC_SLIDER4_LABEL2,
+ IDC_SLIDER4_LABEL3,
+ };
+
+ for (int x = 0; x < sizeof(tab)/sizeof(UINT); x ++)
+ {
+ EnableWindow(GetDlgItem(hwndDlg,tab[x]),en);
+ }
+
+ UINT tab2[]={
+ IDC_SAVE,
+ IDC_SHOWHELP,
+ IDC_INIT,
+ IDC_ONSLIDERCHANGE,
+ IDC_PERSAMPLE,
+ };
+
+ for (int x = 0; x < sizeof(tab2)/sizeof(UINT); x++)
+ {
+ ShowWindow(GetDlgItem(hwndDlg,tab2[x]),en?SW_SHOWNA:SW_HIDE);
+ }
+}
+
+#endif
+
+char* BuildFilterString(void)
+{
+ static char filterStr[MAX_PATH] = {0};
+ if(!filterStr[0])
+ {
+ char* temp = filterStr;
+ //"SPS presets\0*.sps\0All files\0*.*\0"
+ WASABI_API_LNGSTRING_BUF(IDS_SPS_PRESETS,filterStr,128);
+ temp += lstrlen(filterStr)+1;
+ lstrcpyn(temp, "*.sps", MAX_PATH);
+ temp = temp + lstrlen(temp) + 1;
+ lstrcpyn(temp, WASABI_API_LNGSTRING(IDS_ALL_FILES), 128);
+ temp = temp + lstrlen(temp) + 1;
+ lstrcpyn(temp, "*.*", MAX_PATH);
+ *(temp = temp + lstrlen(temp) + 1) = 0;
+ }
+ return filterStr;
+}
+
+static void updatePresetText(HWND hwndDlg, SPSEffectContext *ctx)
+{
+ char *p=strrchr(ctx->curpreset_name,'\\');
+ if (!p) p=ctx->curpreset_name;
+ else p++;
+ char *p2=strrchr(p,'.');
+ if (p2) *p2=0;
+ SetDlgItemText(hwndDlg,IDC_PRESET,p);
+ if (p2) *p2='.';
+}
+
+static void dosavePreset(HWND hwndDlg, SPSEffectContext *ctx)
+{
+ char temp[2048] = {0};
+ OPENFILENAME l={sizeof(l),0};
+ char buf1[2048],buf2[2048];
+ GetCurrentDirectory(sizeof(buf2),buf2);
+ strcpy(buf1,g_path);
+ l.hwndOwner = hwndDlg;
+ l.lpstrFilter = BuildFilterString();
+ l.lpstrFile = temp;
+ strcpy(temp,ctx->curpreset_name);
+ l.nMaxFile = 2048-1;
+ l.lpstrTitle = WASABI_API_LNGSTRING(IDS_SAVE_PRESET);
+ l.lpstrDefExt = "SPS";
+ l.lpstrInitialDir = buf1;
+ l.Flags = OFN_HIDEREADONLY|OFN_EXPLORER|OFN_OVERWRITEPROMPT;
+ if (GetSaveFileName(&l))
+ {
+ strcpy(ctx->curpreset_name,temp);
+ SPS_save_preset(ctx,ctx->curpreset_name,"SPS PRESET");
+ updatePresetText(hwndDlg,ctx);
+ }
+ SetCurrentDirectory(buf2);
+}
+
+static void presetToDialog(HWND hwndDlg, SPSEffectContext *ctx)
+{
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,1000-ctx->curpreset.sliderpos[0]);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,1000-ctx->curpreset.sliderpos[1]);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETPOS,1,1000-ctx->curpreset.sliderpos[2]);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETPOS,1,1000-ctx->curpreset.sliderpos[3]);
+
+ SetDlgItemText(hwndDlg,IDC_SLIDER1_LABEL1,ctx->curpreset.slider_labels[0][0]);
+ SetDlgItemText(hwndDlg,IDC_SLIDER1_LABEL2,ctx->curpreset.slider_labels[0][1]);
+ SetDlgItemText(hwndDlg,IDC_SLIDER1_LABEL3,ctx->curpreset.slider_labels[0][2]);
+ SetDlgItemText(hwndDlg,IDC_SLIDER2_LABEL1,ctx->curpreset.slider_labels[1][0]);
+ SetDlgItemText(hwndDlg,IDC_SLIDER2_LABEL2,ctx->curpreset.slider_labels[1][1]);
+ SetDlgItemText(hwndDlg,IDC_SLIDER2_LABEL3,ctx->curpreset.slider_labels[1][2]);
+ SetDlgItemText(hwndDlg,IDC_SLIDER3_LABEL1,ctx->curpreset.slider_labels[2][0]);
+ SetDlgItemText(hwndDlg,IDC_SLIDER3_LABEL2,ctx->curpreset.slider_labels[2][1]);
+ SetDlgItemText(hwndDlg,IDC_SLIDER3_LABEL3,ctx->curpreset.slider_labels[2][2]);
+ SetDlgItemText(hwndDlg,IDC_SLIDER4_LABEL1,ctx->curpreset.slider_labels[3][0]);
+ SetDlgItemText(hwndDlg,IDC_SLIDER4_LABEL2,ctx->curpreset.slider_labels[3][1]);
+ SetDlgItemText(hwndDlg,IDC_SLIDER4_LABEL3,ctx->curpreset.slider_labels[3][2]);
+
+ SetDlgItemText(hwndDlg,IDC_INIT,ctx->curpreset.code_text[0]);
+ SetDlgItemText(hwndDlg,IDC_PERSAMPLE,ctx->curpreset.code_text[1]);
+ SetDlgItemText(hwndDlg,IDC_ONSLIDERCHANGE,ctx->curpreset.code_text[2]);
+
+ updatePresetText(hwndDlg,ctx);
+#ifdef SPS_CONFIGDLG_HIDEABLE_EDITOR
+ showHideSliders(hwndDlg,ctx);
+#endif
+}
+
+static int m_help_lastpage=4;
+static char *m_localtext;
+static void _dosetsel(HWND hwndDlg)
+{
+ HWND tabwnd=GetDlgItem(hwndDlg,IDC_TAB1);
+ int sel=TabCtrl_GetCurSel(tabwnd);
+ char *text="";
+
+ m_help_lastpage=sel;
+
+ text=SPSHELP_gethelptext(sel);
+
+ if (!text && sel == 4 && m_localtext) text=m_localtext;
+
+ SetDlgItemText(hwndDlg,IDC_EDIT1,text);
+}
+
+static BOOL CALLBACK evalHelpDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ TCITEM item;
+ HWND tabwnd=GetDlgItem(hwndDlg,IDC_TAB1);
+ helpWnd=hwndDlg;
+ item.mask=TCIF_TEXT;
+ item.pszText=WASABI_API_LNGSTRING(IDS_GENERAL);
+ TabCtrl_InsertItem(tabwnd,0,&item);
+ item.pszText=WASABI_API_LNGSTRING(IDS_OPERATORS);
+ TabCtrl_InsertItem(tabwnd,1,&item);
+ item.pszText=WASABI_API_LNGSTRING(IDS_FUNCTIONS);
+ TabCtrl_InsertItem(tabwnd,2,&item);
+ item.pszText=WASABI_API_LNGSTRING(IDS_CONSTANTS);
+ TabCtrl_InsertItem(tabwnd,3,&item);
+ // fucko: context specific stuff
+ m_localtext=0;
+ if (lParam)
+ {
+ item.pszText=(char *)lParam;
+ m_localtext=item.pszText + strlen(item.pszText)+1;
+ TabCtrl_InsertItem(tabwnd,4,&item);
+ }
+ else if (m_help_lastpage > 3) m_help_lastpage=0;
+
+ TabCtrl_SetCurSel(tabwnd,m_help_lastpage);
+ _dosetsel(hwndDlg);
+ }
+ return 0;
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
+ {
+ EndDialog(hwndDlg,1);
+ helpWnd = 0;
+ }
+ return 0;
+
+ case WM_NOTIFY:
+ {
+ LPNMHDR p=(LPNMHDR) lParam;
+ if (p->idFrom == IDC_TAB1 && p->code == TCN_SELCHANGE) _dosetsel(hwndDlg);
+ }
+ return 0;
+ }
+ return 0;
+}
+
+BOOL CALLBACK SPS_configWindowProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+ SPSEffectContext *ctx;
+
+ if ( uMsg == WM_INITDIALOG )
+ SetWindowLong( hwndDlg, DWL_USER, lParam );
+
+ ctx = (SPSEffectContext *) GetWindowLong( hwndDlg, DWL_USER );
+
+ if ( ctx )
+ {
+ switch ( uMsg )
+ {
+ case WM_INITDIALOG:
+ SetWindowText( hwndDlg, hdr.description );
+
+ SendDlgItemMessage( hwndDlg, IDC_SLIDER1, TBM_SETTICFREQ, 100, 0 );
+ SendDlgItemMessage( hwndDlg, IDC_SLIDER2, TBM_SETTICFREQ, 100, 0 );
+ SendDlgItemMessage( hwndDlg, IDC_SLIDER3, TBM_SETTICFREQ, 100, 0 );
+ SendDlgItemMessage( hwndDlg, IDC_SLIDER4, TBM_SETTICFREQ, 100, 0 );
+ SendDlgItemMessage( hwndDlg, IDC_SLIDER1, TBM_SETRANGEMIN, 0, 0 );
+ SendDlgItemMessage( hwndDlg, IDC_SLIDER1, TBM_SETRANGEMAX, 0, 1000 );
+ SendDlgItemMessage( hwndDlg, IDC_SLIDER2, TBM_SETRANGEMIN, 0, 0 );
+ SendDlgItemMessage( hwndDlg, IDC_SLIDER2, TBM_SETRANGEMAX, 0, 1000 );
+ SendDlgItemMessage( hwndDlg, IDC_SLIDER3, TBM_SETRANGEMIN, 0, 0 );
+ SendDlgItemMessage( hwndDlg, IDC_SLIDER3, TBM_SETRANGEMAX, 0, 1000 );
+ SendDlgItemMessage( hwndDlg, IDC_SLIDER4, TBM_SETRANGEMIN, 0, 0 );
+ SendDlgItemMessage( hwndDlg, IDC_SLIDER4, TBM_SETRANGEMAX, 0, 1000 );
+
+#ifdef SPS_CONFIGDLG_HIDEABLE_EDITOR
+ showHideEditor( hwndDlg, TRUE );
+ showHideSliders( hwndDlg, ctx );
+#else
+ ShowWindow( GetDlgItem( hwndDlg, IDC_EDIT ), SW_HIDE );
+#endif
+ if ( !ctx->bypass )
+ CheckDlgButton( hwndDlg, IDC_BYPASS, BST_CHECKED );
+
+ presetToDialog( hwndDlg, ctx );
+ return 0;
+
+ case WM_USER + 0x80:
+ ShowWindow( hwndDlg, SW_SHOW );
+ SetForegroundWindow( hwndDlg );
+ return 0;
+
+ case WM_COMMAND:
+ {
+ int w = 0;
+ switch ( LOWORD( wParam ) )
+ {
+ case IDC_SLIDER1_LABEL1: w++;
+ case IDC_SLIDER1_LABEL2: w++;
+ case IDC_SLIDER1_LABEL3: w++;
+ case IDC_SLIDER2_LABEL1: w++;
+ case IDC_SLIDER2_LABEL2: w++;
+ case IDC_SLIDER2_LABEL3: w++;
+ case IDC_SLIDER3_LABEL1: w++;
+ case IDC_SLIDER3_LABEL2: w++;
+ case IDC_SLIDER3_LABEL3: w++;
+ case IDC_SLIDER4_LABEL1: w++;
+ case IDC_SLIDER4_LABEL2: w++;
+ case IDC_SLIDER4_LABEL3: w++;
+ if ( HIWORD( wParam ) == EN_CHANGE )
+ {
+ w = 12 - w;
+ GetDlgItemText( hwndDlg, LOWORD( wParam ), ctx->curpreset.slider_labels[ w / 3 ][ w % 3 ], MAX_LABEL_LEN );
+ }
+ break;
+#ifdef SPS_CONFIGDLG_HIDEABLE_EDITOR
+ case IDC_EDIT:
+ SPS_CONFIGDLG_HIDEABLE_EDITOR = !SPS_CONFIGDLG_HIDEABLE_EDITOR;
+ showHideEditor( hwndDlg, FALSE );
+ showHideSliders( hwndDlg, ctx );
+ break;
+#endif
+ case IDC_BYPASS:
+ ctx->bypass = !IsDlgButtonChecked( hwndDlg, IDC_BYPASS );
+ break;
+
+ case IDC_LOAD:
+ {
+ SendMessage( mod.hwndParent, WM_WA_IPC, 0, IPC_PUSH_DISABLE_EXIT );
+ char temp[ 2048 ] = { 0 };
+ OPENFILENAME l = { sizeof( l ),0 };
+ char buf1[ 2048 ], buf2[ 2048 ];
+ GetCurrentDirectory( sizeof( buf2 ), buf2 );
+ strcpy( buf1, g_path );
+ l.lpstrInitialDir = buf1;
+ l.hwndOwner = hwndDlg;
+ l.lpstrFilter = BuildFilterString();
+ l.lpstrFile = temp;
+ l.nMaxFile = 2048 - 1;
+ l.lpstrTitle = WASABI_API_LNGSTRING( IDS_LOAD_PRESET );
+ l.lpstrDefExt = "SPS";
+ l.Flags = OFN_HIDEREADONLY | OFN_EXPLORER;
+ if ( GetOpenFileName( &l ) )
+ {
+ SPS_load_preset( ctx, temp, "SPS PRESET" );
+ presetToDialog( hwndDlg, ctx );
+ }
+ SetCurrentDirectory( buf2 );
+ SendMessage( mod.hwndParent, WM_WA_IPC, 0, IPC_POP_DISABLE_EXIT );
+ }
+ break;
+
+ case IDC_NEW:
+ char title[ 32 ];
+ if ( MessageBox( hwndDlg, WASABI_API_LNGSTRING( IDS_CLEAR_CURRENT_SETTINGS ),
+ WASABI_API_LNGSTRING_BUF( IDS_CONFIRMATION, title, 32 ), MB_YESNO ) == IDYES )
+ {
+ EnterCriticalSection( &ctx->code_cs );
+ memset( &ctx->curpreset, 0, sizeof( ctx->curpreset ) );
+ ctx->code_needrecompile = 7;
+ memset( &ctx->triggers, 0, sizeof( ctx->triggers ) );
+ ctx->curpreset_name[ 0 ] = 0;
+ LeaveCriticalSection( &ctx->code_cs );
+
+ presetToDialog( hwndDlg, ctx );
+ }
+ break;
+
+ case IDC_SAVE:
+ SendMessage( mod.hwndParent, WM_WA_IPC, 0, IPC_PUSH_DISABLE_EXIT );
+ dosavePreset( hwndDlg, ctx );
+ SendMessage( mod.hwndParent, WM_WA_IPC, 0, IPC_POP_DISABLE_EXIT );
+ break;
+
+ case IDC_INIT:
+ if ( HIWORD( wParam ) == EN_CHANGE )
+ {
+ KillTimer( hwndDlg, 100 );
+ SetTimer( hwndDlg, 100, 250, NULL );
+ }
+ break;
+
+ case IDC_PERSAMPLE:
+ if ( HIWORD( wParam ) == EN_CHANGE )
+ {
+ KillTimer( hwndDlg, 101 );
+ SetTimer( hwndDlg, 101, 250, NULL );
+ }
+ break;
+
+ case IDC_ONSLIDERCHANGE:
+ if ( HIWORD( wParam ) == EN_CHANGE )
+ {
+ KillTimer( hwndDlg, 102 );
+ SetTimer( hwndDlg, 102, 250, NULL );
+ }
+ break;
+
+ case IDC_SHOWHELP:
+ WASABI_API_DIALOGBOX( IDD_EVAL_HELP, hwndDlg, evalHelpDlgProc );
+ break;
+
+ case IDC_TRIGGER1:
+ ctx->triggers[ 0 ]++;
+ break;
+
+ case IDC_TRIGGER2:
+ ctx->triggers[ 1 ]++;
+ break;
+
+ case IDC_TRIGGER3:
+ ctx->triggers[ 2 ]++;
+ break;
+
+ case IDC_TRIGGER4:
+ ctx->triggers[ 3 ]++;
+ break;
+ }
+
+ return 0;
+ }
+
+ case WM_TIMER:
+ if ( wParam == 100 || wParam == 101 || wParam == 102 )
+ {
+ KillTimer( hwndDlg, wParam );
+ EnterCriticalSection( &ctx->code_cs );
+ GetDlgItemText( hwndDlg, wParam == 100 ? IDC_INIT : ( wParam == 101 ? IDC_PERSAMPLE : IDC_ONSLIDERCHANGE ), ctx->curpreset.code_text[ wParam - 100 ], MAX_CODE_LEN );
+ ctx->code_needrecompile |= 1 << ( wParam - 100 );
+ LeaveCriticalSection( &ctx->code_cs );
+ }
+ return 0;
+
+ case WM_CLOSE:
+#ifdef SPS_CONFIGDLG_ON_WM_CLOSE
+ SPS_CONFIGDLG_ON_WM_CLOSE
+#endif
+ return 0;
+
+ case WM_VSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage( swnd, TBM_GETPOS, 0, 0 );
+ if ( swnd == GetDlgItem( hwndDlg, IDC_SLIDER1 ) )
+ {
+ ctx->curpreset.sliderpos[ 0 ] = 1000 - t;
+ ctx->sliderchange = 1;
+ }
+
+ if ( swnd == GetDlgItem( hwndDlg, IDC_SLIDER2 ) )
+ {
+ ctx->curpreset.sliderpos[ 1 ] = 1000 - t;
+ ctx->sliderchange = 1;
+ }
+
+ if ( swnd == GetDlgItem( hwndDlg, IDC_SLIDER3 ) )
+ {
+ ctx->curpreset.sliderpos[ 2 ] = 1000 - t;
+ ctx->sliderchange = 1;
+ }
+
+ if ( swnd == GetDlgItem( hwndDlg, IDC_SLIDER4 ) )
+ {
+ ctx->curpreset.sliderpos[ 3 ] = 1000 - t;
+ ctx->sliderchange = 1;
+ }
+ }
+ break;
+ }
+ return 0;
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/DSP/dsp_sps/version.rc2 b/Src/Plugins/DSP/dsp_sps/version.rc2
new file mode 100644
index 00000000..48daf777
--- /dev/null
+++ b/Src/Plugins/DSP/dsp_sps/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "../../../Winamp/buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,2,0
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp DSP Plug-in"
+ VALUE "FileVersion", "1,0,2,0"
+ VALUE "InternalName", "Nullsoft Signal Processing Studio DSP"
+ VALUE "LegalCopyright", "Copyright © 2003-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "dsp_sps.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END