00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <math.h>
00012 #include "stdafx.h"
00013 #include "sndfile.h"
00014
00015 #define MMCMP_SUPPORT
00016
00017 #ifdef MMCMP_SUPPORT
00018 extern BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength);
00019 #endif
00020
00021
00022 extern void AMSUnpack(const char *psrc, UINT inputlen, char *pdest, UINT dmax, char packcharacter);
00023 extern WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n);
00024 extern int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen);
00025 extern DWORD ITReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n);
00026 extern void ITUnpack8Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215);
00027 extern void ITUnpack16Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215);
00028
00029
00030 #define MAX_PACK_TABLES 3
00031
00032
00033
00034 static const signed char UnpackTable[MAX_PACK_TABLES][16] =
00035
00036 {
00037
00038 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
00039
00040 {0, 1, 2, 4, 8, 16, 32, 64,
00041 -1, -2, -4, -8, -16, -32, -48, -64},
00042
00043 {0, 1, 2, 3, 5, 7, 12, 19,
00044 -1, -2, -3, -5, -7, -12, -19, -31}
00045 };
00046
00047
00049
00050
00051 CSoundFile::CSoundFile()
00052
00053 {
00054 m_nType = MOD_TYPE_NONE;
00055 m_dwSongFlags = 0;
00056 m_nChannels = 0;
00057 m_nMixChannels = 0;
00058 m_nSamples = 0;
00059 m_nInstruments = 0;
00060 m_nPatternNames = 0;
00061 m_lpszPatternNames = NULL;
00062 m_lpszSongComments = NULL;
00063 m_nFreqFactor = m_nTempoFactor = 128;
00064 m_nMasterVolume = 128;
00065 m_nMinPeriod = 0x20;
00066 m_nMaxPeriod = 0x7FFF;
00067 m_nRepeatCount = 0;
00068 memset(Chn, 0, sizeof(Chn));
00069 memset(ChnMix, 0, sizeof(ChnMix));
00070 memset(Ins, 0, sizeof(Ins));
00071 memset(ChnSettings, 0, sizeof(ChnSettings));
00072 memset(Headers, 0, sizeof(Headers));
00073 memset(Order, 0xFF, sizeof(Order));
00074 memset(Patterns, 0, sizeof(Patterns));
00075 memset(m_szNames, 0, sizeof(m_szNames));
00076 memset(m_MixPlugins, 0, sizeof(m_MixPlugins));
00077 }
00078
00079
00080 CSoundFile::~CSoundFile()
00081
00082 {
00083 Destroy();
00084 }
00085
00086
00087 BOOL CSoundFile::Create(LPCBYTE lpStream, DWORD dwMemLength)
00088
00089 {
00090 int i;
00091
00092 m_nType = MOD_TYPE_NONE;
00093 m_dwSongFlags = 0;
00094 m_nChannels = 0;
00095 m_nMixChannels = 0;
00096 m_nSamples = 0;
00097 m_nInstruments = 0;
00098 m_nFreqFactor = m_nTempoFactor = 128;
00099 m_nMasterVolume = 128;
00100 m_nDefaultGlobalVolume = 256;
00101 m_nGlobalVolume = 256;
00102 m_nOldGlbVolSlide = 0;
00103 m_nDefaultSpeed = 6;
00104 m_nDefaultTempo = 125;
00105 m_nPatternDelay = 0;
00106 m_nFrameDelay = 0;
00107 m_nNextRow = 0;
00108 m_nRow = 0;
00109 m_nPattern = 0;
00110 m_nCurrentPattern = 0;
00111 m_nNextPattern = 0;
00112 m_nRestartPos = 0;
00113 m_nMinPeriod = 16;
00114 m_nMaxPeriod = 32767;
00115 m_nSongPreAmp = 0x30;
00116 m_nPatternNames = 0;
00117 m_nMaxOrderPosition = 0;
00118 m_lpszPatternNames = NULL;
00119 m_lpszSongComments = NULL;
00120 memset(Ins, 0, sizeof(Ins));
00121 memset(ChnMix, 0, sizeof(ChnMix));
00122 memset(Chn, 0, sizeof(Chn));
00123 memset(Headers, 0, sizeof(Headers));
00124 memset(Order, 0xFF, sizeof(Order));
00125 memset(Patterns, 0, sizeof(Patterns));
00126 memset(m_szNames, 0, sizeof(m_szNames));
00127 memset(m_MixPlugins, 0, sizeof(m_MixPlugins));
00128 ResetMidiCfg();
00129 for (UINT npt=0; npt<MAX_PATTERNS; npt++) PatternSize[npt] = 64;
00130 for (UINT nch=0; nch<MAX_BASECHANNELS; nch++)
00131 {
00132 ChnSettings[nch].nPan = 128;
00133 ChnSettings[nch].nVolume = 64;
00134 ChnSettings[nch].dwFlags = 0;
00135 ChnSettings[nch].szName[0] = 0;
00136 }
00137 if (lpStream)
00138 {
00139 #ifdef MMCMP_SUPPORT
00140 BOOL bMMCmp = MMCMP_Unpack(&lpStream, &dwMemLength);
00141 #endif
00142 if ((!ReadXM(lpStream, dwMemLength))
00143 && (!ReadIT(lpStream, dwMemLength))
00144 && (!ReadS3M(lpStream, dwMemLength))
00145
00146 #ifndef MODPLUG_BASIC_SUPPORT
00147 && (!ReadSTM(lpStream, dwMemLength))
00148 && (!ReadMed(lpStream, dwMemLength))
00149 && (!ReadMTM(lpStream, dwMemLength))
00150 && (!ReadMDL(lpStream, dwMemLength))
00151 && (!ReadDBM(lpStream, dwMemLength))
00152 && (!Read669(lpStream, dwMemLength))
00153 && (!ReadFAR(lpStream, dwMemLength))
00154 && (!ReadAMS(lpStream, dwMemLength))
00155 && (!ReadOKT(lpStream, dwMemLength))
00156 && (!ReadPTM(lpStream, dwMemLength))
00157 && (!ReadUlt(lpStream, dwMemLength))
00158 && (!ReadDMF(lpStream, dwMemLength))
00159 && (!ReadDSM(lpStream, dwMemLength))
00160 && (!ReadUMX(lpStream, dwMemLength))
00161 && (!ReadAMF(lpStream, dwMemLength))
00162 && (!ReadPSM(lpStream, dwMemLength))
00163 && (!ReadMT2(lpStream, dwMemLength))
00164 #endif
00165 && (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE;
00166 #ifdef MMCMP_SUPPORT
00167 if (bMMCmp)
00168 {
00169 GlobalFreePtr(lpStream);
00170 lpStream = NULL;
00171 }
00172 #endif
00173 }
00174
00175 for (i=0; i<MAX_SAMPLES; i++)
00176 {
00177 LPSTR p = m_szNames[i];
00178 int j = 31;
00179 p[j] = 0;
00180 while ((j>=0) && (p[j]<=' ')) p[j--] = 0;
00181 while (j>=0)
00182 {
00183 if (((BYTE)p[j]) < ' ') p[j] = ' ';
00184 j--;
00185 }
00186 }
00187
00188 for (i=0; i<MAX_BASECHANNELS; i++)
00189 {
00190 if (ChnSettings[i].nVolume > 64) ChnSettings[i].nVolume = 64;
00191 if (ChnSettings[i].nPan > 256) ChnSettings[i].nPan = 128;
00192 Chn[i].nPan = ChnSettings[i].nPan;
00193 Chn[i].nGlobalVol = ChnSettings[i].nVolume;
00194 Chn[i].dwFlags = ChnSettings[i].dwFlags;
00195 Chn[i].nVolume = 256;
00196 Chn[i].nCutOff = 0x7F;
00197 }
00198
00199 MODINSTRUMENT *pins = Ins;
00200
00201 for (i=0; i<MAX_INSTRUMENTS; i++, pins++)
00202 {
00203 if (pins->pSample)
00204 {
00205 if (pins->nLoopEnd > pins->nLength) pins->nLoopEnd = pins->nLength;
00206 if (pins->nLoopStart + 3 >= pins->nLoopEnd)
00207 {
00208 pins->nLoopStart = 0;
00209 pins->nLoopEnd = 0;
00210 }
00211 if (pins->nSustainEnd > pins->nLength) pins->nSustainEnd = pins->nLength;
00212 if (pins->nSustainStart + 3 >= pins->nSustainEnd)
00213 {
00214 pins->nSustainStart = 0;
00215 pins->nSustainEnd = 0;
00216 }
00217 } else
00218 {
00219 pins->nLength = 0;
00220 pins->nLoopStart = 0;
00221 pins->nLoopEnd = 0;
00222 pins->nSustainStart = 0;
00223 pins->nSustainEnd = 0;
00224 }
00225 if (!pins->nLoopEnd) pins->uFlags &= ~CHN_LOOP;
00226 if (!pins->nSustainEnd) pins->uFlags &= ~CHN_SUSTAINLOOP;
00227 if (pins->nGlobalVol > 64) pins->nGlobalVol = 64;
00228 }
00229
00230 while ((m_nInstruments > 0) && (!Headers[m_nInstruments])) m_nInstruments--;
00231
00232 if (m_nSongPreAmp < 0x20) m_nSongPreAmp = 0x20;
00233 if (m_nDefaultTempo < 32) m_nDefaultTempo = 125;
00234 if (!m_nDefaultSpeed) m_nDefaultSpeed = 6;
00235 m_nMusicSpeed = m_nDefaultSpeed;
00236 m_nMusicTempo = m_nDefaultTempo;
00237 m_nGlobalVolume = m_nDefaultGlobalVolume;
00238 m_nNextPattern = 0;
00239 m_nCurrentPattern = 0;
00240 m_nPattern = 0;
00241 m_nBufferCount = 0;
00242 m_nTickCount = m_nMusicSpeed;
00243 m_nNextRow = 0;
00244 m_nRow = 0;
00245 if ((m_nRestartPos >= MAX_ORDERS) || (Order[m_nRestartPos] >= MAX_PATTERNS)) m_nRestartPos = 0;
00246
00247 if (gpMixPluginCreateProc)
00248 {
00249 for (UINT iPlug=0; iPlug<MAX_MIXPLUGINS; iPlug++)
00250 {
00251 if ((m_MixPlugins[iPlug].Info.dwPluginId1)
00252 || (m_MixPlugins[iPlug].Info.dwPluginId2))
00253 {
00254 gpMixPluginCreateProc(&m_MixPlugins[iPlug]);
00255 if (m_MixPlugins[iPlug].pMixPlugin)
00256 {
00257 m_MixPlugins[iPlug].pMixPlugin->RestoreAllParameters();
00258 }
00259 }
00260 }
00261 }
00262 if (m_nType)
00263 {
00264 UINT maxpreamp = 0x10+(m_nChannels*8);
00265 if (maxpreamp > 100) maxpreamp = 100;
00266 if (m_nSongPreAmp > maxpreamp) m_nSongPreAmp = maxpreamp;
00267 return TRUE;
00268 }
00269 return FALSE;
00270 }
00271
00272
00273 BOOL CSoundFile::Destroy()
00274
00275
00276 {
00277 int i;
00278 for (i=0; i<MAX_PATTERNS; i++) if (Patterns[i])
00279 {
00280 FreePattern(Patterns[i]);
00281 Patterns[i] = NULL;
00282 }
00283 m_nPatternNames = 0;
00284 if (m_lpszPatternNames)
00285 {
00286 delete m_lpszPatternNames;
00287 m_lpszPatternNames = NULL;
00288 }
00289 if (m_lpszSongComments)
00290 {
00291 delete m_lpszSongComments;
00292 m_lpszSongComments = NULL;
00293 }
00294 for (i=1; i<MAX_SAMPLES; i++)
00295 {
00296 MODINSTRUMENT *pins = &Ins[i];
00297 if (pins->pSample)
00298 {
00299 FreeSample(pins->pSample);
00300 pins->pSample = NULL;
00301 }
00302 }
00303 for (i=0; i<MAX_INSTRUMENTS; i++)
00304 {
00305 if (Headers[i])
00306 {
00307 delete Headers[i];
00308 Headers[i] = NULL;
00309 }
00310 }
00311 for (i=0; i<MAX_MIXPLUGINS; i++)
00312 {
00313 if ((m_MixPlugins[i].nPluginDataSize) && (m_MixPlugins[i].pPluginData))
00314 {
00315 m_MixPlugins[i].nPluginDataSize = 0;
00316 delete [] (signed char*)m_MixPlugins[i].pPluginData;
00317 m_MixPlugins[i].pPluginData = NULL;
00318 }
00319 m_MixPlugins[i].pMixState = NULL;
00320 if (m_MixPlugins[i].pMixPlugin)
00321 {
00322 m_MixPlugins[i].pMixPlugin->Release();
00323 m_MixPlugins[i].pMixPlugin = NULL;
00324 }
00325 }
00326 m_nType = MOD_TYPE_NONE;
00327 m_nChannels = m_nSamples = m_nInstruments = 0;
00328 return TRUE;
00329 }
00330
00331
00333
00334
00335 MODCOMMAND *CSoundFile::AllocatePattern(UINT rows, UINT nchns)
00336
00337 {
00338 MODCOMMAND *p = new MODCOMMAND[rows*nchns];
00339 if (p) memset(p, 0, rows*nchns*sizeof(MODCOMMAND));
00340 return p;
00341 }
00342
00343
00344 void CSoundFile::FreePattern(LPVOID pat)
00345
00346 {
00347 if (pat) delete [] (signed char*)pat;
00348 }
00349
00350
00351 signed char* CSoundFile::AllocateSample(UINT nbytes)
00352
00353 {
00354 signed char * p = (signed char *)GlobalAllocPtr(GHND, (nbytes+39) & ~7);
00355 if (p) p += 16;
00356 return p;
00357 }
00358
00359
00360 void CSoundFile::FreeSample(LPVOID p)
00361
00362 {
00363 if (p)
00364 {
00365 GlobalFreePtr(((LPSTR)p)-16);
00366 }
00367 }
00368
00369
00371
00372
00373 void CSoundFile::ResetMidiCfg()
00374
00375 {
00376 memset(&m_MidiCfg, 0, sizeof(m_MidiCfg));
00377 lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_START*32], "FF");
00378 lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_STOP*32], "FC");
00379 lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_NOTEON*32], "9c n v");
00380 lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_NOTEOFF*32], "9c n 0");
00381 lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_PROGRAM*32], "Cc p");
00382 lstrcpy(&m_MidiCfg.szMidiSFXExt[0], "F0F000z");
00383 for (int iz=0; iz<16; iz++) wsprintf(&m_MidiCfg.szMidiZXXExt[iz*32], "F0F001%02X", iz*8);
00384 }
00385
00386
00387 UINT CSoundFile::GetNumChannels() const
00388
00389 {
00390 UINT n = 0;
00391 for (UINT i=0; i<m_nChannels; i++) if (ChnSettings[i].nVolume) n++;
00392 return n;
00393 }
00394
00395
00396 UINT CSoundFile::GetSongComments(LPSTR s, UINT len, UINT linesize)
00397
00398 {
00399 LPCSTR p = m_lpszSongComments;
00400 if (!p) return 0;
00401 UINT i = 2, ln=0;
00402 if ((len) && (s)) s[0] = '\x0D';
00403 if ((len > 1) && (s)) s[1] = '\x0A';
00404 while ((*p) && (i+2 < len))
00405 {
00406 BYTE c = (BYTE)*p++;
00407 if ((c == 0x0D) || ((c == ' ') && (ln >= linesize)))
00408 { if (s) { s[i++] = '\x0D'; s[i++] = '\x0A'; } else i+= 2; ln=0; }
00409 else
00410 if (c >= 0x20) { if (s) s[i++] = c; else i++; ln++; }
00411 }
00412 if (s) s[i] = 0;
00413 return i;
00414 }
00415
00416
00417 UINT CSoundFile::GetRawSongComments(LPSTR s, UINT len, UINT linesize)
00418
00419 {
00420 LPCSTR p = m_lpszSongComments;
00421 if (!p) return 0;
00422 UINT i = 0, ln=0;
00423 while ((*p) && (i < len-1))
00424 {
00425 BYTE c = (BYTE)*p++;
00426 if ((c == 0x0D) || (c == 0x0A))
00427 {
00428 if (ln)
00429 {
00430 while (ln < linesize) { if (s) s[i] = ' '; i++; ln++; }
00431 ln = 0;
00432 }
00433 } else
00434 if ((c == ' ') && (!ln))
00435 {
00436 UINT k=0;
00437 while ((p[k]) && (p[k] >= ' ')) k++;
00438 if (k <= linesize)
00439 {
00440 if (s) s[i] = ' ';
00441 i++;
00442 ln++;
00443 }
00444 } else
00445 {
00446 if (s) s[i] = c;
00447 i++;
00448 ln++;
00449 if (ln == linesize) ln = 0;
00450 }
00451 }
00452 if (ln)
00453 {
00454 while ((ln < linesize) && (i < len))
00455 {
00456 if (s) s[i] = ' ';
00457 i++;
00458 ln++;
00459 }
00460 }
00461 if (s) s[i] = 0;
00462 return i;
00463 }
00464
00465
00466 BOOL CSoundFile::SetWaveConfig(UINT nRate,UINT nBits,UINT nChannels,BOOL bMMX)
00467
00468 {
00469 BOOL bReset = FALSE;
00470 DWORD d = gdwSoundSetup & ~SNDMIX_ENABLEMMX;
00471 if (bMMX) d |= SNDMIX_ENABLEMMX;
00472 if ((gdwMixingFreq != nRate) || (gnBitsPerSample != nBits) || (gnChannels != nChannels) || (d != gdwSoundSetup)) bReset = TRUE;
00473 gnChannels = nChannels;
00474 gdwSoundSetup = d;
00475 gdwMixingFreq = nRate;
00476 gnBitsPerSample = nBits;
00477 InitPlayer(bReset);
00478 return TRUE;
00479 }
00480
00481
00482 BOOL CSoundFile::SetResamplingMode(UINT nMode)
00483
00484 {
00485 DWORD d = gdwSoundSetup & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE);
00486 switch(nMode)
00487 {
00488 case SRCMODE_NEAREST: d |= SNDMIX_NORESAMPLING; break;
00489 case SRCMODE_LINEAR: break;
00490 case SRCMODE_SPLINE: d |= SNDMIX_HQRESAMPLER; break;
00491 case SRCMODE_POLYPHASE: d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); break;
00492 default:
00493 return FALSE;
00494 }
00495 gdwSoundSetup = d;
00496 return TRUE;
00497 }
00498
00499
00500 BOOL CSoundFile::SetMasterVolume(UINT nVol, BOOL bAdjustAGC)
00501
00502 {
00503 if (nVol < 1) nVol = 1;
00504 if (nVol > 0x200) nVol = 0x200;
00505 if ((nVol < m_nMasterVolume) && (nVol) && (gdwSoundSetup & SNDMIX_AGC) && (bAdjustAGC))
00506 {
00507 gnAGC = gnAGC * m_nMasterVolume / nVol;
00508 if (gnAGC > AGC_UNITY) gnAGC = AGC_UNITY;
00509 }
00510 m_nMasterVolume = nVol;
00511 return TRUE;
00512 }
00513
00514
00515 void CSoundFile::SetAGC(BOOL b)
00516
00517 {
00518 if (b)
00519 {
00520 if (!(gdwSoundSetup & SNDMIX_AGC))
00521 {
00522 gdwSoundSetup |= SNDMIX_AGC;
00523 gnAGC = AGC_UNITY;
00524 }
00525 } else gdwSoundSetup &= ~SNDMIX_AGC;
00526 }
00527
00528
00529 UINT CSoundFile::GetNumPatterns() const
00530
00531 {
00532 UINT i = 0;
00533 while ((i < MAX_ORDERS) && (Order[i] < 0xFF)) i++;
00534 return i;
00535 }
00536
00537
00538 UINT CSoundFile::GetNumInstruments() const
00539
00540 {
00541 UINT n=0;
00542 for (UINT i=0; i<MAX_INSTRUMENTS; i++) if (Ins[i].pSample) n++;
00543 return n;
00544 }
00545
00546
00547 UINT CSoundFile::GetMaxPosition() const
00548
00549 {
00550 UINT max = 0;
00551 UINT i = 0;
00552
00553 while ((i < MAX_ORDERS) && (Order[i] != 0xFF))
00554 {
00555 if (Order[i] < MAX_PATTERNS) max += PatternSize[Order[i]];
00556 i++;
00557 }
00558 return max;
00559 }
00560
00561
00562 UINT CSoundFile::GetCurrentPos() const
00563
00564 {
00565 UINT pos = 0;
00566
00567 for (UINT i=0; i<m_nCurrentPattern; i++) if (Order[i] < MAX_PATTERNS)
00568 pos += PatternSize[Order[i]];
00569 return pos + m_nRow;
00570 }
00571
00572
00573 void CSoundFile::SetCurrentPos(UINT nPos)
00574
00575 {
00576 UINT i, nPattern;
00577
00578 for (i=0; i<MAX_CHANNELS; i++)
00579 {
00580 Chn[i].nNote = Chn[i].nNewNote = Chn[i].nNewIns = 0;
00581 Chn[i].pInstrument = NULL;
00582 Chn[i].pHeader = NULL;
00583 Chn[i].nPortamentoDest = 0;
00584 Chn[i].nCommand = 0;
00585 Chn[i].nPatternLoopCount = 0;
00586 Chn[i].nPatternLoop = 0;
00587 Chn[i].nFadeOutVol = 0;
00588 Chn[i].dwFlags |= CHN_KEYOFF|CHN_NOTEFADE;
00589 Chn[i].nTremorCount = 0;
00590 }
00591 if (!nPos)
00592 {
00593 for (i=0; i<MAX_CHANNELS; i++)
00594 {
00595 Chn[i].nPeriod = 0;
00596 Chn[i].nPos = Chn[i].nLength = 0;
00597 Chn[i].nLoopStart = 0;
00598 Chn[i].nLoopEnd = 0;
00599 Chn[i].nROfs = Chn[i].nLOfs = 0;
00600 Chn[i].pSample = NULL;
00601 Chn[i].pInstrument = NULL;
00602 Chn[i].pHeader = NULL;
00603 Chn[i].nCutOff = 0x7F;
00604 Chn[i].nResonance = 0;
00605 Chn[i].nLeftVol = Chn[i].nRightVol = 0;
00606 Chn[i].nNewLeftVol = Chn[i].nNewRightVol = 0;
00607 Chn[i].nLeftRamp = Chn[i].nRightRamp = 0;
00608 Chn[i].nVolume = 256;
00609 if (i < MAX_BASECHANNELS)
00610 {
00611 Chn[i].dwFlags = ChnSettings[i].dwFlags;
00612 Chn[i].nPan = ChnSettings[i].nPan;
00613 Chn[i].nGlobalVol = ChnSettings[i].nVolume;
00614 } else
00615 {
00616 Chn[i].dwFlags = 0;
00617 Chn[i].nPan = 128;
00618 Chn[i].nGlobalVol = 64;
00619 }
00620 }
00621 m_nGlobalVolume = m_nDefaultGlobalVolume;
00622 m_nMusicSpeed = m_nDefaultSpeed;
00623 m_nMusicTempo = m_nDefaultTempo;
00624 }
00625 m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE);
00626 for (nPattern = 0; nPattern < MAX_ORDERS; nPattern++)
00627 {
00628 UINT ord = Order[nPattern];
00629 if (ord == 0xFE) continue;
00630 if (ord == 0xFF) break;
00631 if (ord < MAX_PATTERNS)
00632 {
00633 if (nPos < (UINT)PatternSize[ord]) break;
00634 nPos -= PatternSize[ord];
00635 }
00636 }
00637
00638 if ((nPattern >= MAX_ORDERS)
00639 || (Order[nPattern] >= MAX_PATTERNS)
00640 || (nPos >= PatternSize[Order[nPattern]]))
00641 {
00642 nPos = 0;
00643 nPattern = 0;
00644 }
00645 UINT nRow = nPos;
00646 if ((nRow) && (Order[nPattern] < MAX_PATTERNS))
00647 {
00648 MODCOMMAND *p = Patterns[Order[nPattern]];
00649 if ((p) && (nRow < PatternSize[Order[nPattern]]))
00650 {
00651 BOOL bOk = FALSE;
00652 while ((!bOk) && (nRow > 0))
00653 {
00654 UINT n = nRow * m_nChannels;
00655 for (UINT k=0; k<m_nChannels; k++, n++)
00656 {
00657 if (p[n].note)
00658 {
00659 bOk = TRUE;
00660 break;
00661 }
00662 }
00663 if (!bOk) nRow--;
00664 }
00665 }
00666 }
00667 m_nNextPattern = nPattern;
00668 m_nNextRow = nRow;
00669 m_nTickCount = m_nMusicSpeed;
00670 m_nBufferCount = 0;
00671 m_nPatternDelay = 0;
00672 m_nFrameDelay = 0;
00673 }
00674
00675
00676 void CSoundFile::SetCurrentOrder(UINT nPos)
00677
00678 {
00679 while ((nPos < MAX_ORDERS) && (Order[nPos] == 0xFE)) nPos++;
00680 if ((nPos >= MAX_ORDERS) || (Order[nPos] >= MAX_PATTERNS)) return;
00681 for (UINT j=0; j<MAX_CHANNELS; j++)
00682 {
00683 Chn[j].nPeriod = 0;
00684 Chn[j].nNote = 0;
00685 Chn[j].nPortamentoDest = 0;
00686 Chn[j].nCommand = 0;
00687 Chn[j].nPatternLoopCount = 0;
00688 Chn[j].nPatternLoop = 0;
00689 Chn[j].nTremorCount = 0;
00690 }
00691 if (!nPos)
00692 {
00693 SetCurrentPos(0);
00694 } else
00695 {
00696 m_nNextPattern = nPos;
00697 m_nRow = m_nNextRow = 0;
00698 m_nPattern = 0;
00699 m_nTickCount = m_nMusicSpeed;
00700 m_nBufferCount = 0;
00701 m_nTotalCount = 0;
00702 m_nPatternDelay = 0;
00703 m_nFrameDelay = 0;
00704 }
00705 m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE);
00706 }
00707
00708
00709 void CSoundFile::ResetChannels()
00710
00711 {
00712 m_dwSongFlags &= ~(SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE);
00713 m_nBufferCount = 0;
00714 for (UINT i=0; i<MAX_CHANNELS; i++)
00715 {
00716 Chn[i].nROfs = Chn[i].nLOfs = 0;
00717 }
00718 }
00719
00720
00721 void CSoundFile::LoopPattern(int nPat, int nRow)
00722
00723 {
00724 if ((nPat < 0) || (nPat >= MAX_PATTERNS) || (!Patterns[nPat]))
00725 {
00726 m_dwSongFlags &= ~SONG_PATTERNLOOP;
00727 } else
00728 {
00729 if ((nRow < 0) || (nRow >= PatternSize[nPat])) nRow = 0;
00730 m_nPattern = nPat;
00731 m_nRow = m_nNextRow = nRow;
00732 m_nTickCount = m_nMusicSpeed;
00733 m_nPatternDelay = 0;
00734 m_nFrameDelay = 0;
00735 m_nBufferCount = 0;
00736 m_dwSongFlags |= SONG_PATTERNLOOP;
00737 }
00738 }
00739
00740
00741 UINT CSoundFile::GetBestSaveFormat() const
00742
00743 {
00744 if ((!m_nSamples) || (!m_nChannels)) return MOD_TYPE_NONE;
00745 if (!m_nType) return MOD_TYPE_NONE;
00746 if (m_nType & (MOD_TYPE_MOD|MOD_TYPE_OKT))
00747 return MOD_TYPE_MOD;
00748 if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_STM|MOD_TYPE_ULT|MOD_TYPE_FAR|MOD_TYPE_PTM))
00749 return MOD_TYPE_S3M;
00750 if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MED|MOD_TYPE_MTM|MOD_TYPE_MT2))
00751 return MOD_TYPE_XM;
00752 return MOD_TYPE_IT;
00753 }
00754
00755
00756 UINT CSoundFile::GetSaveFormats() const
00757
00758 {
00759 UINT n = 0;
00760 if ((!m_nSamples) || (!m_nChannels) || (m_nType == MOD_TYPE_NONE)) return 0;
00761 switch(m_nType)
00762 {
00763 case MOD_TYPE_MOD: n = MOD_TYPE_MOD;
00764 case MOD_TYPE_S3M: n = MOD_TYPE_S3M;
00765 }
00766 n |= MOD_TYPE_XM | MOD_TYPE_IT;
00767 if (!m_nInstruments)
00768 {
00769 if (m_nSamples < 32) n |= MOD_TYPE_MOD;
00770 n |= MOD_TYPE_S3M;
00771 }
00772 return n;
00773 }
00774
00775
00776 UINT CSoundFile::GetSampleName(UINT nSample,LPSTR s) const
00777
00778 {
00779 char sztmp[40] = "";
00780 memcpy(sztmp, m_szNames[nSample],32);
00781 sztmp[31] = 0;
00782 if (s) strcpy(s, sztmp);
00783 return strlen(sztmp);
00784 }
00785
00786
00787 UINT CSoundFile::GetInstrumentName(UINT nInstr,LPSTR s) const
00788
00789 {
00790 char sztmp[40] = "";
00791 if ((nInstr >= MAX_INSTRUMENTS) || (!Headers[nInstr]))
00792 {
00793 if (s) *s = 0;
00794 return 0;
00795 }
00796 INSTRUMENTHEADER *penv = Headers[nInstr];
00797 memcpy(sztmp, penv->name, 32);
00798 sztmp[31] = 0;
00799 if (s) strcpy(s, sztmp);
00800 return strlen(sztmp);
00801 }
00802
00803
00804 #ifndef NO_PACKING
00805 UINT CSoundFile::PackSample(int &sample, int next)
00806
00807 {
00808 UINT i = 0;
00809 int delta = next - sample;
00810 if (delta >= 0)
00811 {
00812 for (i=0; i<7; i++) if (delta <= (int)CompressionTable[i+1]) break;
00813 } else
00814 {
00815 for (i=8; i<15; i++) if (delta >= (int)CompressionTable[i+1]) break;
00816 }
00817 sample += (int)CompressionTable[i];
00818 return i;
00819 }
00820
00821
00822 BOOL CSoundFile::CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result)
00823
00824 {
00825 int pos, old, oldpos, besttable = 0;
00826 DWORD dwErr, dwTotal, dwResult;
00827 int i,j;
00828
00829 if (result) *result = 0;
00830 if ((!pSample) || (nLen < 1024)) return FALSE;
00831
00832 dwResult = 0;
00833 for (j=1; j<MAX_PACK_TABLES; j++)
00834 {
00835 memcpy(CompressionTable, UnpackTable[j], 16);
00836 dwErr = 0;
00837 dwTotal = 1;
00838 old = pos = oldpos = 0;
00839 for (i=0; i<(int)nLen; i++)
00840 {
00841 int s = (int)pSample[i];
00842 PackSample(pos, s);
00843 dwErr += abs(pos - oldpos);
00844 dwTotal += abs(s - old);
00845 old = s;
00846 oldpos = pos;
00847 }
00848 dwErr = _muldiv(dwErr, 100, dwTotal);
00849 if (dwErr >= dwResult)
00850 {
00851 dwResult = dwErr;
00852 besttable = j;
00853 }
00854 }
00855 memcpy(CompressionTable, UnpackTable[besttable], 16);
00856 if (result)
00857 {
00858 if (dwResult > 100) *result = 100; else *result = (BYTE)dwResult;
00859 }
00860 return (dwResult >= nPacking) ? TRUE : FALSE;
00861 }
00862 #endif // NO_PACKING
00863
00864 #ifndef MODPLUG_NO_FILESAVE
00865
00866 UINT CSoundFile::WriteSample(FILE *f, MODINSTRUMENT *pins, UINT nFlags, UINT nMaxLen)
00867
00868 {
00869 UINT len = 0, bufcount;
00870 signed char buffer[4096];
00871 signed char *pSample = (signed char *)pins->pSample;
00872 UINT nLen = pins->nLength;
00873
00874 if ((nMaxLen) && (nLen > nMaxLen)) nLen = nMaxLen;
00875 if ((!pSample) || (f == NULL) || (!nLen)) return 0;
00876 switch(nFlags)
00877 {
00878 #ifndef NO_PACKING
00879
00880 case RS_ADPCM4:
00881 {
00882 int pos;
00883 len = (nLen + 1) / 2;
00884 fwrite(CompressionTable, 16, 1, f);
00885 bufcount = 0;
00886 pos = 0;
00887 for (UINT j=0; j<len; j++)
00888 {
00889 BYTE b;
00890
00891 b = PackSample(pos, (int)pSample[j*2]);
00892
00893 b |= PackSample(pos, (int)pSample[j*2+1]) << 4;
00894 buffer[bufcount++] = (signed char)b;
00895 if (bufcount >= sizeof(buffer))
00896 {
00897 fwrite(buffer, 1, bufcount, f);
00898 bufcount = 0;
00899 }
00900 }
00901 if (bufcount) fwrite(buffer, 1, bufcount, f);
00902 len += 16;
00903 }
00904 break;
00905 #endif // NO_PACKING
00906
00907
00908 case RS_PCM16U:
00909 case RS_PCM16D:
00910 case RS_PCM16S:
00911 {
00912 short int *p = (short int *)pSample;
00913 int s_old = 0, s_ofs;
00914 len = nLen * 2;
00915 bufcount = 0;
00916 s_ofs = (nFlags == RS_PCM16U) ? 0x8000 : 0;
00917 for (UINT j=0; j<nLen; j++)
00918 {
00919 int s_new = *p;
00920 p++;
00921 if (pins->uFlags & CHN_STEREO)
00922 {
00923 s_new = (s_new + (*p) + 1) >> 1;
00924 p++;
00925 }
00926 if (nFlags == RS_PCM16D)
00927 {
00928 *((short *)(&buffer[bufcount])) = (short)(s_new - s_old);
00929 s_old = s_new;
00930 } else
00931 {
00932 *((short *)(&buffer[bufcount])) = (short)(s_new + s_ofs);
00933 }
00934 bufcount += 2;
00935 if (bufcount >= sizeof(buffer) - 1)
00936 {
00937 fwrite(buffer, 1, bufcount, f);
00938 bufcount = 0;
00939 }
00940 }
00941 if (bufcount) fwrite(buffer, 1, bufcount, f);
00942 }
00943 break;
00944
00945
00946
00947 case RS_STPCM8S:
00948 case RS_STPCM8U:
00949 case RS_STPCM8D:
00950 {
00951 int s_ofs = (nFlags == RS_STPCM8U) ? 0x80 : 0;
00952 for (UINT iCh=0; iCh<2; iCh++)
00953 {
00954 signed char *p = pSample + iCh;
00955 int s_old = 0;
00956
00957 bufcount = 0;
00958 for (UINT j=0; j<nLen; j++)
00959 {
00960 int s_new = *p;
00961 p += 2;
00962 if (nFlags == RS_STPCM8D)
00963 {
00964 buffer[bufcount++] = (signed char)(s_new - s_old);
00965 s_old = s_new;
00966 } else
00967 {
00968 buffer[bufcount++] = (signed char)(s_new + s_ofs);
00969 }
00970 if (bufcount >= sizeof(buffer))
00971 {
00972 fwrite(buffer, 1, bufcount, f);
00973 bufcount = 0;
00974 }
00975 }
00976 if (bufcount) fwrite(buffer, 1, bufcount, f);
00977 }
00978 }
00979 len = nLen * 2;
00980 break;
00981
00982
00983 case RS_STPCM16S:
00984 case RS_STPCM16U:
00985 case RS_STPCM16D:
00986 {
00987 int s_ofs = (nFlags == RS_STPCM16U) ? 0x8000 : 0;
00988 for (UINT iCh=0; iCh<2; iCh++)
00989 {
00990 signed short *p = ((signed short *)pSample) + iCh;
00991 int s_old = 0;
00992
00993 bufcount = 0;
00994 for (UINT j=0; j<nLen; j++)
00995 {
00996 int s_new = *p;
00997 p += 2;
00998 if (nFlags == RS_STPCM16D)
00999 {
01000 *((short *)(&buffer[bufcount])) = (short)(s_new - s_old);
01001 s_old = s_new;
01002 } else
01003 {
01004 *((short *)(&buffer[bufcount])) = (short)(s_new + s_ofs);
01005 }
01006 bufcount += 2;
01007 if (bufcount >= sizeof(buffer))
01008 {
01009 fwrite(buffer, 1, bufcount, f);
01010 bufcount = 0;
01011 }
01012 }
01013 if (bufcount) fwrite(buffer, 1, bufcount, f);
01014 }
01015 }
01016 len = nLen*4;
01017 break;
01018
01019
01020 case RS_STIPCM8S:
01021 case RS_STIPCM16S:
01022 len = nLen * 2;
01023 if (nFlags == RS_STIPCM16S) len *= 2;
01024 fwrite(pSample, 1, len, f);
01025 break;
01026
01027
01028 default:
01029 len = nLen;
01030 bufcount = 0;
01031 {
01032 signed char *p = pSample;
01033 int sinc = (pins->uFlags & CHN_16BIT) ? 2 : 1;
01034 int s_old = 0, s_ofs = (nFlags == RS_PCM8U) ? 0x80 : 0;
01035 if (pins->uFlags & CHN_16BIT) p++;
01036 for (UINT j=0; j<len; j++)
01037 {
01038 int s_new = (signed char)(*p);
01039 p += sinc;
01040 if (pins->uFlags & CHN_STEREO)
01041 {
01042 s_new = (s_new + ((int)*p) + 1) >> 1;
01043 p += sinc;
01044 }
01045 if (nFlags == RS_PCM8D)
01046 {
01047 buffer[bufcount++] = (signed char)(s_new - s_old);
01048 s_old = s_new;
01049 } else
01050 {
01051 buffer[bufcount++] = (signed char)(s_new + s_ofs);
01052 }
01053 if (bufcount >= sizeof(buffer))
01054 {
01055 fwrite(buffer, 1, bufcount, f);
01056 bufcount = 0;
01057 }
01058 }
01059 if (bufcount) fwrite(buffer, 1, bufcount, f);
01060 }
01061 }
01062 return len;
01063 }
01064
01065 #endif // MODPLUG_NO_FILESAVE
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078 UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength)
01079
01080 {
01081 UINT len = 0, mem = pIns->nLength+6;
01082
01083 if ((!pIns) || (pIns->nLength < 4) || (!lpMemFile)) return 0;
01084 if (pIns->nLength > MAX_SAMPLE_LENGTH) pIns->nLength = MAX_SAMPLE_LENGTH;
01085 pIns->uFlags &= ~(CHN_16BIT|CHN_STEREO);
01086 if (nFlags & RSF_16BIT)
01087 {
01088 mem *= 2;
01089 pIns->uFlags |= CHN_16BIT;
01090 }
01091 if (nFlags & RSF_STEREO)
01092 {
01093 mem *= 2;
01094 pIns->uFlags |= CHN_STEREO;
01095 }
01096 if ((pIns->pSample = AllocateSample(mem)) == NULL)
01097 {
01098 pIns->nLength = 0;
01099 return 0;
01100 }
01101 switch(nFlags)
01102 {
01103
01104 case RS_PCM8U:
01105 {
01106 len = pIns->nLength;
01107 if (len > dwMemLength) len = pIns->nLength = dwMemLength;
01108 signed char *pSample = pIns->pSample;
01109 for (UINT j=0; j<len; j++) pSample[j] = (signed char)(lpMemFile[j] - 0x80);
01110 }
01111 break;
01112
01113
01114 case RS_PCM8D:
01115 {
01116 len = pIns->nLength;
01117 if (len > dwMemLength) break;
01118 signed char *pSample = pIns->pSample;
01119 const signed char *p = (const signed char *)lpMemFile;
01120 int delta = 0;
01121
01122 for (UINT j=0; j<len; j++)
01123 {
01124 delta += p[j];
01125 *pSample++ = (signed char)delta;
01126 }
01127 }
01128 break;
01129
01130
01131 case RS_ADPCM4:
01132 {
01133 len = (pIns->nLength + 1) / 2;
01134 if (len > dwMemLength - 16) break;
01135 memcpy(CompressionTable, lpMemFile, 16);
01136 lpMemFile += 16;
01137 signed char *pSample = pIns->pSample;
01138 signed char delta = 0;
01139 for (UINT j=0; j<len; j++)
01140 {
01141 BYTE b0 = (BYTE)lpMemFile[j];
01142 BYTE b1 = (BYTE)(lpMemFile[j] >> 4);
01143 delta = (signed char)GetDeltaValue((int)delta, b0);
01144 pSample[0] = delta;
01145 delta = (signed char)GetDeltaValue((int)delta, b1);
01146 pSample[1] = delta;
01147 pSample += 2;
01148 }
01149 len += 16;
01150 }
01151 break;
01152
01153
01154 case RS_PCM16D:
01155 {
01156 len = pIns->nLength * 2;
01157 if (len > dwMemLength) break;
01158 short int *pSample = (short int *)pIns->pSample;
01159 short int *p = (short int *)lpMemFile;
01160 int delta16 = 0;
01161 for (UINT j=0; j<len; j+=2)
01162 {
01163 delta16 += bswapLE16(*p++);
01164 *pSample++ = (short int)delta16;
01165 }
01166 }
01167 break;
01168
01169
01170 case RS_PCM16S:
01171 {
01172 len = pIns->nLength * 2;
01173 if (len <= dwMemLength) memcpy(pIns->pSample, lpMemFile, len);
01174 short int *pSample = (short int *)pIns->pSample;
01175 for (UINT j=0; j<len; j+=2)
01176 {
01177 *pSample++ = bswapLE16(*pSample);
01178 }
01179 }
01180 break;
01181
01182
01183 case RS_PCM16M:
01184 len = pIns->nLength * 2;
01185 if (len > dwMemLength) len = dwMemLength & ~1;
01186 if (len > 1)
01187 {
01188 signed char *pSample = (signed char *)pIns->pSample;
01189 signed char *pSrc = (signed char *)lpMemFile;
01190 for (UINT j=0; j<len; j+=2)
01191 {
01192
01193
01194 *((unsigned short *)(pSample+j)) = bswapBE16(*((unsigned short *)(pSrc+j)));
01195 }
01196 }
01197 break;
01198
01199
01200 case RS_PCM16U:
01201 {
01202 len = pIns->nLength * 2;
01203 if (len > dwMemLength) break;
01204 short int *pSample = (short int *)pIns->pSample;
01205 short int *pSrc = (short int *)lpMemFile;
01206 for (UINT j=0; j<len; j+=2) *pSample++ = bswapLE16(*(pSrc++)) - 0x8000;
01207 }
01208 break;
01209
01210
01211 case RS_STPCM16M:
01212 len = pIns->nLength * 2;
01213 if (len*2 <= dwMemLength)
01214 {
01215 signed char *pSample = (signed char *)pIns->pSample;
01216 signed char *pSrc = (signed char *)lpMemFile;
01217 for (UINT j=0; j<len; j+=2)
01218 {
01219
01220
01221
01222
01223 *((unsigned short *)(pSample+j*2)) = bswapBE16(*((unsigned short *)(pSrc+j)));
01224 *((unsigned short *)(pSample+j*2+2)) = bswapBE16(*((unsigned short *)(pSrc+j+len)));
01225 }
01226 len *= 2;
01227 }
01228 break;
01229
01230
01231 case RS_STPCM8S:
01232 case RS_STPCM8U:
01233 case RS_STPCM8D:
01234 {
01235 int iadd_l = 0, iadd_r = 0;
01236 if (nFlags == RS_STPCM8U) { iadd_l = iadd_r = -128; }
01237 len = pIns->nLength;
01238 signed char *psrc = (signed char *)lpMemFile;
01239 signed char *pSample = (signed char *)pIns->pSample;
01240 if (len*2 > dwMemLength) break;
01241 for (UINT j=0; j<len; j++)
01242 {
01243 pSample[j*2] = (signed char)(psrc[0] + iadd_l);
01244 pSample[j*2+1] = (signed char)(psrc[len] + iadd_r);
01245 psrc++;
01246 if (nFlags == RS_STPCM8D)
01247 {
01248 iadd_l = pSample[j*2];
01249 iadd_r = pSample[j*2+1];
01250 }
01251 }
01252 len *= 2;
01253 }
01254 break;
01255
01256
01257 case RS_STPCM16S:
01258 case RS_STPCM16U:
01259 case RS_STPCM16D:
01260 {
01261 int iadd_l = 0, iadd_r = 0;
01262 if (nFlags == RS_STPCM16U) { iadd_l = iadd_r = -0x8000; }
01263 len = pIns->nLength;
01264 short int *psrc = (short int *)lpMemFile;
01265 short int *pSample = (short int *)pIns->pSample;
01266 if (len*4 > dwMemLength) break;
01267 for (UINT j=0; j<len; j++)
01268 {
01269 pSample[j*2] = (short int) (bswapLE16(psrc[0]) + iadd_l);
01270 pSample[j*2+1] = (short int) (bswapLE16(psrc[len]) + iadd_r);
01271 psrc++;
01272 if (nFlags == RS_STPCM16D)
01273 {
01274 iadd_l = pSample[j*2];
01275 iadd_r = pSample[j*2+1];
01276 }
01277 }
01278 len *= 4;
01279 }
01280 break;
01281
01282
01283 case RS_IT2148:
01284 case RS_IT21416:
01285 case RS_IT2158:
01286 case RS_IT21516:
01287 len = dwMemLength;
01288 if (len < 4) break;
01289 if ((nFlags == RS_IT2148) || (nFlags == RS_IT2158))
01290 ITUnpack8Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT2158));
01291 else
01292 ITUnpack16Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT21516));
01293 break;
01294
01295 #ifndef MODPLUG_BASIC_SUPPORT
01296 #ifndef FASTSOUNDLIB
01297
01298 case RS_STIPCM8S:
01299 case RS_STIPCM8U:
01300 {
01301 int iadd = 0;
01302 if (nFlags == RS_STIPCM8U) { iadd = -0x80; }
01303 len = pIns->nLength;
01304 if (len*2 > dwMemLength) len = dwMemLength >> 1;
01305 LPBYTE psrc = (LPBYTE)lpMemFile;
01306 LPBYTE pSample = (LPBYTE)pIns->pSample;
01307 for (UINT j=0; j<len; j++)
01308 {
01309 pSample[j*2] = (signed char)(psrc[0] + iadd);
01310 pSample[j*2+1] = (signed char)(psrc[1] + iadd);
01311 psrc+=2;
01312 }
01313 len *= 2;
01314 }
01315 break;
01316
01317
01318 case RS_STIPCM16S:
01319 case RS_STIPCM16U:
01320 {
01321 int iadd = 0;
01322 if (nFlags == RS_STIPCM16U) iadd = -32768;
01323 len = pIns->nLength;
01324 if (len*4 > dwMemLength) len = dwMemLength >> 2;
01325 short int *psrc = (short int *)lpMemFile;
01326 short int *pSample = (short int *)pIns->pSample;
01327 for (UINT j=0; j<len; j++)
01328 {
01329 pSample[j*2] = (short int)(bswapLE16(psrc[0]) + iadd);
01330 pSample[j*2+1] = (short int)(bswapLE16(psrc[1]) + iadd);
01331 psrc += 2;
01332 }
01333 len *= 4;
01334 }
01335 break;
01336
01337
01338 case RS_AMS8:
01339 case RS_AMS16:
01340 len = 9;
01341 if (dwMemLength > 9)
01342 {
01343 const char *psrc = lpMemFile;
01344 char packcharacter = lpMemFile[8], *pdest = (char *)pIns->pSample;
01345 len += bswapLE32(*((LPDWORD)(lpMemFile+4)));
01346 if (len > dwMemLength) len = dwMemLength;
01347 UINT dmax = pIns->nLength;
01348 if (pIns->uFlags & CHN_16BIT) dmax <<= 1;
01349 AMSUnpack(psrc+9, len-9, pdest, dmax, packcharacter);
01350 }
01351 break;
01352
01353
01354 case RS_PTM8DTO16:
01355 {
01356 len = pIns->nLength * 2;
01357 if (len > dwMemLength) break;
01358 signed char *pSample = (signed char *)pIns->pSample;
01359 signed char delta8 = 0;
01360 for (UINT j=0; j<len; j++)
01361 {
01362 delta8 += lpMemFile[j];
01363 *pSample++ = delta8;
01364 }
01365 WORD *pSampleW = (WORD *)pIns->pSample;
01366 for (UINT j=0; j<len; j+=2)
01367 {
01368 *pSampleW++ = bswapLE16(*pSampleW);
01369 }
01370 }
01371 break;
01372
01373
01374 case RS_MDL8:
01375 case RS_MDL16:
01376 len = dwMemLength;
01377 if (len >= 4)
01378 {
01379 LPBYTE pSample = (LPBYTE)pIns->pSample;
01380 LPBYTE ibuf = (LPBYTE)lpMemFile;
01381 DWORD bitbuf = bswapLE32(*((DWORD *)ibuf));
01382 UINT bitnum = 32;
01383 BYTE dlt = 0, lowbyte = 0;
01384 ibuf += 4;
01385 for (UINT j=0; j<pIns->nLength; j++)
01386 {
01387 BYTE hibyte;
01388 BYTE sign;
01389 if (nFlags == RS_MDL16) lowbyte = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 8);
01390 sign = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 1);
01391 if (MDLReadBits(bitbuf, bitnum, ibuf, 1))
01392 {
01393 hibyte = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 3);
01394 } else
01395 {
01396 hibyte = 8;
01397 while (!MDLReadBits(bitbuf, bitnum, ibuf, 1)) hibyte += 0x10;
01398 hibyte += MDLReadBits(bitbuf, bitnum, ibuf, 4);
01399 }
01400 if (sign) hibyte = ~hibyte;
01401 dlt += hibyte;
01402 if (nFlags != RS_MDL16)
01403 pSample[j] = dlt;
01404 else
01405 {
01406 pSample[j<<1] = lowbyte;
01407 pSample[(j<<1)+1] = dlt;
01408 }
01409 }
01410 }
01411 break;
01412
01413 case RS_DMF8:
01414 case RS_DMF16:
01415 len = dwMemLength;
01416 if (len >= 4)
01417 {
01418 UINT maxlen = pIns->nLength;
01419 if (pIns->uFlags & CHN_16BIT) maxlen <<= 1;
01420 LPBYTE ibuf = (LPBYTE)lpMemFile, ibufmax = (LPBYTE)(lpMemFile+dwMemLength);
01421 len = DMFUnpack((LPBYTE)pIns->pSample, ibuf, ibufmax, maxlen);
01422 }
01423 break;
01424
01425 #ifdef MODPLUG_TRACKER
01426
01427 case RS_PCM24S:
01428 case RS_PCM32S:
01429 len = pIns->nLength * 3;
01430 if (nFlags == RS_PCM32S) len += pIns->nLength;
01431 if (len > dwMemLength) break;
01432 if (len > 4*8)
01433 {
01434 UINT slsize = (nFlags == RS_PCM32S) ? 4 : 3;
01435 LPBYTE pSrc = (LPBYTE)lpMemFile;
01436 LONG max = 255;
01437 if (nFlags == RS_PCM32S) pSrc++;
01438 for (UINT j=0; j<len; j+=slsize)
01439 {
01440 LONG l = ((((pSrc[j+2] << 8) + pSrc[j+1]) << 8) + pSrc[j]) << 8;
01441 l /= 256;
01442 if (l > max) max = l;
01443 if (-l > max) max = -l;
01444 }
01445 max = (max / 128) + 1;
01446 signed short *pDest = (signed short *)pIns->pSample;
01447 for (UINT k=0; k<len; k+=slsize)
01448 {
01449 LONG l = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8;
01450 *pDest++ = (signed short)(l / max);
01451 }
01452 }
01453 break;
01454
01455
01456 case RS_STIPCM24S:
01457 case RS_STIPCM32S:
01458 len = pIns->nLength * 6;
01459 if (nFlags == RS_STIPCM32S) len += pIns->nLength * 2;
01460 if (len > dwMemLength) break;
01461 if (len > 8*8)
01462 {
01463 UINT slsize = (nFlags == RS_STIPCM32S) ? 4 : 3;
01464 LPBYTE pSrc = (LPBYTE)lpMemFile;
01465 LONG max = 255;
01466 if (nFlags == RS_STIPCM32S) pSrc++;
01467 for (UINT j=0; j<len; j+=slsize)
01468 {
01469 LONG l = ((((pSrc[j+2] << 8) + pSrc[j+1]) << 8) + pSrc[j]) << 8;
01470 l /= 256;
01471 if (l > max) max = l;
01472 if (-l > max) max = -l;
01473 }
01474 max = (max / 128) + 1;
01475 signed short *pDest = (signed short *)pIns->pSample;
01476 for (UINT k=0; k<len; k+=slsize)
01477 {
01478 LONG lr = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8;
01479 k += slsize;
01480 LONG ll = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8;
01481 pDest[0] = (signed short)ll;
01482 pDest[1] = (signed short)lr;
01483 pDest += 2;
01484 }
01485 }
01486 break;
01487
01488
01489 case RS_STIPCM16M:
01490 {
01491 len = pIns->nLength;
01492 if (len*4 > dwMemLength) len = dwMemLength >> 2;
01493 LPCBYTE psrc = (LPCBYTE)lpMemFile;
01494 short int *pSample = (short int *)pIns->pSample;
01495 for (UINT j=0; j<len; j++)
01496 {
01497 pSample[j*2] = (signed short)(((UINT)psrc[0] << 8) | (psrc[1]));
01498 pSample[j*2+1] = (signed short)(((UINT)psrc[2] << 8) | (psrc[3]));
01499 psrc += 4;
01500 }
01501 len *= 4;
01502 }
01503 break;
01504
01505 #endif // MODPLUG_TRACKER
01506 #endif // !FASTSOUNDLIB
01507 #endif // !MODPLUG_BASIC_SUPPORT
01508
01509
01510 default:
01511 len = pIns->nLength;
01512 if (len > dwMemLength) len = pIns->nLength = dwMemLength;
01513 memcpy(pIns->pSample, lpMemFile, len);
01514 }
01515 if (len > dwMemLength)
01516 {
01517 if (pIns->pSample)
01518 {
01519 pIns->nLength = 0;
01520 FreeSample(pIns->pSample);
01521 pIns->pSample = NULL;
01522 }
01523 return 0;
01524 }
01525 AdjustSampleLoop(pIns);
01526 return len;
01527 }
01528
01529
01530 void CSoundFile::AdjustSampleLoop(MODINSTRUMENT *pIns)
01531
01532 {
01533 if (!pIns->pSample) return;
01534 if (pIns->nLoopEnd > pIns->nLength) pIns->nLoopEnd = pIns->nLength;
01535 if (pIns->nLoopStart+2 >= pIns->nLoopEnd)
01536 {
01537 pIns->nLoopStart = pIns->nLoopEnd = 0;
01538 pIns->uFlags &= ~CHN_LOOP;
01539 }
01540 UINT len = pIns->nLength;
01541 if (pIns->uFlags & CHN_16BIT)
01542 {
01543 short int *pSample = (short int *)pIns->pSample;
01544
01545 if (pIns->uFlags & CHN_STEREO)
01546 {
01547 pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2];
01548 pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1];
01549 } else
01550 {
01551 pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1];
01552 }
01553 if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
01554 {
01555
01556 if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & MOD_TYPE_S3M))
01557 {
01558 pSample[pIns->nLoopEnd] = pSample[pIns->nLoopStart];
01559 pSample[pIns->nLoopEnd+1] = pSample[pIns->nLoopStart+1];
01560 pSample[pIns->nLoopEnd+2] = pSample[pIns->nLoopStart+2];
01561 pSample[pIns->nLoopEnd+3] = pSample[pIns->nLoopStart+3];
01562 pSample[pIns->nLoopEnd+4] = pSample[pIns->nLoopStart+4];
01563 }
01564 }
01565 } else
01566 {
01567 signed char *pSample = pIns->pSample;
01568 #ifndef FASTSOUNDLIB
01569
01570 if ((pIns->nLength > 0x100) && (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M))
01571 && (!(pIns->uFlags & CHN_STEREO)))
01572 {
01573 int smpend = pSample[pIns->nLength-1], smpfix = 0, kscan;
01574 for (kscan=pIns->nLength-1; kscan>0; kscan--)
01575 {
01576 smpfix = pSample[kscan-1];
01577 if (smpfix != smpend) break;
01578 }
01579 int delta = smpfix - smpend;
01580 if (((!(pIns->uFlags & CHN_LOOP)) || (kscan > (int)pIns->nLoopEnd))
01581 && ((delta < -8) || (delta > 8)))
01582 {
01583 while (kscan<(int)pIns->nLength)
01584 {
01585 if (!(kscan & 7))
01586 {
01587 if (smpfix > 0) smpfix--;
01588 if (smpfix < 0) smpfix++;
01589 }
01590 pSample[kscan] = (signed char)smpfix;
01591 kscan++;
01592 }
01593 }
01594 }
01595 #endif
01596
01597 if (pIns->uFlags & CHN_STEREO)
01598 {
01599 pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2];
01600 pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1];
01601 } else
01602 {
01603 pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1];
01604 }
01605 if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
01606 {
01607 if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M)))
01608 {
01609 pSample[pIns->nLoopEnd] = pSample[pIns->nLoopStart];
01610 pSample[pIns->nLoopEnd+1] = pSample[pIns->nLoopStart+1];
01611 pSample[pIns->nLoopEnd+2] = pSample[pIns->nLoopStart+2];
01612 pSample[pIns->nLoopEnd+3] = pSample[pIns->nLoopStart+3];
01613 pSample[pIns->nLoopEnd+4] = pSample[pIns->nLoopStart+4];
01614 }
01615 }
01616 }
01617 }
01618
01619
01621
01622
01623
01624 DWORD CSoundFile::TransposeToFrequency(int transp, int ftune)
01625
01626 {
01627
01628 return (DWORD)(8363*pow(2, (transp*128+ftune)/(1536)));
01629
01630 #ifdef WIN32
01631 const float _fbase = 8363;
01632 const float _factor = 1.0f/(12.0f*128.0f);
01633 int result;
01634 DWORD freq;
01635
01636 transp = (transp << 7) + ftune;
01637 _asm {
01638 fild transp
01639 fld _factor
01640 fmulp st(1), st(0)
01641 fist result
01642 fisub result
01643 f2xm1
01644 fild result
01645 fld _fbase
01646 fscale
01647 fstp st(1)
01648 fmul st(1), st(0)
01649 faddp st(1), st(0)
01650 fistp freq
01651 }
01652 UINT derr = freq % 11025;
01653 if (derr <= 8) freq -= derr;
01654 if (derr >= 11015) freq += 11025-derr;
01655 derr = freq % 1000;
01656 if (derr <= 5) freq -= derr;
01657 if (derr >= 995) freq += 1000-derr;
01658 return freq;
01659 #endif
01660 }
01661
01662
01663
01664 int CSoundFile::FrequencyToTranspose(DWORD freq)
01665
01666 {
01667
01668 return int(1536*(log(freq/8363)/log(2)));
01669
01670 #ifdef WIN32
01671 const float _f1_8363 = 1.0f / 8363.0f;
01672 const float _factor = 128 * 12;
01673 LONG result;
01674
01675 if (!freq) return 0;
01676 _asm {
01677 fld _factor
01678 fild freq
01679 fld _f1_8363
01680 fmulp st(1), st(0)
01681 fyl2x
01682 fistp result
01683 }
01684 return result;
01685 #endif
01686 }
01687
01688
01689 void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp)
01690
01691 {
01692 int f2t = FrequencyToTranspose(psmp->nC4Speed);
01693 int transp = f2t >> 7;
01694 int ftune = f2t & 0x7F;
01695 if (ftune > 80)
01696 {
01697 transp++;
01698 ftune -= 128;
01699 }
01700 if (transp > 127) transp = 127;
01701 if (transp < -127) transp = -127;
01702 psmp->RelativeTone = transp;
01703 psmp->nFineTune = ftune;
01704 }
01705
01706
01707 void CSoundFile::CheckCPUUsage(UINT nCPU)
01708
01709 {
01710 if (nCPU > 100) nCPU = 100;
01711 gnCPUUsage = nCPU;
01712 if (nCPU < 90)
01713 {
01714 m_dwSongFlags &= ~SONG_CPUVERYHIGH;
01715 } else
01716 if ((m_dwSongFlags & SONG_CPUVERYHIGH) && (nCPU >= 94))
01717 {
01718 UINT i=MAX_CHANNELS;
01719 while (i >= 8)
01720 {
01721 i--;
01722 if (Chn[i].nLength)
01723 {
01724 Chn[i].nLength = Chn[i].nPos = 0;
01725 nCPU -= 2;
01726 if (nCPU < 94) break;
01727 }
01728 }
01729 } else
01730 if (nCPU > 90)
01731 {
01732 m_dwSongFlags |= SONG_CPUVERYHIGH;
01733 }
01734 }
01735
01736
01737 BOOL CSoundFile::SetPatternName(UINT nPat, LPCSTR lpszName)
01738
01739 {
01740 char szName[MAX_PATTERNNAME] = "";
01741 if (nPat >= MAX_PATTERNS) return FALSE;
01742 if (lpszName) lstrcpyn(szName, lpszName, MAX_PATTERNNAME);
01743 szName[MAX_PATTERNNAME-1] = 0;
01744 if (!m_lpszPatternNames) m_nPatternNames = 0;
01745 if (nPat >= m_nPatternNames)
01746 {
01747 if (!lpszName[0]) return TRUE;
01748 UINT len = (nPat+1)*MAX_PATTERNNAME;
01749 char *p = new char[len];
01750 if (!p) return FALSE;
01751 memset(p, 0, len);
01752 if (m_lpszPatternNames)
01753 {
01754 memcpy(p, m_lpszPatternNames, m_nPatternNames * MAX_PATTERNNAME);
01755 delete m_lpszPatternNames;
01756 m_lpszPatternNames = NULL;
01757 }
01758 m_lpszPatternNames = p;
01759 m_nPatternNames = nPat + 1;
01760 }
01761 memcpy(m_lpszPatternNames + nPat * MAX_PATTERNNAME, szName, MAX_PATTERNNAME);
01762 return TRUE;
01763 }
01764
01765
01766 BOOL CSoundFile::GetPatternName(UINT nPat, LPSTR lpszName, UINT cbSize) const
01767
01768 {
01769 if ((!lpszName) || (!cbSize)) return FALSE;
01770 lpszName[0] = 0;
01771 if (cbSize > MAX_PATTERNNAME) cbSize = MAX_PATTERNNAME;
01772 if ((m_lpszPatternNames) && (nPat < m_nPatternNames))
01773 {
01774 memcpy(lpszName, m_lpszPatternNames + nPat * MAX_PATTERNNAME, cbSize);
01775 lpszName[cbSize-1] = 0;
01776 return TRUE;
01777 }
01778 return FALSE;
01779 }
01780
01781
01782 #ifndef FASTSOUNDLIB
01783
01784 UINT CSoundFile::DetectUnusedSamples(BOOL *pbIns)
01785
01786 {
01787 UINT nExt = 0;
01788
01789 if (!pbIns) return 0;
01790 if (m_nInstruments)
01791 {
01792 memset(pbIns, 0, MAX_SAMPLES * sizeof(BOOL));
01793 for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++)
01794 {
01795 MODCOMMAND *p = Patterns[ipat];
01796 if (p)
01797 {
01798 UINT jmax = PatternSize[ipat] * m_nChannels;
01799 for (UINT j=0; j<jmax; j++, p++)
01800 {
01801 if ((p->note) && (p->note <= 120))
01802 {
01803 if ((p->instr) && (p->instr < MAX_INSTRUMENTS))
01804 {
01805 INSTRUMENTHEADER *penv = Headers[p->instr];
01806 if (penv)
01807 {
01808 UINT n = penv->Keyboard[p->note-1];
01809 if (n < MAX_SAMPLES) pbIns[n] = TRUE;
01810 }
01811 } else
01812 {
01813 for (UINT k=1; k<=m_nInstruments; k++)
01814 {
01815 INSTRUMENTHEADER *penv = Headers[k];
01816 if (penv)
01817 {
01818 UINT n = penv->Keyboard[p->note-1];
01819 if (n < MAX_SAMPLES) pbIns[n] = TRUE;
01820 }
01821 }
01822 }
01823 }
01824 }
01825 }
01826 }
01827 for (UINT ichk=1; ichk<=m_nSamples; ichk++)
01828 {
01829 if ((!pbIns[ichk]) && (Ins[ichk].pSample)) nExt++;
01830 }
01831 }
01832 return nExt;
01833 }
01834
01835
01836 BOOL CSoundFile::RemoveSelectedSamples(BOOL *pbIns)
01837
01838 {
01839 if (!pbIns) return FALSE;
01840 for (UINT j=1; j<MAX_SAMPLES; j++)
01841 {
01842 if ((!pbIns[j]) && (Ins[j].pSample))
01843 {
01844 DestroySample(j);
01845 if ((j == m_nSamples) && (j > 1)) m_nSamples--;
01846 }
01847 }
01848 return TRUE;
01849 }
01850
01851
01852 BOOL CSoundFile::DestroySample(UINT nSample)
01853
01854 {
01855 if ((!nSample) || (nSample >= MAX_SAMPLES)) return FALSE;
01856 if (!Ins[nSample].pSample) return TRUE;
01857 MODINSTRUMENT *pins = &Ins[nSample];
01858 signed char *pSample = pins->pSample;
01859 pins->pSample = NULL;
01860 pins->nLength = 0;
01861 pins->uFlags &= ~(CHN_16BIT);
01862 for (UINT i=0; i<MAX_CHANNELS; i++)
01863 {
01864 if (Chn[i].pSample == pSample)
01865 {
01866 Chn[i].nPos = Chn[i].nLength = 0;
01867 Chn[i].pSample = Chn[i].pCurrentSample = NULL;
01868 }
01869 }
01870 FreeSample(pSample);
01871 return TRUE;
01872 }
01873
01874 #endif // FASTSOUNDLIB
01875