MAIN.C 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. ** Example Winamp input plug-in
  3. ** Copyright (c) 1998, Justin Frankel/Nullsoft Inc.
  4. */
  5. #include <windows.h>
  6. #include <mmreg.h>
  7. #include <msacm.h>
  8. #include <math.h>
  9. #include <stdio.h>
  10. #include "../Winamp/in2.h"
  11. #define WM_WA_MPEG_EOF WM_USER+2
  12. extern In_Module mod;
  13. char lastfn[MAX_PATH];
  14. short sample_buffer[576*2];
  15. /*
  16. // avoid CRT. Evil. Big. Bloated.
  17. BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
  18. {
  19. return TRUE;
  20. }
  21. */
  22. int paused;
  23. DWORD WINAPI __stdcall PlayThread(void *b);
  24. int gen_freq=2600;
  25. int killDecodeThread=0;
  26. HANDLE thread_handle=INVALID_HANDLE_VALUE;
  27. void config(HWND hwndParent)
  28. {
  29. MessageBoxA(hwndParent,"To use, open 'tone://2600' (for 2600hz).","Configuration",MB_OK); // Must stay in ANSI
  30. }
  31. void about(HWND hwndParent)
  32. {
  33. MessageBoxA(hwndParent,"Nullsoft Tone Generator, by Justin Frankel","About Nullsoft Tone Generator",MB_OK); // Must stay in ANSI
  34. }
  35. int init()
  36. {
  37. return 0;
  38. }
  39. void quit() { }
  40. int isourfile(const char *fn)
  41. {
  42. char buf[8];
  43. memcpy(buf,fn,7);
  44. buf[7]=0;
  45. return lstrcmpA(buf,"tone://")?0:1; // Must stay in ANSI
  46. }
  47. int play(const char *fn) {
  48. int maxlatency;
  49. int tmp;
  50. strcpy(lastfn,fn);
  51. // simple atoi() inline so that we don't have to use libc (for a nice 4k dll)
  52. {
  53. const char *s=fn+7;
  54. int n=0;
  55. while (*s >= '0' && *s <= '9')
  56. {
  57. n*=10;
  58. n += *s++ -'0';
  59. }
  60. gen_freq=n;
  61. }
  62. paused=0;
  63. memset(sample_buffer,0,sizeof(sample_buffer));
  64. maxlatency = mod.outMod->Open(44100,1,16, -1,-1);
  65. if (maxlatency < 0)
  66. {
  67. return 1;
  68. }
  69. mod.SetInfo(0,44,1,1);
  70. mod.SAVSAInit(maxlatency,44100);
  71. mod.VSASetInfo(44100,1);
  72. mod.outMod->SetVolume(-666);
  73. killDecodeThread=0;
  74. thread_handle = (HANDLE) CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) PlayThread,(void *) &killDecodeThread,0,&tmp);
  75. return 0;
  76. }
  77. void pause() { paused=1; mod.outMod->Pause(1); }
  78. void unpause() { paused=0; mod.outMod->Pause(0); }
  79. int ispaused() { return paused; }
  80. void stop() {
  81. if (thread_handle != INVALID_HANDLE_VALUE)
  82. {
  83. killDecodeThread=1;
  84. if (WaitForSingleObject(thread_handle,INFINITE) == WAIT_TIMEOUT)
  85. {
  86. MessageBoxA(mod.hMainWindow,"error asking thread to die!\n","error killing decode thread",0); // Must stay in ANSI
  87. TerminateThread(thread_handle,0);
  88. }
  89. CloseHandle(thread_handle);
  90. thread_handle = INVALID_HANDLE_VALUE;
  91. }
  92. mod.outMod->Close();
  93. mod.SAVSADeInit();
  94. }
  95. int getlength() { return -1000; }
  96. int getoutputtime() { return mod.outMod->GetOutputTime(); }
  97. void setoutputtime(int time_in_ms) { }
  98. void setvolume(int volume) { mod.outMod->SetVolume(volume); }
  99. void setpan(int pan) { mod.outMod->SetPan(pan); }
  100. int infoDlg(const char *fn, HWND hwnd)
  101. {
  102. return 0;
  103. }
  104. void getfileinfo(const char *filename, char *title, int *length_in_ms)
  105. {
  106. if (!filename || !*filename) filename=lastfn;
  107. if (title)
  108. {
  109. const char *s=filename+7;
  110. int n=0;
  111. while (*s >= '0' && *s <= '9')
  112. {
  113. n*=10;
  114. n += *s++ -'0';
  115. }
  116. sprintf(title,"%dhz Tone",n);
  117. }
  118. if (length_in_ms) *length_in_ms=-1000;
  119. }
  120. void eq_set(int on, char data[10], int preamp)
  121. {
  122. }
  123. In_Module mod =
  124. {
  125. IN_VER,
  126. L"Nullsoft Tone Generator v0.2 "
  127. /* #ifdef __alpha
  128. "(AXP)"
  129. #else
  130. "(x86)"
  131. #endif */
  132. ,
  133. 0, // hMainWindow
  134. 0, // hDllInstance
  135. "\0"
  136. ,
  137. 0, // is_seekable
  138. 1, // uses output
  139. config,
  140. about,
  141. init,
  142. quit,
  143. getfileinfo,
  144. infoDlg,
  145. isourfile,
  146. play,
  147. pause,
  148. unpause,
  149. ispaused,
  150. stop,
  151. getlength,
  152. getoutputtime,
  153. setoutputtime,
  154. setvolume,
  155. setpan,
  156. 0,0,0,0,0,0,0,0,0, // vis stuff
  157. 0,0, // dsp
  158. eq_set,
  159. NULL, // setinfo
  160. 0 // out_mod
  161. };
  162. __declspec( dllexport ) In_Module * winampGetInModule2()
  163. {
  164. return &mod;
  165. }
  166. int _fltused=0;
  167. DWORD WINAPI __stdcall PlayThread(void *b)
  168. {
  169. double angle=0.0,dangle=3.14159*2.0*(double)gen_freq/(double)44100.0;
  170. while (! *((int *)b) )
  171. {
  172. if (mod.outMod->CanWrite() >= ((sizeof(sample_buffer)/2)<<(mod.dsp_isactive()?1:0)))
  173. {
  174. int l=sizeof(sample_buffer)/2,x=l/2;
  175. short *s=sample_buffer;
  176. while (x--)
  177. {
  178. int i;
  179. double d = sin(angle)*32766.5;
  180. #ifndef __alpha
  181. __asm {
  182. fld d
  183. fistp i
  184. }
  185. #else
  186. i = (int) d;
  187. #endif
  188. *s++=i;
  189. angle += dangle;
  190. }
  191. {
  192. int t=mod.outMod->GetWrittenTime();
  193. mod.SAAddPCMData((char *)sample_buffer,1,16,t);
  194. mod.VSAAddPCMData((char *)sample_buffer,1,16,t);
  195. }
  196. l=mod.dsp_dosamples(sample_buffer,l/2,16,1,44100)*2;
  197. mod.outMod->Write((char *)sample_buffer,l);
  198. }
  199. else Sleep(50);
  200. }
  201. return 0;
  202. }