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

Windows CE

开发平台:

C/C++

  1. /* MikMod sound library
  2. (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS
  3. for complete list.
  4. This library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of
  7. the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  17. 02111-1307, USA.
  18. */
  19. /*==============================================================================
  20.   $Id: virtch_common.c,v 1.2 2004/02/13 13:31:54 raph Exp $
  21.   Common source parts between the two software mixers.
  22.   This file is probably the ugliest part of libmikmod...
  23. ==============================================================================*/
  24. #ifndef _IN_VIRTCH_
  25. #include "mikmod_internals.h"
  26. extern BOOL  VC1_Init(void);
  27. extern BOOL  VC2_Init(void);
  28. static BOOL (*VC_Init_ptr)(void)=VC1_Init;
  29. extern void  VC1_Exit(void);
  30. extern void  VC2_Exit(void);
  31. static void (*VC_Exit_ptr)(void)=VC1_Exit;
  32. extern BOOL  VC1_SetNumVoices(void);
  33. extern BOOL  VC2_SetNumVoices(void);
  34. static BOOL (*VC_SetNumVoices_ptr)(void);
  35. extern ULONG VC1_SampleSpace(int);
  36. extern ULONG VC2_SampleSpace(int);
  37. static ULONG (*VC_SampleSpace_ptr)(int);
  38. extern ULONG VC1_SampleLength(int,SAMPLE*);
  39. extern ULONG VC2_SampleLength(int,SAMPLE*);
  40. static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*);
  41. extern BOOL  VC1_PlayStart(void);
  42. extern BOOL  VC2_PlayStart(void);
  43. static BOOL (*VC_PlayStart_ptr)(void);
  44. extern void  VC1_PlayStop(void);
  45. extern void  VC2_PlayStop(void);
  46. static void (*VC_PlayStop_ptr)(void);
  47. extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int);
  48. extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int);
  49. static SWORD (*VC_SampleLoad_ptr)(struct SAMPLOAD*,int);
  50. extern void  VC1_SampleUnload(SWORD);
  51. extern void  VC2_SampleUnload(SWORD);
  52. static void (*VC_SampleUnload_ptr)(SWORD);
  53. extern ULONG VC1_WriteBytes(SBYTE*,ULONG);
  54. extern ULONG VC2_WriteBytes(SBYTE*,ULONG);
  55. static ULONG (*VC_WriteBytes_ptr)(SBYTE*,ULONG);
  56. extern ULONG VC1_SilenceBytes(SBYTE*,ULONG);
  57. extern ULONG VC2_SilenceBytes(SBYTE*,ULONG);
  58. static ULONG (*VC_SilenceBytes_ptr)(SBYTE*,ULONG);
  59. extern void  VC1_VoiceSetVolume(UBYTE,UWORD);
  60. extern void  VC2_VoiceSetVolume(UBYTE,UWORD);
  61. static void (*VC_VoiceSetVolume_ptr)(UBYTE,UWORD);
  62. extern UWORD VC1_VoiceGetVolume(UBYTE);
  63. extern UWORD VC2_VoiceGetVolume(UBYTE);
  64. static UWORD (*VC_VoiceGetVolume_ptr)(UBYTE);
  65. extern void  VC1_VoiceSetFrequency(UBYTE,ULONG);
  66. extern void  VC2_VoiceSetFrequency(UBYTE,ULONG);
  67. static void (*VC_VoiceSetFrequency_ptr)(UBYTE,ULONG);
  68. extern ULONG VC1_VoiceGetFrequency(UBYTE);
  69. extern ULONG VC2_VoiceGetFrequency(UBYTE);
  70. static ULONG (*VC_VoiceGetFrequency_ptr)(UBYTE);
  71. extern void  VC1_VoiceSetPanning(UBYTE,ULONG);
  72. extern void  VC2_VoiceSetPanning(UBYTE,ULONG);
  73. static void (*VC_VoiceSetPanning_ptr)(UBYTE,ULONG);
  74. extern ULONG VC1_VoiceGetPanning(UBYTE);
  75. extern ULONG VC2_VoiceGetPanning(UBYTE);
  76. static ULONG (*VC_VoiceGetPanning_ptr)(UBYTE);
  77. extern void  VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
  78. extern void  VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
  79. static void (*VC_VoicePlay_ptr)(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
  80. extern void  VC1_VoiceStop(UBYTE);
  81. extern void  VC2_VoiceStop(UBYTE);
  82. static void (*VC_VoiceStop_ptr)(UBYTE);
  83. extern BOOL  VC1_VoiceStopped(UBYTE);
  84. extern BOOL  VC2_VoiceStopped(UBYTE);
  85. static BOOL (*VC_VoiceStopped_ptr)(UBYTE);
  86. extern SLONG VC1_VoiceGetPosition(UBYTE);
  87. extern SLONG VC2_VoiceGetPosition(UBYTE);
  88. static SLONG (*VC_VoiceGetPosition_ptr)(UBYTE);
  89. extern ULONG VC1_VoiceRealVolume(UBYTE);
  90. extern ULONG VC2_VoiceRealVolume(UBYTE);
  91. static ULONG (*VC_VoiceRealVolume_ptr)(UBYTE);
  92. #if defined __STDC__ || defined _MSC_VER
  93. #define VC_PROC0(suffix) 
  94. MIKMODAPI void VC_##suffix (void) { VC_##suffix##_ptr(); }
  95. #define VC_FUNC0(suffix,ret) 
  96. MIKMODAPI ret VC_##suffix (void) { return VC_##suffix##_ptr(); }
  97. #define VC_PROC1(suffix,typ1) 
  98. MIKMODAPI void VC_##suffix (typ1 a) { VC_##suffix##_ptr(a); }
  99. #define VC_FUNC1(suffix,ret,typ1) 
  100. MIKMODAPI ret VC_##suffix (typ1 a) { return VC_##suffix##_ptr(a); }
  101. #define VC_PROC2(suffix,typ1,typ2) 
  102. MIKMODAPI void VC_##suffix (typ1 a,typ2 b) { VC_##suffix##_ptr(a,b); }
  103. #define VC_FUNC2(suffix,ret,typ1,typ2) 
  104. MIKMODAPI ret VC_##suffix (typ1 a,typ2 b) { return VC_##suffix##_ptr(a,b); }
  105. #else
  106. #define VC_PROC0(suffix) 
  107. MIKMODAPI void VC_/**/suffix (void) { VC_/**/suffix/**/_ptr(); }
  108. #define VC_FUNC0(suffix,ret) 
  109. MIKMODAPI ret VC_/**/suffix (void) { return VC_/**/suffix/**/_ptr(); }
  110. #define VC_PROC1(suffix,typ1) 
  111. MIKMODAPI void VC_/**/suffix (typ1 a) { VC_/**/suffix/**/_ptr(a); }
  112. #define VC_FUNC1(suffix,ret,typ1) 
  113. MIKMODAPI ret VC_/**/suffix (typ1 a) { return VC_/**/suffix/**/_ptr(a); }
  114. #define VC_PROC2(suffix,typ1,typ2) 
  115. MIKMODAPI void VC_/**/suffix (typ1 a,typ2 b) { VC_/**/suffix/**/_ptr(a,b); }
  116. #define VC_FUNC2(suffix,ret,typ1,typ2) 
  117. MIKMODAPI ret VC_/**/suffix (typ1 a,typ2 b) { return VC_/**/suffix/**/_ptr(a,b); }
  118. #endif
  119. VC_FUNC0(Init,BOOL)
  120. VC_PROC0(Exit)
  121. VC_FUNC0(SetNumVoices,BOOL)
  122. VC_FUNC1(SampleSpace,ULONG,int)
  123. VC_FUNC2(SampleLength,ULONG,int,SAMPLE*)
  124. VC_FUNC0(PlayStart,BOOL)
  125. VC_PROC0(PlayStop)
  126. VC_FUNC2(SampleLoad,SWORD,struct SAMPLOAD*,int)
  127. VC_PROC1(SampleUnload,SWORD)
  128. VC_FUNC2(WriteBytes,ULONG,SBYTE*,ULONG)
  129. VC_FUNC2(SilenceBytes,ULONG,SBYTE*,ULONG)
  130. VC_PROC2(VoiceSetVolume,UBYTE,UWORD)
  131. VC_FUNC1(VoiceGetVolume,UWORD,UBYTE)
  132. VC_PROC2(VoiceSetFrequency,UBYTE,ULONG)
  133. VC_FUNC1(VoiceGetFrequency,ULONG,UBYTE)
  134. VC_PROC2(VoiceSetPanning,UBYTE,ULONG)
  135. VC_FUNC1(VoiceGetPanning,ULONG,UBYTE)
  136. void  VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g)
  137. { VC_VoicePlay_ptr(a,b,c,d,e,f,g); }
  138. VC_PROC1(VoiceStop,UBYTE)
  139. VC_FUNC1(VoiceStopped,BOOL,UBYTE)
  140. VC_FUNC1(VoiceGetPosition,SLONG,UBYTE)
  141. VC_FUNC1(VoiceRealVolume,ULONG,UBYTE)
  142. void VC_SetupPointers(void)
  143. {
  144. if (md_mode&DMODE_HQMIXER) {
  145. VC_Init_ptr=VC2_Init;
  146. VC_Exit_ptr=VC2_Exit;
  147. VC_SetNumVoices_ptr=VC2_SetNumVoices;
  148. VC_SampleSpace_ptr=VC2_SampleSpace;
  149. VC_SampleLength_ptr=VC2_SampleLength;
  150. VC_PlayStart_ptr=VC2_PlayStart;
  151. VC_PlayStop_ptr=VC2_PlayStop;
  152. VC_SampleLoad_ptr=VC2_SampleLoad;
  153. VC_SampleUnload_ptr=VC2_SampleUnload;
  154. VC_WriteBytes_ptr=VC2_WriteBytes;
  155. VC_SilenceBytes_ptr=VC2_SilenceBytes;
  156. VC_VoiceSetVolume_ptr=VC2_VoiceSetVolume;
  157. VC_VoiceGetVolume_ptr=VC2_VoiceGetVolume;
  158. VC_VoiceSetFrequency_ptr=VC2_VoiceSetFrequency;
  159. VC_VoiceGetFrequency_ptr=VC2_VoiceGetFrequency;
  160. VC_VoiceSetPanning_ptr=VC2_VoiceSetPanning;
  161. VC_VoiceGetPanning_ptr=VC2_VoiceGetPanning;
  162. VC_VoicePlay_ptr=VC2_VoicePlay;
  163. VC_VoiceStop_ptr=VC2_VoiceStop;
  164. VC_VoiceStopped_ptr=VC2_VoiceStopped;
  165. VC_VoiceGetPosition_ptr=VC2_VoiceGetPosition;
  166. VC_VoiceRealVolume_ptr=VC2_VoiceRealVolume;
  167. } else {
  168. VC_Init_ptr=VC1_Init;
  169. VC_Exit_ptr=VC1_Exit;
  170. VC_SetNumVoices_ptr=VC1_SetNumVoices;
  171. VC_SampleSpace_ptr=VC1_SampleSpace;
  172. VC_SampleLength_ptr=VC1_SampleLength;
  173. VC_PlayStart_ptr=VC1_PlayStart;
  174. VC_PlayStop_ptr=VC1_PlayStop;
  175. VC_SampleLoad_ptr=VC1_SampleLoad;
  176. VC_SampleUnload_ptr=VC1_SampleUnload;
  177. VC_WriteBytes_ptr=VC1_WriteBytes;
  178. VC_SilenceBytes_ptr=VC1_SilenceBytes;
  179. VC_VoiceSetVolume_ptr=VC1_VoiceSetVolume;
  180. VC_VoiceGetVolume_ptr=VC1_VoiceGetVolume;
  181. VC_VoiceSetFrequency_ptr=VC1_VoiceSetFrequency;
  182. VC_VoiceGetFrequency_ptr=VC1_VoiceGetFrequency;
  183. VC_VoiceSetPanning_ptr=VC1_VoiceSetPanning;
  184. VC_VoiceGetPanning_ptr=VC1_VoiceGetPanning;
  185. VC_VoicePlay_ptr=VC1_VoicePlay;
  186. VC_VoiceStop_ptr=VC1_VoiceStop;
  187. VC_VoiceStopped_ptr=VC1_VoiceStopped;
  188. VC_VoiceGetPosition_ptr=VC1_VoiceGetPosition;
  189. VC_VoiceRealVolume_ptr=VC1_VoiceRealVolume;
  190. }
  191. }
  192. #else
  193. #ifndef _VIRTCH_COMMON_
  194. #define _VIRTCH_COMMON_
  195. static ULONG samples2bytes(ULONG samples)
  196. {
  197. if(vc_mode & DMODE_FLOAT) samples <<= 2;
  198. else if(vc_mode & DMODE_16BITS) samples <<= 1;
  199. if(vc_mode & DMODE_STEREO) samples <<= 1;
  200. return samples;
  201. }
  202. static ULONG bytes2samples(ULONG bytes)
  203. {
  204. if(vc_mode & DMODE_FLOAT) bytes >>= 2;
  205. else if(vc_mode & DMODE_16BITS) bytes >>= 1;
  206. if(vc_mode & DMODE_STEREO) bytes >>= 1;
  207. return bytes;
  208. }
  209. /* Fill the buffer with 'todo' bytes of silence (it depends on the mixing mode
  210.    how the buffer is filled) */
  211. ULONG VC1_SilenceBytes(SBYTE* buf,ULONG todo)
  212. {
  213. todo=samples2bytes(bytes2samples(todo));
  214. /* clear the buffer to zero (16 bits signed) or 0x80 (8 bits unsigned) */
  215. if(vc_mode & DMODE_FLOAT)
  216. memset(buf,0,todo);
  217. else if(vc_mode & DMODE_16BITS)
  218. memset(buf,0,todo);
  219. else
  220. memset(buf,0x80,todo);
  221. return todo;
  222. }
  223. void VC1_WriteSamples(SBYTE*,ULONG);
  224. /* Writes 'todo' mixed SBYTES (!!) to 'buf'. It returns the number of SBYTES
  225.    actually written to 'buf' (which is rounded to number of samples that fit
  226.    into 'todo' bytes). */
  227. ULONG VC1_WriteBytes(SBYTE* buf,ULONG todo)
  228. {
  229. if(!vc_softchn)
  230. return VC1_SilenceBytes(buf,todo);
  231. todo = bytes2samples(todo);
  232. VC1_WriteSamples(buf,todo);
  233. return samples2bytes(todo);
  234. }
  235. void VC1_Exit(void)
  236. {
  237. if(vc_tickbuf) free(vc_tickbuf);
  238. if(vinf) free(vinf);
  239. if(Samples) free(Samples);
  240. vc_tickbuf = NULL;
  241. vinf = NULL;
  242. Samples = NULL;
  243. VC_SetupPointers();
  244. }
  245. UWORD VC1_VoiceGetVolume(UBYTE voice)
  246. {
  247. return vinf[voice].vol;
  248. }
  249. ULONG VC1_VoiceGetPanning(UBYTE voice)
  250. {
  251. return vinf[voice].pan;
  252. }
  253. void VC1_VoiceSetFrequency(UBYTE voice,ULONG frq)
  254. {
  255. vinf[voice].frq=frq;
  256. }
  257. ULONG VC1_VoiceGetFrequency(UBYTE voice)
  258. {
  259. return vinf[voice].frq;
  260. }
  261. void VC1_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags)
  262. {
  263. vinf[voice].flags    = flags;
  264. vinf[voice].handle   = handle;
  265. vinf[voice].start    = start;
  266. vinf[voice].size     = size;
  267. vinf[voice].reppos   = reppos;
  268. vinf[voice].repend   = repend;
  269. vinf[voice].kick     = 1;
  270. }
  271. void VC1_VoiceStop(UBYTE voice)
  272. {
  273. vinf[voice].active = 0;
  274. }  
  275. BOOL VC1_VoiceStopped(UBYTE voice)
  276. {
  277. return(vinf[voice].active==0);
  278. }
  279. SLONG VC1_VoiceGetPosition(UBYTE voice)
  280. {
  281. return(vinf[voice].current>>FRACBITS);
  282. }
  283. void VC1_VoiceSetVolume(UBYTE voice,UWORD vol)
  284. {    
  285. /* protect against clicks if volume variation is too high */
  286. if(abs((int)vinf[voice].vol-(int)vol)>32)
  287. vinf[voice].rampvol=CLICK_BUFFER;
  288. vinf[voice].vol=vol;
  289. }
  290. void VC1_VoiceSetPanning(UBYTE voice,ULONG pan)
  291. {
  292. /* protect against clicks if panning variation is too high */
  293. if(abs((int)vinf[voice].pan-(int)pan)>48)
  294. vinf[voice].rampvol=CLICK_BUFFER;
  295. vinf[voice].pan=pan;
  296. }
  297. /*========== External mixer interface */
  298. void VC1_SampleUnload(SWORD handle)
  299. {
  300. if (handle<MAXSAMPLEHANDLES) {
  301. if (Samples[handle])
  302. free(Samples[handle]);
  303. Samples[handle]=NULL;
  304. }
  305. }
  306. SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
  307. {
  308. SAMPLE *s = sload->sample;
  309. int handle;
  310. ULONG t, length,loopstart,loopend;
  311. if(type==MD_HARDWARE) return -1;
  312. /* Find empty slot to put sample address in */
  313. for(handle=0;handle<MAXSAMPLEHANDLES;handle++)
  314. if(!Samples[handle]) break;
  315. if(handle==MAXSAMPLEHANDLES) {
  316. _mm_errno = MMERR_OUT_OF_HANDLES;
  317. return -1;
  318. }
  319. /* Reality check for loop settings */
  320. if (s->loopend > s->length)
  321. s->loopend = s->length;
  322. if (s->loopstart >= s->loopend)
  323. s->flags &= ~SF_LOOP;
  324. length    = s->length;
  325. loopstart = s->loopstart;
  326. loopend   = s->loopend;
  327. SL_SampleSigned(sload);
  328. SL_Sample8to16(sload);
  329. if(!(Samples[handle]=(SWORD*)_mm_malloc((length+20)<<1))) {
  330. _mm_errno = MMERR_SAMPLE_TOO_BIG;
  331. return -1;
  332. }
  333. /* read sample into buffer */
  334. if (SL_Load(Samples[handle],sload,length))
  335. return -1;
  336. /* Unclick sample */
  337. if(s->flags & SF_LOOP) {
  338. if(s->flags & SF_BIDI)
  339. for(t=0;t<16;t++)
  340. Samples[handle][loopend+t]=Samples[handle][(loopend-t)-1];
  341. else
  342. for(t=0;t<16;t++)
  343. Samples[handle][loopend+t]=Samples[handle][t+loopstart];
  344. } else
  345. for(t=0;t<16;t++)
  346. Samples[handle][t+length]=0;
  347. return handle;
  348. }
  349. ULONG VC1_SampleSpace(int type)
  350. {
  351. return vc_memory;
  352. }
  353. ULONG VC1_SampleLength(int type,SAMPLE* s)
  354. {
  355. if (!s) return 0;
  356. return (s->length*((s->flags&SF_16BITS)?2:1))+16;
  357. }
  358. ULONG VC1_VoiceRealVolume(UBYTE voice)
  359. {
  360. ULONG i,s,size;
  361. int k,j;
  362. SWORD *smp;
  363. SLONG t;
  364. t = vinf[voice].current>>FRACBITS;
  365. if(!vinf[voice].active) return 0;
  366. s = vinf[voice].handle;
  367. size = vinf[voice].size;
  368. i=64; t-=64; k=0; j=0;
  369. if(i>size) i = size;
  370. if(t<0) t = 0;
  371. if(t+i > size) t = size-i;
  372. i &= ~1;  /* make sure it's EVEN. */
  373. smp = &Samples[s][t];
  374. for(;i;i--,smp++) {
  375. if(k<*smp) k = *smp;
  376. if(j>*smp) j = *smp;
  377. }
  378. return abs(k-j);
  379. }
  380. #endif
  381. #endif
  382. /* ex:set ts=4: */