in_asap.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:6k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * in_asap.c - ASAP plugin for Winamp
  3.  *
  4.  * Copyright (C) 2005-2006  Piotr Fusik
  5.  *
  6.  * This file is part of ASAP (Another Slight Atari Player),
  7.  * see http://asap.sourceforge.net
  8.  *
  9.  * ASAP is free software; you can redistribute it and/or modify it
  10.  * under the terms of the GNU General Public License as published
  11.  * by the Free Software Foundation; either version 2 of the License,
  12.  * or (at your option) any later version.
  13.  *
  14.  * ASAP is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty
  16.  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17.  * See the GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with ASAP; if not, write to the Free Software Foundation, Inc.,
  21.  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  22.  */
  23. #include "config.h"
  24. #include <windows.h>
  25. #include <string.h>
  26. #include "in2.h"
  27. #include "asap.h"
  28. #define FREQUENCY          44100
  29. #define BITS_PER_SAMPLE    16
  30. #define QUALITY            1
  31. // This is a magic size for Winamp, better do not modify it
  32. #define BUFFERED_BLOCKS    576
  33. // Winamp's equalizer works only with 16-bit samples and sounds awfully,
  34. // probably because of the DC offset of the generated sound
  35. #define SUPPORT_EQUALIZER  0
  36. static unsigned int channels;
  37. static unsigned int buffered_bytes;
  38. #if 0
  39. // This is used in Winamp examples to disable C runtime in order to produce smaller DLL.
  40. // Currently it doesn't work here, because the following CRT functions are used:
  41. // _fltused, _ftol, floor, rand, free, malloc
  42. BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
  43. {
  44. return TRUE;
  45. }
  46. #endif
  47. static In_Module mod;
  48. static char current_filename[MAX_PATH] = "";
  49. static HANDLE thread_handle = NULL;
  50. static volatile int thread_run = FALSE;
  51. static int paused = 0;
  52. static void config(HWND hwndParent)
  53. {
  54. // TODO
  55. }
  56. static void about(HWND hwndParent)
  57. {
  58. MessageBox(hwndParent, ASAP_CREDITS "n" ASAP_COPYRIGHT,
  59. "About ASAP Winamp plugin " ASAP_VERSION, MB_OK);
  60. }
  61. static void init(void)
  62. {
  63. ASAP_Initialize(FREQUENCY,
  64. BITS_PER_SAMPLE == 8 ? AUDIO_FORMAT_U8 : AUDIO_FORMAT_S16_NE, QUALITY);
  65. }
  66. static void quit(void)
  67. {
  68. }
  69. static void getFileInfo(char *file, char *title, int *length_in_ms)
  70. {
  71. if (file == NULL || file[0] == '')
  72. file = current_filename;
  73. if (title != NULL) {
  74. const char *dirsep;
  75. dirsep = strrchr(file, '\');
  76. strcpy(title, dirsep != NULL ? dirsep + 1 : file);
  77. }
  78. if (length_in_ms != NULL)
  79. *length_in_ms = -1000;
  80. }
  81. static int infoBox(char *file, HWND hwndParent)
  82. {
  83. // TODO
  84. return 0;
  85. }
  86. static int isOurFile(char *fn)
  87. {
  88. return 0;
  89. }
  90. static DWORD WINAPI playThread(LPVOID dummy)
  91. {
  92. while (thread_run) {
  93. if (mod.outMod->CanWrite() >= (int) buffered_bytes
  94. #if SUPPORT_EQUALIZER
  95. << mod.dsp_isactive()
  96. #endif
  97. ) {
  98. static
  99. #if BITS_PER_SAMPLE == 8
  100. unsigned char
  101. #else
  102. short int
  103. #endif
  104. buffer[BUFFERED_BLOCKS * 2
  105. #if SUPPORT_EQUALIZER
  106. * 2
  107. #endif
  108. ];
  109. int t;
  110. ASAP_Generate(buffer, buffered_bytes);
  111. t = mod.outMod->GetWrittenTime();
  112. mod.SAAddPCMData(buffer, channels, BITS_PER_SAMPLE, t);
  113. mod.VSAAddPCMData(buffer, channels, BITS_PER_SAMPLE, t);
  114. #if SUPPORT_EQUALIZER
  115. t = mod.dsp_dosamples((short int *) buffer, BUFFERED_BLOCKS,
  116. BITS_PER_SAMPLE, channels, FREQUENCY) * channels * (BITS_PER_SAMPLE / 8);
  117. mod.outMod->Write((char *) buffer, t);
  118. #else
  119. mod.outMod->Write((char *) buffer, buffered_bytes);
  120. #endif
  121. }
  122. else
  123. Sleep(20);
  124. }
  125. return 0;
  126. }
  127. static int play(char *fn)
  128. {
  129. HANDLE fh;
  130. static unsigned char module[65000];
  131. DWORD module_len;
  132. int maxlatency;
  133. DWORD threadId;
  134. strcpy(current_filename, fn);
  135. fh = CreateFile(fn, GENERIC_READ, 0, NULL, OPEN_EXISTING,
  136.                 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  137. if (fh == INVALID_HANDLE_VALUE)
  138. return -1;
  139. if (!ReadFile(fh, module, sizeof(module), &module_len, NULL)) {
  140. CloseHandle(fh);
  141. return -1;
  142. }
  143. CloseHandle(fh);
  144. if (!ASAP_Load(fn, module, (unsigned int) module_len))
  145. return 1;
  146. ASAP_PlaySong(ASAP_GetDefSong());
  147. channels = ASAP_GetChannels();
  148. buffered_bytes = BUFFERED_BLOCKS * channels * (BITS_PER_SAMPLE / 8);
  149. maxlatency = mod.outMod->Open(FREQUENCY, channels, BITS_PER_SAMPLE, -1, -1);
  150. if (maxlatency < 0)
  151. return 1;
  152. mod.SetInfo(BITS_PER_SAMPLE, FREQUENCY / 1000, channels, 1);
  153. mod.SAVSAInit(maxlatency, FREQUENCY);
  154. // the order of VSASetInfo's arguments in in2.h is wrong!
  155. // http://forums.winamp.com/showthread.php?postid=1841035
  156. mod.VSASetInfo(FREQUENCY, channels);
  157. mod.outMod->SetVolume(-666);
  158. thread_run = TRUE;
  159. thread_handle = CreateThread(NULL, 0, playThread, NULL, 0, &threadId);
  160. return thread_handle != NULL ? 0 : 1;
  161. }
  162. static void pause(void)
  163. {
  164. paused = 1;
  165. mod.outMod->Pause(1);
  166. }
  167. static void unPause(void)
  168. {
  169. paused = 0;
  170. mod.outMod->Pause(0);
  171. }
  172. static int isPaused(void)
  173. {
  174. return paused;
  175. }
  176. static void stop(void)
  177. {
  178. if (thread_handle != NULL) {
  179. thread_run = FALSE;
  180. // wait max 30 seconds
  181. if (WaitForSingleObject(thread_handle, 30 * 1000) == WAIT_TIMEOUT)
  182. TerminateThread(thread_handle, 0);
  183. CloseHandle(thread_handle);
  184. thread_handle = NULL;
  185. }
  186. mod.outMod->Close();
  187. mod.SAVSADeInit();
  188. }
  189. static int getLength(void)
  190. {
  191. return -1000;
  192. }
  193. static int getOutputTime(void)
  194. {
  195. return mod.outMod->GetOutputTime();
  196. }
  197. static void setOutputTime(int time_in_ms)
  198. {
  199. }
  200. static void setVolume(int volume)
  201. {
  202. mod.outMod->SetVolume(volume);
  203. }
  204. static void setPan(int pan)
  205. {
  206. mod.outMod->SetPan(pan);
  207. }
  208. static void eqSet(int on, char data[10], int preamp)
  209. {
  210. }
  211. static In_Module mod = {
  212. IN_VER,
  213. "ASAP " ASAP_VERSION,
  214. 0, 0, // filled by Winamp
  215. "sapSlight Atari Player (*.SAP)"
  216. "cmcChaos Music Composer (*.CMC)"
  217. "cmrChaos Music Composer / Rzog (*.CMR)"
  218. "dmcDoublePlay Chaos Music Composer (*.DMC)"
  219. "mptMusic ProTracker (*.MPT)"
  220. "mpdMusic ProTracker DoublePlay (*.MPD)"
  221. "rmtRaster Music Tracker (*.RMT)"
  222. "tmcTheta Music Composer 1.x 4-channel (*.TMC)"
  223. #ifdef STEREO_SOUND
  224. "tm8Theta Music Composer 1.x 8-channel (*.TM8)"
  225. #endif
  226. "tm2Theta Music Composer 2.x (*.TM2)"
  227. ,
  228. 0,    // is_seekable
  229. 1,    // UsesOutputPlug
  230. config,
  231. about,
  232. init,
  233. quit,
  234. getFileInfo,
  235. infoBox,
  236. isOurFile,
  237. play,
  238. pause,
  239. unPause,
  240. isPaused,
  241. stop,
  242. getLength,
  243. getOutputTime,
  244. setOutputTime,
  245. setVolume,
  246. setPan,
  247. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // filled by Winamp
  248. eqSet,
  249. NULL, // SetInfo
  250. NULL  // filled by Winamp
  251. };
  252. __declspec(dllexport) In_Module *winampGetInModule2(void)
  253. {
  254. return &mod;
  255. }