1 /* 2 * Schism Tracker - a cross-platform Impulse Tracker clone 3 * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com> 4 * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org> 5 * copyright (c) 2009 Storlek & Mrs. Brisby 6 * copyright (c) 2010-2012 Storlek 7 * URL: http://schismtracker.org/ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 24 #define NEED_BYTESWAP 25 #include "headers.h" 26 #include "slurp.h" 27 #include "fmt.h" 28 #include "log.h" 29 30 #include "sndfile.h" 31 32 /* --------------------------------------------------------------------- */ 33 34 /* MDL is nice, but it's a pain to read the title... */ 35 36 int fmt_mdl_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) 37 { 38 uint32_t position, block_length; 39 40 /* data[4] = major version number (accept 0 or 1) */ 41 if (!(length > 5 && ((data[4] & 0xf0) >> 4) <= 1 && memcmp(data, "DMDL", 4) == 0)) 42 return 0; 43 44 position = 5; 45 while (position + 6 < length) { 46 memcpy(&block_length, data + position + 2, 4); 47 block_length = bswapLE32(block_length); 48 if (block_length + position > length) 49 return 0; 50 if (memcmp(data + position, "IN", 2) == 0) { 51 /* hey! we have a winner */ 52 file->title = strn_dup((const char *)data + position + 6, 32); 53 file->artist = strn_dup((const char *)data + position + 38, 20); 54 file->description = "Digitrakker"; 55 /*file->extension = str_dup("mdl");*/ 56 file->type = TYPE_MODULE_XM; 57 return 1; 58 } /* else... */ 59 position += 6 + block_length; 60 } 61 62 return 0; 63 } 64 65 /* --------------------------------------------------------------------------------------------------------- */ 66 /* Structs and stuff for the loader */ 67 68 #define MDL_BLOCK(a,b) (((a) << 8) | (b)) 69 #define MDL_BLK_INFO MDL_BLOCK('I','N') 70 #define MDL_BLK_MESSAGE MDL_BLOCK('M','E') 71 #define MDL_BLK_PATTERNS MDL_BLOCK('P','A') 72 #define MDL_BLK_PATTERNNAMES MDL_BLOCK('P','N') 73 #define MDL_BLK_TRACKS MDL_BLOCK('T','R') 74 #define MDL_BLK_INSTRUMENTS MDL_BLOCK('I','I') 75 #define MDL_BLK_VOLENVS MDL_BLOCK('V','E') 76 #define MDL_BLK_PANENVS MDL_BLOCK('P','E') 77 #define MDL_BLK_FREQENVS MDL_BLOCK('F','E') 78 #define MDL_BLK_SAMPLEINFO MDL_BLOCK('I','S') 79 #define MDL_BLK_SAMPLEDATA MDL_BLOCK('S','A') 80 81 #define MDL_FADE_CUT 0xffff 82 83 enum { 84 MDLNOTE_NOTE = 1 << 0, 85 MDLNOTE_SAMPLE = 1 << 1, 86 MDLNOTE_VOLUME = 1 << 2, 87 MDLNOTE_EFFECTS = 1 << 3, 88 MDLNOTE_PARAM1 = 1 << 4, 89 MDLNOTE_PARAM2 = 1 << 5, 90 }; 91 92 #pragma pack(push,1) 93 struct mdl_infoblock { 94 char title[32]; 95 char composer[20]; 96 uint16_t numorders; 97 uint16_t repeatpos; 98 uint8_t globalvol; 99 uint8_t speed; 100 uint8_t tempo; 101 uint8_t chanpan[32]; 102 }; 103 104 /* This is actually a part of the instrument (II) block */ 105 struct mdl_samplehdr { 106 uint8_t smpnum; 107 uint8_t lastnote; 108 uint8_t volume; 109 uint8_t volenv_flags; // 6 bits env #, 2 bits flags 110 uint8_t panning; 111 uint8_t panenv_flags; 112 uint16_t fadeout; 113 uint8_t vibspeed; 114 uint8_t vibdepth; 115 uint8_t vibsweep; 116 uint8_t vibtype; 117 uint8_t reserved; // zero 118 uint8_t freqenv_flags; 119 }; 120 121 struct mdl_sampleinfo { 122 uint8_t smpnum; 123 char name[32]; 124 char filename[8]; 125 uint32_t c4speed; // c4, c5, whatever 126 uint32_t length; 127 uint32_t loopstart; 128 uint32_t looplen; 129 uint8_t unused; // was volume in v0.0, why it was changed I have no idea 130 uint8_t flags; 131 }; 132 133 struct mdl_sampleinfo_v0 { 134 uint8_t smpnum; 135 char name[32]; 136 char filename[8]; 137 uint16_t c4speed; 138 uint32_t length; 139 uint32_t loopstart; 140 uint32_t looplen; 141 uint8_t volume; 142 uint8_t flags; 143 }; 144 145 struct mdl_envelope { 146 uint8_t envnum; 147 struct { 148 uint8_t x; // delta-value from last point, 0 means no more points defined 149 uint8_t y; // 0-63 150 } nodes[15]; 151 uint8_t flags; 152 uint8_t loop; // lower 4 bits = start, upper 4 bits = end 153 }; 154 #pragma pack(pop) 155 156 /* --------------------------------------------------------------------------------------------------------- */ 157 /* Internal definitions */ 158 159 struct mdlpat { 160 int track; // which track to put here 161 int rows; // 1-256 162 song_note_t *note; // first note -- add 64 for next note, etc. 163 struct mdlpat *next; 164 }; 165 166 struct mdlenv { 167 uint32_t flags; 168 song_envelope_t data; 169 }; 170 171 enum { 172 MDL_HAS_INFO = 1 << 0, 173 MDL_HAS_MESSAGE = 1 << 1, 174 MDL_HAS_PATTERNS = 1 << 2, 175 MDL_HAS_TRACKS = 1 << 3, 176 MDL_HAS_INSTRUMENTS = 1 << 4, 177 MDL_HAS_VOLENVS = 1 << 5, 178 MDL_HAS_PANENVS = 1 << 6, 179 MDL_HAS_FREQENVS = 1 << 7, 180 MDL_HAS_SAMPLEINFO = 1 << 8, 181 MDL_HAS_SAMPLEDATA = 1 << 9, 182 }; 183 184 static const uint8_t mdl_efftrans[] = { 185 /* 0 */ FX_NONE, 186 /* 1st column only */ 187 /* 1 */ FX_PORTAMENTOUP, 188 /* 2 */ FX_PORTAMENTODOWN, 189 /* 3 */ FX_TONEPORTAMENTO, 190 /* 4 */ FX_VIBRATO, 191 /* 5 */ FX_ARPEGGIO, 192 /* 6 */ FX_NONE, 193 /* Either column */ 194 /* 7 */ FX_TEMPO, 195 /* 8 */ FX_PANNING, 196 /* 9 */ FX_SETENVPOSITION, 197 /* A */ FX_NONE, 198 /* B */ FX_POSITIONJUMP, 199 /* C */ FX_GLOBALVOLUME, 200 /* D */ FX_PATTERNBREAK, 201 /* E */ FX_SPECIAL, 202 /* F */ FX_SPEED, 203 /* 2nd column only */ 204 /* G */ FX_VOLUMESLIDE, // up 205 /* H */ FX_VOLUMESLIDE, // down 206 /* I */ FX_RETRIG, 207 /* J */ FX_TREMOLO, 208 /* K */ FX_TREMOR, 209 /* L */ FX_NONE, 210 }; 211 212 static const uint8_t autovib_import[] = {VIB_SINE, VIB_RAMP_DOWN, VIB_SQUARE, VIB_SINE}; 213 214 /* --------------------------------------------------------------------------------------------------------- */ 215 /* a highly overcomplicated mess to import effects */ 216 217 // receive an MDL effect, give back a 'normal' one. 218 static void translate_fx(uint8_t *pe, uint8_t *pp) 219 { 220 uint8_t e = *pe; 221 uint8_t p = *pp; 222 223 if (e > 21) 224 e = 0; // (shouldn't ever happen) 225 *pe = mdl_efftrans[e]; 226 227 switch (e) { 228 case 7: // tempo 229 // MDL supports any nonzero tempo value, but we don't 230 p = MAX(p, 0x20); 231 break; 232 case 8: // panning 233 p = MIN(p << 1, 0xff); 234 break; 235 case 0xd: // pattern break 236 // convert from stupid decimal-hex 237 p = 10 * (p >> 4) + (p & 0xf); 238 break; 239 case 0xe: // special 240 switch (p >> 4) { 241 case 0: // unused 242 case 3: // unused 243 case 5: // set finetune 244 case 8: // set samplestatus (what?) 245 *pe = FX_NONE; 246 break; 247 case 1: // pan slide left 248 *pe = FX_PANNINGSLIDE; 249 p = (MAX(p & 0xf, 0xe) << 4) | 0xf; 250 break; 251 case 2: // pan slide right 252 *pe = FX_PANNINGSLIDE; 253 p = 0xf0 | MAX(p & 0xf, 0xe); 254 break; 255 case 4: // vibrato waveform 256 p = 0x30 | (p & 0xf); 257 break; 258 case 6: // pattern loop 259 p = 0xb0 | (p & 0xf); 260 break; 261 case 7: // tremolo waveform 262 p = 0x40 | (p & 0xf); 263 break; 264 case 9: // retrig 265 *pe = FX_RETRIG; 266 p &= 0xf; 267 break; 268 case 0xa: // global vol slide up 269 *pe = FX_GLOBALVOLSLIDE; 270 p = 0xf0 & (((p & 0xf) + 1) << 3); 271 break; 272 case 0xb: // global vol slide down 273 *pe = FX_GLOBALVOLSLIDE; 274 p = ((p & 0xf) + 1) >> 1; 275 break; 276 case 0xc: // note cut 277 case 0xd: // note delay 278 case 0xe: // pattern delay 279 // nothing to change here 280 break; 281 case 0xf: // offset -- further mangled later. 282 *pe = FX_OFFSET; 283 break; 284 } 285 break; 286 case 0x10: // volslide up 287 if (p < 0xE0) { // Gxy -> Dz0 (z=(xy>>2)) 288 p >>= 2; 289 if (p > 0x0F) 290 p = 0x0F; 291 p <<= 4; 292 } else if (p < 0xF0) { // GEy -> DzF (z=(y>>2)) 293 p = (((p & 0x0F) << 2) | 0x0F); 294 } else { // GFy -> DyF 295 p = ((p << 4) | 0x0F); 296 } 297 break; 298 case 0x11: // volslide down 299 if (p < 0xE0) { // Hxy -> D0z (z=(xy>>2)) 300 p >>= 2; 301 if(p > 0x0F) 302 p = 0x0F; 303 } else if (p < 0xF0) { // HEy -> DFz (z=(y>>2)) 304 p = (((p & 0x0F) >> 2) | 0xF0); 305 } else { // HFy -> DFy 306 // Nothing to do 307 } 308 break; 309 } 310 311 *pp = p; 312 } 313 314 // return: 1 if an effect was lost, 0 if not. 315 static int cram_mdl_effects(song_note_t *note, uint8_t vol, uint8_t e1, uint8_t e2, uint8_t p1, uint8_t p2) 316 { 317 int lostfx = 0; 318 int n; 319 uint8_t tmp; 320 321 // map second effect values 1-6 to effects G-L 322 if (e2 >= 1 && e2 <= 6) 323 e2 += 15; 324 325 translate_fx(&e1, &p1); 326 translate_fx(&e2, &p2); 327 /* From the Digitrakker documentation: 328 * EFx -xx - Set Sample Offset 329 This is a double-command. It starts the 330 sample at adress xxx*256. 331 Example: C-5 01 -- EF1 -23 ->starts sample 332 01 at address 12300 (in hex). 333 Kind of screwy, but I guess it's better than the mess required to do it with IT (which effectively 334 requires 3 rows in order to set the offset past 0xff00). If we had access to the entire track, we 335 *might* be able to shove the high offset SAy into surrounding rows, but it wouldn't always be possible, 336 it'd make the loader a lot uglier, and generally would be more trouble than it'd be worth to implement. 337 338 What's more is, if there's another effect in the second column, it's ALSO processed in addition to the 339 offset, and the second data byte is shared between the two effects. 340 And: an offset effect without a note will retrigger the previous note, but I'm not even going to try to 341 handle that behavior. */ 342 if (e1 == FX_OFFSET) { 343 // EFy -xx => offset yxx00 344 p1 = (p1 & 0xf) ? 0xff : p2; 345 if (e2 == FX_OFFSET) 346 e2 = FX_NONE; 347 } else if (e2 == FX_OFFSET) { 348 // --- EFy => offset y0000 (best we can do without doing a ton of extra work is 0xff00) 349 p2 = (p2 & 0xf) ? 0xff : 0; 350 } 351 352 if (vol) { 353 note->voleffect = VOLFX_VOLUME; 354 note->volparam = (vol + 2) >> 2; 355 } 356 357 /* If we have Dxx + G00, or Dxx + H00, combine them into Lxx/Kxx. 358 (Since pitch effects only "fit" in the first effect column, and volume effects only work in the 359 second column, we don't have to check every combination here.) */ 360 if (e2 == FX_VOLUMESLIDE && p1 == 0) { 361 if (e1 == FX_TONEPORTAMENTO) { 362 e1 = FX_NONE; 363 e2 = FX_TONEPORTAVOL; 364 } else if (e1 == FX_VIBRATO) { 365 e1 = FX_NONE; 366 e2 = FX_VIBRATOVOL; 367 } 368 } 369 370 /* Try to fit the "best" effect into e2. */ 371 if (e1 == FX_NONE) { 372 // easy 373 } else if (e2 == FX_NONE) { 374 // almost as easy 375 e2 = e1; 376 p2 = p1; 377 e1 = FX_NONE; 378 } else if (e1 == e2 && e1 != FX_SPECIAL) { 379 /* Digitrakker processes the effects left-to-right, so if both effects are the same, the 380 second essentially overrides the first. */ 381 e1 = FX_NONE; 382 } else if (!vol) { 383 // The volume column is free, so try to shove one of them into there. 384 385 // See also xm.c. 386 // (Just because I'm using the same sort of code twice doesn't make it any less of a hack) 387 for (n = 0; n < 4; n++) { 388 if (convert_voleffect(&e1, &p1, n >> 1)) { 389 note->voleffect = e1; 390 note->volparam = p1; 391 e1 = FX_NONE; 392 break; 393 } else { 394 // swap them 395 tmp = e2; e2 = e1; e1 = tmp; 396 tmp = p2; p2 = p1; p1 = tmp; 397 } 398 } 399 } 400 401 // If we still have two effects, pick the 'best' one 402 if (e1 != FX_NONE && e2 != FX_NONE) { 403 lostfx++; 404 if (effect_weight[e1] < effect_weight[e2]) { 405 e2 = e1; 406 p2 = p1; 407 } 408 } 409 410 note->effect = e2; 411 note->param = p2; 412 413 return lostfx; 414 } 415 416 /* --------------------------------------------------------------------------------------------------------- */ 417 /* block reading */ 418 419 // return: repeat position. 420 static int mdl_read_info(song_t *song, slurp_t *fp) 421 { 422 struct mdl_infoblock info; 423 int n, songlen; 424 uint8_t b; 425 426 slurp_read(fp, &info, sizeof(info)); 427 info.numorders = bswapLE16(info.numorders); 428 info.repeatpos = bswapLE16(info.repeatpos); 429 430 // title is space-padded 431 info.title[31] = '\0'; 432 trim_string(info.title); 433 strncpy(song->title, info.title, 25); 434 song->title[25] = '\0'; 435 436 song->initial_global_volume = (info.globalvol + 1) >> 1; 437 song->initial_speed = info.speed ?: 1; 438 song->initial_tempo = MAX(info.tempo, 31); // MDL tempo range is actually 4-255 439 440 // channel pannings 441 for (n = 0; n < 32; n++) { 442 song->channels[n].panning = (info.chanpan[n] & 127) << 1; // ugh 443 if (info.chanpan[n] & 128) 444 song->channels[n].flags |= CHN_MUTE; 445 } 446 for (; n < 64; n++) { 447 song->channels[n].panning = 128; 448 song->channels[n].flags |= CHN_MUTE; 449 } 450 451 songlen = MIN(info.numorders, MAX_ORDERS - 1); 452 for (n = 0; n < songlen; n++) { 453 b = slurp_getc(fp); 454 song->orderlist[n] = (b < MAX_PATTERNS) ? b : ORDER_SKIP; 455 } 456 457 return info.repeatpos; 458 } 459 460 static void mdl_read_message(song_t *song, slurp_t *fp, uint32_t blklen) 461 { 462 char *ptr = song->message; 463 464 blklen = MIN(blklen, MAX_MESSAGE); 465 slurp_read(fp, ptr, blklen); 466 ptr[blklen] = '\0'; 467 468 while ((ptr = strchr(ptr, '\r')) != NULL) 469 *ptr = '\n'; 470 } 471 472 static struct mdlpat *mdl_read_patterns(song_t *song, slurp_t *fp) 473 { 474 struct mdlpat pat_head = { .next = NULL }; // only exists for .next 475 struct mdlpat *patptr = &pat_head; 476 song_note_t *note; 477 int npat, nchn, rows, pat, chn; 478 uint16_t trknum; 479 480 npat = slurp_getc(fp); 481 npat = MIN(npat, MAX_PATTERNS); 482 for (pat = 0; pat < npat; pat++) { 483 484 nchn = slurp_getc(fp); 485 rows = slurp_getc(fp) + 1; 486 slurp_seek(fp, 16, SEEK_CUR); // skip the name 487 488 note = song->patterns[pat] = csf_allocate_pattern(rows); 489 song->pattern_size[pat] = song->pattern_alloc_size[pat] = rows; 490 for (chn = 0; chn < nchn; chn++, note++) { 491 slurp_read(fp, &trknum, 2); 492 trknum = bswapLE16(trknum); 493 if (!trknum) 494 continue; 495 496 patptr->next = mem_alloc(sizeof(struct mdlpat)); 497 patptr = patptr->next; 498 patptr->track = trknum; 499 patptr->rows = rows; 500 patptr->note = note; 501 patptr->next = NULL; 502 } 503 } 504 505 return pat_head.next; 506 } 507 508 // mostly the same as above 509 static struct mdlpat *mdl_read_patterns_v0(song_t *song, slurp_t *fp) 510 { 511 struct mdlpat pat_head = { .next = NULL }; 512 struct mdlpat *patptr = &pat_head; 513 song_note_t *note; 514 int npat, pat, chn; 515 uint16_t trknum; 516 517 npat = slurp_getc(fp); 518 npat = MIN(npat, MAX_PATTERNS); 519 for (pat = 0; pat < npat; pat++) { 520 521 note = song->patterns[pat] = csf_allocate_pattern(64); 522 song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; 523 for (chn = 0; chn < 32; chn++, note++) { 524 slurp_read(fp, &trknum, 2); 525 trknum = bswapLE16(trknum); 526 if (!trknum) 527 continue; 528 529 patptr->next = mem_alloc(sizeof(struct mdlpat)); 530 patptr = patptr->next; 531 patptr->track = trknum; 532 patptr->rows = 64; 533 patptr->note = note; 534 patptr->next = NULL; 535 } 536 } 537 538 return pat_head.next; 539 } 540 541 static song_note_t **mdl_read_tracks(slurp_t *fp) 542 { 543 song_note_t **tracks = mem_calloc(65536, sizeof(song_note_t *)); 544 int ntrks, trk, row, lostfx = 0; 545 uint16_t h; 546 uint8_t b, x, y; 547 uint8_t vol, e1, e2, p1, p2; 548 size_t bytesleft, reallen = fp->length; 549 550 slurp_read(fp, &h, 2); 551 ntrks = bswapLE16(h); 552 553 // track 0 is always blank 554 for (trk = 1; trk <= ntrks; trk++) { 555 slurp_read(fp, &h, 2); 556 bytesleft = bswapLE16(h); 557 fp->length = MIN(fp->length, fp->pos + bytesleft); // narrow 558 tracks[trk] = mem_calloc(256, sizeof(song_note_t)); 559 row = 0; 560 while (row < 256 && !slurp_eof(fp)) { 561 b = slurp_getc(fp); 562 x = b >> 2; 563 y = b & 3; 564 switch (y) { 565 case 0: // (x+1) empty notes follow 566 row += x + 1; 567 break; 568 case 1: // Repeat previous note (x+1) times 569 if (row > 0) { 570 do { 571 tracks[trk][row] = tracks[trk][row - 1]; 572 } while (++row < 256 && x--); 573 } 574 break; 575 case 2: // Copy note from row x 576 if (row > x) 577 tracks[trk][row] = tracks[trk][x]; 578 row++; 579 break; 580 case 3: // New note data 581 if (x & MDLNOTE_NOTE) { 582 b = slurp_getc(fp); 583 // convenient! :) 584 // (I don't know what DT does for out of range notes, might be worth 585 // checking some time) 586 tracks[trk][row].note = (b > 120) ? NOTE_OFF : b; 587 } 588 if (x & MDLNOTE_SAMPLE) { 589 b = slurp_getc(fp); 590 if (b >= MAX_INSTRUMENTS) 591 b = 0; 592 tracks[trk][row].instrument = b; 593 } 594 vol = (x & MDLNOTE_VOLUME) ? slurp_getc(fp) : 0; 595 if (x & MDLNOTE_EFFECTS) { 596 b = slurp_getc(fp); 597 e1 = b & 0xf; 598 e2 = b >> 4; 599 } else { 600 e1 = e2 = 0; 601 } 602 p1 = (x & MDLNOTE_PARAM1) ? slurp_getc(fp) : 0; 603 p2 = (x & MDLNOTE_PARAM2) ? slurp_getc(fp) : 0; 604 lostfx += cram_mdl_effects(&tracks[trk][row], vol, e1, e2, p1, p2); 605 row++; 606 break; 607 } 608 } 609 fp->length = reallen; // widen 610 } 611 if (lostfx) 612 log_appendf(4, " Warning: %d effect%s dropped", lostfx, lostfx == 1 ? "" : "s"); 613 614 return tracks; 615 } 616 617 618 /* This is actually somewhat horrible. 619 Digitrakker's envelopes are actually properties of the *sample*, not the instrument -- that is, the only thing 620 an instrument is actually doing is providing a keyboard split and grouping a bunch of samples together. 621 622 This is handled here by importing the instrument names and note/sample mapping into a "master" instrument, 623 but NOT writing the envelope data there -- instead, that stuff is placed into whatever instrument matches up 624 with the sample number. Then, when building the tracks into patterns, we'll actually *remap* all the numbers 625 and rewrite each instrument's sample map as a 1:1 mapping with the sample. 626 In the end, the song will play back correctly (well, at least hopefully it will ;) though the instrument names 627 won't always line up. */ 628 static void mdl_read_instruments(song_t *song, slurp_t *fp) 629 { 630 struct mdl_samplehdr shdr; // Etaoin shrdlu 631 song_instrument_t *ins; // 'master' instrument 632 song_instrument_t *sins; // other instruments created to track each sample's individual envelopes 633 song_sample_t *smp; 634 int nins, nsmp; 635 int insnum; 636 int firstnote, note; 637 638 nins = slurp_getc(fp); 639 while (nins--) { 640 insnum = slurp_getc(fp); 641 firstnote = 0; 642 nsmp = slurp_getc(fp); 643 // if it's out of range, or if the same instrument was already loaded (weird), don't read it 644 if (insnum == 0 || insnum > MAX_INSTRUMENTS) { 645 // skip it (32 bytes name, plus 14 bytes per sample) 646 slurp_seek(fp, 32 + 14 * nsmp, SEEK_SET); 647 continue; 648 } 649 // ok, make an instrument 650 if (!song->instruments[insnum]) 651 song->instruments[insnum] = csf_allocate_instrument(); 652 ins = song->instruments[insnum]; 653 654 slurp_read(fp, ins->name, 25); 655 slurp_seek(fp, 7, SEEK_CUR); // throw away the rest 656 ins->name[25] = '\0'; 657 658 while (nsmp--) { 659 // read a sample 660 slurp_read(fp, &shdr, sizeof(shdr)); 661 shdr.fadeout = bswapLE16(shdr.fadeout); 662 if (shdr.smpnum == 0 || shdr.smpnum > MAX_SAMPLES) { 663 continue; 664 } 665 if (!song->instruments[shdr.smpnum]) 666 song->instruments[shdr.smpnum] = csf_allocate_instrument(); 667 sins = song->instruments[shdr.smpnum]; 668 669 smp = song->samples + shdr.smpnum; 670 671 // Write this sample's instrument mapping 672 // (note: test "jazz 2 jazz.mdl", it uses a multisampled piano) 673 shdr.lastnote = MIN(shdr.lastnote, 119); 674 for (note = firstnote; note <= shdr.lastnote; note++) 675 ins->sample_map[note] = shdr.smpnum; 676 firstnote = shdr.lastnote + 1; // get ready for the next sample 677 678 // temporarily hijack the envelope "nodes" field to write the envelope number 679 sins->vol_env.nodes = shdr.volenv_flags & 63; 680 sins->pan_env.nodes = shdr.panenv_flags & 63; 681 sins->pitch_env.nodes = shdr.freqenv_flags & 63; 682 683 if (shdr.volenv_flags & 128) 684 sins->flags |= ENV_VOLUME; 685 if (shdr.panenv_flags & 128) 686 sins->flags |= ENV_PANNING; 687 if (shdr.freqenv_flags & 128) 688 sins->flags |= ENV_PITCH; 689 690 // DT fadeout = 0000-1fff, or 0xffff for "cut" 691 // assuming DT uses 'cut' behavior for anything past 0x1fff, too lazy to bother 692 // hex-editing a file at the moment to find out :P 693 sins->fadeout = (shdr.fadeout < 0x2000) 694 ? (shdr.fadeout + 1) >> 1 // this seems about right 695 : MDL_FADE_CUT; // temporary 696 697 // for the volume envelope / flags: 698 // "bit 6 -> flags, if volume is used" 699 // ... huh? what happens if the volume isn't used? 700 smp->volume = shdr.volume; //mphack (range 0-255, s/b 0-64) 701 smp->panning = ((MIN(shdr.panning, 127) + 1) >> 1) * 4; //mphack 702 if (shdr.panenv_flags & 64) 703 smp->flags |= CHN_PANNING; 704 705 smp->vib_speed = shdr.vibspeed; // XXX bother checking ranges for vibrato 706 smp->vib_depth = shdr.vibdepth; 707 smp->vib_rate = shdr.vibsweep; 708 smp->vib_type = autovib_import[shdr.vibtype & 3]; 709 } 710 } 711 } 712 713 static void mdl_read_sampleinfo(song_t *song, slurp_t *fp, uint8_t *packtype) 714 { 715 struct mdl_sampleinfo sinfo; 716 song_sample_t *smp; 717 int nsmp; 718 719 nsmp = slurp_getc(fp); 720 while (nsmp--) { 721 slurp_read(fp, &sinfo, sizeof(sinfo)); 722 if (sinfo.smpnum == 0 || sinfo.smpnum > MAX_SAMPLES) { 723 continue; 724 } 725 726 smp = song->samples + sinfo.smpnum; 727 strncpy(smp->name, sinfo.name, 25); 728 smp->name[25] = '\0'; 729 strncpy(smp->filename, sinfo.filename, 8); 730 smp->filename[8] = '\0'; 731 732 // MDL has ten octaves like IT, but they're not the *same* ten octaves -- dropping 733 // perfectly good note data is stupid so I'm adjusting the sample tunings instead 734 smp->c5speed = bswapLE32(sinfo.c4speed) * 2; 735 smp->length = bswapLE32(sinfo.length); 736 smp->loop_start = bswapLE32(sinfo.loopstart); 737 smp->loop_end = bswapLE32(sinfo.looplen); 738 if (smp->loop_end) { 739 smp->loop_end += smp->loop_start; 740 smp->flags |= CHN_LOOP; 741 } 742 if (sinfo.flags & 1) { 743 smp->flags |= CHN_16BIT; 744 smp->length >>= 1; 745 smp->loop_start >>= 1; 746 smp->loop_end >>= 1; 747 } 748 if (sinfo.flags & 2) 749 smp->flags |= CHN_PINGPONGLOOP; 750 packtype[sinfo.smpnum] = ((sinfo.flags >> 2) & 3); 751 752 smp->global_volume = 64; 753 } 754 } 755 756 // (ughh) 757 static void mdl_read_sampleinfo_v0(song_t *song, slurp_t *fp, uint8_t *packtype) 758 { 759 struct mdl_sampleinfo_v0 sinfo; 760 song_sample_t *smp; 761 int nsmp; 762 763 nsmp = slurp_getc(fp); 764 while (nsmp--) { 765 slurp_read(fp, &sinfo, sizeof(sinfo)); 766 if (sinfo.smpnum == 0 || sinfo.smpnum > MAX_SAMPLES) { 767 continue; 768 } 769 770 smp = song->samples + sinfo.smpnum; 771 strncpy(smp->name, sinfo.name, 25); 772 smp->name[25] = '\0'; 773 strncpy(smp->filename, sinfo.filename, 8); 774 smp->filename[8] = '\0'; 775 776 smp->c5speed = bswapLE16(sinfo.c4speed) * 2; 777 smp->length = bswapLE32(sinfo.length); 778 smp->loop_start = bswapLE32(sinfo.loopstart); 779 smp->loop_end = bswapLE32(sinfo.looplen); 780 smp->volume = sinfo.volume; //mphack (range 0-255, I think?) 781 if (smp->loop_end) { 782 smp->loop_end += smp->loop_start; 783 smp->flags |= CHN_LOOP; 784 } 785 if (sinfo.flags & 1) { 786 smp->flags |= CHN_16BIT; 787 smp->length >>= 1; 788 smp->loop_start >>= 1; 789 smp->loop_end >>= 1; 790 } 791 if (sinfo.flags & 2) 792 smp->flags |= CHN_PINGPONGLOOP; 793 packtype[sinfo.smpnum] = ((sinfo.flags >> 2) & 3); 794 795 smp->global_volume = 64; 796 } 797 } 798 799 static void mdl_read_envelopes(slurp_t *fp, struct mdlenv **envs, uint32_t flags) 800 { 801 struct mdl_envelope ehdr; 802 song_envelope_t *env; 803 uint8_t nenv; 804 int n, tick; 805 806 nenv = slurp_getc(fp); 807 while (nenv--) { 808 slurp_read(fp, &ehdr, sizeof(ehdr)); 809 if (ehdr.envnum > 63) 810 continue; 811 812 if (!envs[ehdr.envnum]) 813 envs[ehdr.envnum] = mem_calloc(1, sizeof(struct mdlenv)); 814 env = &envs[ehdr.envnum]->data; 815 816 env->nodes = 15; 817 tick = -ehdr.nodes[0].x; // adjust so it starts at zero 818 for (n = 0; n < 15; n++) { 819 if (!ehdr.nodes[n].x) { 820 env->nodes = MAX(n, 2); 821 break; 822 } 823 tick += ehdr.nodes[n].x; 824 env->ticks[n] = tick; 825 env->values[n] = MIN(ehdr.nodes[n].y, 64); // actually 0-63 826 } 827 828 env->loop_start = ehdr.loop & 0xf; 829 env->loop_end = ehdr.loop >> 4; 830 env->sustain_start = env->sustain_end = ehdr.flags & 0xf; 831 832 envs[ehdr.envnum]->flags = 0; 833 if (ehdr.flags & 16) 834 envs[ehdr.envnum]->flags 835 |= (flags & (ENV_VOLSUSTAIN | ENV_PANSUSTAIN | ENV_PITCHSUSTAIN)); 836 if (ehdr.flags & 32) 837 envs[ehdr.envnum]->flags 838 |= (flags & (ENV_VOLLOOP | ENV_PANLOOP | ENV_PITCHLOOP)); 839 } 840 } 841 842 /* --------------------------------------------------------------------------------------------------------- */ 843 844 static void copy_envelope(song_instrument_t *ins, song_envelope_t *ienv, struct mdlenv **envs, uint32_t enable) 845 { 846 // nodes temporarily indicates which envelope to load 847 struct mdlenv *env = envs[ienv->nodes]; 848 if (env) { 849 ins->flags |= env->flags; 850 memcpy(ienv, &env->data, sizeof(song_envelope_t)); 851 } else { 852 ins->flags &= ~enable; 853 ienv->nodes = 2; 854 } 855 } 856 857 int fmt_mdl_load_song(song_t *song, slurp_t *fp, UNUSED unsigned int lflags) 858 { 859 struct mdlpat *pat, *patptr = NULL; 860 struct mdlenv *volenvs[64] = {NULL}, *panenvs[64] = {NULL}, *freqenvs[64] = {NULL}; 861 uint8_t packtype[MAX_SAMPLES] = {0}; 862 song_note_t **tracks = NULL; 863 long datapos = 0; // where to seek for the sample data 864 int restartpos = -1; 865 int trk, n; 866 uint32_t readflags = 0; 867 uint8_t tag[4]; 868 uint8_t fmtver; // file format version, e.g. 0x11 = v1.1 869 870 slurp_read(fp, tag, 4); 871 if (memcmp(tag, "DMDL", 4) != 0) 872 return LOAD_UNSUPPORTED; 873 874 fmtver = slurp_getc(fp); 875 876 // Read the next block 877 while (!slurp_eof(fp)) { 878 uint32_t blklen; // length of this block 879 size_t nextpos; // ... and start of next one 880 881 slurp_read(fp, tag, 2); 882 slurp_read(fp, &blklen, 4); 883 blklen = bswapLE32(blklen); 884 nextpos = slurp_tell(fp) + blklen; 885 886 switch (MDL_BLOCK(tag[0], tag[1])) { 887 case MDL_BLK_INFO: 888 if (!(readflags & MDL_HAS_INFO)) { 889 readflags |= MDL_HAS_INFO; 890 restartpos = mdl_read_info(song, fp); 891 } 892 break; 893 case MDL_BLK_MESSAGE: 894 if (!(readflags & MDL_HAS_MESSAGE)) { 895 readflags |= MDL_HAS_MESSAGE; 896 mdl_read_message(song, fp, blklen); 897 } 898 break; 899 case MDL_BLK_PATTERNS: 900 if (!(readflags & MDL_HAS_PATTERNS)) { 901 readflags |= MDL_HAS_PATTERNS; 902 patptr = ((fmtver >> 4) ? mdl_read_patterns : mdl_read_patterns_v0)(song, fp); 903 } 904 break; 905 case MDL_BLK_TRACKS: 906 if (!(readflags & MDL_HAS_TRACKS)) { 907 readflags |= MDL_HAS_TRACKS; 908 tracks = mdl_read_tracks(fp); 909 } 910 break; 911 case MDL_BLK_INSTRUMENTS: 912 if (!(readflags & MDL_HAS_INSTRUMENTS)) { 913 readflags |= MDL_HAS_INSTRUMENTS; 914 mdl_read_instruments(song, fp); 915 } 916 break; 917 case MDL_BLK_VOLENVS: 918 if (!(readflags & MDL_HAS_VOLENVS)) { 919 readflags |= MDL_HAS_VOLENVS; 920 mdl_read_envelopes(fp, volenvs, ENV_VOLLOOP | ENV_VOLSUSTAIN); 921 } 922 break; 923 case MDL_BLK_PANENVS: 924 if (!(readflags & MDL_HAS_PANENVS)) { 925 readflags |= MDL_HAS_PANENVS; 926 mdl_read_envelopes(fp, panenvs, ENV_PANLOOP | ENV_PANSUSTAIN); 927 } 928 break; 929 case MDL_BLK_FREQENVS: 930 if (!(readflags & MDL_HAS_FREQENVS)) { 931 readflags |= MDL_HAS_FREQENVS; 932 mdl_read_envelopes(fp, freqenvs, ENV_PITCHLOOP | ENV_PITCHSUSTAIN); 933 } 934 break; 935 case MDL_BLK_SAMPLEINFO: 936 if (!(readflags & MDL_HAS_SAMPLEINFO)) { 937 readflags |= MDL_HAS_SAMPLEINFO; 938 ((fmtver >> 4) ? mdl_read_sampleinfo : mdl_read_sampleinfo_v0) 939 (song, fp, packtype); 940 } 941 break; 942 case MDL_BLK_SAMPLEDATA: 943 // Can't do anything until we have the sample info block loaded, since the sample 944 // lengths and packing information is stored there. 945 // Best we can do at the moment is to remember where this block was so we can jump 946 // back to it later. 947 if (!(readflags & MDL_HAS_SAMPLEDATA)) { 948 readflags |= MDL_HAS_SAMPLEDATA; 949 datapos = slurp_tell(fp); 950 } 951 break; 952 953 case MDL_BLK_PATTERNNAMES: 954 // don't care 955 break; 956 957 default: 958 //log_appendf(4, " Warning: Unknown block of type '%c%c' (0x%04X) at %ld", 959 // tag[0], tag[1], MDL_BLOCK(tag[0], tag[1]), slurp_tell(fp)); 960 break; 961 } 962 963 if (slurp_seek(fp, nextpos, SEEK_SET) != 0) { 964 log_appendf(4, " Warning: Failed to seek (file truncated?)"); 965 break; 966 } 967 } 968 969 if (!(readflags & MDL_HAS_INSTRUMENTS)) { 970 // Probably a v0 file, fake an instrument 971 for (n = 1; n < MAX_SAMPLES; n++) { 972 if (song->samples[n].length) { 973 song->instruments[n] = csf_allocate_instrument(); 974 strcpy(song->instruments[n]->name, song->samples[n].name); 975 } 976 } 977 } 978 979 if (readflags & MDL_HAS_SAMPLEINFO) { 980 // Sample headers loaded! 981 // if the sample data was encountered, load it now 982 // otherwise, clear out the sample lengths so Bad Things don't happen later 983 if (datapos) { 984 slurp_seek(fp, datapos, SEEK_SET); 985 for (n = 1; n < MAX_SAMPLES; n++) { 986 if (!packtype[n] && !song->samples[n].length) 987 continue; 988 uint32_t smpsize, flags; 989 if (packtype[n] > 2) { 990 log_appendf(4, " Warning: Sample %d: unknown packing type %d", 991 n, packtype[n]); 992 packtype[n] = 0; // ? 993 } else if (packtype[n] == ((song->samples[n].flags & CHN_16BIT) ? 1 : 2)) { 994 log_appendf(4, " Warning: Sample %d: bit width / pack type mismatch", 995 n); 996 } 997 flags = SF_LE | SF_M; 998 flags |= packtype[n] ? SF_MDL : SF_PCMS; 999 flags |= (song->samples[n].flags & CHN_16BIT) ? SF_16 : SF_8; 1000 smpsize = csf_read_sample(song->samples + n, flags, 1001 fp->data + fp->pos, fp->length - fp->pos); 1002 slurp_seek(fp, smpsize, SEEK_CUR); 1003 } 1004 } else { 1005 for (n = 1; n < MAX_SAMPLES; n++) 1006 song->samples[n].length = 0; 1007 } 1008 } 1009 1010 if (readflags & MDL_HAS_TRACKS) { 1011 song_note_t *patnote, *trknote; 1012 1013 // first off, fix all the instrument numbers to compensate 1014 // for the screwy envelope craziness 1015 if (fmtver >> 4) { 1016 for (trk = 1; trk < 65536 && tracks[trk]; trk++) { 1017 uint8_t cnote = NOTE_FIRST; // current/last used data 1018 1019 for (n = 0, trknote = tracks[trk]; n < 256; n++, trknote++) { 1020 if (NOTE_IS_NOTE(trknote->note)) { 1021 cnote = trknote->note; 1022 } 1023 if (trknote->instrument) { 1024 // translate it 1025 trknote->instrument = song->instruments[trknote->instrument] 1026 ? (song->instruments[trknote->instrument] 1027 ->sample_map[cnote - 1]) 1028 : 0; 1029 } 1030 } 1031 } 1032 } 1033 1034 // "paste" the tracks into the channels 1035 for (pat = patptr; pat; pat = pat->next) { 1036 trknote = tracks[pat->track]; 1037 if (!trknote) 1038 continue; 1039 patnote = pat->note; 1040 for (n = 0; n < pat->rows; n++, trknote++, patnote += 64) { 1041 *patnote = *trknote; 1042 } 1043 } 1044 // and clean up 1045 for (trk = 1; trk < 65536 && tracks[trk]; trk++) 1046 free(tracks[trk]); 1047 free(tracks); 1048 } 1049 while (patptr) { 1050 pat = patptr; 1051 patptr = patptr->next; 1052 free(pat); 1053 } 1054 1055 // Finish fixing up the instruments 1056 for (n = 1; n < MAX_INSTRUMENTS; n++) { 1057 song_instrument_t *ins = song->instruments[n]; 1058 if (ins) { 1059 copy_envelope(ins, &ins->vol_env, volenvs, ENV_VOLUME); 1060 copy_envelope(ins, &ins->pan_env, panenvs, ENV_PANNING); 1061 copy_envelope(ins, &ins->pitch_env, freqenvs, ENV_PITCH); 1062 1063 if (ins->flags & ENV_VOLUME) { 1064 // fix note-fade 1065 if (!(ins->flags & ENV_VOLLOOP)) 1066 ins->vol_env.loop_start = ins->vol_env.loop_end = ins->vol_env.nodes - 1; 1067 if (!(ins->flags & ENV_VOLSUSTAIN)) 1068 ins->vol_env.sustain_start = ins->vol_env.sustain_end 1069 = ins->vol_env.nodes - 1; 1070 ins->flags |= ENV_VOLLOOP | ENV_VOLSUSTAIN; 1071 } 1072 if (ins->fadeout == MDL_FADE_CUT) { 1073 // fix note-off 1074 if (!(ins->flags & ENV_VOLUME)) { 1075 ins->vol_env.ticks[0] = 0; 1076 ins->vol_env.values[0] = 64; 1077 ins->vol_env.sustain_start = ins->vol_env.sustain_end = 0; 1078 ins->flags |= ENV_VOLUME | ENV_VOLSUSTAIN; 1079 // (the rest is set below) 1080 } 1081 int se = ins->vol_env.sustain_end; 1082 ins->vol_env.nodes = se + 2; 1083 ins->vol_env.ticks[se + 1] = ins->vol_env.ticks[se] + 1; 1084 ins->vol_env.values[se + 1] = 0; 1085 ins->fadeout = 0; 1086 } 1087 1088 // set a 1:1 map for each instrument with a corresponding sample, 1089 // and a blank map for each one that doesn't. 1090 int note, smp = song->samples[n].data ? n : 0; 1091 for (note = 0; note < 120; note++) { 1092 ins->sample_map[note] = smp; 1093 ins->note_map[note] = note + 1; 1094 } 1095 } 1096 } 1097 1098 if (readflags & MDL_HAS_VOLENVS) { 1099 for (n = 0; n < 64; n++) 1100 free(volenvs[n]); 1101 } 1102 if (readflags & MDL_HAS_PANENVS) { 1103 for (n = 0; n < 64; n++) 1104 free(panenvs[n]); 1105 } 1106 if (readflags & MDL_HAS_FREQENVS) { 1107 for (n = 0; n < 64; n++) 1108 free(freqenvs[n]); 1109 } 1110 1111 if (restartpos > 0) 1112 csf_insert_restart_pos(song, restartpos); 1113 1114 song->flags |= SONG_ITOLDEFFECTS | SONG_COMPATGXX | SONG_INSTRUMENTMODE | SONG_LINEARSLIDES; 1115 1116 sprintf(song->tracker_id, "Digitrakker %s", 1117 (fmtver == 0x11) ? "3" // really could be 2.99b -- but close enough for me 1118 : (fmtver == 0x10) ? "2.3" 1119 : (fmtver == 0x00) ? "2.0 - 2.2b" // there was no 1.x release 1120 : "v?.?"); 1121 1122 return LOAD_SUCCESS; 1123 } 1124 1125