dsp_sps.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #include <windows.h>
  2. #include <commctrl.h>
  3. #include "../winamp/dsp.h"
  4. #include "resource.h"
  5. #include "sps_common.h"
  6. #include "../winamp/wa_ipc.h"
  7. #include "../../General/gen_hotkeys/wa_hotkeys.h"
  8. #define SPS_HOTKEY_ID "dsp_sps sc"
  9. #include "sps_configdlg.h"
  10. //#define PLUGIN_NAME "Nullsoft Signal Processing Studio DSP v1.0b"
  11. #define PLUGIN_VERSION "v1.0b"
  12. // config, winamp specific shit here:
  13. struct
  14. {
  15. int showeditor; //def 0
  16. int visible; //def 1
  17. } g_config;
  18. SPSEffectContext g_wacontext;
  19. HWND g_configwindow;
  20. HWND helpWnd;
  21. int helpWndOpenHack = 0;
  22. char *INI_FILE;
  23. static int loaded_once = 0;
  24. char g_path[MAX_PATH];
  25. // wasabi based services for localisation support
  26. api_service *WASABI_API_SVC = 0;
  27. api_language *WASABI_API_LNG = 0;
  28. HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
  29. // module getter.
  30. winampDSPModule *getModule(int which);
  31. void config(struct winampDSPModule *this_mod);
  32. int init(struct winampDSPModule *this_mod);
  33. void quit(struct winampDSPModule *this_mod);
  34. int modify_samples(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate);
  35. // Module header, includes version, description, and address of the module retriever function
  36. typedef struct
  37. {
  38. int version; // DSP_HDRVER
  39. char *description; // description of library
  40. winampDSPModule* (*getModule)(int); // module retrieval function
  41. int (*sf)(int);
  42. } winampDSPHeaderEx;
  43. static int sf(int v)
  44. {
  45. int res;
  46. res = v * (unsigned long)1103515245;
  47. res += (unsigned long)13293;
  48. res &= (unsigned long)0x7FFFFFFF;
  49. res ^= v;
  50. return res;
  51. }
  52. winampDSPHeaderEx hdr = { DSP_HDRVER+1, 0, getModule, sf };
  53. // first module
  54. winampDSPModule mod =
  55. {
  56. 0,//"Signal Processing Studio",
  57. NULL, // hwndParent
  58. NULL, // hDllInstance
  59. config,
  60. init,
  61. modify_samples,
  62. quit
  63. };
  64. extern "C"
  65. {
  66. static HINSTANCE GetMyInstance()
  67. {
  68. MEMORY_BASIC_INFORMATION mbi = {0};
  69. if(VirtualQuery(GetMyInstance, &mbi, sizeof(mbi)))
  70. return (HINSTANCE)mbi.AllocationBase;
  71. return NULL;
  72. }
  73. __declspec( dllexport ) winampDSPHeaderEx *winampDSPGetHeader2(HWND hwndParent)
  74. {
  75. if(IsWindow(hwndParent))
  76. {
  77. if(!WASABI_API_LNG_HINST)
  78. {
  79. // loader so that we can get the localisation service api for use
  80. WASABI_API_SVC = (api_service*)SendMessageW(hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
  81. if (WASABI_API_SVC == (api_service*)1)
  82. WASABI_API_SVC = NULL;
  83. waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
  84. if (sf)
  85. WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
  86. // need to have this initialised before we try to do anything with localisation features
  87. WASABI_API_START_LANG(GetMyInstance(),DspSpsLangGUID);
  88. }
  89. static char szDescription[256];
  90. if(!szDescription[0])
  91. {
  92. char temp[256];
  93. wsprintfA(szDescription,"%s %s",WASABI_API_LNGSTRING_BUF(IDS_SPS_TITLE,temp,256), PLUGIN_VERSION );
  94. hdr.description = szDescription;
  95. }
  96. static char szDescription2[256];
  97. if(!szDescription2[0])
  98. {
  99. mod.description = WASABI_API_LNGSTRING_BUF(IDS_SPS_MODULE_TITLE,szDescription2,256);
  100. }
  101. }
  102. return &hdr;
  103. }
  104. }
  105. // getmodule routine from the main header. Returns NULL if an invalid module was requested,
  106. // otherwise returns either mod1 or mod2 depending on 'which'.
  107. winampDSPModule *getModule(int which)
  108. {
  109. switch (which)
  110. {
  111. case 0: return &mod;
  112. default:return NULL;
  113. }
  114. }
  115. void config(struct winampDSPModule *this_mod)
  116. {
  117. // show config
  118. if (g_configwindow && IsWindow(g_configwindow))
  119. {
  120. g_config.visible=1;
  121. ShowWindow(g_configwindow,SW_SHOW);
  122. }
  123. }
  124. static void WriteInt(char *section, char *name,int value, char *fn)
  125. {
  126. char str[128];
  127. wsprintf(str,"%d",value);
  128. WritePrivateProfileString(section,name,str,fn);
  129. }
  130. static char ghkStr[64];
  131. static genHotkeysAddStruct sps_ghas_showconfig = {
  132. ghkStr,
  133. 0,
  134. WM_USER+0x80,
  135. 0,
  136. 0,
  137. SPS_HOTKEY_ID,
  138. 0,
  139. };
  140. static int m_genhotkeys_add_ipc;
  141. int init(struct winampDSPModule *this_mod)
  142. {
  143. wsprintf(g_path,"%s\\dsp_sps",(char*)SendMessageW(this_mod->hwndParent,WM_WA_IPC,0,IPC_GETPLUGINDIRECTORY));
  144. CreateDirectory(g_path,NULL);
  145. // loader so that we can get the localisation service api for use
  146. WASABI_API_SVC = (api_service*)SendMessageW(this_mod->hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
  147. if (WASABI_API_SVC == (api_service*)1)
  148. WASABI_API_SVC = NULL;
  149. waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
  150. if (sf)
  151. WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
  152. // need to have this initialised before we try to do anything with localisation features
  153. WASABI_API_START_LANG(this_mod->hDllInstance,DspSpsLangGUID);
  154. SPS_initapp();
  155. SPS_initcontext(&g_wacontext);
  156. /* read config */
  157. INI_FILE = (char*)SendMessageW(this_mod->hwndParent,WM_WA_IPC,0,IPC_GETINIFILE);
  158. g_config.showeditor=GetPrivateProfileInt("DSP_SPS","showeditor",0,INI_FILE);
  159. g_config.visible=GetPrivateProfileInt("DSP_SPS","visible",1,INI_FILE);
  160. g_wacontext.bypass=GetPrivateProfileInt("DSP_SPS","bypass",1,INI_FILE);
  161. SPS_load_preset(&g_wacontext,INI_FILE,"DSP_SPS");
  162. GetPrivateProfileString("DSP_SPS","last_preset","",g_wacontext.curpreset_name,sizeof(g_wacontext.curpreset_name),INI_FILE);
  163. g_configwindow=WASABI_API_CREATEDIALOGPARAM(IDD_DIALOG1,this_mod->hwndParent,SPS_configWindowProc,(LPARAM)&g_wacontext);
  164. // we are starting minimised so process as needed (keep our window hidden)
  165. if(!loaded_once)
  166. {
  167. loaded_once = 1;
  168. if (g_config.visible)
  169. ShowWindow(g_configwindow,!GetPrivateProfileInt("Winamp","minimized",1,INI_FILE)?SW_SHOWNA:SW_SHOWMINNOACTIVE);
  170. }
  171. else{
  172. if (g_config.visible)
  173. ShowWindow(g_configwindow,SW_SHOWNA);
  174. }
  175. m_genhotkeys_add_ipc=SendMessageW(this_mod->hwndParent,WM_WA_IPC,(WPARAM)&"GenHotkeysAdd",IPC_REGISTER_WINAMP_IPCMESSAGE);
  176. WASABI_API_LNGSTRING_BUF(IDS_SPS_SHOW_CONFIG,ghkStr,64);
  177. sps_ghas_showconfig.flags &= ~HKF_DISABLED;
  178. sps_ghas_showconfig.wnd = g_configwindow;
  179. if (m_genhotkeys_add_ipc > 65536)
  180. 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
  181. return 0;
  182. }
  183. void quit(struct winampDSPModule *this_mod)
  184. {
  185. if(IsWindow(helpWnd))
  186. {
  187. DestroyWindow(helpWnd);
  188. helpWndOpenHack = 1;
  189. }
  190. helpWnd = 0;
  191. if(IsWindow(g_configwindow))
  192. {
  193. DestroyWindow(g_configwindow);
  194. }
  195. g_configwindow=0;
  196. /* write config */
  197. WriteInt("DSP_SPS","showeditor",g_config.showeditor,INI_FILE);
  198. WriteInt("DSP_SPS","visible",g_config.visible,INI_FILE);
  199. WritePrivateProfileString("DSP_SPS","last_preset",g_wacontext.curpreset_name,INI_FILE);
  200. WriteInt("DSP_SPS","bypass",g_wacontext.bypass,INI_FILE);
  201. SPS_save_preset(&g_wacontext,INI_FILE,"DSP_SPS");
  202. SPS_quitcontext(&g_wacontext);
  203. SPS_quitapp();
  204. sps_ghas_showconfig.flags |= HKF_DISABLED;
  205. sps_ghas_showconfig.wnd=0;
  206. if (m_genhotkeys_add_ipc > 65536)
  207. {
  208. DWORD d;
  209. SendMessageTimeout(this_mod->hwndParent,WM_WA_IPC,(WPARAM)&sps_ghas_showconfig,m_genhotkeys_add_ipc,SMTO_BLOCK|SMTO_ABORTIFHUNG,500,&d);
  210. }
  211. // helps to work around a crash on close issue when the help dialog is open
  212. if(helpWndOpenHack)
  213. {
  214. char buf[MAX_PATH];
  215. GetModuleFileName(this_mod->hDllInstance, buf, MAX_PATH);
  216. LoadLibrary(buf);
  217. }
  218. }
  219. int modify_samples(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate)
  220. {
  221. return SPS_process_samples(&g_wacontext,samples,numsamples,0,bps,nch,srate,numsamples*2,1);
  222. }
  223. BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID)
  224. {
  225. if (fdwReason == DLL_PROCESS_ATTACH)
  226. {
  227. DisableThreadLibraryCalls(hinstDLL);
  228. }
  229. return TRUE;
  230. }
  231. extern "C" __declspec( dllexport ) int winampUninstallPlugin(HINSTANCE hDllInst, HWND hwndDlg, int param)
  232. {
  233. // force plugin to be uninstalled from a restart so that we can deal with the case of the help dialog being open
  234. return helpWndOpenHack;
  235. }
  236. //////////// common dialog stuff
  237. #define SPS_CONFIGDLG_IMPL
  238. #define SPS_CONFIGDLG_ON_WM_CLOSE { ShowWindow(hwndDlg,SW_HIDE); g_config.visible=0; }
  239. #define SPS_CONFIGDLG_HIDEABLE_EDITOR g_config.showeditor
  240. #include "sps_configdlg.h"