00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00013 #include "stdafx.h"
00014 #include "sndfile.h"
00015
00016
00017
00018
00019
00020 #pragma pack(1)
00021
00022 typedef struct DMFHEADER
00023 {
00024 DWORD id;
00025 BYTE version;
00026 CHAR trackername[8];
00027 CHAR songname[30];
00028 CHAR composer[20];
00029 BYTE date[3];
00030 } Q_PACKED DMFHEADER;
00031
00032 typedef struct DMFINFO
00033 {
00034 DWORD id;
00035 DWORD infosize;
00036 } Q_PACKED DMFINFO;
00037
00038 typedef struct DMFSEQU
00039 {
00040 DWORD id;
00041 DWORD seqsize;
00042 WORD loopstart;
00043 WORD loopend;
00044 WORD sequ[2];
00045 } Q_PACKED DMFSEQU;
00046
00047 typedef struct DMFPATT
00048 {
00049 DWORD id;
00050 DWORD patsize;
00051 WORD numpat;
00052 BYTE tracks;
00053 BYTE firstpatinfo;
00054 } Q_PACKED DMFPATT;
00055
00056 typedef struct DMFTRACK
00057 {
00058 BYTE tracks;
00059 BYTE beat;
00060 WORD ticks;
00061 DWORD jmpsize;
00062 } Q_PACKED DMFTRACK;
00063
00064 typedef struct DMFSMPI
00065 {
00066 DWORD id;
00067 DWORD size;
00068 BYTE samples;
00069 } Q_PACKED DMFSMPI;
00070
00071 typedef struct DMFSAMPLE
00072 {
00073 DWORD len;
00074 DWORD loopstart;
00075 DWORD loopend;
00076 WORD c3speed;
00077 BYTE volume;
00078 BYTE flags;
00079 } Q_PACKED DMFSAMPLE;
00080
00081 #pragma pack()
00082
00083
00084 #ifdef DMFLOG
00085 extern void Log(LPCSTR s, ...);
00086 #endif
00087
00088
00089 BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
00090
00091 {
00092 DMFHEADER *pfh = (DMFHEADER *)lpStream;
00093 DMFINFO *psi;
00094 DMFSEQU *sequ;
00095 DWORD dwMemPos;
00096 BYTE infobyte[32];
00097 BYTE smplflags[MAX_SAMPLES];
00098
00099 if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
00100 if ((pfh->id != 0x464d4444) || (!pfh->version) || (pfh->version & 0xF0)) return FALSE;
00101 dwMemPos = 66;
00102 memcpy(m_szNames[0], pfh->songname, 30);
00103 m_szNames[0][30] = 0;
00104 m_nType = MOD_TYPE_DMF;
00105 m_nChannels = 0;
00106 #ifdef DMFLOG
00107 Log("DMF version %d: \"%s\": %d bytes (0x%04X)\n", pfh->version, m_szNames[0], dwMemLength, dwMemLength);
00108 #endif
00109 while (dwMemPos + 7 < dwMemLength)
00110 {
00111 DWORD id = *((LPDWORD)(lpStream+dwMemPos));
00112
00113 switch(id)
00114 {
00115
00116 case 0x4f464e49:
00117
00118 case 0x47534d43:
00119 psi = (DMFINFO *)(lpStream+dwMemPos);
00120 if (id == 0x47534d43) dwMemPos++;
00121 if ((psi->infosize > dwMemLength) || (psi->infosize + dwMemPos + 8 > dwMemLength)) goto dmfexit;
00122 if ((psi->infosize >= 8) && (!m_lpszSongComments))
00123 {
00124 m_lpszSongComments = new char[psi->infosize];
00125 if (m_lpszSongComments)
00126 {
00127 for (UINT i=0; i<psi->infosize-1; i++)
00128 {
00129 CHAR c = lpStream[dwMemPos+8+i];
00130 if ((i % 40) == 39)
00131 m_lpszSongComments[i] = 0x0d;
00132 else
00133 m_lpszSongComments[i] = (c < ' ') ? ' ' : c;
00134 }
00135 m_lpszSongComments[psi->infosize-1] = 0;
00136 }
00137 }
00138 dwMemPos += psi->infosize + 8 - 1;
00139 break;
00140
00141
00142 case 0x55514553:
00143 sequ = (DMFSEQU *)(lpStream+dwMemPos);
00144 if ((sequ->seqsize >= dwMemLength) || (dwMemPos + sequ->seqsize + 12 > dwMemLength)) goto dmfexit;
00145 {
00146 UINT nseq = sequ->seqsize >> 1;
00147 if (nseq >= MAX_ORDERS-1) nseq = MAX_ORDERS-1;
00148 if (sequ->loopstart < nseq) m_nRestartPos = sequ->loopstart;
00149 for (UINT i=0; i<nseq; i++) Order[i] = (BYTE)sequ->sequ[i];
00150 }
00151 dwMemPos += sequ->seqsize + 8;
00152 break;
00153
00154
00155 case 0x54544150:
00156 if (!m_nChannels)
00157 {
00158 DMFPATT *patt = (DMFPATT *)(lpStream+dwMemPos);
00159 UINT numpat;
00160 DWORD dwPos = dwMemPos + 11;
00161 if ((patt->patsize >= dwMemLength) || (dwMemPos + patt->patsize + 8 > dwMemLength)) goto dmfexit;
00162 numpat = patt->numpat;
00163 if (numpat > MAX_PATTERNS) numpat = MAX_PATTERNS;
00164 m_nChannels = patt->tracks;
00165 if (m_nChannels < patt->firstpatinfo) m_nChannels = patt->firstpatinfo;
00166 if (m_nChannels > 32) m_nChannels = 32;
00167 if (m_nChannels < 4) m_nChannels = 4;
00168 for (UINT npat=0; npat<numpat; npat++)
00169 {
00170 DMFTRACK *pt = (DMFTRACK *)(lpStream+dwPos);
00171 #ifdef DMFLOG
00172 Log("Pattern #%d: %d tracks, %d rows\n", npat, pt->tracks, pt->ticks);
00173 #endif
00174 UINT tracks = pt->tracks;
00175 if (tracks > 32) tracks = 32;
00176 UINT ticks = pt->ticks;
00177 if (ticks > 256) ticks = 256;
00178 if (ticks < 16) ticks = 16;
00179 dwPos += 8;
00180 if ((pt->jmpsize >= dwMemLength) || (dwPos + pt->jmpsize + 4 >= dwMemLength)) break;
00181 PatternSize[npat] = (WORD)ticks;
00182 MODCOMMAND *m = AllocatePattern(PatternSize[npat], m_nChannels);
00183 if (!m) goto dmfexit;
00184 Patterns[npat] = m;
00185 DWORD d = dwPos;
00186 dwPos += pt->jmpsize;
00187 UINT ttype = 1;
00188 UINT tempo = 125;
00189 UINT glbinfobyte = 0;
00190 UINT pbeat = (pt->beat & 0xf0) ? pt->beat>>4 : 8;
00191 BOOL tempochange = (pt->beat & 0xf0) ? TRUE : FALSE;
00192 memset(infobyte, 0, sizeof(infobyte));
00193 for (UINT row=0; row<ticks; row++)
00194 {
00195 MODCOMMAND *p = &m[row*m_nChannels];
00196
00197 if (!glbinfobyte)
00198 {
00199 BYTE info = lpStream[d++];
00200 BYTE infoval = 0;
00201 if ((info & 0x80) && (d < dwPos)) glbinfobyte = lpStream[d++];
00202 info &= 0x7f;
00203 if ((info) && (d < dwPos)) infoval = lpStream[d++];
00204 switch(info)
00205 {
00206 case 1: ttype = 0; tempo = infoval; tempochange = TRUE; break;
00207 case 2: ttype = 1; tempo = infoval; tempochange = TRUE; break;
00208 case 3: pbeat = infoval>>4; tempochange = ttype; break;
00209 #ifdef DMFLOG
00210 default: if (info) Log("GLB: %02X.%02X\n", info, infoval);
00211 #endif
00212 }
00213 } else
00214 {
00215 glbinfobyte--;
00216 }
00217
00218 for (UINT i=0; i<tracks; i++) if (!infobyte[i])
00219 {
00220 MODCOMMAND cmd = {0,0,0,0,0,0};
00221 BYTE info = lpStream[d++];
00222 if (info & 0x80) infobyte[i] = lpStream[d++];
00223
00224 if (info & 0x40)
00225 {
00226 cmd.instr = lpStream[d++];
00227 }
00228
00229 if (info & 0x20)
00230 {
00231 cmd.note = lpStream[d++];
00232 if ((cmd.note) && (cmd.note < 0xfe)) cmd.note &= 0x7f;
00233 if ((cmd.note) && (cmd.note < 128)) cmd.note += 24;
00234 }
00235
00236 if (info & 0x10)
00237 {
00238 cmd.volcmd = VOLCMD_VOLUME;
00239 cmd.vol = (lpStream[d++]+3)>>2;
00240 }
00241
00242 if (info & 0x08)
00243 {
00244 BYTE efx = lpStream[d++];
00245 BYTE eval = lpStream[d++];
00246 switch(efx)
00247 {
00248
00249 case 1: if (!cmd.note) cmd.note = 0xFE; break;
00250
00251
00252 case 4: if (eval&0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xD0; } break;
00253
00254 case 5: if (eval&0xe0) { cmd.command = CMD_RETRIG; cmd.param = (eval>>5); } break;
00255
00256 case 6: cmd.command = CMD_OFFSET; cmd.param = eval; break;
00257 #ifdef DMFLOG
00258 default: Log("FX1: %02X.%02X\n", efx, eval);
00259 #endif
00260 }
00261 }
00262
00263 if (info & 0x04)
00264 {
00265 BYTE efx = lpStream[d++];
00266 BYTE eval = lpStream[d++];
00267 switch(efx)
00268 {
00269
00270 case 1: if (eval&0xf0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>4)|0x20; } break;
00271
00272 case 2: if (eval&0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xD0; } break;
00273
00274 case 3: if (eval) { cmd.command = CMD_ARPEGGIO; cmd.param = eval; } break;
00275
00276 case 4: cmd.command = CMD_PORTAMENTOUP; cmd.param = (eval >= 0xe0) ? 0xdf : eval; break;
00277
00278 case 5: cmd.command = CMD_PORTAMENTODOWN; cmd.param = (eval >= 0xe0) ? 0xdf : eval; break;
00279
00280 case 6: cmd.command = CMD_TONEPORTAMENTO; cmd.param = eval; break;
00281
00282 case 8: cmd.command = CMD_VIBRATO; cmd.param = eval; break;
00283
00284 case 12: if (eval & 0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xc0; }
00285 else if (!cmd.note) { cmd.note = 0xfe; } break;
00286 #ifdef DMFLOG
00287 default: Log("FX2: %02X.%02X\n", efx, eval);
00288 #endif
00289 }
00290 }
00291
00292 if (info & 0x02)
00293 {
00294 BYTE efx = lpStream[d++];
00295 BYTE eval = lpStream[d++];
00296 switch(efx)
00297 {
00298
00299 case 1: if (eval == 0xff) break;
00300 eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
00301 cmd.command = CMD_VOLUMESLIDE; cmd.param = eval<<4; break;
00302
00303 case 2: if (eval == 0xff) break;
00304 eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
00305 cmd.command = CMD_VOLUMESLIDE; cmd.param = eval; break;
00306
00307 case 7: if (!cmd.volcmd) { cmd.volcmd = VOLCMD_PANNING; cmd.vol = (eval+3)>>2; }
00308 else { cmd.command = CMD_PANNING8; cmd.param = eval; } break;
00309
00310 case 8: eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
00311 cmd.command = CMD_PANNINGSLIDE; cmd.param = eval<<4; break;
00312
00313 case 9: eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
00314 cmd.command = CMD_PANNINGSLIDE; cmd.param = eval; break;
00315 #ifdef DMFLOG
00316 default: Log("FX3: %02X.%02X\n", efx, eval);
00317 #endif
00318
00319 }
00320 }
00321
00322 if (i < m_nChannels) p[i] = cmd;
00323 if (d > dwPos)
00324 {
00325 #ifdef DMFLOG
00326 Log("Unexpected EOP: row=%d\n", row);
00327 #endif
00328 break;
00329 }
00330 } else
00331 {
00332 infobyte[i]--;
00333 }
00334
00335
00336 if (tempochange)
00337 {
00338 tempochange = FALSE;
00339 UINT speed=6, modtempo=tempo;
00340 UINT rpm = ((ttype) && (pbeat)) ? tempo*pbeat : (tempo+1)*15;
00341 for (speed=30; speed>1; speed--)
00342 {
00343 modtempo = rpm*speed/24;
00344 if (modtempo <= 200) break;
00345 if ((speed < 6) && (modtempo < 256)) break;
00346 }
00347 #ifdef DMFLOG
00348 Log("Tempo change: ttype=%d pbeat=%d tempo=%3d -> speed=%d tempo=%d\n",
00349 ttype, pbeat, tempo, speed, modtempo);
00350 #endif
00351 for (UINT ich=0; ich<m_nChannels; ich++) if (!p[ich].command)
00352 {
00353 if (speed)
00354 {
00355 p[ich].command = CMD_SPEED;
00356 p[ich].param = (BYTE)speed;
00357 speed = 0;
00358 } else
00359 if ((modtempo >= 32) && (modtempo < 256))
00360 {
00361 p[ich].command = CMD_TEMPO;
00362 p[ich].param = (BYTE)modtempo;
00363 modtempo = 0;
00364 } else
00365 {
00366 break;
00367 }
00368 }
00369 }
00370 if (d >= dwPos) break;
00371 }
00372 #ifdef DMFLOG
00373 Log(" %d/%d bytes remaining\n", dwPos-d, pt->jmpsize);
00374 #endif
00375 if (dwPos + 8 >= dwMemLength) break;
00376 }
00377 dwMemPos += patt->patsize + 8;
00378 }
00379 break;
00380
00381
00382 case 0x49504d53:
00383 {
00384 DMFSMPI *pds = (DMFSMPI *)(lpStream+dwMemPos);
00385 if (pds->size <= dwMemLength - dwMemPos)
00386 {
00387 DWORD dwPos = dwMemPos + 9;
00388 m_nSamples = pds->samples;
00389 if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1;
00390 for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++)
00391 {
00392 UINT namelen = lpStream[dwPos];
00393 smplflags[iSmp] = 0;
00394 if (dwPos+namelen+1+sizeof(DMFSAMPLE) > dwMemPos+pds->size+8) break;
00395 if (namelen)
00396 {
00397 UINT rlen = (namelen < 32) ? namelen : 31;
00398 memcpy(m_szNames[iSmp], lpStream+dwPos+1, rlen);
00399 m_szNames[iSmp][rlen] = 0;
00400 }
00401 dwPos += namelen + 1;
00402 DMFSAMPLE *psh = (DMFSAMPLE *)(lpStream+dwPos);
00403 MODINSTRUMENT *psmp = &Ins[iSmp];
00404 psmp->nLength = psh->len;
00405 psmp->nLoopStart = psh->loopstart;
00406 psmp->nLoopEnd = psh->loopend;
00407 psmp->nC4Speed = psh->c3speed;
00408 psmp->nGlobalVol = 64;
00409 psmp->nVolume = (psh->volume) ? ((WORD)psh->volume)+1 : (WORD)256;
00410 psmp->uFlags = (psh->flags & 2) ? CHN_16BIT : 0;
00411 if (psmp->uFlags & CHN_16BIT) psmp->nLength >>= 1;
00412 if (psh->flags & 1) psmp->uFlags |= CHN_LOOP;
00413 smplflags[iSmp] = psh->flags;
00414 dwPos += (pfh->version < 8) ? 22 : 30;
00415 #ifdef DMFLOG
00416 Log("SMPI %d/%d: len=%d flags=0x%02X\n", iSmp, m_nSamples, psmp->nLength, psh->flags);
00417 #endif
00418 }
00419 }
00420 dwMemPos += pds->size + 8;
00421 }
00422 break;
00423
00424
00425 case 0x44504d53:
00426 {
00427 DWORD dwPos = dwMemPos + 8;
00428 UINT ismpd = 0;
00429 for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++)
00430 {
00431 ismpd++;
00432 DWORD pksize;
00433 if (dwPos + 4 >= dwMemLength)
00434 {
00435 #ifdef DMFLOG
00436 Log("Unexpected EOF at sample %d/%d! (pos=%d)\n", iSmp, m_nSamples, dwPos);
00437 #endif
00438 break;
00439 }
00440 pksize = *((LPDWORD)(lpStream+dwPos));
00441 #ifdef DMFLOG
00442 Log("sample %d: pos=0x%X pksize=%d ", iSmp, dwPos, pksize);
00443 Log("len=%d flags=0x%X [%08X]\n", Ins[iSmp].nLength, smplflags[ismpd], *((LPDWORD)(lpStream+dwPos+4)));
00444 #endif
00445 dwPos += 4;
00446 if (pksize > dwMemLength - dwPos)
00447 {
00448 #ifdef DMFLOG
00449 Log("WARNING: pksize=%d, but only %d bytes left\n", pksize, dwMemLength-dwPos);
00450 #endif
00451 pksize = dwMemLength - dwPos;
00452 }
00453 if ((pksize) && (iSmp <= m_nSamples))
00454 {
00455 UINT flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
00456 if (smplflags[ismpd] & 4) flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_DMF16 : RS_DMF8;
00457 ReadSample(&Ins[iSmp], flags, (LPSTR)(lpStream+dwPos), pksize);
00458 }
00459 dwPos += pksize;
00460 }
00461 dwMemPos = dwPos;
00462 }
00463 break;
00464
00465
00466 case 0x45444e45:
00467 goto dmfexit;
00468
00469
00470 default:
00471 dwMemPos += 4;
00472 break;
00473 }
00474 }
00475 dmfexit:
00476 if (!m_nChannels)
00477 {
00478 if (!m_nSamples)
00479 {
00480 m_nType = MOD_TYPE_NONE;
00481 return FALSE;
00482 }
00483 m_nChannels = 4;
00484 }
00485 return TRUE;
00486 }
00487
00488
00490
00491
00492 #pragma pack(1)
00493
00494 typedef struct DMF_HNODE
00495 {
00496 short int left, right;
00497 BYTE value;
00498 } Q_PACKED DMF_HNODE;
00499
00500 typedef struct DMF_HTREE
00501 {
00502 LPBYTE ibuf, ibufmax;
00503 DWORD bitbuf;
00504 UINT bitnum;
00505 UINT lastnode, nodecount;
00506 DMF_HNODE nodes[256];
00507 } Q_PACKED DMF_HTREE;
00508
00509 #pragma pack()
00510
00511
00512
00513 BYTE DMFReadBits(DMF_HTREE *tree, UINT nbits)
00514
00515 {
00516 BYTE x = 0, bitv = 1;
00517 while (nbits--)
00518 {
00519 if (tree->bitnum)
00520 {
00521 tree->bitnum--;
00522 } else
00523 {
00524 tree->bitbuf = (tree->ibuf < tree->ibufmax) ? *(tree->ibuf++) : 0;
00525 tree->bitnum = 7;
00526 }
00527 if (tree->bitbuf & 1) x |= bitv;
00528 bitv <<= 1;
00529 tree->bitbuf >>= 1;
00530 }
00531 return x;
00532 }
00533
00534
00535
00536
00537
00538 void DMFNewNode(DMF_HTREE *tree)
00539
00540 {
00541 BYTE isleft, isright;
00542 UINT actnode;
00543
00544 actnode = tree->nodecount;
00545 if (actnode > 255) return;
00546 tree->nodes[actnode].value = DMFReadBits(tree, 7);
00547 isleft = DMFReadBits(tree, 1);
00548 isright = DMFReadBits(tree, 1);
00549 actnode = tree->lastnode;
00550 if (actnode > 255) return;
00551 tree->nodecount++;
00552 tree->lastnode = tree->nodecount;
00553 if (isleft)
00554 {
00555 tree->nodes[actnode].left = tree->lastnode;
00556 DMFNewNode(tree);
00557 } else
00558 {
00559 tree->nodes[actnode].left = -1;
00560 }
00561 tree->lastnode = tree->nodecount;
00562 if (isright)
00563 {
00564 tree->nodes[actnode].right = tree->lastnode;
00565 DMFNewNode(tree);
00566 } else
00567 {
00568 tree->nodes[actnode].right = -1;
00569 }
00570 }
00571
00572
00573 int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen)
00574
00575 {
00576 DMF_HTREE tree;
00577 UINT actnode;
00578 BYTE value, sign, delta = 0;
00579
00580 memset(&tree, 0, sizeof(tree));
00581 tree.ibuf = ibuf;
00582 tree.ibufmax = ibufmax;
00583 DMFNewNode(&tree);
00584 value = 0;
00585 for (UINT i=0; i<maxlen; i++)
00586 {
00587 actnode = 0;
00588 sign = DMFReadBits(&tree, 1);
00589 do
00590 {
00591 if (DMFReadBits(&tree, 1))
00592 actnode = tree.nodes[actnode].right;
00593 else
00594 actnode = tree.nodes[actnode].left;
00595 if (actnode > 255) break;
00596 delta = tree.nodes[actnode].value;
00597 if ((tree.ibuf >= tree.ibufmax) && (!tree.bitnum)) break;
00598 } while ((tree.nodes[actnode].left >= 0) && (tree.nodes[actnode].right >= 0));
00599 if (sign) delta ^= 0xFF;
00600 value += delta;
00601 psample[i] = (i) ? value : 0;
00602 }
00603 #ifdef DMFLOG
00604
00605 #endif
00606 return tree.ibuf - ibuf;
00607 }
00608
00609