00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
00013
00014
00015
00016
00017
00019 #include "stdafx.h"
00020 #include "sndfile.h"
00021
00022
00023
00024
00025
00026 #pragma pack(1)
00027
00028 typedef struct _AMFFILEHEADER
00029 {
00030 UCHAR szAMF[3];
00031 UCHAR version;
00032 CHAR title[32];
00033 UCHAR numsamples;
00034 UCHAR numorders;
00035 USHORT numtracks;
00036 UCHAR numchannels;
00037 } Q_PACKED AMFFILEHEADER;
00038
00039 typedef struct _AMFSAMPLE
00040 {
00041 UCHAR type;
00042 CHAR samplename[32];
00043 CHAR filename[13];
00044 ULONG offset;
00045 ULONG length;
00046 USHORT c2spd;
00047 UCHAR volume;
00048 } Q_PACKED AMFSAMPLE;
00049
00050
00051 #pragma pack()
00052
00053
00054 #ifdef AMFLOG
00055 extern void Log(LPCSTR, ...);
00056 #endif
00057
00058 VOID AMF_Unpack(MODCOMMAND *pPat, const BYTE *pTrack, UINT nRows, UINT nChannels)
00059
00060 {
00061 UINT lastinstr = 0;
00062 UINT nTrkSize = *(USHORT *)pTrack;
00063 nTrkSize += (UINT)pTrack[2] << 16;
00064 pTrack += 3;
00065 while (nTrkSize--)
00066 {
00067 UINT row = pTrack[0];
00068 UINT cmd = pTrack[1];
00069 UINT arg = pTrack[2];
00070 if (row >= nRows) break;
00071 MODCOMMAND *m = pPat + row * nChannels;
00072 if (cmd < 0x7F)
00073 {
00074 m->note = cmd+1;
00075 if (!m->instr) m->instr = lastinstr;
00076 m->volcmd = VOLCMD_VOLUME;
00077 m->vol = arg;
00078 } else
00079 if (cmd == 0x7F)
00080 {
00081 signed char rdelta = (signed char)arg;
00082 int rowsrc = (int)row + (int)rdelta;
00083 if ((rowsrc >= 0) && (rowsrc < (int)nRows)) *m = pPat[rowsrc*nChannels];
00084 } else
00085 if (cmd == 0x80)
00086 {
00087 m->instr = arg+1;
00088 lastinstr = m->instr;
00089 } else
00090 if (cmd == 0x83)
00091 {
00092 m->volcmd = VOLCMD_VOLUME;
00093 m->vol = arg;
00094 } else
00095
00096 {
00097 UINT command = cmd & 0x7F;
00098 UINT param = arg;
00099 switch(command)
00100 {
00101
00102 case 0x01: command = CMD_SPEED; break;
00103
00104
00105
00106 case 0x02: command = CMD_VOLUMESLIDE;
00107 case 0x0A: if (command == 0x0A) command = CMD_TONEPORTAVOL;
00108 case 0x0B: if (command == 0x0B) command = CMD_VIBRATOVOL;
00109 if (param & 0x80) param = (-(signed char)param)&0x0F;
00110 else param = (param&0x0F)<<4;
00111 break;
00112
00113 case 0x04: if (param & 0x80) { command = CMD_PORTAMENTOUP; param = -(signed char)param; }
00114 else { command = CMD_PORTAMENTODOWN; } break;
00115
00116 case 0x06: command = CMD_TONEPORTAMENTO; break;
00117
00118 case 0x07: command = CMD_TREMOR; break;
00119
00120 case 0x08: command = CMD_ARPEGGIO; break;
00121
00122 case 0x09: command = CMD_VIBRATO; break;
00123
00124 case 0x0C: command = CMD_PATTERNBREAK; break;
00125
00126 case 0x0D: command = CMD_POSITIONJUMP; break;
00127
00128 case 0x0F: command = CMD_RETRIG; break;
00129
00130 case 0x10: command = CMD_OFFSET; break;
00131
00132 case 0x11: if (param) { command = CMD_VOLUMESLIDE;
00133 if (param & 0x80) param = 0xF0|((-(signed char)param)&0x0F);
00134 else param = 0x0F|((param&0x0F)<<4);
00135 } else command = 0; break;
00136
00137
00138 case 0x12:
00139 case 0x16: if (param) { int mask = (command == 0x16) ? 0xE0 : 0xF0;
00140 command = (param & 0x80) ? CMD_PORTAMENTOUP : CMD_PORTAMENTODOWN;
00141 if (param & 0x80) param = mask|((-(signed char)param)&0x0F);
00142 else param |= mask;
00143 } else command = 0; break;
00144
00145 case 0x13: command = CMD_S3MCMDEX; param = 0xD0|(param & 0x0F); break;
00146
00147 case 0x14: command = CMD_S3MCMDEX; param = 0xC0|(param & 0x0F); break;
00148
00149 case 0x15: command = CMD_TEMPO; break;
00150
00151 case 0x17: param = (param+64)&0x7F;
00152 if (m->command) { if (!m->volcmd) { m->volcmd = VOLCMD_PANNING; m->vol = param/2; } command = 0; }
00153 else { command = CMD_PANNING8; }
00154
00155 default: command = param = 0;
00156 }
00157 if (command)
00158 {
00159 m->command = command;
00160 m->param = param;
00161 }
00162 }
00163 pTrack += 3;
00164 }
00165 }
00166
00167
00168
00169 BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, DWORD dwMemLength)
00170
00171 {
00172 AMFFILEHEADER *pfh = (AMFFILEHEADER *)lpStream;
00173 DWORD dwMemPos;
00174
00175 if ((!lpStream) || (dwMemLength < 2048)) return FALSE;
00176 if ((!strncmp((LPCTSTR)lpStream, "ASYLUM Music Format V1.0", 25)) && (dwMemLength > 4096))
00177 {
00178 UINT numorders, numpats, numsamples;
00179
00180 dwMemPos = 32;
00181 numpats = lpStream[dwMemPos+3];
00182 numorders = lpStream[dwMemPos+4];
00183 numsamples = 64;
00184 dwMemPos += 6;
00185 if ((!numpats) || (numpats > MAX_PATTERNS) || (!numorders)
00186 || (numpats*64*32 + 294 + 37*64 >= dwMemLength)) return FALSE;
00187 m_nType = MOD_TYPE_AMF0;
00188 m_nChannels = 8;
00189 m_nInstruments = 0;
00190 m_nSamples = 31;
00191 m_nDefaultTempo = 125;
00192 m_nDefaultSpeed = 6;
00193 for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
00194 {
00195 Order[iOrd] = (iOrd < numorders) ? lpStream[dwMemPos+iOrd] : 0xFF;
00196 }
00197 dwMemPos = 294;
00198 for (UINT iSmp=0; iSmp<numsamples; iSmp++)
00199 {
00200 MODINSTRUMENT *psmp = &Ins[iSmp+1];
00201 memcpy(m_szNames[iSmp+1], lpStream+dwMemPos, 22);
00202 psmp->nFineTune = MOD2XMFineTune(lpStream[dwMemPos+22]);
00203 psmp->nVolume = lpStream[dwMemPos+23];
00204 psmp->nGlobalVol = 64;
00205 if (psmp->nVolume > 0x40) psmp->nVolume = 0x40;
00206 psmp->nVolume <<= 2;
00207 psmp->nLength = *((LPDWORD)(lpStream+dwMemPos+25));
00208 psmp->nLoopStart = *((LPDWORD)(lpStream+dwMemPos+29));
00209 psmp->nLoopEnd = psmp->nLoopStart + *((LPDWORD)(lpStream+dwMemPos+33));
00210 if ((psmp->nLoopEnd > psmp->nLoopStart) && (psmp->nLoopEnd <= psmp->nLength))
00211 {
00212 psmp->uFlags = CHN_LOOP;
00213 } else
00214 {
00215 psmp->nLoopStart = psmp->nLoopEnd = 0;
00216 }
00217 if ((psmp->nLength) && (iSmp>31)) m_nSamples = iSmp+1;
00218 dwMemPos += 37;
00219 }
00220 for (UINT iPat=0; iPat<numpats; iPat++)
00221 {
00222 MODCOMMAND *p = AllocatePattern(64, m_nChannels);
00223 if (!p) break;
00224 Patterns[iPat] = p;
00225 PatternSize[iPat] = 64;
00226 const UCHAR *pin = lpStream + dwMemPos;
00227 for (UINT i=0; i<8*64; i++)
00228 {
00229 p->note = 0;
00230
00231 if (pin[0])
00232 {
00233 p->note = pin[0] + 13;
00234 }
00235 p->instr = pin[1];
00236 p->command = pin[2];
00237 p->param = pin[3];
00238 if (p->command > 0x0F)
00239 {
00240 #ifdef AMFLOG
00241 Log("0x%02X.0x%02X ?", p->command, p->param);
00242 #endif
00243 p->command = 0;
00244 }
00245 ConvertModCommand(p);
00246 pin += 4;
00247 p++;
00248 }
00249 dwMemPos += 64*32;
00250 }
00251
00252 for (UINT iData=0; iData<m_nSamples; iData++)
00253 {
00254 MODINSTRUMENT *psmp = &Ins[iData+1];
00255 if (psmp->nLength)
00256 {
00257 dwMemPos += ReadSample(psmp, RS_PCM8S, (LPCSTR)(lpStream+dwMemPos), dwMemLength);
00258 }
00259 }
00260 return TRUE;
00261 }
00263
00264 USHORT *ptracks[MAX_PATTERNS];
00265 DWORD sampleseekpos[MAX_SAMPLES];
00266
00267 if ((pfh->szAMF[0] != 'A') || (pfh->szAMF[1] != 'M') || (pfh->szAMF[2] != 'F')
00268 || (pfh->version < 10) || (pfh->version > 14) || (!pfh->numtracks)
00269 || (!pfh->numorders) || (pfh->numorders > MAX_PATTERNS)
00270 || (!pfh->numsamples) || (pfh->numsamples > MAX_SAMPLES)
00271 || (pfh->numchannels < 4) || (pfh->numchannels > 32))
00272 return FALSE;
00273 memcpy(m_szNames[0], pfh->title, 32);
00274 dwMemPos = sizeof(AMFFILEHEADER);
00275 m_nType = MOD_TYPE_AMF;
00276 m_nChannels = pfh->numchannels;
00277 m_nSamples = pfh->numsamples;
00278 m_nInstruments = 0;
00279
00280 if (pfh->version >= 11)
00281 {
00282 signed char *panpos = (signed char *)(lpStream + dwMemPos);
00283 UINT nchannels = (pfh->version >= 13) ? 32 : 16;
00284 for (UINT i=0; i<nchannels; i++)
00285 {
00286 int pan = (panpos[i] + 64) * 2;
00287 if (pan < 0) pan = 0;
00288 if (pan > 256) { pan = 128; ChnSettings[i].dwFlags |= CHN_SURROUND; }
00289 ChnSettings[i].nPan = pan;
00290 }
00291 dwMemPos += nchannels;
00292 } else
00293 {
00294 for (UINT i=0; i<16; i++)
00295 {
00296 ChnSettings[i].nPan = (lpStream[dwMemPos+i] & 1) ? 0x30 : 0xD0;
00297 }
00298 dwMemPos += 16;
00299 }
00300
00301 m_nDefaultTempo = 125;
00302 m_nDefaultSpeed = 6;
00303 if (pfh->version >= 13)
00304 {
00305 if (lpStream[dwMemPos] >= 32) m_nDefaultTempo = lpStream[dwMemPos];
00306 if (lpStream[dwMemPos+1] <= 32) m_nDefaultSpeed = lpStream[dwMemPos+1];
00307 dwMemPos += 2;
00308 }
00309
00310 for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
00311 {
00312 Order[iOrd] = 0xFF;
00313 if (iOrd < pfh->numorders)
00314 {
00315 Order[iOrd] = iOrd;
00316 PatternSize[iOrd] = 64;
00317 if (pfh->version >= 14)
00318 {
00319 PatternSize[iOrd] = *(USHORT *)(lpStream+dwMemPos);
00320 dwMemPos += 2;
00321 }
00322 ptracks[iOrd] = (USHORT *)(lpStream+dwMemPos);
00323 dwMemPos += m_nChannels * sizeof(USHORT);
00324 }
00325 }
00326 if (dwMemPos + m_nSamples * (sizeof(AMFSAMPLE)+8) > dwMemLength) return TRUE;
00327
00328 UINT maxsampleseekpos = 0;
00329 for (UINT iIns=0; iIns<m_nSamples; iIns++)
00330 {
00331 MODINSTRUMENT *pins = &Ins[iIns+1];
00332 AMFSAMPLE *psh = (AMFSAMPLE *)(lpStream + dwMemPos);
00333
00334 dwMemPos += sizeof(AMFSAMPLE);
00335 memcpy(m_szNames[iIns+1], psh->samplename, 32);
00336 memcpy(pins->name, psh->filename, 13);
00337 pins->nLength = psh->length;
00338 pins->nC4Speed = psh->c2spd;
00339 pins->nGlobalVol = 64;
00340 pins->nVolume = psh->volume * 4;
00341 if (pfh->version >= 11)
00342 {
00343 pins->nLoopStart = *(DWORD *)(lpStream+dwMemPos);
00344 pins->nLoopEnd = *(DWORD *)(lpStream+dwMemPos+4);
00345 dwMemPos += 8;
00346 } else
00347 {
00348 pins->nLoopStart = *(WORD *)(lpStream+dwMemPos);
00349 pins->nLoopEnd = pins->nLength;
00350 dwMemPos += 2;
00351 }
00352 sampleseekpos[iIns] = 0;
00353 if ((psh->type) && (psh->offset < dwMemLength-1))
00354 {
00355 sampleseekpos[iIns] = psh->offset;
00356 if (psh->offset > maxsampleseekpos) maxsampleseekpos = psh->offset;
00357 if ((pins->nLoopEnd > pins->nLoopStart + 2)
00358 && (pins->nLoopEnd <= pins->nLength)) pins->uFlags |= CHN_LOOP;
00359 }
00360 }
00361
00362 USHORT *pTrackMap = (USHORT *)(lpStream+dwMemPos);
00363 UINT realtrackcnt = 0;
00364 dwMemPos += pfh->numtracks * sizeof(USHORT);
00365 for (UINT iTrkMap=0; iTrkMap<pfh->numtracks; iTrkMap++)
00366 {
00367 if (realtrackcnt < pTrackMap[iTrkMap]) realtrackcnt = pTrackMap[iTrkMap];
00368 }
00369
00370 BYTE **pTrackData = new BYTE *[realtrackcnt];
00371 memset(pTrackData, 0, sizeof(pTrackData));
00372 for (UINT iTrack=0; iTrack<realtrackcnt; iTrack++) if (dwMemPos + 3 <= dwMemLength)
00373 {
00374 UINT nTrkSize = *(USHORT *)(lpStream+dwMemPos);
00375 nTrkSize += (UINT)lpStream[dwMemPos+2] << 16;
00376 if (dwMemPos + nTrkSize * 3 + 3 <= dwMemLength)
00377 {
00378 pTrackData[iTrack] = (BYTE *)(lpStream + dwMemPos);
00379 }
00380 dwMemPos += nTrkSize * 3 + 3;
00381 }
00382
00383 for (UINT iPat=0; iPat<pfh->numorders; iPat++)
00384 {
00385 MODCOMMAND *p = AllocatePattern(PatternSize[iPat], m_nChannels);
00386 if (!p) break;
00387 Patterns[iPat] = p;
00388 for (UINT iChn=0; iChn<m_nChannels; iChn++)
00389 {
00390 UINT nTrack = ptracks[iPat][iChn];
00391 if ((nTrack) && (nTrack <= pfh->numtracks))
00392 {
00393 UINT realtrk = pTrackMap[nTrack-1];
00394 if (realtrk)
00395 {
00396 realtrk--;
00397 if ((realtrk < realtrackcnt) && (pTrackData[realtrk]))
00398 {
00399 AMF_Unpack(p+iChn, pTrackData[realtrk], PatternSize[iPat], m_nChannels);
00400 }
00401 }
00402 }
00403 }
00404 }
00405 delete pTrackData;
00406
00407 for (UINT iSeek=1; iSeek<=maxsampleseekpos; iSeek++)
00408 {
00409 if (dwMemPos >= dwMemLength) break;
00410 for (UINT iSmp=0; iSmp<m_nSamples; iSmp++) if (iSeek == sampleseekpos[iSmp])
00411 {
00412 MODINSTRUMENT *pins = &Ins[iSmp+1];
00413 dwMemPos += ReadSample(pins, RS_PCM8U, (LPCSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
00414 break;
00415 }
00416 }
00417 return TRUE;
00418 }
00419
00420