1 /* MikMod sound library 2 (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for 3 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 15 instrument MOD loader 26 Also supports Ultimate Sound Tracker (old M15 format) 27 28 ==============================================================================*/ 29 30 #ifdef HAVE_CONFIG_H 31 #include "config.h" 32 #endif 33 34 #include <string.h> 35 36 #include "unimod_priv.h" 37 38 /*========== Module Structure */ 39 40 typedef struct MSAMPINFO 41 { 42 CHAR samplename[23]; /* 22 in module, 23 in memory */ 43 UWORD length; 44 UBYTE finetune; 45 UBYTE volume; 46 UWORD reppos; 47 UWORD replen; 48 } 49 MSAMPINFO; 50 51 typedef struct MODULEHEADER 52 { 53 CHAR songname[21]; /* the songname.., 20 in module, 21 in memory */ 54 MSAMPINFO samples[15]; /* all sampleinfo */ 55 UBYTE songlength; /* number of patterns used */ 56 UBYTE magic1; /* should be 127 */ 57 UBYTE positions[128]; /* which pattern to play at pos */ 58 } 59 MODULEHEADER; 60 61 typedef struct MODNOTE 62 { 63 UBYTE a, b, c, d; 64 } 65 MODNOTE; 66 67 /*========== Loader variables */ 68 69 static MODULEHEADER *mh = NULL; 70 static MODNOTE *patbuf = NULL; 71 static BOOL ust_loader = 0; /* if TRUE, load as an ust module. */ 72 73 /* known file formats which can confuse the loader */ 74 #define REJECT 2 75 static const char *signatures[REJECT] = 76 { 77 "CAKEWALK", /* cakewalk midi files */ 78 "SZDD" /* Microsoft compressed files */ 79 }; 80 static int siglen[REJECT] = 81 {8, 4}; 82 83 /*========== Loader code */ 84 85 static BOOL 86 LoadModuleHeader (MODULEHEADER * mh) 87 { 88 int t, u; 89 90 _mm_read_string (mh->songname, 20, modreader); 91 mh->songname[20] = 0; /* just in case */ 92 93 /* sanity check : title should contain printable characters and a bunch 94 of null chars */ 95 for (t = 0; t < 20; t++) 96 if ((mh->songname[t]) && (mh->songname[t] < 32)) 97 return 0; 98 for (t = 0; (mh->songname[t]) && (t < 20); t++); 99 if (t < 20) 100 for (; t < 20; t++) 101 if (mh->songname[t]) 102 return 0; 103 104 for (t = 0; t < 15; t++) 105 { 106 MSAMPINFO *s = &mh->samples[t]; 107 108 _mm_read_string (s->samplename, 22, modreader); 109 s->samplename[22] = 0; /* just in case */ 110 s->length = _mm_read_M_UWORD (modreader); 111 s->finetune = _mm_read_UBYTE (modreader); 112 s->volume = _mm_read_UBYTE (modreader); 113 s->reppos = _mm_read_M_UWORD (modreader); 114 s->replen = _mm_read_M_UWORD (modreader); 115 116 /* sanity check : sample title should contain printable characters and 117 a bunch of null chars */ 118 for (u = 0; u < 20; u++) 119 if ((s->samplename[u]) && (s->samplename[u] < /*32 */ 14)) 120 return 0; 121 for (u = 0; (s->samplename[u]) && (u < 20); u++); 122 if (u < 20) 123 for (; u < 20; u++) 124 if (s->samplename[u]) 125 return 0; 126 127 /* sanity check : finetune values */ 128 if (s->finetune >> 4) 129 return 0; 130 } 131 132 mh->songlength = _mm_read_UBYTE (modreader); 133 mh->magic1 = _mm_read_UBYTE (modreader); /* should be 127 */ 134 135 /* sanity check : no more than 128 positions, restart position in range */ 136 if ((!mh->songlength) || (mh->songlength > 128)) 137 return 0; 138 /* values encountered so far are 0x6a and 0x78 */ 139 if (((mh->magic1 & 0xf8) != 0x78) && (mh->magic1 != 0x6a) && (mh->magic1 > mh->songlength)) 140 return 0; 141 142 _mm_read_UBYTES (mh->positions, 128, modreader); 143 144 /* sanity check : pattern range is 0..63 */ 145 for (t = 0; t < 128; t++) 146 if (mh->positions[t] > 63) 147 return 0; 148 149 return (!_mm_eof (modreader)); 150 } 151 152 /* Checks the patterns in the modfile for UST / 15-inst indications. 153 For example, if an effect 3xx is found, it is assumed that the song 154 is 15-inst. If a 1xx effect has dat greater than 0x20, it is UST. 155 156 Returns: 0 indecisive; 1 = UST; 2 = 15-inst */ 157 static int 158 CheckPatternType (int numpat) 159 { 160 int t; 161 UBYTE eff, dat; 162 163 for (t = 0; t < numpat * (64U * 4); t++) 164 { 165 /* Load the pattern into the temp buffer and scan it */ 166 _mm_read_UBYTE (modreader); 167 _mm_read_UBYTE (modreader); 168 eff = _mm_read_UBYTE (modreader); 169 dat = _mm_read_UBYTE (modreader); 170 171 switch (eff) 172 { 173 case 1: 174 if (dat > 0x1f) 175 return 1; 176 if (dat < 0x3) 177 return 2; 178 break; 179 case 2: 180 if (dat > 0x1f) 181 return 1; 182 return 2; 183 case 3: 184 if (dat) 185 return 2; 186 break; 187 default: 188 return 2; 189 } 190 } 191 return 0; 192 } 193 194 static BOOL 195 M15_Test (void) 196 { 197 int t, numpat; 198 MODULEHEADER mh; 199 200 ust_loader = 0; 201 if (!LoadModuleHeader (&mh)) 202 return 0; 203 204 /* reject other file types */ 205 for (t = 0; t < REJECT; t++) 206 if (!memcmp (mh.songname, signatures[t], siglen[t])) 207 return 0; 208 209 if (mh.magic1 > 127) 210 return 0; 211 if ((!mh.songlength) || (mh.songlength > mh.magic1)) 212 return 0; 213 214 for (t = 0; t < 15; t++) 215 { 216 /* all finetunes should be zero */ 217 if (mh.samples[t].finetune) 218 return 0; 219 220 /* all volumes should be <= 64 */ 221 if (mh.samples[t].volume > 64) 222 return 0; 223 224 /* all instrument names should begin with s, st-, or a number */ 225 if (mh.samples[t].samplename[0] == 's') 226 { 227 if ((memcmp (mh.samples[t].samplename, "st-", 3)) && 228 (memcmp (mh.samples[t].samplename, "ST-", 3)) && 229 (*mh.samples[t].samplename)) 230 ust_loader = 1; 231 } 232 else if ((mh.samples[t].samplename[0] < '0') || 233 (mh.samples[t].samplename[0] > '9')) 234 ust_loader = 1; 235 236 if (mh.samples[t].length > 4999 || mh.samples[t].reppos > 9999) 237 { 238 ust_loader = 0; 239 if (mh.samples[t].length > 32768) 240 return 0; 241 } 242 243 /* if loop information is incorrect as words, but correct as bytes, 244 this is likely to be an ust-style module */ 245 if((mh.samples[t].reppos + mh.samples[t].replen > mh.samples[t].length) && 246 (mh.samples[t].reppos + mh.samples[t].replen < (mh.samples[t].length << 1))) 247 { 248 ust_loader = 1; 249 return 1; 250 } 251 252 if (!ust_loader) 253 return 1; 254 } 255 256 for (numpat = 0, t = 0; t < mh.songlength; t++) 257 if (mh.positions[t] > numpat) 258 numpat = mh.positions[t]; 259 numpat++; 260 switch (CheckPatternType (numpat)) 261 { 262 case 0: /* indecisive, so check more clues... */ 263 break; 264 case 1: 265 ust_loader = 1; 266 break; 267 case 2: 268 ust_loader = 0; 269 break; 270 } 271 return 1; 272 } 273 274 static BOOL 275 M15_Init (void) 276 { 277 if (!(mh = (MODULEHEADER *) _mm_malloc (sizeof (MODULEHEADER)))) 278 return 0; 279 return 1; 280 } 281 282 static void 283 M15_Cleanup (void) 284 { 285 _mm_free (mh); 286 _mm_free (patbuf); 287 } 288 289 /* 290 Old (amiga) noteinfo: 291 292 _____byte 1_____ byte2_ _____byte 3_____ byte4_ 293 / \ / \ / \ / \ 294 0000 0000-00000000 0000 0000-00000000 295 296 Upper four 12 bits for Lower four Effect command. 297 bits of sam- note period. bits of sam- 298 ple number. ple number. 299 */ 300 301 static UWORD npertab[7 * OCTAVE] = 302 { 303 /* -> Tuning 0 */ 304 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 906, 305 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453, 306 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226, 307 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113, 308 107, 101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56, 309 310 53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28, 311 27, 25, 24, 22, 21, 20, 19, 18, 17, 16, 15, 14 312 }; 313 314 315 static void 316 M15_ConvertNote (MODNOTE * n) 317 { 318 UBYTE instrument, effect, effdat, note; 319 UWORD period; 320 UBYTE lastnote = 0; 321 322 /* decode the 4 bytes that make up a single note */ 323 instrument = n->c >> 4; 324 period = (((UWORD) n->a & 0xf) << 8) + n->b; 325 effect = n->c & 0xf; 326 effdat = n->d; 327 328 /* Convert the period to a note number */ 329 note = 0; 330 if (period) 331 { 332 for (note = 0; note < 7 * OCTAVE; note++) 333 if (period >= npertab[note]) 334 break; 335 if (note == 7 * OCTAVE) 336 note = 0; 337 else 338 note++; 339 } 340 341 if (instrument) 342 { 343 /* if instrument does not exist, note cut */ 344 if ((instrument > 15) || (!mh->samples[instrument - 1].length)) 345 { 346 UniPTEffect (0xc, 0); 347 if (effect == 0xc) 348 effect = effdat = 0; 349 } 350 else 351 { 352 /* if we had a note, then change instrument... */ 353 if (note) 354 UniInstrument (instrument - 1); 355 /* ...otherwise, only adjust volume... */ 356 else 357 { 358 /* ...unless an effect was specified, which forces a new note 359 to be played */ 360 if (effect || effdat) 361 { 362 UniInstrument (instrument - 1); 363 note = lastnote; 364 } 365 else 366 UniPTEffect (0xc, mh->samples[instrument - 1].volume & 0x7f); 367 } 368 } 369 } 370 if (note) 371 { 372 UniNote (note + 2 * OCTAVE - 1); 373 lastnote = note; 374 } 375 376 /* Handle ``heavy'' volumes correctly */ 377 if ((effect == 0xc) && (effdat > 0x40)) 378 effdat = 0x40; 379 380 /* Convert pattern jump from Dec to Hex */ 381 if (effect == 0xd) 382 effdat = (((effdat & 0xf0) >> 4) * 10) + (effdat & 0xf); 383 384 /* Volume slide, up has priority */ 385 if ((effect == 0xa) && (effdat & 0xf) && (effdat & 0xf0)) 386 effdat &= 0xf0; 387 388 if (ust_loader) 389 { 390 switch (effect) 391 { 392 case 0: 393 case 3: 394 break; 395 case 1: 396 UniPTEffect (0, effdat); 397 break; 398 case 2: 399 if (effdat & 0xf) 400 UniPTEffect (1, effdat & 0xf); 401 if (effdat >> 2) 402 UniPTEffect (2, effdat >> 2); 403 break; 404 default: 405 UniPTEffect (effect, effdat); 406 break; 407 } 408 } 409 else { 410 /* Ignore 100, 200 and 300 (there is no porta memory in mod files) */ 411 if ((!effdat) && ((effect == 1)||(effect == 2)||(effect == 3))) 412 effect = 0; 413 414 UniPTEffect (effect, effdat); 415 } 416 } 417 418 static UBYTE * 419 M15_ConvertTrack (MODNOTE * n) 420 { 421 int t; 422 423 UniReset (); 424 for (t = 0; t < 64; t++) 425 { 426 M15_ConvertNote (n); 427 UniNewline (); 428 n += 4; 429 } 430 return UniDup (); 431 } 432 433 /* Loads all patterns of a modfile and converts them into the 3 byte format. */ 434 static BOOL 435 M15_LoadPatterns (void) 436 { 437 int t, s, tracks = 0; 438 439 if (!AllocPatterns ()) 440 return 0; 441 if (!AllocTracks ()) 442 return 0; 443 444 /* Allocate temporary buffer for loading and converting the patterns */ 445 if (!(patbuf = (MODNOTE *) _mm_calloc (64U * 4, sizeof (MODNOTE)))) 446 return 0; 447 448 for (t = 0; t < of.numpat; t++) 449 { 450 /* Load the pattern into the temp buffer and convert it */ 451 for (s = 0; s < (64U * 4); s++) 452 { 453 patbuf[s].a = _mm_read_UBYTE (modreader); 454 patbuf[s].b = _mm_read_UBYTE (modreader); 455 patbuf[s].c = _mm_read_UBYTE (modreader); 456 patbuf[s].d = _mm_read_UBYTE (modreader); 457 } 458 459 for (s = 0; s < 4; s++) 460 if (!(of.tracks[tracks++] = M15_ConvertTrack (patbuf + s))) 461 return 0; 462 } 463 return 1; 464 } 465 466 static BOOL 467 M15_Load (BOOL curious) 468 { 469 int t, scan; 470 SAMPLE *q; 471 MSAMPINFO *s; 472 473 /* try to read module header */ 474 if (!LoadModuleHeader (mh)) 475 { 476 _mm_errno = MMERR_LOADING_HEADER; 477 return 0; 478 } 479 480 if (ust_loader) 481 of.modtype = strdup ("Ultimate Soundtracker"); 482 else 483 of.modtype = strdup ("Soundtracker"); 484 485 /* set module variables */ 486 of.initspeed = 6; 487 of.inittempo = 125; 488 of.numchn = 4; 489 of.songname = DupStr (mh->songname, 21, 1); 490 of.numpos = mh->songlength; 491 of.reppos = 0; 492 493 /* Count the number of patterns */ 494 of.numpat = 0; 495 for (t = 0; t < of.numpos; t++) 496 if (mh->positions[t] > of.numpat) 497 of.numpat = mh->positions[t]; 498 /* since some old modules embed extra patterns, we have to check the 499 whole list to get the samples' file offsets right - however we can find 500 garbage here, so check carefully */ 501 scan = 1; 502 for (t = of.numpos; t < 128; t++) 503 if (mh->positions[t] >= 0x80) 504 scan = 0; 505 if (scan) 506 for (t = of.numpos; t < 128; t++) 507 { 508 if (mh->positions[t] > of.numpat) 509 of.numpat = mh->positions[t]; 510 if ((curious) && (mh->positions[t])) 511 of.numpos = t + 1; 512 } 513 of.numpat++; 514 of.numtrk = of.numpat * of.numchn; 515 516 if (!AllocPositions (of.numpos)) 517 return 0; 518 for (t = 0; t < of.numpos; t++) 519 of.positions[t] = mh->positions[t]; 520 521 /* Finally, init the sampleinfo structures */ 522 of.numins = of.numsmp = 15; 523 if (!AllocSamples ()) 524 return 0; 525 526 s = mh->samples; 527 q = of.samples; 528 529 for (t = 0; t < of.numins; t++) 530 { 531 /* convert the samplename */ 532 q->samplename = DupStr (s->samplename, 23, 1); 533 534 /* init the sampleinfo variables and convert the size pointers */ 535 q->speed = finetune[s->finetune & 0xf]; 536 q->volume = s->volume; 537 if (ust_loader) 538 q->loopstart = s->reppos; 539 else 540 q->loopstart = s->reppos << 1; 541 q->loopend = q->loopstart + (s->replen << 1); 542 q->length = s->length << 1; 543 544 q->flags = SF_SIGNED; 545 if(ust_loader) 546 q->flags |= SF_UST_LOOP; 547 if(s->replen > 2) 548 q->flags |= SF_LOOP; 549 550 /* fix replen if repend>length */ 551 if (q->loopend > q->length) 552 q->loopend = q->length; 553 554 s++; 555 q++; 556 } 557 558 if (!M15_LoadPatterns ()) 559 return 0; 560 ust_loader = 0; 561 562 return 1; 563 } 564 565 static CHAR * 566 M15_LoadTitle (void) 567 { 568 CHAR s[21]; 569 570 _mm_fseek (modreader, 0, SEEK_SET); 571 if (!_mm_read_UBYTES (s, 20, modreader)) 572 return NULL; 573 s[20] = 0; /* just in case */ 574 return (DupStr (s, 21, 1)); 575 } 576 577 /*========== Loader information */ 578 579 MLOADER load_m15 = 580 { 581 NULL, 582 "15-instrument module", 583 "MOD (15 instruments)", 584 M15_Init, 585 M15_Test, 586 M15_Load, 587 M15_Cleanup, 588 M15_LoadTitle 589 }; 590 591 /* ex:set ts=4: */ 592