Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

load_mt2.cpp

Go to the documentation of this file.
00001 #include "stdafx.h"
00002 #include "sndfile.h"
00003 
00004 //#define MT2DEBUG
00005 
00006 #pragma pack(1)
00007 
00008 typedef struct _MT2FILEHEADER
00009 {
00010         DWORD dwMT20;   // 0x3032544D "MT20"
00011         DWORD dwSpecial;
00012         WORD wVersion;
00013         CHAR szTrackerName[32]; // "MadTracker 2.0"
00014         CHAR szSongName[64];
00015         WORD nOrders;
00016         WORD wRestart;
00017         WORD wPatterns;
00018         WORD wChannels;
00019         WORD wSamplesPerTick;
00020         BYTE bTicksPerLine;
00021         BYTE bLinesPerBeat;
00022         DWORD fulFlags; // b0=packed patterns
00023         WORD wInstruments;
00024         WORD wSamples;
00025         BYTE Orders[256];
00026 } Q_PACKED MT2FILEHEADER;
00027 
00028 typedef struct _MT2PATTERN
00029 {
00030         WORD wLines;
00031         DWORD wDataLen;
00032 } Q_PACKED MT2PATTERN;
00033 
00034 typedef struct _MT2COMMAND
00035 {
00036         BYTE note;      // 0=nothing, 97=note off
00037         BYTE instr;
00038         BYTE vol;
00039         BYTE pan;
00040         BYTE fxcmd;
00041         BYTE fxparam1;
00042         BYTE fxparam2;
00043 } Q_PACKED MT2COMMAND;
00044 
00045 typedef struct _MT2DRUMSDATA
00046 {
00047         WORD wDrumPatterns;
00048         WORD wDrumSamples[8];
00049         BYTE DrumPatternOrder[256];
00050 } Q_PACKED MT2DRUMSDATA;
00051 
00052 typedef struct _MT2AUTOMATION
00053 {
00054         DWORD dwFlags;
00055         DWORD dwEffectId;
00056         DWORD nEnvPoints;
00057 } Q_PACKED MT2AUTOMATION;
00058 
00059 typedef struct _MT2INSTRUMENT
00060 {
00061         CHAR szName[32];
00062         DWORD dwDataLen;
00063         WORD wSamples;
00064         BYTE GroupsMapping[96];
00065         BYTE bVibType;
00066         BYTE bVibSweep;
00067         BYTE bVibDepth;
00068         BYTE bVibRate;
00069         WORD wFadeOut;
00070         WORD wNNA;
00071         WORD wInstrFlags;
00072         WORD wEnvFlags1;
00073         WORD wEnvFlags2;
00074 } Q_PACKED MT2INSTRUMENT;
00075 
00076 typedef struct _MT2ENVELOPE
00077 {
00078         BYTE nFlags;
00079         BYTE nPoints;
00080         BYTE nSustainPos;
00081         BYTE nLoopStart;
00082         BYTE nLoopEnd;
00083         BYTE bReserved[3];
00084         BYTE EnvData[64];
00085 } Q_PACKED MT2ENVELOPE;
00086 
00087 typedef struct _MT2SYNTH
00088 {
00089         BYTE nSynthId;
00090         BYTE nFxId;
00091         WORD wCutOff;
00092         BYTE nResonance;
00093         BYTE nAttack;
00094         BYTE nDecay;
00095         BYTE bReserved[25];
00096 } Q_PACKED MT2SYNTH;
00097 
00098 typedef struct _MT2SAMPLE
00099 {
00100         CHAR szName[32];
00101         DWORD dwDataLen;
00102         DWORD dwLength;
00103         DWORD dwFrequency;
00104         BYTE nQuality;
00105         BYTE nChannels;
00106         BYTE nFlags;
00107         BYTE nLoop;
00108         DWORD dwLoopStart;
00109         DWORD dwLoopEnd;
00110         WORD wVolume;
00111         BYTE nPan;
00112         BYTE nBaseNote;
00113         WORD wSamplesPerBeat;
00114 } Q_PACKED MT2SAMPLE;
00115 
00116 typedef struct _MT2GROUP
00117 {
00118         BYTE nSmpNo;
00119         BYTE nVolume;   // 0-128
00120         BYTE nFinePitch;
00121         BYTE Reserved[5];
00122 } Q_PACKED MT2GROUP;
00123 
00124 #pragma pack()
00125 
00126 
00127 static VOID ConvertMT2Command(CSoundFile *that, MODCOMMAND *m, MT2COMMAND *p)
00128 //---------------------------------------------------------------------------
00129 {
00130         // Note
00131         m->note = 0;
00132         if (p->note) m->note = (p->note > 96) ? 0xFF : p->note+12;
00133         // Instrument
00134         m->instr = p->instr;
00135         // Volume Column
00136         if ((p->vol >= 0x10) && (p->vol <= 0x90))
00137         {
00138                 m->volcmd = VOLCMD_VOLUME;
00139                 m->vol = (p->vol - 0x10) >> 1;
00140         } else
00141         if ((p->vol >= 0xA0) && (p->vol <= 0xAF))
00142         {
00143                 m->volcmd = VOLCMD_VOLSLIDEDOWN;
00144                 m->vol = (p->vol & 0x0f);
00145         } else
00146         if ((p->vol >= 0xB0) && (p->vol <= 0xBF))
00147         {
00148                 m->volcmd = VOLCMD_VOLSLIDEUP;
00149                 m->vol = (p->vol & 0x0f);
00150         } else
00151         if ((p->vol >= 0xC0) && (p->vol <= 0xCF))
00152         {
00153                 m->volcmd = VOLCMD_FINEVOLDOWN;
00154                 m->vol = (p->vol & 0x0f);
00155         } else
00156         if ((p->vol >= 0xD0) && (p->vol <= 0xDF))
00157         {
00158                 m->volcmd = VOLCMD_FINEVOLUP;
00159                 m->vol = (p->vol & 0x0f);
00160         } else
00161         {
00162                 m->volcmd = 0;
00163                 m->vol = 0;
00164         }
00165         // Effects
00166         m->command = 0;
00167         m->param = 0;
00168         if ((p->fxcmd) || (p->fxparam1) || (p->fxparam2))
00169         {
00170                 if (!p->fxcmd)
00171                 {
00172                         m->command = p->fxparam2;
00173                         m->param = p->fxparam1;
00174                         that->ConvertModCommand(m);
00175                 } else
00176                 {
00177                         // TODO: MT2 Effects
00178                 }
00179         }
00180 }
00181 
00182 
00183 BOOL CSoundFile::ReadMT2(LPCBYTE lpStream, DWORD dwMemLength)
00184 //-----------------------------------------------------------
00185 {
00186         MT2FILEHEADER *pfh = (MT2FILEHEADER *)lpStream;
00187         DWORD dwMemPos, dwDrumDataPos, dwExtraDataPos;
00188         UINT nDrumDataLen, nExtraDataLen;
00189         MT2DRUMSDATA *pdd;
00190         MT2INSTRUMENT *InstrMap[255];
00191         MT2SAMPLE *SampleMap[256];
00192 
00193         if ((!lpStream) || (dwMemLength < sizeof(MT2FILEHEADER))
00194          || (pfh->dwMT20 != 0x3032544D)
00195          || (pfh->wVersion < 0x0200) || (pfh->wVersion >= 0x0300)
00196          || (pfh->wChannels < 4) || (pfh->wChannels > 64)) return FALSE;
00197         pdd = NULL;
00198         m_nType = MOD_TYPE_MT2;
00199         m_nChannels = pfh->wChannels;
00200         m_nRestartPos = pfh->wRestart;
00201         m_nDefaultSpeed = pfh->bTicksPerLine;
00202         m_nDefaultTempo = 125;
00203         if ((pfh->wSamplesPerTick > 100) && (pfh->wSamplesPerTick < 5000))
00204         {
00205                 m_nDefaultTempo = 110250 / pfh->wSamplesPerTick;
00206         }
00207         for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
00208         {
00209                 Order[iOrd] = (BYTE)((iOrd < pfh->nOrders) ? pfh->Orders[iOrd] : 0xFF);
00210         }
00211         memcpy(m_szNames[0], pfh->szSongName, 32);
00212         m_szNames[0][31] = 0;
00213         dwMemPos = sizeof(MT2FILEHEADER);
00214         nDrumDataLen = *(WORD *)(lpStream + dwMemPos);
00215         dwDrumDataPos = dwMemPos + 2;
00216         if (nDrumDataLen >= 2) pdd = (MT2DRUMSDATA *)(lpStream+dwDrumDataPos);
00217         dwMemPos += 2 + nDrumDataLen;
00218 #ifdef MT2DEBUG
00219 
00220         Log("MT2 v%03X: \"%s\" (flags=%04X)\n", pfh->wVersion, m_szNames[0], pfh->fulFlags);
00221         Log("%d Channels, %d Patterns, %d Instruments, %d Samples\n", pfh->wChannels, pfh->wPatterns, pfh->wInstruments, pfh->wSamples);
00222         Log("Drum Data: %d bytes @%04X\n", nDrumDataLen, dwDrumDataPos);
00223 #endif
00224         if (dwMemPos >= dwMemLength-12) return TRUE;
00225         if (!*(DWORD *)(lpStream+dwMemPos)) dwMemPos += 4;
00226         if (!*(DWORD *)(lpStream+dwMemPos)) dwMemPos += 4;
00227         nExtraDataLen = *(DWORD *)(lpStream+dwMemPos);
00228         dwExtraDataPos = dwMemPos + 4;
00229         dwMemPos += 4;
00230 #ifdef MT2DEBUG
00231         Log("Extra Data: %d bytes @%04X\n", nExtraDataLen, dwExtraDataPos);
00232 #endif
00233         if (dwMemPos + nExtraDataLen >= dwMemLength) return TRUE;
00234         while (dwMemPos+8 < dwExtraDataPos + nExtraDataLen)
00235         {
00236                 DWORD dwId = *(DWORD *)(lpStream+dwMemPos);
00237                 DWORD dwLen = *(DWORD *)(lpStream+dwMemPos+4);
00238                 dwMemPos += 8;
00239                 if (dwMemPos + dwLen > dwMemLength) return TRUE;
00240 #ifdef MT2DEBUG
00241                 CHAR s[5];
00242                 memcpy(s, &dwId, 4);
00243                 s[4] = 0;
00244                 Log("pos=0x%04X: %s: %d bytes\n", dwMemPos-8, s, dwLen);
00245 #endif
00246                 switch(dwId)
00247                 {
00248                 // MSG
00249                 case 0x0047534D:
00250                         if ((dwLen > 3) && (!m_lpszSongComments))
00251                         {
00252                                 DWORD nTxtLen = dwLen;
00253                                 if (nTxtLen > 32000) nTxtLen = 32000;
00254                                 m_lpszSongComments = new char[nTxtLen];  // changed from CHAR
00255                                 if (m_lpszSongComments)
00256                                 {
00257                                         memcpy(m_lpszSongComments, lpStream+dwMemPos+1, nTxtLen-1);
00258                                         m_lpszSongComments[nTxtLen-1] = 0;
00259                                 }
00260                         }
00261                         break;
00262                 // SUM -> author name (or "Unregistered")
00263                 // TMAP
00264                 // TRKS
00265                 case 0x534b5254:
00266                         break;
00267                 }
00268                 dwMemPos += dwLen;
00269         }
00270         // Load Patterns
00271         dwMemPos = dwExtraDataPos + nExtraDataLen;
00272         for (UINT iPat=0; iPat<pfh->wPatterns; iPat++) if (dwMemPos < dwMemLength-6)
00273         {
00274                 MT2PATTERN *pmp = (MT2PATTERN *)(lpStream+dwMemPos);
00275                 UINT wDataLen = (pmp->wDataLen + 1) & ~1;
00276                 dwMemPos += 6;
00277                 if (dwMemPos + wDataLen > dwMemLength) break;
00278                 UINT nLines = pmp->wLines;
00279                 if ((iPat < MAX_PATTERNS) && (nLines > 0) && (nLines <= 256))
00280                 {
00281         #ifdef MT2DEBUG
00282                         Log("Pattern #%d @%04X: %d lines, %d bytes\n", iPat, dwMemPos-6, nLines, pmp->wDataLen);
00283         #endif
00284                         PatternSize[iPat] = nLines;
00285                         Patterns[iPat] = AllocatePattern(nLines, m_nChannels);
00286                         if (!Patterns[iPat]) return TRUE;
00287                         MODCOMMAND *m = Patterns[iPat];
00288                         UINT len = wDataLen;
00289                         if (pfh->fulFlags & 1) // Packed Patterns
00290                         {
00291                                 BYTE *p = (BYTE *)(lpStream+dwMemPos);
00292                                 UINT pos = 0, row=0, ch=0;
00293                                 while (pos < len)
00294                                 {
00295                                         MT2COMMAND cmd;
00296                                         UINT infobyte = p[pos++];
00297                                         UINT rptcount = 0;
00298                                         if (infobyte == 0xff)
00299                                         {
00300                                                 rptcount = p[pos++];
00301                                                 infobyte = p[pos++];
00302                                 #if 0
00303                                                 Log("(%d.%d) FF(%02X).%02X\n", row, ch, rptcount, infobyte);
00304                                         } else
00305                                         {
00306                                                 Log("(%d.%d) %02X\n", row, ch, infobyte);
00307                                 #endif
00308                                         }
00309                                         if (infobyte & 0x7f)
00310                                         {
00311                                                 UINT patpos = row*m_nChannels+ch;
00312                                                 cmd.note = cmd.instr = cmd.vol = cmd.pan = cmd.fxcmd = cmd.fxparam1 = cmd.fxparam2 = 0;
00313                                                 if (infobyte & 1) cmd.note = p[pos++];
00314                                                 if (infobyte & 2) cmd.instr = p[pos++];
00315                                                 if (infobyte & 4) cmd.vol = p[pos++];
00316                                                 if (infobyte & 8) cmd.pan = p[pos++];
00317                                                 if (infobyte & 16) cmd.fxcmd = p[pos++];
00318                                                 if (infobyte & 32) cmd.fxparam1 = p[pos++];
00319                                                 if (infobyte & 64) cmd.fxparam2 = p[pos++];
00320                                         #ifdef MT2DEBUG
00321                                                 if (cmd.fxcmd)
00322                                                 {
00323                                                         Log("(%d.%d) MT2 FX=%02X.%02X.%02X\n", row, ch, cmd.fxcmd, cmd.fxparam1, cmd.fxparam2);
00324                                                 }
00325                                         #endif
00326                                                 ConvertMT2Command(this, &m[patpos], &cmd);
00327                                         }
00328                                         row += rptcount+1;
00329                                         while (row >= nLines) { row-=nLines; ch++; }
00330                                         if (ch >= m_nChannels) break;
00331                                 }
00332                         } else
00333                         {
00334                                 MT2COMMAND *p = (MT2COMMAND *)(lpStream+dwMemPos);
00335                                 UINT n = 0;
00336                                 while ((len > sizeof(MT2COMMAND)) && (n < m_nChannels*nLines))
00337                                 {
00338                                         ConvertMT2Command(this, m, p);
00339                                         len -= sizeof(MT2COMMAND);
00340                                         n++;
00341                                         p++;
00342                                         m++;
00343                                 }
00344                         }
00345                 }
00346                 dwMemPos += wDataLen;
00347         }
00348         // Skip Drum Patterns
00349         if (pdd)
00350         {
00351         #ifdef MT2DEBUG
00352                 Log("%d Drum Patterns at offset 0x%08X\n", pdd->wDrumPatterns, dwMemPos);
00353         #endif
00354                 for (UINT iDrm=0; iDrm<pdd->wDrumPatterns; iDrm++)
00355                 {
00356                         if (dwMemPos > dwMemLength-2) return TRUE;
00357                         UINT nLines = *(WORD *)(lpStream+dwMemPos);
00358                 #ifdef MT2DEBUG
00359                         if (nLines != 64) Log("Drum Pattern %d: %d Lines @%04X\n", iDrm, nLines, dwMemPos);
00360                 #endif
00361                         dwMemPos += 2 + nLines * 32;
00362                 }
00363         }
00364         // Automation
00365         if (pfh->fulFlags & 2)
00366         {
00367         #ifdef MT2DEBUG
00368                 Log("Automation at offset 0x%08X\n", dwMemPos);
00369         #endif
00370                 UINT nAutoCount = m_nChannels;
00371                 if (pfh->fulFlags & 0x10) nAutoCount++; // Master Automation
00372                 if ((pfh->fulFlags & 0x08) && (pdd)) nAutoCount += 8; // Drums Automation
00373                 nAutoCount *= pfh->wPatterns;
00374                 for (UINT iAuto=0; iAuto<nAutoCount; iAuto++)
00375                 {
00376                         if (dwMemPos+12 >= dwMemLength) return TRUE;
00377                         MT2AUTOMATION *pma = (MT2AUTOMATION *)(lpStream+dwMemPos);
00378                         dwMemPos += (pfh->wVersion <= 0x201) ? 4 : 8;
00379                         for (UINT iEnv=0; iEnv<14; iEnv++)
00380                         {
00381                                 if (pma->dwFlags & (1 << iEnv))
00382                                 {
00383                                 #ifdef MT2DEBUG
00384                                         UINT nPoints = *(DWORD *)(lpStream+dwMemPos);
00385                                         Log("  Env[%d/%d] %04X @%04X: %d points\n", iAuto, nAutoCount, 1 << iEnv, dwMemPos-8, nPoints);
00386                                 #endif
00387                                         dwMemPos += 260;
00388                                 }
00389                         }
00390                 }
00391         }
00392         // Load Instruments
00393 #ifdef MT2DEBUG
00394         Log("Loading instruments at offset 0x%08X\n", dwMemPos);
00395 #endif
00396         memset(InstrMap, 0, sizeof(InstrMap));
00397         m_nInstruments = (pfh->wInstruments < MAX_INSTRUMENTS) ? pfh->wInstruments : MAX_INSTRUMENTS-1;
00398         for (UINT iIns=1; iIns<=255; iIns++)
00399         {
00400                 if (dwMemPos+36 > dwMemLength) return TRUE;
00401                 MT2INSTRUMENT *pmi = (MT2INSTRUMENT *)(lpStream+dwMemPos);
00402                 INSTRUMENTHEADER *penv = NULL;
00403                 if (iIns <= m_nInstruments)
00404                 {
00405                         penv = new INSTRUMENTHEADER;
00406                         Headers[iIns] = penv;
00407                         if (penv)
00408                         {
00409                                 memset(penv, 0, sizeof(INSTRUMENTHEADER));
00410                                 memcpy(penv->name, pmi->szName, 32);
00411                                 penv->nGlobalVol = 64;
00412                                 penv->nPan = 128;
00413                                 for (UINT i=0; i<120; i++)
00414                                 {
00415                                         penv->NoteMap[i] = i+1;
00416                                 }
00417                         }
00418                 }
00419         #ifdef MT2DEBUG
00420                 if (iIns <= pfh->wInstruments) Log("  Instrument #%d at offset %04X: %d bytes\n", iIns, dwMemPos, pmi->dwDataLen);
00421         #endif
00422                 if (((LONG)pmi->dwDataLen > 0) && (dwMemPos + pmi->dwDataLen + 40 <= dwMemLength))
00423                 {
00424                         InstrMap[iIns-1] = pmi;
00425                         if (penv)
00426                         {
00427                                 penv->nFadeOut = pmi->wFadeOut;
00428                                 penv->nNNA = pmi->wNNA & 3;
00429                                 penv->nDCT = (pmi->wNNA>>8) & 3;
00430                                 penv->nDNA = (pmi->wNNA>>12) & 3;
00431                                 MT2ENVELOPE *pehdr[4];
00432                                 WORD *pedata[4];
00433                                 if (pfh->wVersion <= 0x201)
00434                                 {
00435                                         DWORD dwEnvPos = dwMemPos + sizeof(MT2INSTRUMENT) - 4;
00436                                         pehdr[0] = (MT2ENVELOPE *)(lpStream+dwEnvPos);
00437                                         pehdr[1] = (MT2ENVELOPE *)(lpStream+dwEnvPos+8);
00438                                         pehdr[2] = pehdr[3] = NULL;
00439                                         pedata[0] = (WORD *)(lpStream+dwEnvPos+16);
00440                                         pedata[1] = (WORD *)(lpStream+dwEnvPos+16+64);
00441                                         pedata[2] = pedata[3] = NULL;
00442                                 } else
00443                                 {
00444                                         DWORD dwEnvPos = dwMemPos + sizeof(MT2INSTRUMENT);
00445                                         for (UINT i=0; i<4; i++)
00446                                         {
00447                                                 if (pmi->wEnvFlags1 & (1<<i))
00448                                                 {
00449                                                         pehdr[i] = (MT2ENVELOPE *)(lpStream+dwEnvPos);
00450                                                         pedata[i] = (WORD *)pehdr[i]->EnvData;
00451                                                         dwEnvPos += sizeof(MT2ENVELOPE);
00452                                                 } else
00453                                                 {
00454                                                         pehdr[i] = NULL;
00455                                                         pedata[i] = NULL;
00456                                                 }
00457                                         }
00458                                 }
00459                                 // Load envelopes
00460                                 for (UINT iEnv=0; iEnv<4; iEnv++) if (pehdr[iEnv])
00461                                 {
00462                                         MT2ENVELOPE *pme = pehdr[iEnv];
00463                                         WORD *pEnvPoints = NULL;
00464                                         BYTE *pEnvData = NULL;
00465                                 #ifdef MT2DEBUG
00466                                         Log("  Env %d.%d @%04X: %d points\n", iIns, iEnv, (UINT)(((BYTE *)pme)-lpStream), pme->nPoints);
00467                                 #endif
00468                                         switch(iEnv)
00469                                         {
00470                                         // Volume Envelope
00471                                         case 0:
00472                                                 if (pme->nFlags & 1) penv->dwFlags |= ENV_VOLUME;
00473                                                 if (pme->nFlags & 2) penv->dwFlags |= ENV_VOLSUSTAIN;
00474                                                 if (pme->nFlags & 4) penv->dwFlags |= ENV_VOLLOOP;
00475                                                 penv->nVolEnv = (pme->nPoints > 16) ? 16 : pme->nPoints;
00476                                                 penv->nVolSustainBegin = penv->nVolSustainEnd = pme->nSustainPos;
00477                                                 penv->nVolLoopStart = pme->nLoopStart;
00478                                                 penv->nVolLoopEnd = pme->nLoopEnd;
00479                                                 pEnvPoints = penv->VolPoints;
00480                                                 pEnvData = penv->VolEnv;
00481                                                 break;
00482 
00483                                         // Panning Envelope
00484                                         case 1:
00485                                                 if (pme->nFlags & 1) penv->dwFlags |= ENV_PANNING;
00486                                                 if (pme->nFlags & 2) penv->dwFlags |= ENV_PANSUSTAIN;
00487                                                 if (pme->nFlags & 4) penv->dwFlags |= ENV_PANLOOP;
00488                                                 penv->nPanEnv = (pme->nPoints > 16) ? 16 : pme->nPoints;
00489                                                 penv->nPanSustainBegin = penv->nPanSustainEnd = pme->nSustainPos;
00490                                                 penv->nPanLoopStart = pme->nLoopStart;
00491                                                 penv->nPanLoopEnd = pme->nLoopEnd;
00492                                                 pEnvPoints = penv->PanPoints;
00493                                                 pEnvData = penv->PanEnv;
00494                                                 break;
00495 
00496                                         // Pitch/Filter envelope
00497                                         default:
00498                                                 if (pme->nFlags & 1) penv->dwFlags |= (iEnv==3) ? (ENV_PITCH|ENV_FILTER) : ENV_PITCH;
00499                                                 if (pme->nFlags & 2) penv->dwFlags |= ENV_PITCHSUSTAIN;
00500                                                 if (pme->nFlags & 4) penv->dwFlags |= ENV_PITCHLOOP;
00501                                                 penv->nPitchEnv = (pme->nPoints > 16) ? 16 : pme->nPoints;
00502                                                 penv->nPitchSustainBegin = penv->nPitchSustainEnd = pme->nSustainPos;
00503                                                 penv->nPitchLoopStart = pme->nLoopStart;
00504                                                 penv->nPitchLoopEnd = pme->nLoopEnd;
00505                                                 pEnvPoints = penv->PitchPoints;
00506                                                 pEnvData = penv->PitchEnv;
00507                                         }
00508                                         // Envelope data
00509                                         if ((pEnvPoints) && (pEnvData) && (pedata[iEnv]))
00510                                         {
00511                                                 WORD *psrc = pedata[iEnv];
00512                                                 for (UINT i=0; i<16; i++)
00513                                                 {
00514                                                         pEnvPoints[i] = psrc[i*2];
00515                                                         pEnvData[i] = (BYTE)psrc[i*2+1];
00516                                                 }
00517                                         }
00518                                 }
00519                         }
00520                         dwMemPos += pmi->dwDataLen + 36;
00521                         if (pfh->wVersion > 0x201) dwMemPos += 4; // ?
00522                 } else
00523                 {
00524                         dwMemPos += 36;
00525                 }
00526         }
00527 #ifdef MT2DEBUG
00528         Log("Loading samples at offset 0x%08X\n", dwMemPos);
00529 #endif
00530         memset(SampleMap, 0, sizeof(SampleMap));
00531         m_nSamples = (pfh->wSamples < MAX_SAMPLES) ? pfh->wSamples : MAX_SAMPLES-1;
00532         for (UINT iSmp=1; iSmp<=256; iSmp++)
00533         {
00534                 if (dwMemPos+36 > dwMemLength) return TRUE;
00535                 MT2SAMPLE *pms = (MT2SAMPLE *)(lpStream+dwMemPos);
00536         #ifdef MT2DEBUG
00537                 if (iSmp <= m_nSamples) Log("  Sample #%d at offset %04X: %d bytes\n", iSmp, dwMemPos, pms->dwDataLen);
00538         #endif
00539                 if (iSmp < MAX_SAMPLES)
00540                 {
00541                         memcpy(m_szNames[iSmp], pms->szName, 32);
00542                 }
00543                 if (pms->dwDataLen > 0)
00544                 {
00545                         SampleMap[iSmp-1] = pms;
00546                         if (iSmp < MAX_SAMPLES)
00547                         {
00548                                 MODINSTRUMENT *psmp = &Ins[iSmp];
00549                                 psmp->nGlobalVol = 64;
00550                                 psmp->nVolume = (pms->wVolume >> 7);
00551                                 psmp->nPan = (pms->nPan == 0x80) ? 128 : (pms->nPan^0x80);
00552                                 psmp->nLength = pms->dwLength;
00553                                 psmp->nC4Speed = pms->dwFrequency;
00554                                 psmp->nLoopStart = pms->dwLoopStart;
00555                                 psmp->nLoopEnd = pms->dwLoopEnd;
00556                                 FrequencyToTranspose(psmp);
00557                                 psmp->RelativeTone -= pms->nBaseNote - 49;
00558                                 psmp->nC4Speed = TransposeToFrequency(psmp->RelativeTone, psmp->nFineTune);
00559                                 if (pms->nQuality == 2) { psmp->uFlags |= CHN_16BIT; psmp->nLength >>= 1; }
00560                                 if (pms->nChannels == 2) { psmp->nLength >>= 1; }
00561                                 if (pms->nLoop == 1) psmp->uFlags |= CHN_LOOP;
00562                                 if (pms->nLoop == 2) psmp->uFlags |= CHN_LOOP|CHN_PINGPONGLOOP;
00563                         }
00564                         dwMemPos += pms->dwDataLen + 36;
00565                 } else
00566                 {
00567                         dwMemPos += 36;
00568                 }
00569         }
00570 #ifdef MT2DEBUG
00571         Log("Loading groups at offset 0x%08X\n", dwMemPos);
00572 #endif
00573         for (UINT iMap=0; iMap<255; iMap++) if (InstrMap[iMap])
00574         {
00575                 if (dwMemPos+8 > dwMemLength) return TRUE;
00576                 MT2INSTRUMENT *pmi = InstrMap[iMap];
00577                 INSTRUMENTHEADER *penv = NULL;
00578                 if (iMap<m_nInstruments) penv = Headers[iMap+1];
00579                 for (UINT iGrp=0; iGrp<pmi->wSamples; iGrp++)
00580                 {
00581                         if (penv)
00582                         {
00583                                 MT2GROUP *pmg = (MT2GROUP *)(lpStream+dwMemPos);
00584                                 for (UINT i=0; i<96; i++)
00585                                 {
00586                                         if (pmi->GroupsMapping[i] == iGrp)
00587                                         {
00588                                                 UINT nSmp = pmg->nSmpNo+1;
00589                                                 penv->Keyboard[i+12] = (BYTE)nSmp;
00590                                                 if (nSmp <= m_nSamples)
00591                                                 {
00592                                                         Ins[nSmp].nVibType = pmi->bVibType;
00593                                                         Ins[nSmp].nVibSweep = pmi->bVibSweep;
00594                                                         Ins[nSmp].nVibDepth = pmi->bVibDepth;
00595                                                         Ins[nSmp].nVibRate = pmi->bVibRate;
00596                                                 }
00597                                         }
00598                                 }
00599                         }
00600                         dwMemPos += 8;
00601                 }
00602         }
00603 #ifdef MT2DEBUG
00604         Log("Loading sample data at offset 0x%08X\n", dwMemPos);
00605 #endif
00606         for (UINT iData=0; iData<256; iData++) if ((iData < m_nSamples) && (SampleMap[iData]))
00607         {
00608                 MT2SAMPLE *pms = SampleMap[iData];
00609                 MODINSTRUMENT *psmp = &Ins[iData+1];
00610                 if (!(pms->nFlags & 5))
00611                 {
00612                         if (psmp->nLength > 0) 
00613                         {
00614                         #ifdef MT2DEBUG
00615                                 Log("  Reading sample #%d at offset 0x%04X (len=%d)\n", iData+1, dwMemPos, psmp->nLength);
00616                         #endif
00617                                 UINT rsflags;
00618                                 
00619                                 if (pms->nChannels == 2)
00620                                         rsflags = (psmp->uFlags & CHN_16BIT) ? RS_STPCM16D : RS_STPCM8D;
00621                                 else
00622                                         rsflags = (psmp->uFlags & CHN_16BIT) ? RS_PCM16D : RS_PCM8D;
00623 
00624                                 dwMemPos += ReadSample(psmp, rsflags, (LPCSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
00625                         }
00626                 } else
00627                 if (dwMemPos+4 < dwMemLength)
00628                 {
00629                         UINT nNameLen = *(DWORD *)(lpStream+dwMemPos);
00630                         dwMemPos += nNameLen + 16;
00631                 }
00632                 if (dwMemPos+4 >= dwMemLength) break;
00633         }
00634         return TRUE;
00635 }

Generated on Sat Nov 5 16:15:40 2005 for OPIE by  doxygen 1.4.2