1 /* 2 * This source code is public domain. 3 * 4 * Authors: Olivier Lapicque <olivierl@jps.net> 5 */ 6 7 ////////////////////////////////////////////// 8 // DigiTracker (MDL) module loader // 9 ////////////////////////////////////////////// 10 #include "stdafx.h" 11 #include "sndfile.h" 12 13 //#pragma warning(disable:4244) 14 15 typedef struct MDLSONGHEADER 16 { 17 DWORD id; // "DMDL" = 0x4C444D44 18 BYTE version; 19 } MDLSONGHEADER; 20 21 22 typedef struct MDLINFOBLOCK 23 { 24 CHAR songname[32]; 25 CHAR composer[20]; 26 WORD norders; 27 WORD repeatpos; 28 BYTE globalvol; 29 BYTE speed; 30 BYTE tempo; 31 BYTE channelinfo[32]; 32 BYTE seq[256]; 33 } MDLINFOBLOCK; 34 35 36 typedef struct MDLPATTERNDATA 37 { 38 BYTE channels; 39 BYTE lastrow; // nrows = lastrow+1 40 CHAR name[16]; 41 WORD data[1]; 42 } MDLPATTERNDATA; 43 44 45 static void ConvertMDLCommand(MODCOMMAND *m, UINT eff, UINT data) 46 //-------------------------------------------------------- 47 { 48 UINT command = 0, param = data; 49 switch(eff) 50 { 51 case 0x01: command = CMD_PORTAMENTOUP; break; 52 case 0x02: command = CMD_PORTAMENTODOWN; break; 53 case 0x03: command = CMD_TONEPORTAMENTO; break; 54 case 0x04: command = CMD_VIBRATO; break; 55 case 0x05: command = CMD_ARPEGGIO; break; 56 case 0x07: command = (param < 0x20) ? CMD_SPEED : CMD_TEMPO; break; 57 case 0x08: command = CMD_PANNING8; param <<= 1; break; 58 case 0x0B: command = CMD_POSITIONJUMP; break; 59 case 0x0C: command = CMD_GLOBALVOLUME; break; 60 case 0x0D: command = CMD_PATTERNBREAK; param = (data & 0x0F) + (data>>4)*10; break; 61 case 0x0E: 62 command = CMD_S3MCMDEX; 63 switch(data & 0xF0) 64 { 65 case 0x00: command = 0; break; // What is E0x in MDL (there is a bunch) ? 66 case 0x10: if (param & 0x0F) { param |= 0xF0; command = CMD_PANNINGSLIDE; } else command = 0; break; 67 case 0x20: if (param & 0x0F) { param = (param << 4) | 0x0F; command = CMD_PANNINGSLIDE; } else command = 0; break; 68 case 0x30: param = (data & 0x0F) | 0x10; break; // glissando 69 case 0x40: param = (data & 0x0F) | 0x30; break; // vibrato waveform 70 case 0x60: param = (data & 0x0F) | 0xB0; break; 71 case 0x70: param = (data & 0x0F) | 0x40; break; // tremolo waveform 72 case 0x90: command = CMD_RETRIG; param &= 0x0F; break; 73 case 0xA0: param = (data & 0x0F) << 4; command = CMD_GLOBALVOLSLIDE; break; 74 case 0xB0: param = data & 0x0F; command = CMD_GLOBALVOLSLIDE; break; 75 case 0xF0: param = ((data >> 8) & 0x0F) | 0xA0; break; 76 } 77 break; 78 case 0x0F: command = CMD_SPEED; break; 79 case 0x10: if ((param & 0xF0) != 0xE0) { command = CMD_VOLUMESLIDE; if ((param & 0xF0) == 0xF0) param = ((param << 4) | 0x0F); else param >>= 2; } break; 80 case 0x20: if ((param & 0xF0) != 0xE0) { command = CMD_VOLUMESLIDE; if ((param & 0xF0) != 0xF0) param >>= 2; } break; 81 case 0x30: command = CMD_RETRIG; break; 82 case 0x40: command = CMD_TREMOLO; break; 83 case 0x50: command = CMD_TREMOR; break; 84 case 0xEF: if (param > 0xFF) param = 0xFF; command = CMD_OFFSET; break; 85 } 86 if (command) 87 { 88 m->command = command; 89 m->param = param; 90 } 91 } 92 93 94 static void UnpackMDLTrack(MODCOMMAND *pat, UINT nChannels, UINT nRows, UINT nTrack, const BYTE *lpTracks, UINT len) 95 //------------------------------------------------------------------------------------------------- 96 { 97 MODCOMMAND cmd, *m = pat; 98 UINT pos = 0, row = 0, i; 99 100 cmd.note = cmd.instr = 0; 101 cmd.volcmd = cmd.vol = 0; 102 cmd.command = cmd.param = 0; 103 while ((row < nRows) && (pos < len)) 104 { 105 UINT xx; 106 BYTE b = lpTracks[pos++]; 107 xx = b >> 2; 108 switch(b & 0x03) 109 { 110 case 0x01: 111 for (i=0; i<=xx; i++) 112 { 113 if (row) *m = *(m-nChannels); 114 m += nChannels; 115 row++; 116 if (row >= nRows) break; 117 } 118 break; 119 120 case 0x02: 121 if (xx < row) *m = pat[nChannels*xx]; 122 m += nChannels; 123 row++; 124 break; 125 126 case 0x03: 127 { 128 cmd.note = (xx & 0x01) ? lpTracks[pos++] : 0; 129 cmd.instr = (xx & 0x02) ? lpTracks[pos++] : 0; 130 cmd.volcmd = cmd.vol = 0; 131 cmd.command = cmd.param = 0; 132 if ((cmd.note < NOTE_MAX-12) && (cmd.note)) cmd.note += 12; 133 UINT volume = (xx & 0x04) ? lpTracks[pos++] : 0; 134 UINT commands = (xx & 0x08) ? lpTracks[pos++] : 0; 135 UINT command1 = commands & 0x0F; 136 UINT command2 = commands & 0xF0; 137 UINT param1 = (xx & 0x10) ? lpTracks[pos++] : 0; 138 UINT param2 = (xx & 0x20) ? lpTracks[pos++] : 0; 139 if ((command1 == 0x0E) && ((param1 & 0xF0) == 0xF0) && (!command2)) 140 { 141 param1 = ((param1 & 0x0F) << 8) | param2; 142 command1 = 0xEF; 143 command2 = param2 = 0; 144 } 145 if (volume) 146 { 147 cmd.volcmd = VOLCMD_VOLUME; 148 cmd.vol = (volume+1) >> 2; 149 } 150 ConvertMDLCommand(&cmd, command1, param1); 151 if ((cmd.command != CMD_SPEED) 152 && (cmd.command != CMD_TEMPO) 153 && (cmd.command != CMD_PATTERNBREAK)) 154 ConvertMDLCommand(&cmd, command2, param2); 155 *m = cmd; 156 m += nChannels; 157 row++; 158 } 159 break; 160 161 // Empty Slots 162 default: 163 row += xx+1; 164 m += (xx+1)*nChannels; 165 if (row >= nRows) break; 166 } 167 } 168 } 169 170 171 BOOL CSoundFile::ReadMDL(const BYTE *lpStream, DWORD dwMemLength) 172 //--------------------------------------------------------------- 173 { 174 DWORD dwMemPos, dwPos, blocklen, dwTrackPos; 175 const MDLSONGHEADER *pmsh = (const MDLSONGHEADER *)lpStream; 176 const MDLINFOBLOCK *pmib; 177 UINT i,j, norders = 0, npatterns = 0, ntracks = 0; 178 UINT ninstruments = 0, nsamples = 0; 179 WORD block; 180 WORD patterntracks[MAX_PATTERNS*32]; 181 BYTE smpinfo[MAX_SAMPLES]; 182 BYTE insvolenv[MAX_INSTRUMENTS]; 183 BYTE inspanenv[MAX_INSTRUMENTS]; 184 LPCBYTE pvolenv, ppanenv, ppitchenv; 185 UINT nvolenv, npanenv, npitchenv; 186 187 if ((!lpStream) || (dwMemLength < 1024)) return FALSE; 188 if ((pmsh->id != 0x4C444D44) || ((pmsh->version & 0xF0) > 0x10)) return FALSE; 189 const UINT hdrLen = (pmsh->version>0)? 59 : 57; 190 memset(patterntracks, 0, sizeof(patterntracks)); 191 memset(smpinfo, 0, sizeof(smpinfo)); 192 memset(insvolenv, 0, sizeof(insvolenv)); 193 memset(inspanenv, 0, sizeof(inspanenv)); 194 dwMemPos = 5; 195 dwTrackPos = 0; 196 pvolenv = ppanenv = ppitchenv = NULL; 197 nvolenv = npanenv = npitchenv = 0; 198 m_nSamples = m_nInstruments = 0; 199 while (dwMemPos+6 < dwMemLength) 200 { 201 const BYTE *pp = lpStream + dwMemPos; 202 block = pp[0] | (pp[1] << 8); 203 blocklen = pp[2] | (pp[3] << 8) | (pp[4] << 16) | (pp[5] << 24); 204 dwMemPos += 6; 205 if (blocklen > dwMemLength - dwMemPos) 206 { 207 if (dwMemPos == 11) return FALSE; 208 break; 209 } 210 switch(block) 211 { 212 // IN: infoblock 213 case 0x4E49: 214 pmib = (const MDLINFOBLOCK *)(lpStream+dwMemPos); 215 memcpy(m_szNames[0], pmib->songname, 32); 216 m_szNames[0][31] = 0; 217 norders = pmib->norders; 218 if (norders > MAX_ORDERS) norders = MAX_ORDERS; 219 m_nRestartPos = pmib->repeatpos; 220 m_nDefaultGlobalVolume = pmib->globalvol; 221 m_nDefaultTempo = pmib->tempo; 222 m_nDefaultSpeed = pmib->speed; 223 m_nChannels = 4; 224 for (i=0; i<32; i++) 225 { 226 ChnSettings[i].nVolume = 64; 227 ChnSettings[i].nPan = (pmib->channelinfo[i] & 0x7F) << 1; 228 if (pmib->channelinfo[i] & 0x80) 229 ChnSettings[i].dwFlags |= CHN_MUTE; 230 else 231 m_nChannels = i+1; 232 } 233 for (j=0; j<norders; j++) Order[j] = pmib->seq[j]; 234 break; 235 // ME: song message 236 case 0x454D: 237 if (blocklen) 238 { 239 if (m_lpszSongComments) delete [] m_lpszSongComments; 240 m_lpszSongComments = new char[blocklen]; 241 if (m_lpszSongComments) 242 { 243 memcpy(m_lpszSongComments, lpStream+dwMemPos, blocklen); 244 m_lpszSongComments[blocklen-1] = 0; 245 } 246 } 247 break; 248 // PA: Pattern Data 249 case 0x4150: 250 npatterns = lpStream[dwMemPos]; 251 if (npatterns > MAX_PATTERNS) npatterns = MAX_PATTERNS; 252 dwPos = dwMemPos + 1; 253 for (i=0; i<npatterns; i++) 254 { 255 const BYTE *data; 256 UINT ch; 257 if (pmsh->version == 0) { 258 if (m_nChannels < 32) m_nChannels = 32; 259 ch = 32; 260 } else { 261 if (dwPos+18 >= dwMemLength) break; 262 const MDLPATTERNDATA *pmpd = (const MDLPATTERNDATA *)(lpStream + dwPos); 263 if (pmpd->channels > 32) break; 264 PatternSize[i] = pmpd->lastrow+1; 265 if (m_nChannels < pmpd->channels) m_nChannels = pmpd->channels; 266 ch = pmpd->channels; 267 } 268 269 if (2 * ch >= dwMemLength - dwPos) break; 270 data = lpStream + dwPos; 271 dwPos += 2 * ch; 272 for (j=0; j<ch && j<m_nChannels; j++, data+=2) 273 { 274 patterntracks[i*32+j] = data[0] | (data[1] << 8); 275 } 276 } 277 break; 278 // TR: Track Data 279 case 0x5254: 280 if (dwTrackPos) break; 281 pp = lpStream + dwMemPos; 282 ntracks = pp[0] | (pp[1] << 8); 283 dwTrackPos = dwMemPos+2; 284 break; 285 // II: Instruments 286 case 0x4949: 287 ninstruments = lpStream[dwMemPos]; 288 dwPos = dwMemPos+1; 289 for (i=0; i<ninstruments; i++) 290 { 291 UINT nins = lpStream[dwPos]; 292 if ((nins >= MAX_INSTRUMENTS) || (!nins)) break; 293 if (m_nInstruments < nins) m_nInstruments = nins; 294 if (!Headers[nins]) 295 { 296 UINT note = 12; 297 if ((Headers[nins] = new INSTRUMENTHEADER) == NULL) break; 298 INSTRUMENTHEADER *penv = Headers[nins]; 299 memset(penv, 0, sizeof(INSTRUMENTHEADER)); 300 memcpy(penv->name, lpStream+dwPos+2, 32); 301 penv->nGlobalVol = 64; 302 penv->nPPC = 5*12; 303 for (j=0; j<lpStream[dwPos+1]; j++) 304 { 305 const BYTE *ps = lpStream+dwPos+34+14*j; 306 while ((note < (UINT)(ps[1]+12)) && (note < NOTE_MAX)) 307 { 308 penv->NoteMap[note] = note+1; 309 if (ps[0] < MAX_SAMPLES) 310 { 311 int ismp = ps[0]; 312 penv->Keyboard[note] = ps[0]; 313 Ins[ismp].nVolume = ps[2]; 314 Ins[ismp].nPan = ps[4] << 1; 315 Ins[ismp].nVibType = ps[11]; 316 Ins[ismp].nVibSweep = ps[10]; 317 Ins[ismp].nVibDepth = ps[9]; 318 Ins[ismp].nVibRate = ps[8]; 319 } 320 penv->nFadeOut = (ps[7] << 8) | ps[6]; 321 if (penv->nFadeOut == 0xFFFF) penv->nFadeOut = 0; 322 note++; 323 } 324 // Use volume envelope ? 325 if (ps[3] & 0x80) 326 { 327 penv->dwFlags |= ENV_VOLUME; 328 insvolenv[nins] = (ps[3] & 0x3F) + 1; 329 } 330 // Use panning envelope ? 331 if (ps[5] & 0x80) 332 { 333 penv->dwFlags |= ENV_PANNING; 334 inspanenv[nins] = (ps[5] & 0x3F) + 1; 335 } 336 } 337 } 338 dwPos += 34 + 14*lpStream[dwPos+1]; 339 } 340 for (j=1; j<=m_nInstruments; j++) if (!Headers[j]) 341 { 342 Headers[j] = new INSTRUMENTHEADER; 343 if (Headers[j]) memset(Headers[j], 0, sizeof(INSTRUMENTHEADER)); 344 } 345 break; 346 // VE: Volume Envelope 347 case 0x4556: 348 if ((nvolenv = lpStream[dwMemPos]) == 0) break; 349 if (dwMemPos + nvolenv*32 + 1 <= dwMemLength) pvolenv = lpStream + dwMemPos + 1; 350 break; 351 // PE: Panning Envelope 352 case 0x4550: 353 if ((npanenv = lpStream[dwMemPos]) == 0) break; 354 if (dwMemPos + npanenv*32 + 1 <= dwMemLength) ppanenv = lpStream + dwMemPos + 1; 355 break; 356 // FE: Pitch Envelope 357 case 0x4546: 358 if ((npitchenv = lpStream[dwMemPos]) == 0) break; 359 if (dwMemPos + npitchenv*32 + 1 <= dwMemLength) ppitchenv = lpStream + dwMemPos + 1; 360 break; 361 // IS: Sample Infoblock 362 case 0x5349: 363 nsamples = lpStream[dwMemPos]; 364 i = blocklen / hdrLen; 365 if (i< nsamples) nsamples = i; 366 dwPos = dwMemPos+1; 367 for (i=0; i<nsamples; i++, dwPos += hdrLen) 368 { 369 UINT nins = lpStream[dwPos]; 370 if ((nins >= MAX_SAMPLES) || (!nins)) continue; 371 if (m_nSamples < nins) m_nSamples = nins; 372 MODINSTRUMENT *pins = &Ins[nins]; 373 memcpy(m_szNames[nins], lpStream+dwPos+1, 32); 374 m_szNames[nins][31] = 0; 375 memcpy(pins->name, lpStream+dwPos+33, 8); 376 pp = lpStream + dwPos + 41; 377 pins->nC4Speed = pp[0] | (pp[1] << 8); pp += 2; 378 if (pmsh->version > 0) { 379 pins->nC4Speed |= (pp[0] << 16) | (pp[1] << 24); pp += 2; 380 } 381 pins->nLength = pp[0] | (pp[1] << 8) | (pp[2] << 16) | (pp[3] << 24); pp += 4; 382 pins->nLoopStart = pp[0] | (pp[1] << 8) | (pp[2] << 16) | (pp[3] << 24); pp += 4; 383 pins->nLoopEnd = pins->nLoopStart + (pp[0] | (pp[1] << 8) | (pp[2] << 16) | (pp[3] << 24)); 384 if (pins->nLoopEnd > pins->nLoopStart) pins->uFlags |= CHN_LOOP; 385 pins->nGlobalVol = 64; 386 if (pmsh->version == 0) pins->nVolume = pp[4]; 387 if (lpStream[dwPos+hdrLen-1] & 0x01) 388 { 389 pins->uFlags |= CHN_16BIT; 390 pins->nLength >>= 1; 391 pins->nLoopStart >>= 1; 392 pins->nLoopEnd >>= 1; 393 } 394 if (lpStream[dwPos+hdrLen-1] & 0x02) pins->uFlags |= CHN_PINGPONGLOOP; 395 smpinfo[nins] = (lpStream[dwPos+hdrLen-1] >> 2) & 3; 396 } 397 break; 398 // SA: Sample Data 399 case 0x4153: 400 dwPos = dwMemPos; 401 for (i=1; i<=m_nSamples; i++) if ((Ins[i].nLength) && (!Ins[i].pSample) && (smpinfo[i] != 3) && (dwPos < dwMemLength)) 402 { 403 const BYTE *pp = lpStream + dwPos; 404 MODINSTRUMENT *pins = &Ins[i]; 405 UINT flags = (pins->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S; 406 if (!smpinfo[i]) 407 { 408 dwPos += ReadSample(pins, flags, (LPSTR)pp, dwMemLength - dwPos); 409 } else 410 { 411 DWORD dwLen = pp[0] | (pp[1] << 8) | (pp[2] << 16) | (pp[3] << 24); pp += 4; 412 dwPos += 4; 413 if ((dwLen <= dwMemLength) && (dwPos <= dwMemLength - dwLen) && (dwLen > 4)) 414 { 415 flags = (pins->uFlags & CHN_16BIT) ? RS_MDL16 : RS_MDL8; 416 ReadSample(pins, flags, (LPSTR)pp, dwLen); 417 } 418 dwPos += dwLen; 419 } 420 } 421 break; 422 } 423 dwMemPos += blocklen; 424 } 425 // Unpack Patterns 426 if ((dwTrackPos) && (npatterns) && (m_nChannels) && (ntracks)) 427 { 428 for (UINT ipat=0; ipat<npatterns; ipat++) 429 { 430 if ((Patterns[ipat] = AllocatePattern(PatternSize[ipat], m_nChannels)) == NULL) break; 431 for (UINT chn=0; chn<m_nChannels; chn++) if ((patterntracks[ipat*32+chn]) && (patterntracks[ipat*32+chn] <= ntracks)) 432 { 433 const BYTE *lpTracks = lpStream + dwTrackPos; 434 UINT len = lpTracks[0] | (lpTracks[1] << 8); 435 if (len < dwMemLength-dwTrackPos) { 436 MODCOMMAND *m = Patterns[ipat] + chn; 437 UINT nTrack = patterntracks[ipat*32+chn]; 438 439 lpTracks += 2; 440 for (UINT ntrk=1; ntrk<nTrack && lpTracks < (dwMemLength + lpStream - len); ntrk++) 441 { 442 lpTracks += len; 443 len = lpTracks[0] | (lpTracks[1] << 8); 444 lpTracks += 2; 445 } 446 447 if ( len > dwMemLength - dwTrackPos ) len = 0; 448 449 UnpackMDLTrack(m, m_nChannels, PatternSize[ipat], nTrack, lpTracks, len); 450 } 451 } 452 } 453 } 454 // Set up envelopes 455 for (UINT iIns=1; iIns<=m_nInstruments; iIns++) if (Headers[iIns]) 456 { 457 INSTRUMENTHEADER *penv = Headers[iIns]; 458 // Setup volume envelope 459 if ((nvolenv) && (pvolenv) && (insvolenv[iIns])) 460 { 461 LPCBYTE pve = pvolenv; 462 for (UINT nve=0; nve<nvolenv; nve++, pve+=33) if (pve[0]+1 == insvolenv[iIns]) 463 { 464 WORD vtick = 1; 465 penv->nVolEnv = 15; 466 for (UINT iv=0; iv<15; iv++) 467 { 468 if (iv) vtick += pve[iv*2+1]; 469 penv->VolPoints[iv] = vtick; 470 penv->VolEnv[iv] = pve[iv*2+2]; 471 if (!pve[iv*2+1]) 472 { 473 penv->nVolEnv = iv+1; 474 break; 475 } 476 } 477 penv->nVolSustainBegin = penv->nVolSustainEnd = pve[31] & 0x0F; 478 if (pve[31] & 0x10) penv->dwFlags |= ENV_VOLSUSTAIN; 479 if (pve[31] & 0x20) penv->dwFlags |= ENV_VOLLOOP; 480 penv->nVolLoopStart = pve[32] & 0x0F; 481 penv->nVolLoopEnd = pve[32] >> 4; 482 } 483 } 484 // Setup panning envelope 485 if ((npanenv) && (ppanenv) && (inspanenv[iIns])) 486 { 487 LPCBYTE ppe = ppanenv; 488 for (UINT npe=0; npe<npanenv; npe++, ppe+=33) if (ppe[0]+1 == inspanenv[iIns]) 489 { 490 WORD vtick = 1; 491 penv->nPanEnv = 15; 492 for (UINT iv=0; iv<15; iv++) 493 { 494 if (iv) vtick += ppe[iv*2+1]; 495 penv->PanPoints[iv] = vtick; 496 penv->PanEnv[iv] = ppe[iv*2+2]; 497 if (!ppe[iv*2+1]) 498 { 499 penv->nPanEnv = iv+1; 500 break; 501 } 502 } 503 if (ppe[31] & 0x10) penv->dwFlags |= ENV_PANSUSTAIN; 504 if (ppe[31] & 0x20) penv->dwFlags |= ENV_PANLOOP; 505 penv->nPanLoopStart = ppe[32] & 0x0F; 506 penv->nPanLoopEnd = ppe[32] >> 4; 507 } 508 } 509 } 510 m_dwSongFlags |= SONG_LINEARSLIDES; 511 m_nType = MOD_TYPE_MDL; 512 return TRUE; 513 } 514 515 516 ///////////////////////////////////////////////////////////////////////// 517 // MDL Sample Unpacking 518 519 // MDL Huffman ReadBits compression 520 WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n) 521 //----------------------------------------------------------------- 522 { 523 WORD v = (WORD)(bitbuf & ((1 << n) - 1) ); 524 bitbuf >>= n; 525 bitnum -= n; 526 if (bitnum <= 24) 527 { 528 bitbuf |= (((DWORD)(*ibuf++)) << bitnum); 529 bitnum += 8; 530 } 531 return v; 532 } 533