A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 341 lines 9.1 kB view raw
1/* MikMod sound library 2 (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS 3 for complete list. 4 5 This library is free software; you can redistribute it and/or modify 6 it under the terms of the GNU Library General Public License as 7 published by the Free Software Foundation; either version 2 of 8 the License, or (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 18 02111-1307, USA. 19*/ 20 21/*============================================================================== 22 23 $Id$ 24 25 Utility functions for the module loader 26 27==============================================================================*/ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#ifdef HAVE_MEMORY_H 34#include <memory.h> 35#endif 36#include <string.h> 37 38#include "mikmod_internals.h" 39 40#ifdef SUNOS 41extern int fprintf(FILE *, const char *, ...); 42#endif 43 44/*========== Shared tracker identifiers */ 45 46const CHAR *STM_Signatures[STM_NTRACKERS] = { 47 "!Scream!", 48 "BMOD2STM", 49 "WUZAMOD!" 50}; 51 52const CHAR *STM_Version[STM_NTRACKERS] = { 53 "Screamtracker 2", 54 "Converted by MOD2STM (STM format)", 55 "Wuzamod (STM format)" 56}; 57 58/*========== Shared loader variables */ 59 60SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */ 61UBYTE* poslookup=NULL; /* lookup table for pattern jumps after blank 62 pattern removal */ 63UWORD poslookupcnt; 64UWORD* origpositions=NULL; 65 66int filters; /* resonant filters in use */ 67UBYTE activemacro; /* active midi macro number for Sxx,xx<80h */ 68UBYTE filtermacros[UF_MAXMACRO]; /* midi macro settings */ 69FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */ 70 71/*========== Linear periods stuff */ 72 73int* noteindex=NULL; /* remap value for linear period modules */ 74static unsigned noteindexcount=0; 75 76int *AllocLinear(void) 77{ 78 if(of.numsmp>noteindexcount) { 79 noteindexcount=of.numsmp; 80 noteindex=(int*)MikMod_realloc(noteindex,noteindexcount*sizeof(int)); 81 } 82 return noteindex; 83} 84 85void FreeLinear(void) 86{ 87 MikMod_free(noteindex); 88 noteindex=NULL; 89 noteindexcount=0; 90} 91 92int speed_to_finetune(ULONG speed,int sample) 93{ 94 ULONG ctmp=0,tmp,note=1,ft=0; 95 96 speed>>=1; 97 while((tmp=getfrequency(of.flags,getlinearperiod(note<<1,0)))<speed) { 98 ctmp=tmp; 99 note++; 100 } 101 102 if(tmp!=speed) { 103 if((tmp-speed)<(speed-ctmp)) 104 while(tmp>speed) 105 tmp=getfrequency(of.flags,getlinearperiod(note<<1,--ft)); 106 else { 107 note--; 108 while(ctmp<speed) 109 ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++ft)); 110 } 111 } 112 113 noteindex[sample]=note-4*OCTAVE; 114 return ft; 115} 116 117/*========== Order stuff */ 118 119/* handles S3M and IT orders */ 120void S3MIT_CreateOrders(int curious) 121{ 122 int t; 123 124 of.numpos = 0; 125 memset(of.positions,0,poslookupcnt*sizeof(UWORD)); 126 memset(poslookup,-1,256); 127 for(t=0;t<poslookupcnt;t++) { 128 int order=origpositions[t]; 129 if(order==255) order=LAST_PATTERN; 130 of.positions[of.numpos]=order; 131 poslookup[t]=of.numpos; /* bug fix for freaky S3Ms / ITs */ 132 if(origpositions[t]<254) of.numpos++; 133 else 134 /* end of song special order */ 135 if((order==LAST_PATTERN)&&(!(curious--))) break; 136 } 137} 138 139/*========== Effect stuff */ 140 141/* handles S3M and IT effects */ 142void S3MIT_ProcessCmd(UBYTE cmd, UBYTE inf, unsigned int flags) 143{ 144 UBYTE lo = inf&0xF; 145 /* process S3M / IT specific command structure */ 146 147 if(cmd!=255) { 148 switch(cmd) { 149 case 1: /* Axx set speed to xx */ 150 UniEffect(UNI_S3MEFFECTA,inf); 151 break; 152 case 2: /* Bxx position jump */ 153 if (inf<poslookupcnt) { 154 /* switch to curious mode if necessary, for example 155 sympex.it, deep joy.it */ 156 if(((SBYTE)poslookup[inf]<0)&&(origpositions[inf]!=255)) 157 S3MIT_CreateOrders(1); 158 159 if(!((SBYTE)poslookup[inf]<0)) 160 UniPTEffect(0xb,poslookup[inf]); 161 } 162 break; 163 case 3: /* Cxx patternbreak to row xx */ 164 if ((flags & S3MIT_OLDSTYLE) && !(flags & S3MIT_IT)) 165 UniPTEffect(0xd,(inf>>4)*10+(inf&0xf)); 166 else 167 UniPTEffect(0xd,inf); 168 break; 169 case 4: /* Dxy volumeslide */ 170 UniEffect(UNI_S3MEFFECTD,inf); 171 break; 172 case 5: /* Exy toneslide down */ 173 UniEffect(UNI_S3MEFFECTE,inf); 174 break; 175 case 6: /* Fxy toneslide up */ 176 UniEffect(UNI_S3MEFFECTF,inf); 177 break; 178 case 7: /* Gxx Tone portamento, speed xx */ 179 if (flags & S3MIT_OLDSTYLE) 180 UniPTEffect(0x3,inf); 181 else 182 UniEffect(UNI_ITEFFECTG,inf); 183 break; 184 case 8: /* Hxy vibrato */ 185 if (flags & S3MIT_OLDSTYLE) { 186 if (flags & S3MIT_IT) 187 UniEffect(UNI_ITEFFECTH_OLD,inf); 188 else 189 UniEffect(UNI_S3MEFFECTH,inf); 190 } else 191 UniEffect(UNI_ITEFFECTH,inf); 192 break; 193 case 9: /* Ixy tremor, ontime x, offtime y */ 194 if (flags & S3MIT_OLDSTYLE) 195 UniEffect(UNI_S3MEFFECTI,inf); 196 else 197 UniEffect(UNI_ITEFFECTI,inf); 198 break; 199 case 0xa: /* Jxy arpeggio */ 200 UniPTEffect(0x0,inf); 201 break; 202 case 0xb: /* Kxy Dual command H00 & Dxy */ 203 if (flags & S3MIT_OLDSTYLE) { 204 if (flags & S3MIT_IT) 205 UniEffect(UNI_ITEFFECTH_OLD,0); 206 else 207 UniEffect(UNI_S3MEFFECTH,0); 208 } else 209 UniEffect(UNI_ITEFFECTH,0); 210 UniEffect(UNI_S3MEFFECTD,inf); 211 break; 212 case 0xc: /* Lxy Dual command G00 & Dxy */ 213 if (flags & S3MIT_OLDSTYLE) 214 UniPTEffect(0x3,0); 215 else 216 UniEffect(UNI_ITEFFECTG,0); 217 UniEffect(UNI_S3MEFFECTD,inf); 218 break; 219 case 0xd: /* Mxx Set Channel Volume */ 220 /* Ignore invalid values > 64. */ 221 if (inf <= 0x40) 222 UniEffect(UNI_ITEFFECTM,inf); 223 break; 224 case 0xe: /* Nxy Slide Channel Volume */ 225 UniEffect(UNI_ITEFFECTN,inf); 226 break; 227 case 0xf: /* Oxx set sampleoffset xx00h */ 228 UniPTEffect(0x9,inf); 229 break; 230 case 0x10: /* Pxy Slide Panning Commands */ 231 UniEffect(UNI_ITEFFECTP,inf); 232 break; 233 case 0x11: /* Qxy Retrig (+volumeslide) */ 234 UniWriteByte(UNI_S3MEFFECTQ); 235 if(inf && !lo && !(flags & S3MIT_OLDSTYLE)) 236 UniWriteByte(1); 237 else 238 UniWriteByte(inf); 239 break; 240 case 0x12: /* Rxy tremolo speed x, depth y */ 241 UniEffect(UNI_S3MEFFECTR,inf); 242 break; 243 case 0x13: /* Sxx special commands */ 244 if (inf>=0xf0) { 245 /* change resonant filter settings if necessary */ 246 if((filters)&&((inf&0xf)!=activemacro)) { 247 activemacro=inf&0xf; 248 for(inf=0;inf<0x80;inf++) 249 filtersettings[inf].filter=filtermacros[activemacro]; 250 } 251 } else { 252 /* Scream Tracker does not have samples larger than 253 64 Kb, thus doesn't need the SAx effect */ 254 if ((flags & S3MIT_SCREAM) && ((inf & 0xf0) == 0xa0)) 255 break; 256 257 UniEffect(UNI_ITEFFECTS0,inf); 258 } 259 break; 260 case 0x14: /* Txx tempo */ 261 if(inf>=0x20) 262 UniEffect(UNI_S3MEFFECTT,inf); 263 else { 264 if(!(flags & S3MIT_OLDSTYLE)) 265 /* IT Tempo slide */ 266 UniEffect(UNI_ITEFFECTT,inf); 267 } 268 break; 269 case 0x15: /* Uxy Fine Vibrato speed x, depth y */ 270 if(flags & S3MIT_OLDSTYLE) { 271 if (flags & S3MIT_IT) 272 UniEffect(UNI_ITEFFECTU_OLD,inf); 273 else 274 UniEffect(UNI_S3MEFFECTU,inf); 275 } else 276 UniEffect(UNI_ITEFFECTU,inf); 277 break; 278 case 0x16: /* Vxx Set Global Volume */ 279 UniEffect(UNI_XMEFFECTG,inf); 280 break; 281 case 0x17: /* Wxy Global Volume Slide */ 282 UniEffect(UNI_ITEFFECTW,inf); 283 break; 284 case 0x18: /* Xxx amiga command 8xx */ 285 if(flags & S3MIT_OLDSTYLE) { 286 if(inf>128) 287 UniEffect(UNI_ITEFFECTS0,0x91); /* surround */ 288 else 289 UniPTEffect(0x8,(inf==128)?255:(inf<<1)); 290 } else 291 UniPTEffect(0x8,inf); 292 break; 293 case 0x19: /* Yxy Panbrello speed x, depth y */ 294 UniEffect(UNI_ITEFFECTY,inf); 295 break; 296 case 0x1a: /* Zxx midi/resonant filters */ 297 if(filtersettings[inf].filter) { 298 UniWriteByte(UNI_ITEFFECTZ); 299 UniWriteByte(filtersettings[inf].filter); 300 UniWriteByte(filtersettings[inf].inf); 301 } 302 break; 303 } 304 } 305} 306 307/*========== Unitrk stuff */ 308 309/* Generic effect writing routine */ 310void UniEffect(UWORD eff,UWORD dat) 311{ 312 if((!eff)||(eff>=UNI_LAST)) return; 313 314 UniWriteByte(eff); 315 if(unioperands[eff]==2) 316 UniWriteWord(dat); 317 else 318 UniWriteByte(dat); 319} 320 321/* Appends UNI_PTEFFECTX opcode to the unitrk stream. */ 322void UniPTEffect(UBYTE eff, UBYTE dat) 323{ 324#ifdef MIKMOD_DEBUG 325 if (eff>=0x10) 326 fprintf(stderr,"UniPTEffect called with incorrect eff value %d\n",eff); 327 else 328#endif 329 if((eff)||(dat)||(of.flags&UF_ARPMEM)) UniEffect(UNI_PTEFFECT0+eff,dat); 330} 331 332/* Appends UNI_VOLEFFECT + effect/dat to unistream. */ 333void UniVolEffect(UWORD eff,UBYTE dat) 334{ 335 if((eff)||(dat)) { /* don't write empty effect */ 336 UniWriteByte(UNI_VOLEFFECTS); 337 UniWriteByte(eff);UniWriteByte(dat); 338 } 339} 340 341/* ex:set ts=4: */