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

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: mlutil.c,v 1.1.1.1 2004/01/21 01:36:35 raph Exp $
  21.   Utility functions for the module loader
  22. ==============================================================================*/
  23. #ifdef HAVE_CONFIG_H
  24. #include "config.h"
  25. #endif
  26. #ifdef HAVE_MEMORY_H
  27. #include <memory.h>
  28. #endif
  29. #include <string.h>
  30. #include "mikmod_internals.h"
  31. #ifdef SUNOS
  32. extern int fprintf(FILE *, const char *, ...);
  33. #endif
  34. /*========== Shared tracker identifiers */
  35. CHAR *STM_Signatures[STM_NTRACKERS] = {
  36. "!Scream!",
  37. "BMOD2STM",
  38. "WUZAMOD!"
  39. };
  40. CHAR *STM_Version[STM_NTRACKERS] = {
  41. "Screamtracker 2",
  42. "Converted by MOD2STM (STM format)",
  43. "Wuzamod (STM format)"
  44. };
  45. /*========== Shared loader variables */
  46. SBYTE  remap[UF_MAXCHAN];   /* for removing empty channels */
  47. UBYTE* poslookup=NULL;      /* lookup table for pattern jumps after blank
  48.                                pattern removal */
  49. UBYTE  poslookupcnt;
  50. UWORD* origpositions=NULL;
  51. BOOL   filters;             /* resonant filters in use */
  52. UBYTE  activemacro;         /* active midi macro number for Sxx,xx<80h */
  53. UBYTE  filtermacros[UF_MAXMACRO];    /* midi macro settings */
  54. FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */
  55. /*========== Linear periods stuff */
  56. int*   noteindex=NULL;      /* remap value for linear period modules */
  57. static int noteindexcount=0;
  58. int *AllocLinear(void)
  59. {
  60. if(of.numsmp>noteindexcount) {
  61. noteindexcount=of.numsmp;
  62. noteindex=realloc(noteindex,noteindexcount*sizeof(int));
  63. }
  64. return noteindex;
  65. }
  66. void FreeLinear(void)
  67. {
  68. if(noteindex) {
  69. free(noteindex);
  70. noteindex=NULL;
  71. }
  72. noteindexcount=0;
  73. }
  74. int speed_to_finetune(ULONG speed,int sample)
  75. {
  76.     int ctmp=0,tmp,note=1,finetune=0;
  77.     speed>>=1;
  78.     while((tmp=getfrequency(of.flags,getlinearperiod(note<<1,0)))<speed) {
  79.         ctmp=tmp;
  80.         note++;
  81.     }
  82.     if(tmp!=speed) {
  83.         if((tmp-speed)<(speed-ctmp))
  84.             while(tmp>speed)
  85.                 tmp=getfrequency(of.flags,getlinearperiod(note<<1,--finetune));
  86.         else {
  87.             note--;
  88.             while(ctmp<speed)
  89.                 ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++finetune));
  90.         }
  91.     }
  92.     noteindex[sample]=note-4*OCTAVE;
  93.     return finetune;
  94. }
  95. /*========== Order stuff */
  96. /* handles S3M and IT orders */
  97. void S3MIT_CreateOrders(BOOL curious)
  98. {
  99. int t;
  100. of.numpos = 0;
  101. memset(of.positions,0,poslookupcnt*sizeof(UWORD));
  102. memset(poslookup,-1,256);
  103. for(t=0;t<poslookupcnt;t++) {
  104. int order=origpositions[t];
  105. if(order==255) order=LAST_PATTERN;
  106. of.positions[of.numpos]=order;
  107. poslookup[t]=of.numpos; /* bug fix for freaky S3Ms / ITs */
  108. if(origpositions[t]<254) of.numpos++;
  109. else
  110. /* end of song special order */
  111. if((order==LAST_PATTERN)&&(!(curious--))) break;
  112. }
  113. }
  114. /*========== Effect stuff */
  115. /* handles S3M and IT effects */
  116. void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
  117. {
  118. UBYTE hi,lo;
  119. lo=inf&0xf;
  120. hi=inf>>4;
  121. /* process S3M / IT specific command structure */
  122. if(cmd!=255) {
  123. switch(cmd) {
  124. case 1: /* Axx set speed to xx */
  125. UniEffect(UNI_S3MEFFECTA,inf);
  126. break;
  127. case 2: /* Bxx position jump */
  128. if (inf<poslookupcnt) {
  129. /* switch to curious mode if necessary, for example
  130.    sympex.it, deep joy.it */
  131. if(((SBYTE)poslookup[inf]<0)&&(origpositions[inf]!=255))
  132. S3MIT_CreateOrders(1);
  133. if(!((SBYTE)poslookup[inf]<0))
  134. UniPTEffect(0xb,poslookup[inf]);
  135. }
  136. break;
  137. case 3: /* Cxx patternbreak to row xx */
  138. if ((flags & S3MIT_OLDSTYLE) && !(flags & S3MIT_IT))
  139. UniPTEffect(0xd,(inf>>4)*10+(inf&0xf));
  140. else
  141. UniPTEffect(0xd,inf);
  142. break;
  143. case 4: /* Dxy volumeslide */
  144. UniEffect(UNI_S3MEFFECTD,inf);
  145. break;
  146. case 5: /* Exy toneslide down */
  147. UniEffect(UNI_S3MEFFECTE,inf);
  148. break;
  149. case 6: /* Fxy toneslide up */
  150. UniEffect(UNI_S3MEFFECTF,inf);
  151. break;
  152. case 7: /* Gxx Tone portamento, speed xx */
  153. if (flags & S3MIT_OLDSTYLE)
  154. UniPTEffect(0x3,inf);
  155. else
  156. UniEffect(UNI_ITEFFECTG,inf);
  157. break;
  158. case 8: /* Hxy vibrato */
  159. if (flags & S3MIT_OLDSTYLE)
  160. UniPTEffect(0x4,inf);
  161. else
  162. UniEffect(UNI_ITEFFECTH,inf);
  163. break;
  164. case 9: /* Ixy tremor, ontime x, offtime y */
  165. if (flags & S3MIT_OLDSTYLE)
  166. UniEffect(UNI_S3MEFFECTI,inf);
  167. else                     
  168. UniEffect(UNI_ITEFFECTI,inf);
  169. break;
  170. case 0xa: /* Jxy arpeggio */
  171. UniPTEffect(0x0,inf);
  172. break;
  173. case 0xb: /* Kxy Dual command H00 & Dxy */
  174. if (flags & S3MIT_OLDSTYLE)
  175. UniPTEffect(0x4,0);    
  176. else
  177. UniEffect(UNI_ITEFFECTH,0);
  178. UniEffect(UNI_S3MEFFECTD,inf);
  179. break;
  180. case 0xc: /* Lxy Dual command G00 & Dxy */
  181. if (flags & S3MIT_OLDSTYLE)
  182. UniPTEffect(0x3,0);
  183. else
  184. UniEffect(UNI_ITEFFECTG,0);
  185. UniEffect(UNI_S3MEFFECTD,inf);
  186. break;
  187. case 0xd: /* Mxx Set Channel Volume */
  188. UniEffect(UNI_ITEFFECTM,inf);
  189. break;       
  190. case 0xe: /* Nxy Slide Channel Volume */
  191. UniEffect(UNI_ITEFFECTN,inf);
  192. break;
  193. case 0xf: /* Oxx set sampleoffset xx00h */
  194. UniPTEffect(0x9,inf);
  195. break;
  196. case 0x10: /* Pxy Slide Panning Commands */
  197. UniEffect(UNI_ITEFFECTP,inf);
  198. break;
  199. case 0x11: /* Qxy Retrig (+volumeslide) */
  200. UniWriteByte(UNI_S3MEFFECTQ);
  201. if(inf && !lo && !(flags & S3MIT_OLDSTYLE))
  202. UniWriteByte(1);
  203. else
  204. UniWriteByte(inf); 
  205. break;
  206. case 0x12: /* Rxy tremolo speed x, depth y */
  207. UniEffect(UNI_S3MEFFECTR,inf);
  208. break;
  209. case 0x13: /* Sxx special commands */
  210. if (inf>=0xf0) {
  211. /* change resonant filter settings if necessary */
  212. if((filters)&&((inf&0xf)!=activemacro)) {
  213. activemacro=inf&0xf;
  214. for(inf=0;inf<0x80;inf++)
  215. filtersettings[inf].filter=filtermacros[activemacro];
  216. }
  217. } else {
  218. /* Scream Tracker does not have samples larger than
  219.    64 Kb, thus doesn't need the SAx effect */
  220. if ((flags & S3MIT_SCREAM) && ((inf & 0xf0) == 0xa0))
  221. break;
  222. UniEffect(UNI_ITEFFECTS0,inf);
  223. }
  224. break;
  225. case 0x14: /* Txx tempo */
  226. if(inf>=0x20)
  227. UniEffect(UNI_S3MEFFECTT,inf);
  228. else {
  229. if(!(flags & S3MIT_OLDSTYLE))
  230. /* IT Tempo slide */
  231. UniEffect(UNI_ITEFFECTT,inf);
  232. }
  233. break;
  234. case 0x15: /* Uxy Fine Vibrato speed x, depth y */
  235. if(flags & S3MIT_OLDSTYLE)
  236. UniEffect(UNI_S3MEFFECTU,inf);
  237. else
  238. UniEffect(UNI_ITEFFECTU,inf);
  239. break;
  240. case 0x16: /* Vxx Set Global Volume */
  241. UniEffect(UNI_XMEFFECTG,inf);
  242. break;
  243. case 0x17: /* Wxy Global Volume Slide */
  244. UniEffect(UNI_ITEFFECTW,inf);
  245. break;
  246. case 0x18: /* Xxx amiga command 8xx */
  247. if(flags & S3MIT_OLDSTYLE) {
  248. if(inf>128)
  249. UniEffect(UNI_ITEFFECTS0,0x91); /* surround */
  250. else
  251. UniPTEffect(0x8,(inf==128)?255:(inf<<1));
  252. } else
  253. UniPTEffect(0x8,inf);
  254. break;
  255. case 0x19: /* Yxy Panbrello  speed x, depth y */
  256. UniEffect(UNI_ITEFFECTY,inf);
  257. break;
  258. case 0x1a: /* Zxx midi/resonant filters */
  259. if(filtersettings[inf].filter) {
  260. UniWriteByte(UNI_ITEFFECTZ);
  261. UniWriteByte(filtersettings[inf].filter);
  262. UniWriteByte(filtersettings[inf].inf);
  263. }
  264. break;
  265. }
  266. }
  267. }
  268. /*========== Unitrk stuff */
  269. /* Generic effect writing routine */
  270. void UniEffect(UWORD eff,UWORD dat)
  271. {
  272. if((!eff)||(eff>=UNI_LAST)) return;
  273. UniWriteByte(eff);
  274. if(unioperands[eff]==2)
  275. UniWriteWord(dat);
  276. else
  277. UniWriteByte(dat);
  278. }
  279. /*  Appends UNI_PTEFFECTX opcode to the unitrk stream. */
  280. void UniPTEffect(UBYTE eff, UBYTE dat)
  281. {
  282. #ifdef MIKMOD_DEBUG
  283. if (eff>=0x10)
  284. fprintf(stderr,"UniPTEffect called with incorrect eff value %dn",eff);
  285. else
  286. #endif
  287. if((eff)||(dat)||(of.flags&UF_ARPMEM)) UniEffect(UNI_PTEFFECT0+eff,dat);
  288. }
  289. /* Appends UNI_VOLEFFECT + effect/dat to unistream. */
  290. void UniVolEffect(UWORD eff,UBYTE dat)
  291. {
  292. if((eff)||(dat)) { /* don't write empty effect */
  293. UniWriteByte(UNI_VOLEFFECTS);
  294. UniWriteByte(eff);UniWriteByte(dat);
  295. }
  296. }
  297. /* ex:set ts=4: */