2 * This source code is public domain.
4 * Authors: Olivier Lapicque <olivierl@jps.net>,
5 * Adam Goode <adam@evdebs.org> (endian and char fixes for PPC)
12 #include <math.h> //for GCCFIX
19 extern BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength);
22 // External decompressors
23 extern void AMSUnpack(const char *psrc, UINT inputlen, char *pdest, UINT dmax, char packcharacter);
24 extern WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n);
25 extern int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen);
26 extern DWORD ITReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n);
27 extern void ITUnpack8Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215);
28 extern void ITUnpack16Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215);
31 #define MAX_PACK_TABLES 3
35 static signed char UnpackTable[MAX_PACK_TABLES][16] =
36 //--------------------------------------------
38 // CPU-generated dynamic table
39 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
41 {0, 1, 2, 4, 8, 16, 32, 64,
42 -1, -2, -4, -8, -16, -32, -48, -64},
44 {0, 1, 2, 3, 5, 7, 12, 19,
45 -1, -2, -3, -5, -7, -12, -19, -31}
49 //////////////////////////////////////////////////////////
52 CSoundFile::CSoundFile()
53 //----------------------
55 m_nType = MOD_TYPE_NONE;
62 m_lpszPatternNames = NULL;
63 m_lpszSongComments = NULL;
64 m_nFreqFactor = m_nTempoFactor = 128;
65 m_nMasterVolume = 128;
67 m_nMaxPeriod = 0x7FFF;
69 memset(Chn, 0, sizeof(Chn));
70 memset(ChnMix, 0, sizeof(ChnMix));
71 memset(Ins, 0, sizeof(Ins));
72 memset(ChnSettings, 0, sizeof(ChnSettings));
73 memset(Headers, 0, sizeof(Headers));
74 memset(Order, 0xFF, sizeof(Order));
75 memset(Patterns, 0, sizeof(Patterns));
76 memset(m_szNames, 0, sizeof(m_szNames));
77 memset(m_MixPlugins, 0, sizeof(m_MixPlugins));
81 CSoundFile::~CSoundFile()
82 //-----------------------
88 BOOL CSoundFile::Create(LPCBYTE lpStream, DWORD dwMemLength)
89 //----------------------------------------------------------
93 m_nType = MOD_TYPE_NONE;
99 m_nFreqFactor = m_nTempoFactor = 128;
100 m_nMasterVolume = 128;
101 m_nDefaultGlobalVolume = 256;
102 m_nGlobalVolume = 256;
103 m_nOldGlbVolSlide = 0;
105 m_nDefaultTempo = 125;
111 m_nCurrentPattern = 0;
115 m_nMaxPeriod = 32767;
116 m_nSongPreAmp = 0x30;
118 m_nMaxOrderPosition = 0;
119 m_lpszPatternNames = NULL;
120 m_lpszSongComments = NULL;
121 memset(Ins, 0, sizeof(Ins));
122 memset(ChnMix, 0, sizeof(ChnMix));
123 memset(Chn, 0, sizeof(Chn));
124 memset(Headers, 0, sizeof(Headers));
125 memset(Order, 0xFF, sizeof(Order));
126 memset(Patterns, 0, sizeof(Patterns));
127 memset(m_szNames, 0, sizeof(m_szNames));
128 memset(m_MixPlugins, 0, sizeof(m_MixPlugins));
130 for (UINT npt=0; npt<MAX_PATTERNS; npt++) PatternSize[npt] = 64;
131 for (UINT nch=0; nch<MAX_BASECHANNELS; nch++)
133 ChnSettings[nch].nPan = 128;
134 ChnSettings[nch].nVolume = 64;
135 ChnSettings[nch].dwFlags = 0;
136 ChnSettings[nch].szName[0] = 0;
141 BOOL bMMCmp = MMCMP_Unpack(&lpStream, &dwMemLength);
143 if ((!ReadXM(lpStream, dwMemLength))
144 && (!ReadIT(lpStream, dwMemLength))
145 && (!ReadS3M(lpStream, dwMemLength))
146 && (!ReadWav(lpStream, dwMemLength))
147 #ifndef MODPLUG_BASIC_SUPPORT
148 && (!ReadSTM(lpStream, dwMemLength))
149 && (!ReadMed(lpStream, dwMemLength))
150 && (!ReadMTM(lpStream, dwMemLength))
151 && (!ReadMDL(lpStream, dwMemLength))
152 && (!ReadDBM(lpStream, dwMemLength))
153 && (!Read669(lpStream, dwMemLength))
154 && (!ReadFAR(lpStream, dwMemLength))
155 && (!ReadAMS(lpStream, dwMemLength))
156 && (!ReadOKT(lpStream, dwMemLength))
157 && (!ReadPTM(lpStream, dwMemLength))
158 && (!ReadUlt(lpStream, dwMemLength))
159 && (!ReadDMF(lpStream, dwMemLength))
160 && (!ReadDSM(lpStream, dwMemLength))
161 && (!ReadUMX(lpStream, dwMemLength))
162 && (!ReadAMF(lpStream, dwMemLength))
163 && (!ReadPSM(lpStream, dwMemLength))
164 && (!ReadMT2(lpStream, dwMemLength))
165 #endif // MODPLUG_BASIC_SUPPORT
166 && (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE;
170 GlobalFreePtr(lpStream);
176 for (i=0; i<MAX_SAMPLES; i++)
178 LPSTR p = m_szNames[i];
181 while ((j>=0) && (p[j]<=' ')) p[j--] = 0;
184 if (((BYTE)p[j]) < ' ') p[j] = ' ';
189 for (i=0; i<MAX_BASECHANNELS; i++)
191 if (ChnSettings[i].nVolume > 64) ChnSettings[i].nVolume = 64;
192 if (ChnSettings[i].nPan > 256) ChnSettings[i].nPan = 128;
193 Chn[i].nPan = ChnSettings[i].nPan;
194 Chn[i].nGlobalVol = ChnSettings[i].nVolume;
195 Chn[i].dwFlags = ChnSettings[i].dwFlags;
196 Chn[i].nVolume = 256;
197 Chn[i].nCutOff = 0x7F;
199 // Checking instruments
200 MODINSTRUMENT *pins = Ins;
202 for (i=0; i<MAX_INSTRUMENTS; i++, pins++)
206 if (pins->nLoopEnd > pins->nLength) pins->nLoopEnd = pins->nLength;
207 if (pins->nLoopStart + 3 >= pins->nLoopEnd)
209 pins->nLoopStart = 0;
212 if (pins->nSustainEnd > pins->nLength) pins->nSustainEnd = pins->nLength;
213 if (pins->nSustainStart + 3 >= pins->nSustainEnd)
215 pins->nSustainStart = 0;
216 pins->nSustainEnd = 0;
221 pins->nLoopStart = 0;
223 pins->nSustainStart = 0;
224 pins->nSustainEnd = 0;
226 if (!pins->nLoopEnd) pins->uFlags &= ~CHN_LOOP;
227 if (!pins->nSustainEnd) pins->uFlags &= ~CHN_SUSTAINLOOP;
228 if (pins->nGlobalVol > 64) pins->nGlobalVol = 64;
230 // Check invalid instruments
231 while ((m_nInstruments > 0) && (!Headers[m_nInstruments])) m_nInstruments--;
232 // Set default values
233 if (m_nSongPreAmp < 0x20) m_nSongPreAmp = 0x20;
234 if (m_nDefaultTempo < 32) m_nDefaultTempo = 125;
235 if (!m_nDefaultSpeed) m_nDefaultSpeed = 6;
236 m_nMusicSpeed = m_nDefaultSpeed;
237 m_nMusicTempo = m_nDefaultTempo;
238 m_nGlobalVolume = m_nDefaultGlobalVolume;
240 m_nCurrentPattern = 0;
243 m_nTickCount = m_nMusicSpeed;
246 if ((m_nRestartPos >= MAX_ORDERS) || (Order[m_nRestartPos] >= MAX_PATTERNS)) m_nRestartPos = 0;
248 if (gpMixPluginCreateProc)
250 for (UINT iPlug=0; iPlug<MAX_MIXPLUGINS; iPlug++)
252 if ((m_MixPlugins[iPlug].Info.dwPluginId1)
253 || (m_MixPlugins[iPlug].Info.dwPluginId2))
255 gpMixPluginCreateProc(&m_MixPlugins[iPlug]);
256 if (m_MixPlugins[iPlug].pMixPlugin)
258 m_MixPlugins[iPlug].pMixPlugin->RestoreAllParameters();
265 UINT maxpreamp = 0x10+(m_nChannels*8);
266 if (maxpreamp > 100) maxpreamp = 100;
267 if (m_nSongPreAmp > maxpreamp) m_nSongPreAmp = maxpreamp;
274 BOOL CSoundFile::Destroy()
276 //------------------------
279 for (i=0; i<MAX_PATTERNS; i++) if (Patterns[i])
281 FreePattern(Patterns[i]);
285 if (m_lpszPatternNames)
287 delete m_lpszPatternNames;
288 m_lpszPatternNames = NULL;
290 if (m_lpszSongComments)
292 delete m_lpszSongComments;
293 m_lpszSongComments = NULL;
295 for (i=1; i<MAX_SAMPLES; i++)
297 MODINSTRUMENT *pins = &Ins[i];
300 FreeSample(pins->pSample);
301 pins->pSample = NULL;
304 for (i=0; i<MAX_INSTRUMENTS; i++)
312 for (i=0; i<MAX_MIXPLUGINS; i++)
314 if ((m_MixPlugins[i].nPluginDataSize) && (m_MixPlugins[i].pPluginData))
316 m_MixPlugins[i].nPluginDataSize = 0;
317 delete [] (signed char*)m_MixPlugins[i].pPluginData;
318 m_MixPlugins[i].pPluginData = NULL;
320 m_MixPlugins[i].pMixState = NULL;
321 if (m_MixPlugins[i].pMixPlugin)
323 m_MixPlugins[i].pMixPlugin->Release();
324 m_MixPlugins[i].pMixPlugin = NULL;
327 m_nType = MOD_TYPE_NONE;
328 m_nChannels = m_nSamples = m_nInstruments = 0;
333 //////////////////////////////////////////////////////////////////////////
336 MODCOMMAND *CSoundFile::AllocatePattern(UINT rows, UINT nchns)
337 //------------------------------------------------------------
339 MODCOMMAND *p = new MODCOMMAND[rows*nchns];
340 if (p) memset(p, 0, rows*nchns*sizeof(MODCOMMAND));
345 void CSoundFile::FreePattern(LPVOID pat)
346 //--------------------------------------
348 if (pat) delete [] (signed char*)pat;
352 signed char* CSoundFile::AllocateSample(UINT nbytes)
353 //-------------------------------------------
355 signed char * p = (signed char *)GlobalAllocPtr(GHND, (nbytes+39) & ~7);
361 void CSoundFile::FreeSample(LPVOID p)
362 //-----------------------------------
366 GlobalFreePtr(((LPSTR)p)-16);
371 //////////////////////////////////////////////////////////////////////////
374 void CSoundFile::ResetMidiCfg()
375 //-----------------------------
377 memset(&m_MidiCfg, 0, sizeof(m_MidiCfg));
378 lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_START*32], "FF");
379 lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_STOP*32], "FC");
380 lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_NOTEON*32], "9c n v");
381 lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_NOTEOFF*32], "9c n 0");
382 lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_PROGRAM*32], "Cc p");
383 lstrcpy(&m_MidiCfg.szMidiSFXExt[0], "F0F000z");
384 for (int iz=0; iz<16; iz++) wsprintf(&m_MidiCfg.szMidiZXXExt[iz*32], "F0F001%02X", iz*8);
388 UINT CSoundFile::GetNumChannels() const
389 //-------------------------------------
392 for (UINT i=0; i<m_nChannels; i++) if (ChnSettings[i].nVolume) n++;
397 UINT CSoundFile::GetSongComments(LPSTR s, UINT len, UINT linesize)
398 //----------------------------------------------------------------
400 LPCSTR p = m_lpszSongComments;
403 if ((len) && (s)) s[0] = '\x0D';
404 if ((len > 1) && (s)) s[1] = '\x0A';
405 while ((*p) && (i+2 < len))
408 if ((c == 0x0D) || ((c == ' ') && (ln >= linesize)))
409 { if (s) { s[i++] = '\x0D'; s[i++] = '\x0A'; } else i+= 2; ln=0; }
411 if (c >= 0x20) { if (s) s[i++] = c; else i++; ln++; }
418 UINT CSoundFile::GetRawSongComments(LPSTR s, UINT len, UINT linesize)
419 //-------------------------------------------------------------------
421 LPCSTR p = m_lpszSongComments;
424 while ((*p) && (i < len-1))
427 if ((c == 0x0D) || (c == 0x0A))
431 while (ln < linesize) { if (s) s[i] = ' '; i++; ln++; }
435 if ((c == ' ') && (!ln))
438 while ((p[k]) && (p[k] >= ' ')) k++;
450 if (ln == linesize) ln = 0;
455 while ((ln < linesize) && (i < len))
467 BOOL CSoundFile::SetWaveConfig(UINT nRate,UINT nBits,UINT nChannels,BOOL bMMX)
468 //----------------------------------------------------------------------------
471 DWORD d = gdwSoundSetup & ~SNDMIX_ENABLEMMX;
472 if (bMMX) d |= SNDMIX_ENABLEMMX;
473 if ((gdwMixingFreq != nRate) || (gnBitsPerSample != nBits) || (gnChannels != nChannels) || (d != gdwSoundSetup)) bReset = TRUE;
474 gnChannels = nChannels;
476 gdwMixingFreq = nRate;
477 gnBitsPerSample = nBits;
483 BOOL CSoundFile::SetResamplingMode(UINT nMode)
484 //--------------------------------------------
486 DWORD d = gdwSoundSetup & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE);
489 case SRCMODE_NEAREST: d |= SNDMIX_NORESAMPLING; break;
490 case SRCMODE_LINEAR: break;
491 case SRCMODE_SPLINE: d |= SNDMIX_HQRESAMPLER; break;
492 case SRCMODE_POLYPHASE: d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); break;
501 BOOL CSoundFile::SetMasterVolume(UINT nVol, BOOL bAdjustAGC)
502 //----------------------------------------------------------
504 if (nVol < 1) nVol = 1;
505 if (nVol > 0x200) nVol = 0x200; // x4 maximum
506 if ((nVol < m_nMasterVolume) && (nVol) && (gdwSoundSetup & SNDMIX_AGC) && (bAdjustAGC))
508 gnAGC = gnAGC * m_nMasterVolume / nVol;
509 if (gnAGC > AGC_UNITY) gnAGC = AGC_UNITY;
511 m_nMasterVolume = nVol;
516 void CSoundFile::SetAGC(BOOL b)
517 //-----------------------------
521 if (!(gdwSoundSetup & SNDMIX_AGC))
523 gdwSoundSetup |= SNDMIX_AGC;
526 } else gdwSoundSetup &= ~SNDMIX_AGC;
530 UINT CSoundFile::GetNumPatterns() const
531 //-------------------------------------
534 while ((i < MAX_ORDERS) && (Order[i] < 0xFF)) i++;
539 UINT CSoundFile::GetNumInstruments() const
540 //----------------------------------------
543 for (UINT i=0; i<MAX_INSTRUMENTS; i++) if (Ins[i].pSample) n++;
548 UINT CSoundFile::GetMaxPosition() const
549 //-------------------------------------
554 while ((i < MAX_ORDERS) && (Order[i] != 0xFF))
556 if (Order[i] < MAX_PATTERNS) max += PatternSize[Order[i]];
563 UINT CSoundFile::GetCurrentPos() const
564 //------------------------------------
568 for (UINT i=0; i<m_nCurrentPattern; i++) if (Order[i] < MAX_PATTERNS)
569 pos += PatternSize[Order[i]];
574 void CSoundFile::SetCurrentPos(UINT nPos)
575 //---------------------------------------
579 for (i=0; i<MAX_CHANNELS; i++)
581 Chn[i].nNote = Chn[i].nNewNote = Chn[i].nNewIns = 0;
582 Chn[i].pInstrument = NULL;
583 Chn[i].pHeader = NULL;
584 Chn[i].nPortamentoDest = 0;
586 Chn[i].nPatternLoopCount = 0;
587 Chn[i].nPatternLoop = 0;
588 Chn[i].nFadeOutVol = 0;
589 Chn[i].dwFlags |= CHN_KEYOFF|CHN_NOTEFADE;
590 Chn[i].nTremorCount = 0;
594 for (i=0; i<MAX_CHANNELS; i++)
597 Chn[i].nPos = Chn[i].nLength = 0;
598 Chn[i].nLoopStart = 0;
600 Chn[i].nROfs = Chn[i].nLOfs = 0;
601 Chn[i].pSample = NULL;
602 Chn[i].pInstrument = NULL;
603 Chn[i].pHeader = NULL;
604 Chn[i].nCutOff = 0x7F;
605 Chn[i].nResonance = 0;
606 Chn[i].nLeftVol = Chn[i].nRightVol = 0;
607 Chn[i].nNewLeftVol = Chn[i].nNewRightVol = 0;
608 Chn[i].nLeftRamp = Chn[i].nRightRamp = 0;
609 Chn[i].nVolume = 256;
610 if (i < MAX_BASECHANNELS)
612 Chn[i].dwFlags = ChnSettings[i].dwFlags;
613 Chn[i].nPan = ChnSettings[i].nPan;
614 Chn[i].nGlobalVol = ChnSettings[i].nVolume;
619 Chn[i].nGlobalVol = 64;
622 m_nGlobalVolume = m_nDefaultGlobalVolume;
623 m_nMusicSpeed = m_nDefaultSpeed;
624 m_nMusicTempo = m_nDefaultTempo;
626 m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE);
627 for (nPattern = 0; nPattern < MAX_ORDERS; nPattern++)
629 UINT ord = Order[nPattern];
630 if (ord == 0xFE) continue;
631 if (ord == 0xFF) break;
632 if (ord < MAX_PATTERNS)
634 if (nPos < (UINT)PatternSize[ord]) break;
635 nPos -= PatternSize[ord];
639 if ((nPattern >= MAX_ORDERS)
640 || (Order[nPattern] >= MAX_PATTERNS)
641 || (nPos >= PatternSize[Order[nPattern]]))
647 if ((nRow) && (Order[nPattern] < MAX_PATTERNS))
649 MODCOMMAND *p = Patterns[Order[nPattern]];
650 if ((p) && (nRow < PatternSize[Order[nPattern]]))
653 while ((!bOk) && (nRow > 0))
655 UINT n = nRow * m_nChannels;
656 for (UINT k=0; k<m_nChannels; k++, n++)
668 m_nNextPattern = nPattern;
670 m_nTickCount = m_nMusicSpeed;
677 void CSoundFile::SetCurrentOrder(UINT nPos)
678 //-----------------------------------------
680 while ((nPos < MAX_ORDERS) && (Order[nPos] == 0xFE)) nPos++;
681 if ((nPos >= MAX_ORDERS) || (Order[nPos] >= MAX_PATTERNS)) return;
682 for (UINT j=0; j<MAX_CHANNELS; j++)
686 Chn[j].nPortamentoDest = 0;
688 Chn[j].nPatternLoopCount = 0;
689 Chn[j].nPatternLoop = 0;
690 Chn[j].nTremorCount = 0;
697 m_nNextPattern = nPos;
698 m_nRow = m_nNextRow = 0;
700 m_nTickCount = m_nMusicSpeed;
706 m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE);
710 void CSoundFile::ResetChannels()
711 //------------------------------
713 m_dwSongFlags &= ~(SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE);
715 for (UINT i=0; i<MAX_CHANNELS; i++)
717 Chn[i].nROfs = Chn[i].nLOfs = 0;
722 void CSoundFile::LoopPattern(int nPat, int nRow)
723 //----------------------------------------------
725 if ((nPat < 0) || (nPat >= MAX_PATTERNS) || (!Patterns[nPat]))
727 m_dwSongFlags &= ~SONG_PATTERNLOOP;
730 if ((nRow < 0) || (nRow >= PatternSize[nPat])) nRow = 0;
732 m_nRow = m_nNextRow = nRow;
733 m_nTickCount = m_nMusicSpeed;
737 m_dwSongFlags |= SONG_PATTERNLOOP;
742 UINT CSoundFile::GetBestSaveFormat() const
743 //----------------------------------------
745 if ((!m_nSamples) || (!m_nChannels)) return MOD_TYPE_NONE;
746 if (!m_nType) return MOD_TYPE_NONE;
747 if (m_nType & (MOD_TYPE_MOD|MOD_TYPE_OKT))
749 if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_STM|MOD_TYPE_ULT|MOD_TYPE_FAR|MOD_TYPE_PTM))
751 if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MED|MOD_TYPE_MTM|MOD_TYPE_MT2))
757 UINT CSoundFile::GetSaveFormats() const
758 //-------------------------------------
761 if ((!m_nSamples) || (!m_nChannels) || (m_nType == MOD_TYPE_NONE)) return 0;
764 case MOD_TYPE_MOD: n = MOD_TYPE_MOD;
765 case MOD_TYPE_S3M: n = MOD_TYPE_S3M;
767 n |= MOD_TYPE_XM | MOD_TYPE_IT;
770 if (m_nSamples < 32) n |= MOD_TYPE_MOD;
777 UINT CSoundFile::GetSampleName(UINT nSample,LPSTR s) const
778 //--------------------------------------------------------
780 char sztmp[40] = ""; // changed from CHAR
781 memcpy(sztmp, m_szNames[nSample],32);
783 if (s) strcpy(s, sztmp);
784 return strlen(sztmp);
788 UINT CSoundFile::GetInstrumentName(UINT nInstr,LPSTR s) const
789 //-----------------------------------------------------------
791 char sztmp[40] = ""; // changed from CHAR
792 if ((nInstr >= MAX_INSTRUMENTS) || (!Headers[nInstr]))
797 INSTRUMENTHEADER *penv = Headers[nInstr];
798 memcpy(sztmp, penv->name, 32);
800 if (s) strcpy(s, sztmp);
801 return strlen(sztmp);
806 UINT CSoundFile::PackSample(int &sample, int next)
807 //------------------------------------------------
810 int delta = next - sample;
813 for (i=0; i<7; i++) if (delta <= (int)CompressionTable[i+1]) break;
816 for (i=8; i<15; i++) if (delta >= (int)CompressionTable[i+1]) break;
818 sample += (int)CompressionTable[i];
823 BOOL CSoundFile::CanPackSample(signed char * pSample, UINT nLen, UINT nPacking, BYTE *result)
824 //-----------------------------------------------------------------------------------
826 int pos, old, oldpos, besttable = 0;
827 DWORD dwErr, dwTotal, dwResult;
830 if (result) *result = 0;
831 if ((!pSample) || (nLen < 1024)) return FALSE;
832 // Try packing with different tables
834 for (j=1; j<MAX_PACK_TABLES; j++)
836 memcpy(CompressionTable, UnpackTable[j], 16);
839 old = pos = oldpos = 0;
840 for (i=0; i<(int)nLen; i++)
842 int s = (int)pSample[i];
844 dwErr += abs(pos - oldpos);
845 dwTotal += abs(s - old);
849 dwErr = _muldiv(dwErr, 100, dwTotal);
850 if (dwErr >= dwResult)
856 memcpy(CompressionTable, UnpackTable[besttable], 16);
859 if (dwResult > 100) *result = 100; else *result = (BYTE)dwResult;
861 return (dwResult >= nPacking) ? TRUE : FALSE;
865 #ifndef MODPLUG_NO_FILESAVE
867 UINT CSoundFile::WriteSample(FILE *f, MODINSTRUMENT *pins, UINT nFlags, UINT nMaxLen)
868 //-----------------------------------------------------------------------------------
870 UINT len = 0, bufcount;
871 signed char buffer[4096];
872 signed char *pSample = (signed char *)pins->pSample;
873 UINT nLen = pins->nLength;
875 if ((nMaxLen) && (nLen > nMaxLen)) nLen = nMaxLen;
876 if ((!pSample) || (f == NULL) || (!nLen)) return 0;
880 // 3: 4-bit ADPCM data
884 len = (nLen + 1) / 2;
885 fwrite(CompressionTable, 16, 1, f);
888 for (UINT j=0; j<len; j++)
892 b = PackSample(pos, (int)pSample[j*2]);
894 b |= PackSample(pos, (int)pSample[j*2+1]) << 4;
895 buffer[bufcount++] = (signed char)b;
896 if (bufcount >= sizeof(buffer))
898 fwrite(buffer, 1, bufcount, f);
902 if (bufcount) fwrite(buffer, 1, bufcount, f);
913 short int *p = (short int *)pSample;
914 int s_old = 0, s_ofs;
917 s_ofs = (nFlags == RS_PCM16U) ? 0x8000 : 0;
918 for (UINT j=0; j<nLen; j++)
922 if (pins->uFlags & CHN_STEREO)
924 s_new = (s_new + (*p) + 1) >> 1;
927 if (nFlags == RS_PCM16D)
929 *((short *)(&buffer[bufcount])) = (short)(s_new - s_old);
933 *((short *)(&buffer[bufcount])) = (short)(s_new + s_ofs);
936 if (bufcount >= sizeof(buffer) - 1)
938 fwrite(buffer, 1, bufcount, f);
942 if (bufcount) fwrite(buffer, 1, bufcount, f);
947 // 8-bit Stereo samples (not interleaved)
952 int s_ofs = (nFlags == RS_STPCM8U) ? 0x80 : 0;
953 for (UINT iCh=0; iCh<2; iCh++)
955 signed char *p = pSample + iCh;
959 for (UINT j=0; j<nLen; j++)
963 if (nFlags == RS_STPCM8D)
965 buffer[bufcount++] = (signed char)(s_new - s_old);
969 buffer[bufcount++] = (signed char)(s_new + s_ofs);
971 if (bufcount >= sizeof(buffer))
973 fwrite(buffer, 1, bufcount, f);
977 if (bufcount) fwrite(buffer, 1, bufcount, f);
983 // 16-bit Stereo samples (not interleaved)
988 int s_ofs = (nFlags == RS_STPCM16U) ? 0x8000 : 0;
989 for (UINT iCh=0; iCh<2; iCh++)
991 signed short *p = ((signed short *)pSample) + iCh;
995 for (UINT j=0; j<nLen; j++)
999 if (nFlags == RS_STPCM16D)
1001 *((short *)(&buffer[bufcount])) = (short)(s_new - s_old);
1005 *((short *)(&buffer[bufcount])) = (short)(s_new + s_ofs);
1008 if (bufcount >= sizeof(buffer))
1010 fwrite(buffer, 1, bufcount, f);
1014 if (bufcount) fwrite(buffer, 1, bufcount, f);
1020 // Stereo signed interleaved
1024 if (nFlags == RS_STIPCM16S) len *= 2;
1025 fwrite(pSample, 1, len, f);
1028 // Default: assume 8-bit PCM data
1033 signed char *p = pSample;
1034 int sinc = (pins->uFlags & CHN_16BIT) ? 2 : 1;
1035 int s_old = 0, s_ofs = (nFlags == RS_PCM8U) ? 0x80 : 0;
1036 if (pins->uFlags & CHN_16BIT) p++;
1037 for (UINT j=0; j<len; j++)
1039 int s_new = (signed char)(*p);
1041 if (pins->uFlags & CHN_STEREO)
1043 s_new = (s_new + ((int)*p) + 1) >> 1;
1046 if (nFlags == RS_PCM8D)
1048 buffer[bufcount++] = (signed char)(s_new - s_old);
1052 buffer[bufcount++] = (signed char)(s_new + s_ofs);
1054 if (bufcount >= sizeof(buffer))
1056 fwrite(buffer, 1, bufcount, f);
1060 if (bufcount) fwrite(buffer, 1, bufcount, f);
1066 #endif // MODPLUG_NO_FILESAVE
1070 // 0 = signed 8-bit PCM data (default)
1071 // 1 = unsigned 8-bit PCM data
1072 // 2 = 8-bit ADPCM data with linear table
1073 // 3 = 4-bit ADPCM data
1074 // 4 = 16-bit ADPCM data with linear table
1075 // 5 = signed 16-bit PCM data
1076 // 6 = unsigned 16-bit PCM data
1079 UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength)
1080 //------------------------------------------------------------------------------------------------
1082 UINT len = 0, mem = pIns->nLength+6;
1084 if ((!pIns) || ((int)pIns->nLength < 4) || (!lpMemFile)) return 0;
1085 if (pIns->nLength > MAX_SAMPLE_LENGTH) pIns->nLength = MAX_SAMPLE_LENGTH;
1086 pIns->uFlags &= ~(CHN_16BIT|CHN_STEREO);
1087 if (nFlags & RSF_16BIT)
1090 pIns->uFlags |= CHN_16BIT;
1092 if (nFlags & RSF_STEREO)
1095 pIns->uFlags |= CHN_STEREO;
1097 if ((pIns->pSample = AllocateSample(mem)) == NULL)
1104 // 1: 8-bit unsigned PCM data
1107 len = pIns->nLength;
1108 if (len > dwMemLength) len = pIns->nLength = dwMemLength;
1109 signed char *pSample = pIns->pSample;
1110 for (UINT j=0; j<len; j++) pSample[j] = (signed char)(lpMemFile[j] - 0x80);
1114 // 2: 8-bit ADPCM data with linear table
1117 len = pIns->nLength;
1118 if (len > dwMemLength) break;
1119 signed char *pSample = pIns->pSample;
1120 const signed char *p = (const signed char *)lpMemFile;
1123 for (UINT j=0; j<len; j++)
1126 *pSample++ = (signed char)delta;
1131 // 3: 4-bit ADPCM data
1134 len = (pIns->nLength + 1) / 2;
1135 if (len > dwMemLength - 16) break;
1136 memcpy(CompressionTable, lpMemFile, 16);
1138 signed char *pSample = pIns->pSample;
1139 signed char delta = 0;
1140 for (UINT j=0; j<len; j++)
1142 BYTE b0 = (BYTE)lpMemFile[j];
1143 BYTE b1 = (BYTE)(lpMemFile[j] >> 4);
1144 delta = (signed char)GetDeltaValue((int)delta, b0);
1146 delta = (signed char)GetDeltaValue((int)delta, b1);
1154 // 4: 16-bit ADPCM data with linear table
1157 len = pIns->nLength * 2;
1158 if (len > dwMemLength) break;
1159 short int *pSample = (short int *)pIns->pSample;
1160 short int *p = (short int *)lpMemFile;
1162 for (UINT j=0; j<len; j+=2)
1164 delta16 += bswapLE16(*p++);
1165 *pSample++ = (short int)delta16;
1170 // 5: 16-bit signed PCM data
1173 len = pIns->nLength * 2;
1174 if (len <= dwMemLength) memcpy(pIns->pSample, lpMemFile, len);
1175 short int *pSample = (short int *)pIns->pSample;
1176 for (UINT j=0; j<len; j+=2)
1178 short int s = bswapLE16(*pSample);
1184 // 16-bit signed mono PCM motorola byte order
1186 len = pIns->nLength * 2;
1187 if (len > dwMemLength) len = dwMemLength & ~1;
1190 signed char *pSample = (signed char *)pIns->pSample;
1191 signed char *pSrc = (signed char *)lpMemFile;
1192 for (UINT j=0; j<len; j+=2)
1194 // pSample[j] = pSrc[j+1];
1195 // pSample[j+1] = pSrc[j];
1196 *((unsigned short *)(pSample+j)) = bswapBE16(*((unsigned short *)(pSrc+j)));
1201 // 6: 16-bit unsigned PCM data
1204 len = pIns->nLength * 2;
1205 if (len > dwMemLength) break;
1206 short int *pSample = (short int *)pIns->pSample;
1207 short int *pSrc = (short int *)lpMemFile;
1208 for (UINT j=0; j<len; j+=2) *pSample++ = bswapLE16(*(pSrc++)) - 0x8000;
1212 // 16-bit signed stereo big endian
1214 len = pIns->nLength * 2;
1215 if (len*2 <= dwMemLength)
1217 signed char *pSample = (signed char *)pIns->pSample;
1218 signed char *pSrc = (signed char *)lpMemFile;
1219 for (UINT j=0; j<len; j+=2)
1221 // pSample[j*2] = pSrc[j+1];
1222 // pSample[j*2+1] = pSrc[j];
1223 // pSample[j*2+2] = pSrc[j+1+len];
1224 // pSample[j*2+3] = pSrc[j+len];
1225 *((unsigned short *)(pSample+j*2)) = bswapBE16(*((unsigned short *)(pSrc+j)));
1226 *((unsigned short *)(pSample+j*2+2)) = bswapBE16(*((unsigned short *)(pSrc+j+len)));
1232 // 8-bit stereo samples
1237 int iadd_l = 0, iadd_r = 0;
1238 if (nFlags == RS_STPCM8U) { iadd_l = iadd_r = -128; }
1239 len = pIns->nLength;
1240 signed char *psrc = (signed char *)lpMemFile;
1241 signed char *pSample = (signed char *)pIns->pSample;
1242 if (len*2 > dwMemLength) break;
1243 for (UINT j=0; j<len; j++)
1245 pSample[j*2] = (signed char)(psrc[0] + iadd_l);
1246 pSample[j*2+1] = (signed char)(psrc[len] + iadd_r);
1248 if (nFlags == RS_STPCM8D)
1250 iadd_l = pSample[j*2];
1251 iadd_r = pSample[j*2+1];
1258 // 16-bit stereo samples
1263 int iadd_l = 0, iadd_r = 0;
1264 if (nFlags == RS_STPCM16U) { iadd_l = iadd_r = -0x8000; }
1265 len = pIns->nLength;
1266 short int *psrc = (short int *)lpMemFile;
1267 short int *pSample = (short int *)pIns->pSample;
1268 if (len*4 > dwMemLength) break;
1269 for (UINT j=0; j<len; j++)
1271 pSample[j*2] = (short int) (bswapLE16(psrc[0]) + iadd_l);
1272 pSample[j*2+1] = (short int) (bswapLE16(psrc[len]) + iadd_r);
1274 if (nFlags == RS_STPCM16D)
1276 iadd_l = pSample[j*2];
1277 iadd_r = pSample[j*2+1];
1284 // IT 2.14 compressed samples
1291 if ((nFlags == RS_IT2148) || (nFlags == RS_IT2158))
1292 ITUnpack8Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT2158));
1294 ITUnpack16Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT21516));
1297 #ifndef MODPLUG_BASIC_SUPPORT
1298 #ifndef FASTSOUNDLIB
1299 // 8-bit interleaved stereo samples
1304 if (nFlags == RS_STIPCM8U) { iadd = -0x80; }
1305 len = pIns->nLength;
1306 if (len*2 > dwMemLength) len = dwMemLength >> 1;
1307 LPBYTE psrc = (LPBYTE)lpMemFile;
1308 LPBYTE pSample = (LPBYTE)pIns->pSample;
1309 for (UINT j=0; j<len; j++)
1311 pSample[j*2] = (signed char)(psrc[0] + iadd);
1312 pSample[j*2+1] = (signed char)(psrc[1] + iadd);
1319 // 16-bit interleaved stereo samples
1324 if (nFlags == RS_STIPCM16U) iadd = -32768;
1325 len = pIns->nLength;
1326 if (len*4 > dwMemLength) len = dwMemLength >> 2;
1327 short int *psrc = (short int *)lpMemFile;
1328 short int *pSample = (short int *)pIns->pSample;
1329 for (UINT j=0; j<len; j++)
1331 pSample[j*2] = (short int)(bswapLE16(psrc[0]) + iadd);
1332 pSample[j*2+1] = (short int)(bswapLE16(psrc[1]) + iadd);
1339 // AMS compressed samples
1343 if (dwMemLength > 9)
1345 const char *psrc = lpMemFile;
1346 char packcharacter = lpMemFile[8], *pdest = (char *)pIns->pSample;
1347 len += bswapLE32(*((LPDWORD)(lpMemFile+4)));
1348 if (len > dwMemLength) len = dwMemLength;
1349 UINT dmax = pIns->nLength;
1350 if (pIns->uFlags & CHN_16BIT) dmax <<= 1;
1351 AMSUnpack(psrc+9, len-9, pdest, dmax, packcharacter);
1355 // PTM 8bit delta to 16-bit sample
1358 len = pIns->nLength * 2;
1359 if (len > dwMemLength) break;
1360 signed char *pSample = (signed char *)pIns->pSample;
1361 signed char delta8 = 0;
1362 for (UINT j=0; j<len; j++)
1364 delta8 += lpMemFile[j];
1365 *pSample++ = delta8;
1367 WORD *pSampleW = (WORD *)pIns->pSample;
1368 for (UINT j=0; j<len; j+=2) // swaparoni!
1370 WORD s = bswapLE16(*pSampleW);
1376 // Huffman MDL compressed samples
1382 LPBYTE pSample = (LPBYTE)pIns->pSample;
1383 LPBYTE ibuf = (LPBYTE)lpMemFile;
1384 DWORD bitbuf = bswapLE32(*((DWORD *)ibuf));
1386 BYTE dlt = 0, lowbyte = 0;
1388 for (UINT j=0; j<pIns->nLength; j++)
1392 if (nFlags == RS_MDL16) lowbyte = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 8);
1393 sign = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 1);
1394 if (MDLReadBits(bitbuf, bitnum, ibuf, 1))
1396 hibyte = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 3);
1400 while (!MDLReadBits(bitbuf, bitnum, ibuf, 1)) hibyte += 0x10;
1401 hibyte += MDLReadBits(bitbuf, bitnum, ibuf, 4);
1403 if (sign) hibyte = ~hibyte;
1405 if (nFlags != RS_MDL16)
1409 pSample[j<<1] = lowbyte;
1410 pSample[(j<<1)+1] = dlt;
1421 UINT maxlen = pIns->nLength;
1422 if (pIns->uFlags & CHN_16BIT) maxlen <<= 1;
1423 LPBYTE ibuf = (LPBYTE)lpMemFile, ibufmax = (LPBYTE)(lpMemFile+dwMemLength);
1424 len = DMFUnpack((LPBYTE)pIns->pSample, ibuf, ibufmax, maxlen);
1428 #ifdef MODPLUG_TRACKER
1429 // PCM 24-bit signed -> load sample, and normalize it to 16-bit
1432 len = pIns->nLength * 3;
1433 if (nFlags == RS_PCM32S) len += pIns->nLength;
1434 if (len > dwMemLength) break;
1437 UINT slsize = (nFlags == RS_PCM32S) ? 4 : 3;
1438 LPBYTE pSrc = (LPBYTE)lpMemFile;
1440 if (nFlags == RS_PCM32S) pSrc++;
1441 for (UINT j=0; j<len; j+=slsize)
1443 LONG l = ((((pSrc[j+2] << 8) + pSrc[j+1]) << 8) + pSrc[j]) << 8;
1445 if (l > max) max = l;
1446 if (-l > max) max = -l;
1448 max = (max / 128) + 1;
1449 signed short *pDest = (signed short *)pIns->pSample;
1450 for (UINT k=0; k<len; k+=slsize)
1452 LONG l = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8;
1453 *pDest++ = (signed short)(l / max);
1458 // Stereo PCM 24-bit signed -> load sample, and normalize it to 16-bit
1461 len = pIns->nLength * 6;
1462 if (nFlags == RS_STIPCM32S) len += pIns->nLength * 2;
1463 if (len > dwMemLength) break;
1466 UINT slsize = (nFlags == RS_STIPCM32S) ? 4 : 3;
1467 LPBYTE pSrc = (LPBYTE)lpMemFile;
1469 if (nFlags == RS_STIPCM32S) pSrc++;
1470 for (UINT j=0; j<len; j+=slsize)
1472 LONG l = ((((pSrc[j+2] << 8) + pSrc[j+1]) << 8) + pSrc[j]) << 8;
1474 if (l > max) max = l;
1475 if (-l > max) max = -l;
1477 max = (max / 128) + 1;
1478 signed short *pDest = (signed short *)pIns->pSample;
1479 for (UINT k=0; k<len; k+=slsize)
1481 LONG lr = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8;
1483 LONG ll = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8;
1484 pDest[0] = (signed short)ll;
1485 pDest[1] = (signed short)lr;
1491 // 16-bit signed big endian interleaved stereo
1494 len = pIns->nLength;
1495 if (len*4 > dwMemLength) len = dwMemLength >> 2;
1496 LPCBYTE psrc = (LPCBYTE)lpMemFile;
1497 short int *pSample = (short int *)pIns->pSample;
1498 for (UINT j=0; j<len; j++)
1500 pSample[j*2] = (signed short)(((UINT)psrc[0] << 8) | (psrc[1]));
1501 pSample[j*2+1] = (signed short)(((UINT)psrc[2] << 8) | (psrc[3]));
1508 #endif // MODPLUG_TRACKER
1509 #endif // !FASTSOUNDLIB
1510 #endif // !MODPLUG_BASIC_SUPPORT
1512 // Default: 8-bit signed PCM data
1514 len = pIns->nLength;
1515 if (len > dwMemLength) len = pIns->nLength = dwMemLength;
1516 memcpy(pIns->pSample, lpMemFile, len);
1518 if (len > dwMemLength)
1523 FreeSample(pIns->pSample);
1524 pIns->pSample = NULL;
1528 AdjustSampleLoop(pIns);
1533 void CSoundFile::AdjustSampleLoop(MODINSTRUMENT *pIns)
1534 //----------------------------------------------------
1536 if (!pIns->pSample) return;
1537 if (pIns->nLoopEnd > pIns->nLength) pIns->nLoopEnd = pIns->nLength;
1538 if (pIns->nLoopStart+2 >= pIns->nLoopEnd)
1540 pIns->nLoopStart = pIns->nLoopEnd = 0;
1541 pIns->uFlags &= ~CHN_LOOP;
1543 UINT len = pIns->nLength;
1544 if (pIns->uFlags & CHN_16BIT)
1546 short int *pSample = (short int *)pIns->pSample;
1547 // Adjust end of sample
1548 if (pIns->uFlags & CHN_STEREO)
1550 pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2];
1551 pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1];
1554 pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1];
1556 if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
1559 if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & MOD_TYPE_S3M))
1561 pSample[pIns->nLoopEnd] = pSample[pIns->nLoopStart];
1562 pSample[pIns->nLoopEnd+1] = pSample[pIns->nLoopStart+1];
1563 pSample[pIns->nLoopEnd+2] = pSample[pIns->nLoopStart+2];
1564 pSample[pIns->nLoopEnd+3] = pSample[pIns->nLoopStart+3];
1565 pSample[pIns->nLoopEnd+4] = pSample[pIns->nLoopStart+4];
1570 signed char *pSample = pIns->pSample;
1571 #ifndef FASTSOUNDLIB
1572 // Crappy samples (except chiptunes) ?
1573 if ((pIns->nLength > 0x100) && (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M))
1574 && (!(pIns->uFlags & CHN_STEREO)))
1576 int smpend = pSample[pIns->nLength-1], smpfix = 0, kscan;
1577 for (kscan=pIns->nLength-1; kscan>0; kscan--)
1579 smpfix = pSample[kscan-1];
1580 if (smpfix != smpend) break;
1582 int delta = smpfix - smpend;
1583 if (((!(pIns->uFlags & CHN_LOOP)) || (kscan > (int)pIns->nLoopEnd))
1584 && ((delta < -8) || (delta > 8)))
1586 while (kscan<(int)pIns->nLength)
1590 if (smpfix > 0) smpfix--;
1591 if (smpfix < 0) smpfix++;
1593 pSample[kscan] = (signed char)smpfix;
1599 // Adjust end of sample
1600 if (pIns->uFlags & CHN_STEREO)
1602 pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2];
1603 pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1];
1606 pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1];
1608 if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
1610 if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M)))
1612 pSample[pIns->nLoopEnd] = pSample[pIns->nLoopStart];
1613 pSample[pIns->nLoopEnd+1] = pSample[pIns->nLoopStart+1];
1614 pSample[pIns->nLoopEnd+2] = pSample[pIns->nLoopStart+2];
1615 pSample[pIns->nLoopEnd+3] = pSample[pIns->nLoopStart+3];
1616 pSample[pIns->nLoopEnd+4] = pSample[pIns->nLoopStart+4];
1623 /////////////////////////////////////////////////////////////
1624 // Transpose <-> Frequency conversions
1626 // returns 8363*2^((transp*128+ftune)/(12*128))
1627 DWORD CSoundFile::TransposeToFrequency(int transp, int ftune)
1628 //-----------------------------------------------------------
1630 //---GCCFIX: Removed assembly.
1631 return (DWORD)(8363*pow(2.0, (transp*128+ftune)/(1536)));
1634 const float _fbase = 8363;
1635 const float _factor = 1.0f/(12.0f*128.0f);
1639 transp = (transp << 7) + ftune;
1655 UINT derr = freq % 11025;
1656 if (derr <= 8) freq -= derr;
1657 if (derr >= 11015) freq += 11025-derr;
1659 if (derr <= 5) freq -= derr;
1660 if (derr >= 995) freq += 1000-derr;
1666 // returns 12*128*log2(freq/8363)
1667 int CSoundFile::FrequencyToTranspose(DWORD freq)
1668 //----------------------------------------------
1670 //---GCCFIX: Removed assembly.
1671 return int(1536*(log(freq/8363.0)/log(2.0)));
1674 const float _f1_8363 = 1.0f / 8363.0f;
1675 const float _factor = 128 * 12;
1678 if (!freq) return 0;
1692 void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp)
1693 //--------------------------------------------------------
1695 int f2t = FrequencyToTranspose(psmp->nC4Speed);
1696 int transp = f2t >> 7;
1697 int ftune = f2t & 0x7F;
1703 if (transp > 127) transp = 127;
1704 if (transp < -127) transp = -127;
1705 psmp->RelativeTone = transp;
1706 psmp->nFineTune = ftune;
1710 void CSoundFile::CheckCPUUsage(UINT nCPU)
1711 //---------------------------------------
1713 if (nCPU > 100) nCPU = 100;
1717 m_dwSongFlags &= ~SONG_CPUVERYHIGH;
1719 if ((m_dwSongFlags & SONG_CPUVERYHIGH) && (nCPU >= 94))
1721 UINT i=MAX_CHANNELS;
1727 Chn[i].nLength = Chn[i].nPos = 0;
1729 if (nCPU < 94) break;
1735 m_dwSongFlags |= SONG_CPUVERYHIGH;
1740 BOOL CSoundFile::SetPatternName(UINT nPat, LPCSTR lpszName)
1741 //---------------------------------------------------------
1743 char szName[MAX_PATTERNNAME] = ""; // changed from CHAR
1744 if (nPat >= MAX_PATTERNS) return FALSE;
1745 if (lpszName) lstrcpyn(szName, lpszName, MAX_PATTERNNAME);
1746 szName[MAX_PATTERNNAME-1] = 0;
1747 if (!m_lpszPatternNames) m_nPatternNames = 0;
1748 if (nPat >= m_nPatternNames)
1750 if (!lpszName[0]) return TRUE;
1751 UINT len = (nPat+1)*MAX_PATTERNNAME;
1752 char *p = new char[len]; // changed from CHAR
1753 if (!p) return FALSE;
1755 if (m_lpszPatternNames)
1757 memcpy(p, m_lpszPatternNames, m_nPatternNames * MAX_PATTERNNAME);
1758 delete m_lpszPatternNames;
1759 m_lpszPatternNames = NULL;
1761 m_lpszPatternNames = p;
1762 m_nPatternNames = nPat + 1;
1764 memcpy(m_lpszPatternNames + nPat * MAX_PATTERNNAME, szName, MAX_PATTERNNAME);
1769 BOOL CSoundFile::GetPatternName(UINT nPat, LPSTR lpszName, UINT cbSize) const
1770 //---------------------------------------------------------------------------
1772 if ((!lpszName) || (!cbSize)) return FALSE;
1774 if (cbSize > MAX_PATTERNNAME) cbSize = MAX_PATTERNNAME;
1775 if ((m_lpszPatternNames) && (nPat < m_nPatternNames))
1777 memcpy(lpszName, m_lpszPatternNames + nPat * MAX_PATTERNNAME, cbSize);
1778 lpszName[cbSize-1] = 0;
1785 #ifndef FASTSOUNDLIB
1787 UINT CSoundFile::DetectUnusedSamples(BOOL *pbIns)
1788 //-----------------------------------------------
1792 if (!pbIns) return 0;
1795 memset(pbIns, 0, MAX_SAMPLES * sizeof(BOOL));
1796 for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++)
1798 MODCOMMAND *p = Patterns[ipat];
1801 UINT jmax = PatternSize[ipat] * m_nChannels;
1802 for (UINT j=0; j<jmax; j++, p++)
1804 if ((p->note) && (p->note <= 120))
1806 if ((p->instr) && (p->instr < MAX_INSTRUMENTS))
1808 INSTRUMENTHEADER *penv = Headers[p->instr];
1811 UINT n = penv->Keyboard[p->note-1];
1812 if (n < MAX_SAMPLES) pbIns[n] = TRUE;
1816 for (UINT k=1; k<=m_nInstruments; k++)
1818 INSTRUMENTHEADER *penv = Headers[k];
1821 UINT n = penv->Keyboard[p->note-1];
1822 if (n < MAX_SAMPLES) pbIns[n] = TRUE;
1830 for (UINT ichk=1; ichk<=m_nSamples; ichk++)
1832 if ((!pbIns[ichk]) && (Ins[ichk].pSample)) nExt++;
1839 BOOL CSoundFile::RemoveSelectedSamples(BOOL *pbIns)
1840 //-------------------------------------------------
1842 if (!pbIns) return FALSE;
1843 for (UINT j=1; j<MAX_SAMPLES; j++)
1845 if ((!pbIns[j]) && (Ins[j].pSample))
1848 if ((j == m_nSamples) && (j > 1)) m_nSamples--;
1855 BOOL CSoundFile::DestroySample(UINT nSample)
1856 //------------------------------------------
1858 if ((!nSample) || (nSample >= MAX_SAMPLES)) return FALSE;
1859 if (!Ins[nSample].pSample) return TRUE;
1860 MODINSTRUMENT *pins = &Ins[nSample];
1861 signed char *pSample = pins->pSample;
1862 pins->pSample = NULL;
1864 pins->uFlags &= ~(CHN_16BIT);
1865 for (UINT i=0; i<MAX_CHANNELS; i++)
1867 if (Chn[i].pSample == pSample)
1869 Chn[i].nPos = Chn[i].nLength = 0;
1870 Chn[i].pSample = Chn[i].pCurrentSample = NULL;
1873 FreeSample(pSample);
1877 #endif // FASTSOUNDLIB