aca357f0673e82f3eacc1beb8c60c25b33fe2a90
[platform/upstream/gstreamer.git] / gst / modplug / libmodplug / sndfile.cpp
1 /*
2  * This source code is public domain.
3  *
4  * Authors: Olivier Lapicque <olivierl@jps.net>,
5  *          Adam Goode       <adam@evdebs.org> (endian and char fixes for PPC)
6 */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include <math.h>       //for GCCFIX
13 #include "stdafx.h"
14 #include "sndfile.h"
15
16 #define MMCMP_SUPPORT
17
18 #ifdef MMCMP_SUPPORT
19 extern BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength);
20 #endif
21
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);
29
30
31 #define MAX_PACK_TABLES         3
32
33
34 // Compression table
35 static signed char UnpackTable[MAX_PACK_TABLES][16] =
36 //--------------------------------------------
37 {
38         // CPU-generated dynamic table
39         {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
40         // u-Law table
41         {0, 1, 2, 4, 8, 16, 32, 64,
42         -1, -2, -4, -8, -16, -32, -48, -64},
43         // Linear table
44         {0, 1, 2, 3, 5, 7, 12, 19,
45         -1, -2, -3, -5, -7, -12, -19, -31}
46 };
47
48
49 //////////////////////////////////////////////////////////
50 // CSoundFile
51
52 CSoundFile::CSoundFile()
53 //----------------------
54 {
55         m_nType = MOD_TYPE_NONE;
56         m_dwSongFlags = 0;
57         m_nChannels = 0;
58         m_nMixChannels = 0;
59         m_nSamples = 0;
60         m_nInstruments = 0;
61         m_nPatternNames = 0;
62         m_lpszPatternNames = NULL;
63         m_lpszSongComments = NULL;
64         m_nFreqFactor = m_nTempoFactor = 128;
65         m_nMasterVolume = 128;
66         m_nMinPeriod = 0x20;
67         m_nMaxPeriod = 0x7FFF;
68         m_nRepeatCount = 0;
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));
78 }
79
80
81 CSoundFile::~CSoundFile()
82 //-----------------------
83 {
84         Destroy();
85 }
86
87
88 BOOL CSoundFile::Create(LPCBYTE lpStream, DWORD dwMemLength)
89 //----------------------------------------------------------
90 {
91         int i;
92
93         m_nType = MOD_TYPE_NONE;
94         m_dwSongFlags = 0;
95         m_nChannels = 0;
96         m_nMixChannels = 0;
97         m_nSamples = 0;
98         m_nInstruments = 0;
99         m_nFreqFactor = m_nTempoFactor = 128;
100         m_nMasterVolume = 128;
101         m_nDefaultGlobalVolume = 256;
102         m_nGlobalVolume = 256;
103         m_nOldGlbVolSlide = 0;
104         m_nDefaultSpeed = 6;
105         m_nDefaultTempo = 125;
106         m_nPatternDelay = 0;
107         m_nFrameDelay = 0;
108         m_nNextRow = 0;
109         m_nRow = 0;
110         m_nPattern = 0;
111         m_nCurrentPattern = 0;
112         m_nNextPattern = 0;
113         m_nRestartPos = 0;
114         m_nMinPeriod = 16;
115         m_nMaxPeriod = 32767;
116         m_nSongPreAmp = 0x30;
117         m_nPatternNames = 0;
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));
129         ResetMidiCfg();
130         for (UINT npt=0; npt<MAX_PATTERNS; npt++) PatternSize[npt] = 64;
131         for (UINT nch=0; nch<MAX_BASECHANNELS; nch++)
132         {
133                 ChnSettings[nch].nPan = 128;
134                 ChnSettings[nch].nVolume = 64;
135                 ChnSettings[nch].dwFlags = 0;
136                 ChnSettings[nch].szName[0] = 0;
137         }
138         if (lpStream)
139         {
140 #ifdef MMCMP_SUPPORT
141                 BOOL bMMCmp = MMCMP_Unpack(&lpStream, &dwMemLength);
142 #endif
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;
167 #ifdef MMCMP_SUPPORT
168                 if (bMMCmp)
169                 {
170                         GlobalFreePtr(lpStream);
171                         lpStream = NULL;
172                 }
173 #endif
174         }
175         // Adjust song names
176         for (i=0; i<MAX_SAMPLES; i++)
177         {
178                 LPSTR p = m_szNames[i];
179                 int j = 31;
180                 p[j] = 0;
181                 while ((j>=0) && (p[j]<=' ')) p[j--] = 0;
182                 while (j>=0)
183                 {
184                         if (((BYTE)p[j]) < ' ') p[j] = ' ';
185                         j--;
186                 }
187         }
188         // Adjust channels
189         for (i=0; i<MAX_BASECHANNELS; i++)
190         {
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;
198         }
199         // Checking instruments
200         MODINSTRUMENT *pins = Ins;
201
202         for (i=0; i<MAX_INSTRUMENTS; i++, pins++)
203         {
204                 if (pins->pSample)
205                 {
206                         if (pins->nLoopEnd > pins->nLength) pins->nLoopEnd = pins->nLength;
207                         if (pins->nLoopStart + 3 >= pins->nLoopEnd)
208                         {
209                                 pins->nLoopStart = 0;
210                                 pins->nLoopEnd = 0;
211                         }
212                         if (pins->nSustainEnd > pins->nLength) pins->nSustainEnd = pins->nLength;
213                         if (pins->nSustainStart + 3 >= pins->nSustainEnd)
214                         {
215                                 pins->nSustainStart = 0;
216                                 pins->nSustainEnd = 0;
217                         }
218                 } else
219                 {
220                         pins->nLength = 0;
221                         pins->nLoopStart = 0;
222                         pins->nLoopEnd = 0;
223                         pins->nSustainStart = 0;
224                         pins->nSustainEnd = 0;
225                 }
226                 if (!pins->nLoopEnd) pins->uFlags &= ~CHN_LOOP;
227                 if (!pins->nSustainEnd) pins->uFlags &= ~CHN_SUSTAINLOOP;
228                 if (pins->nGlobalVol > 64) pins->nGlobalVol = 64;
229         }
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;
239         m_nNextPattern = 0;
240         m_nCurrentPattern = 0;
241         m_nPattern = 0;
242         m_nBufferCount = 0;
243         m_nTickCount = m_nMusicSpeed;
244         m_nNextRow = 0;
245         m_nRow = 0;
246         if ((m_nRestartPos >= MAX_ORDERS) || (Order[m_nRestartPos] >= MAX_PATTERNS)) m_nRestartPos = 0;
247         // Load plugins
248         if (gpMixPluginCreateProc)
249         {
250                 for (UINT iPlug=0; iPlug<MAX_MIXPLUGINS; iPlug++)
251                 {
252                         if ((m_MixPlugins[iPlug].Info.dwPluginId1)
253                          || (m_MixPlugins[iPlug].Info.dwPluginId2))
254                         {
255                                 gpMixPluginCreateProc(&m_MixPlugins[iPlug]);
256                                 if (m_MixPlugins[iPlug].pMixPlugin)
257                                 {
258                                         m_MixPlugins[iPlug].pMixPlugin->RestoreAllParameters();
259                                 }
260                         }
261                 }
262         }
263         if (m_nType)
264         {
265                 UINT maxpreamp = 0x10+(m_nChannels*8);
266                 if (maxpreamp > 100) maxpreamp = 100;
267                 if (m_nSongPreAmp > maxpreamp) m_nSongPreAmp = maxpreamp;
268                 return TRUE;
269         }
270         return FALSE;
271 }
272
273
274 BOOL CSoundFile::Destroy()
275
276 //------------------------
277 {
278         int i;
279         for (i=0; i<MAX_PATTERNS; i++) if (Patterns[i])
280         {
281                 FreePattern(Patterns[i]);
282                 Patterns[i] = NULL;
283         }
284         m_nPatternNames = 0;
285         if (m_lpszPatternNames)
286         {
287                 delete m_lpszPatternNames;
288                 m_lpszPatternNames = NULL;
289         }
290         if (m_lpszSongComments)
291         {
292                 delete m_lpszSongComments;
293                 m_lpszSongComments = NULL;
294         }
295         for (i=1; i<MAX_SAMPLES; i++)
296         {
297                 MODINSTRUMENT *pins = &Ins[i];
298                 if (pins->pSample)
299                 {
300                         FreeSample(pins->pSample);
301                         pins->pSample = NULL;
302                 }
303         }
304         for (i=0; i<MAX_INSTRUMENTS; i++)
305         {
306                 if (Headers[i])
307                 {
308                         delete Headers[i];
309                         Headers[i] = NULL;
310                 }
311         }
312         for (i=0; i<MAX_MIXPLUGINS; i++)
313         {
314                 if ((m_MixPlugins[i].nPluginDataSize) && (m_MixPlugins[i].pPluginData))
315                 {
316                         m_MixPlugins[i].nPluginDataSize = 0;
317                         delete [] (signed char*)m_MixPlugins[i].pPluginData;
318                         m_MixPlugins[i].pPluginData = NULL;
319                 }
320                 m_MixPlugins[i].pMixState = NULL;
321                 if (m_MixPlugins[i].pMixPlugin)
322                 {
323                         m_MixPlugins[i].pMixPlugin->Release();
324                         m_MixPlugins[i].pMixPlugin = NULL;
325                 }
326         }
327         m_nType = MOD_TYPE_NONE;
328         m_nChannels = m_nSamples = m_nInstruments = 0;
329         return TRUE;
330 }
331
332
333 //////////////////////////////////////////////////////////////////////////
334 // Memory Allocation
335
336 MODCOMMAND *CSoundFile::AllocatePattern(UINT rows, UINT nchns)
337 //------------------------------------------------------------
338 {
339         MODCOMMAND *p = new MODCOMMAND[rows*nchns];
340         if (p) memset(p, 0, rows*nchns*sizeof(MODCOMMAND));
341         return p;
342 }
343
344
345 void CSoundFile::FreePattern(LPVOID pat)
346 //--------------------------------------
347 {
348         if (pat) delete [] (signed char*)pat;
349 }
350
351
352 signed char* CSoundFile::AllocateSample(UINT nbytes)
353 //-------------------------------------------
354 {
355         signed char * p = (signed char *)GlobalAllocPtr(GHND, (nbytes+39) & ~7);
356         if (p) p += 16;
357         return p;
358 }
359
360
361 void CSoundFile::FreeSample(LPVOID p)
362 //-----------------------------------
363 {
364         if (p)
365         {
366                 GlobalFreePtr(((LPSTR)p)-16);
367         }
368 }
369
370
371 //////////////////////////////////////////////////////////////////////////
372 // Misc functions
373
374 void CSoundFile::ResetMidiCfg()
375 //-----------------------------
376 {
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);
385 }
386
387
388 UINT CSoundFile::GetNumChannels() const
389 //-------------------------------------
390 {
391         UINT n = 0;
392         for (UINT i=0; i<m_nChannels; i++) if (ChnSettings[i].nVolume) n++;
393         return n;
394 }
395
396
397 UINT CSoundFile::GetSongComments(LPSTR s, UINT len, UINT linesize)
398 //----------------------------------------------------------------
399 {
400         LPCSTR p = m_lpszSongComments;
401         if (!p) return 0;
402         UINT i = 2, ln=0;
403         if ((len) && (s)) s[0] = '\x0D';
404         if ((len > 1) && (s)) s[1] = '\x0A';
405         while ((*p)     && (i+2 < len))
406         {
407                 BYTE c = (BYTE)*p++;
408                 if ((c == 0x0D) || ((c == ' ') && (ln >= linesize)))
409                         { if (s) { s[i++] = '\x0D'; s[i++] = '\x0A'; } else i+= 2; ln=0; }
410                 else
411                 if (c >= 0x20) { if (s) s[i++] = c; else i++; ln++; }
412         }
413         if (s) s[i] = 0;
414         return i;
415 }
416
417
418 UINT CSoundFile::GetRawSongComments(LPSTR s, UINT len, UINT linesize)
419 //-------------------------------------------------------------------
420 {
421         LPCSTR p = m_lpszSongComments;
422         if (!p) return 0;
423         UINT i = 0, ln=0;
424         while ((*p)     && (i < len-1))
425         {
426                 BYTE c = (BYTE)*p++;
427                 if ((c == 0x0D) || (c == 0x0A))
428                 {
429                         if (ln)
430                         {
431                                 while (ln < linesize) { if (s) s[i] = ' '; i++; ln++; }
432                                 ln = 0;
433                         }
434                 } else
435                 if ((c == ' ') && (!ln))
436                 {
437                         UINT k=0;
438                         while ((p[k]) && (p[k] >= ' ')) k++;
439                         if (k <= linesize)
440                         {
441                                 if (s) s[i] = ' ';
442                                 i++;
443                                 ln++;
444                         }
445                 } else
446                 {
447                         if (s) s[i] = c;
448                         i++;
449                         ln++;
450                         if (ln == linesize) ln = 0;
451                 }
452         }
453         if (ln)
454         {
455                 while ((ln < linesize) && (i < len))
456                 {
457                         if (s) s[i] = ' ';
458                         i++;
459                         ln++;
460                 }
461         }
462         if (s) s[i] = 0;
463         return i;
464 }
465
466
467 BOOL CSoundFile::SetWaveConfig(UINT nRate,UINT nBits,UINT nChannels,BOOL bMMX)
468 //----------------------------------------------------------------------------
469 {
470         BOOL bReset = FALSE;
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;
475         gdwSoundSetup = d;
476         gdwMixingFreq = nRate;
477         gnBitsPerSample = nBits;
478         InitPlayer(bReset);
479         return TRUE;
480 }
481
482
483 BOOL CSoundFile::SetResamplingMode(UINT nMode)
484 //--------------------------------------------
485 {
486         DWORD d = gdwSoundSetup & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE);
487         switch(nMode)
488         {
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;
493         default:
494                 return FALSE;
495         }
496         gdwSoundSetup = d;
497         return TRUE;
498 }
499
500
501 BOOL CSoundFile::SetMasterVolume(UINT nVol, BOOL bAdjustAGC)
502 //----------------------------------------------------------
503 {
504         if (nVol < 1) nVol = 1;
505         if (nVol > 0x200) nVol = 0x200; // x4 maximum
506         if ((nVol < m_nMasterVolume) && (nVol) && (gdwSoundSetup & SNDMIX_AGC) && (bAdjustAGC))
507         {
508                 gnAGC = gnAGC * m_nMasterVolume / nVol;
509                 if (gnAGC > AGC_UNITY) gnAGC = AGC_UNITY;
510         }
511         m_nMasterVolume = nVol;
512         return TRUE;
513 }
514
515
516 void CSoundFile::SetAGC(BOOL b)
517 //-----------------------------
518 {
519         if (b)
520         {
521                 if (!(gdwSoundSetup & SNDMIX_AGC))
522                 {
523                         gdwSoundSetup |= SNDMIX_AGC;
524                         gnAGC = AGC_UNITY;
525                 }
526         } else gdwSoundSetup &= ~SNDMIX_AGC;
527 }
528
529
530 UINT CSoundFile::GetNumPatterns() const
531 //-------------------------------------
532 {
533         UINT i = 0;
534         while ((i < MAX_ORDERS) && (Order[i] < 0xFF)) i++;
535         return i;
536 }
537
538
539 UINT CSoundFile::GetNumInstruments() const
540 //----------------------------------------
541 {
542         UINT n=0;
543         for (UINT i=0; i<MAX_INSTRUMENTS; i++) if (Ins[i].pSample) n++;
544         return n;
545 }
546
547
548 UINT CSoundFile::GetMaxPosition() const
549 //-------------------------------------
550 {
551         UINT max = 0;
552         UINT i = 0;
553
554         while ((i < MAX_ORDERS) && (Order[i] != 0xFF))
555         {
556                 if (Order[i] < MAX_PATTERNS) max += PatternSize[Order[i]];
557                 i++;
558         }
559         return max;
560 }
561
562
563 UINT CSoundFile::GetCurrentPos() const
564 //------------------------------------
565 {
566         UINT pos = 0;
567
568         for (UINT i=0; i<m_nCurrentPattern; i++) if (Order[i] < MAX_PATTERNS)
569                 pos += PatternSize[Order[i]];
570         return pos + m_nRow;
571 }
572
573
574 void CSoundFile::SetCurrentPos(UINT nPos)
575 //---------------------------------------
576 {
577         UINT i, nPattern;
578
579         for (i=0; i<MAX_CHANNELS; i++)
580         {
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;
585                 Chn[i].nCommand = 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;
591         }
592         if (!nPos)
593         {
594                 for (i=0; i<MAX_CHANNELS; i++)
595                 {
596                         Chn[i].nPeriod = 0;
597                         Chn[i].nPos = Chn[i].nLength = 0;
598                         Chn[i].nLoopStart = 0;
599                         Chn[i].nLoopEnd = 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)
611                         {
612                                 Chn[i].dwFlags = ChnSettings[i].dwFlags;
613                                 Chn[i].nPan = ChnSettings[i].nPan;
614                                 Chn[i].nGlobalVol = ChnSettings[i].nVolume;
615                         } else
616                         {
617                                 Chn[i].dwFlags = 0;
618                                 Chn[i].nPan = 128;
619                                 Chn[i].nGlobalVol = 64;
620                         }
621                 }
622                 m_nGlobalVolume = m_nDefaultGlobalVolume;
623                 m_nMusicSpeed = m_nDefaultSpeed;
624                 m_nMusicTempo = m_nDefaultTempo;
625         }
626         m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE);
627         for (nPattern = 0; nPattern < MAX_ORDERS; nPattern++)
628         {
629                 UINT ord = Order[nPattern];
630                 if (ord == 0xFE) continue;
631                 if (ord == 0xFF) break;
632                 if (ord < MAX_PATTERNS)
633                 {
634                         if (nPos < (UINT)PatternSize[ord]) break;
635                         nPos -= PatternSize[ord];
636                 }
637         }
638         // Buggy position ?
639         if ((nPattern >= MAX_ORDERS)
640          || (Order[nPattern] >= MAX_PATTERNS)
641          || (nPos >= PatternSize[Order[nPattern]]))
642         {
643                 nPos = 0;
644                 nPattern = 0;
645         }
646         UINT nRow = nPos;
647         if ((nRow) && (Order[nPattern] < MAX_PATTERNS))
648         {
649                 MODCOMMAND *p = Patterns[Order[nPattern]];
650                 if ((p) && (nRow < PatternSize[Order[nPattern]]))
651                 {
652                         BOOL bOk = FALSE;
653                         while ((!bOk) && (nRow > 0))
654                         {
655                                 UINT n = nRow * m_nChannels;
656                                 for (UINT k=0; k<m_nChannels; k++, n++)
657                                 {
658                                         if (p[n].note)
659                                         {
660                                                 bOk = TRUE;
661                                                 break;
662                                         }
663                                 }
664                                 if (!bOk) nRow--;
665                         }
666                 }
667         }
668         m_nNextPattern = nPattern;
669         m_nNextRow = nRow;
670         m_nTickCount = m_nMusicSpeed;
671         m_nBufferCount = 0;
672         m_nPatternDelay = 0;
673         m_nFrameDelay = 0;
674 }
675
676
677 void CSoundFile::SetCurrentOrder(UINT nPos)
678 //-----------------------------------------
679 {
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++)
683         {
684                 Chn[j].nPeriod = 0;
685                 Chn[j].nNote = 0;
686                 Chn[j].nPortamentoDest = 0;
687                 Chn[j].nCommand = 0;
688                 Chn[j].nPatternLoopCount = 0;
689                 Chn[j].nPatternLoop = 0;
690                 Chn[j].nTremorCount = 0;
691         }
692         if (!nPos)
693         {
694                 SetCurrentPos(0);
695         } else
696         {
697                 m_nNextPattern = nPos;
698                 m_nRow = m_nNextRow = 0;
699                 m_nPattern = 0;
700                 m_nTickCount = m_nMusicSpeed;
701                 m_nBufferCount = 0;
702                 m_nTotalCount = 0;
703                 m_nPatternDelay = 0;
704                 m_nFrameDelay = 0;
705         }
706         m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE);
707 }
708
709
710 void CSoundFile::ResetChannels()
711 //------------------------------
712 {
713         m_dwSongFlags &= ~(SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE);
714         m_nBufferCount = 0;
715         for (UINT i=0; i<MAX_CHANNELS; i++)
716         {
717                 Chn[i].nROfs = Chn[i].nLOfs = 0;
718         }
719 }
720
721
722 void CSoundFile::LoopPattern(int nPat, int nRow)
723 //----------------------------------------------
724 {
725         if ((nPat < 0) || (nPat >= MAX_PATTERNS) || (!Patterns[nPat]))
726         {
727                 m_dwSongFlags &= ~SONG_PATTERNLOOP;
728         } else
729         {
730                 if ((nRow < 0) || (nRow >= PatternSize[nPat])) nRow = 0;
731                 m_nPattern = nPat;
732                 m_nRow = m_nNextRow = nRow;
733                 m_nTickCount = m_nMusicSpeed;
734                 m_nPatternDelay = 0;
735                 m_nFrameDelay = 0;
736                 m_nBufferCount = 0;
737                 m_dwSongFlags |= SONG_PATTERNLOOP;
738         }
739 }
740
741
742 UINT CSoundFile::GetBestSaveFormat() const
743 //----------------------------------------
744 {
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))
748                 return MOD_TYPE_MOD;
749         if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_STM|MOD_TYPE_ULT|MOD_TYPE_FAR|MOD_TYPE_PTM))
750                 return MOD_TYPE_S3M;
751         if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MED|MOD_TYPE_MTM|MOD_TYPE_MT2))
752                 return MOD_TYPE_XM;
753         return MOD_TYPE_IT;
754 }
755
756
757 UINT CSoundFile::GetSaveFormats() const
758 //-------------------------------------
759 {
760         UINT n = 0;
761         if ((!m_nSamples) || (!m_nChannels) || (m_nType == MOD_TYPE_NONE)) return 0;
762         switch(m_nType)
763         {
764         case MOD_TYPE_MOD:      n = MOD_TYPE_MOD;
765         case MOD_TYPE_S3M:      n = MOD_TYPE_S3M;
766         }
767         n |= MOD_TYPE_XM | MOD_TYPE_IT;
768         if (!m_nInstruments)
769         {
770                 if (m_nSamples < 32) n |= MOD_TYPE_MOD;
771                 n |= MOD_TYPE_S3M;
772         }
773         return n;
774 }
775
776
777 UINT CSoundFile::GetSampleName(UINT nSample,LPSTR s) const
778 //--------------------------------------------------------
779 {
780         char sztmp[40] = "";      // changed from CHAR
781         memcpy(sztmp, m_szNames[nSample],32);
782         sztmp[31] = 0;
783         if (s) strcpy(s, sztmp);
784         return strlen(sztmp);
785 }
786
787
788 UINT CSoundFile::GetInstrumentName(UINT nInstr,LPSTR s) const
789 //-----------------------------------------------------------
790 {
791         char sztmp[40] = "";  // changed from CHAR
792         if ((nInstr >= MAX_INSTRUMENTS) || (!Headers[nInstr]))
793         {
794                 if (s) *s = 0;
795                 return 0;
796         }
797         INSTRUMENTHEADER *penv = Headers[nInstr];
798         memcpy(sztmp, penv->name, 32);
799         sztmp[31] = 0;
800         if (s) strcpy(s, sztmp);
801         return strlen(sztmp);
802 }
803
804
805 #ifndef NO_PACKING
806 UINT CSoundFile::PackSample(int &sample, int next)
807 //------------------------------------------------
808 {
809         UINT i = 0;
810         int delta = next - sample;
811         if (delta >= 0)
812         {
813                 for (i=0; i<7; i++) if (delta <= (int)CompressionTable[i+1]) break;
814         } else
815         {
816                 for (i=8; i<15; i++) if (delta >= (int)CompressionTable[i+1]) break;
817         }
818         sample += (int)CompressionTable[i];
819         return i;
820 }
821
822
823 BOOL CSoundFile::CanPackSample(signed char * pSample, UINT nLen, UINT nPacking, BYTE *result)
824 //-----------------------------------------------------------------------------------
825 {
826         int pos, old, oldpos, besttable = 0;
827         DWORD dwErr, dwTotal, dwResult;
828         int i,j;
829
830         if (result) *result = 0;
831         if ((!pSample) || (nLen < 1024)) return FALSE;
832         // Try packing with different tables
833         dwResult = 0;
834         for (j=1; j<MAX_PACK_TABLES; j++)
835         {
836                 memcpy(CompressionTable, UnpackTable[j], 16);
837                 dwErr = 0;
838                 dwTotal = 1;
839                 old = pos = oldpos = 0;
840                 for (i=0; i<(int)nLen; i++)
841                 {
842                         int s = (int)pSample[i];
843                         PackSample(pos, s);
844                         dwErr += abs(pos - oldpos);
845                         dwTotal += abs(s - old);
846                         old = s;
847                         oldpos = pos;
848                 }
849                 dwErr = _muldiv(dwErr, 100, dwTotal);
850                 if (dwErr >= dwResult)
851                 {
852                         dwResult = dwErr;
853                         besttable = j;
854                 }
855         }
856         memcpy(CompressionTable, UnpackTable[besttable], 16);
857         if (result)
858         {
859                 if (dwResult > 100) *result     = 100; else *result = (BYTE)dwResult;
860         }
861         return (dwResult >= nPacking) ? TRUE : FALSE;
862 }
863 #endif // NO_PACKING
864
865 #ifndef MODPLUG_NO_FILESAVE
866
867 UINT CSoundFile::WriteSample(FILE *f, MODINSTRUMENT *pins, UINT nFlags, UINT nMaxLen)
868 //-----------------------------------------------------------------------------------
869 {
870         UINT len = 0, bufcount;
871         signed char buffer[4096];
872         signed char *pSample = (signed char *)pins->pSample;
873         UINT nLen = pins->nLength;
874
875         if ((nMaxLen) && (nLen > nMaxLen)) nLen = nMaxLen;
876         if ((!pSample) || (f == NULL) || (!nLen)) return 0;
877         switch(nFlags)
878         {
879 #ifndef NO_PACKING
880         // 3: 4-bit ADPCM data
881         case RS_ADPCM4:
882                 {
883                         int pos;
884                         len = (nLen + 1) / 2;
885                         fwrite(CompressionTable, 16, 1, f);
886                         bufcount = 0;
887                         pos = 0;
888                         for (UINT j=0; j<len; j++)
889                         {
890                                 BYTE b;
891                                 // Sample #1
892                                 b = PackSample(pos, (int)pSample[j*2]);
893                                 // Sample #2
894                                 b |= PackSample(pos, (int)pSample[j*2+1]) << 4;
895                                 buffer[bufcount++] = (signed char)b;
896                                 if (bufcount >= sizeof(buffer))
897                                 {
898                                         fwrite(buffer, 1, bufcount, f);
899                                         bufcount = 0;
900                                 }
901                         }
902                         if (bufcount) fwrite(buffer, 1, bufcount, f);
903                         len += 16;
904                 }
905                 break;
906 #endif // NO_PACKING
907
908         // 16-bit samples
909         case RS_PCM16U:
910         case RS_PCM16D:
911         case RS_PCM16S:
912                 {
913                         short int *p = (short int *)pSample;
914                         int s_old = 0, s_ofs;
915                         len = nLen * 2;
916                         bufcount = 0;
917                         s_ofs = (nFlags == RS_PCM16U) ? 0x8000 : 0;
918                         for (UINT j=0; j<nLen; j++)
919                         {
920                                 int s_new = *p;
921                                 p++;
922                                 if (pins->uFlags & CHN_STEREO)
923                                 {
924                                         s_new = (s_new + (*p) + 1) >> 1;
925                                         p++;
926                                 }
927                                 if (nFlags == RS_PCM16D)
928                                 {
929                                         *((short *)(&buffer[bufcount])) = (short)(s_new - s_old);
930                                         s_old = s_new;
931                                 } else
932                                 {
933                                         *((short *)(&buffer[bufcount])) = (short)(s_new + s_ofs);
934                                 }
935                                 bufcount += 2;
936                                 if (bufcount >= sizeof(buffer) - 1)
937                                 {
938                                         fwrite(buffer, 1, bufcount, f);
939                                         bufcount = 0;
940                                 }
941                         }
942                         if (bufcount) fwrite(buffer, 1, bufcount, f);
943                 }
944                 break;
945
946
947         // 8-bit Stereo samples (not interleaved)
948         case RS_STPCM8S:
949         case RS_STPCM8U:
950         case RS_STPCM8D:
951                 {
952                         int s_ofs = (nFlags == RS_STPCM8U) ? 0x80 : 0;
953                         for (UINT iCh=0; iCh<2; iCh++)
954                         {
955                                 signed char *p = pSample + iCh;
956                                 int s_old = 0;
957
958                                 bufcount = 0;
959                                 for (UINT j=0; j<nLen; j++)
960                                 {
961                                         int s_new = *p;
962                                         p += 2;
963                                         if (nFlags == RS_STPCM8D)
964                                         {
965                                                 buffer[bufcount++] = (signed char)(s_new - s_old);
966                                                 s_old = s_new;
967                                         } else
968                                         {
969                                                 buffer[bufcount++] = (signed char)(s_new + s_ofs);
970                                         }
971                                         if (bufcount >= sizeof(buffer))
972                                         {
973                                                 fwrite(buffer, 1, bufcount, f);
974                                                 bufcount = 0;
975                                         }
976                                 }
977                                 if (bufcount) fwrite(buffer, 1, bufcount, f);
978                         }
979                 }
980                 len = nLen * 2;
981                 break;
982
983         // 16-bit Stereo samples (not interleaved)
984         case RS_STPCM16S:
985         case RS_STPCM16U:
986         case RS_STPCM16D:
987                 {
988                         int s_ofs = (nFlags == RS_STPCM16U) ? 0x8000 : 0;
989                         for (UINT iCh=0; iCh<2; iCh++)
990                         {
991                                 signed short *p = ((signed short *)pSample) + iCh;
992                                 int s_old = 0;
993
994                                 bufcount = 0;
995                                 for (UINT j=0; j<nLen; j++)
996                                 {
997                                         int s_new = *p;
998                                         p += 2;
999                                         if (nFlags == RS_STPCM16D)
1000                                         {
1001                                                 *((short *)(&buffer[bufcount])) = (short)(s_new - s_old);
1002                                                 s_old = s_new;
1003                                         } else
1004                                         {
1005                                                 *((short *)(&buffer[bufcount])) = (short)(s_new + s_ofs);
1006                                         }
1007                                         bufcount += 2;
1008                                         if (bufcount >= sizeof(buffer))
1009                                         {
1010                                                 fwrite(buffer, 1, bufcount, f);
1011                                                 bufcount = 0;
1012                                         }
1013                                 }
1014                                 if (bufcount) fwrite(buffer, 1, bufcount, f);
1015                         }
1016                 }
1017                 len = nLen*4;
1018                 break;
1019
1020         //      Stereo signed interleaved
1021         case RS_STIPCM8S:
1022         case RS_STIPCM16S:
1023                 len = nLen * 2;
1024                 if (nFlags == RS_STIPCM16S) len *= 2;
1025                 fwrite(pSample, 1, len, f);
1026                 break;
1027
1028         // Default: assume 8-bit PCM data
1029         default:
1030                 len = nLen;
1031                 bufcount = 0;
1032                 {
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++)
1038                         {
1039                                 int s_new = (signed char)(*p);
1040                                 p += sinc;
1041                                 if (pins->uFlags & CHN_STEREO)
1042                                 {
1043                                         s_new = (s_new + ((int)*p) + 1) >> 1;
1044                                         p += sinc;
1045                                 }
1046                                 if (nFlags == RS_PCM8D)
1047                                 {
1048                                         buffer[bufcount++] = (signed char)(s_new - s_old);
1049                                         s_old = s_new;
1050                                 } else
1051                                 {
1052                                         buffer[bufcount++] = (signed char)(s_new + s_ofs);
1053                                 }
1054                                 if (bufcount >= sizeof(buffer))
1055                                 {
1056                                         fwrite(buffer, 1, bufcount, f);
1057                                         bufcount = 0;
1058                                 }
1059                         }
1060                         if (bufcount) fwrite(buffer, 1, bufcount, f);
1061                 }
1062         }
1063         return len;
1064 }
1065
1066 #endif // MODPLUG_NO_FILESAVE
1067
1068
1069 // Flags:
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
1077
1078
1079 UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength)
1080 //------------------------------------------------------------------------------------------------
1081 {
1082         UINT len = 0, mem = pIns->nLength+6;
1083
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)
1088         {
1089                 mem *= 2;
1090                 pIns->uFlags |= CHN_16BIT;
1091         }
1092         if (nFlags & RSF_STEREO)
1093         {
1094                 mem *= 2;
1095                 pIns->uFlags |= CHN_STEREO;
1096         }
1097         if ((pIns->pSample = AllocateSample(mem)) == NULL)
1098         {
1099                 pIns->nLength = 0;
1100                 return 0;
1101         }
1102         switch(nFlags)
1103         {
1104         // 1: 8-bit unsigned PCM data
1105         case RS_PCM8U:
1106                 {
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);
1111                 }
1112                 break;
1113
1114         // 2: 8-bit ADPCM data with linear table
1115         case RS_PCM8D:
1116                 {
1117                         len = pIns->nLength;
1118                         if (len > dwMemLength) break;
1119                         signed char *pSample = pIns->pSample;
1120                         const signed char *p = (const signed char *)lpMemFile;
1121                         int delta = 0;
1122
1123                         for (UINT j=0; j<len; j++)
1124                         {
1125                                 delta += p[j];
1126                                 *pSample++ = (signed char)delta;
1127                         }
1128                 }
1129                 break;
1130
1131         // 3: 4-bit ADPCM data
1132         case RS_ADPCM4:
1133                 {
1134                         len = (pIns->nLength + 1) / 2;
1135                         if (len > dwMemLength - 16) break;
1136                         memcpy(CompressionTable, lpMemFile, 16);
1137                         lpMemFile += 16;
1138                         signed char *pSample = pIns->pSample;
1139                         signed char delta = 0;
1140                         for (UINT j=0; j<len; j++)
1141                         {
1142                                 BYTE b0 = (BYTE)lpMemFile[j];
1143                                 BYTE b1 = (BYTE)(lpMemFile[j] >> 4);
1144                                 delta = (signed char)GetDeltaValue((int)delta, b0);
1145                                 pSample[0] = delta;
1146                                 delta = (signed char)GetDeltaValue((int)delta, b1);
1147                                 pSample[1] = delta;
1148                                 pSample += 2;
1149                         }
1150                         len += 16;
1151                 }
1152                 break;
1153
1154         // 4: 16-bit ADPCM data with linear table
1155         case RS_PCM16D:
1156                 {
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;
1161                         int delta16 = 0;
1162                         for (UINT j=0; j<len; j+=2)
1163                         {
1164                                 delta16 += bswapLE16(*p++);
1165                                 *pSample++ = (short int)delta16;
1166                         }
1167                 }
1168                 break;
1169
1170         // 5: 16-bit signed PCM data
1171         case RS_PCM16S:
1172                 {
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)
1177                         {
1178                                 short int s = bswapLE16(*pSample);
1179                                 *pSample++ = s;
1180                         }
1181                 }
1182                 break;
1183
1184         // 16-bit signed mono PCM motorola byte order
1185         case RS_PCM16M:
1186                 len = pIns->nLength * 2;
1187                 if (len > dwMemLength) len = dwMemLength & ~1;
1188                 if (len > 1)
1189                 {
1190                         signed char *pSample = (signed char *)pIns->pSample;
1191                         signed char *pSrc = (signed char *)lpMemFile;
1192                         for (UINT j=0; j<len; j+=2)
1193                         {
1194                                 // pSample[j] = pSrc[j+1];
1195                                 // pSample[j+1] = pSrc[j];
1196                                 *((unsigned short *)(pSample+j)) = bswapBE16(*((unsigned short *)(pSrc+j)));
1197                         }
1198                 }
1199                 break;
1200
1201         // 6: 16-bit unsigned PCM data
1202         case RS_PCM16U:
1203                 {
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;
1209                 }
1210                 break;
1211
1212         // 16-bit signed stereo big endian
1213         case RS_STPCM16M:
1214                 len = pIns->nLength * 2;
1215                 if (len*2 <= dwMemLength)
1216                 {
1217                         signed char *pSample = (signed char *)pIns->pSample;
1218                         signed char *pSrc = (signed char *)lpMemFile;
1219                         for (UINT j=0; j<len; j+=2)
1220                         {
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)));
1227                         }
1228                         len *= 2;
1229                 }
1230                 break;
1231
1232         // 8-bit stereo samples
1233         case RS_STPCM8S:
1234         case RS_STPCM8U:
1235         case RS_STPCM8D:
1236                 {
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++)
1244                         {
1245                                 pSample[j*2] = (signed char)(psrc[0] + iadd_l);
1246                                 pSample[j*2+1] = (signed char)(psrc[len] + iadd_r);
1247                                 psrc++;
1248                                 if (nFlags == RS_STPCM8D)
1249                                 {
1250                                         iadd_l = pSample[j*2];
1251                                         iadd_r = pSample[j*2+1];
1252                                 }
1253                         }
1254                         len *= 2;
1255                 }
1256                 break;
1257
1258         // 16-bit stereo samples
1259         case RS_STPCM16S:
1260         case RS_STPCM16U:
1261         case RS_STPCM16D:
1262                 {
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++)
1270                         {
1271                                 pSample[j*2] = (short int) (bswapLE16(psrc[0]) + iadd_l);
1272                                 pSample[j*2+1] = (short int) (bswapLE16(psrc[len]) + iadd_r);
1273                                 psrc++;
1274                                 if (nFlags == RS_STPCM16D)
1275                                 {
1276                                         iadd_l = pSample[j*2];
1277                                         iadd_r = pSample[j*2+1];
1278                                 }
1279                         }
1280                         len *= 4;
1281                 }
1282                 break;
1283
1284         // IT 2.14 compressed samples
1285         case RS_IT2148:
1286         case RS_IT21416:
1287         case RS_IT2158:
1288         case RS_IT21516:
1289                 len = dwMemLength;
1290                 if (len < 4) break;
1291                 if ((nFlags == RS_IT2148) || (nFlags == RS_IT2158))
1292                         ITUnpack8Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT2158));
1293                 else
1294                         ITUnpack16Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT21516));
1295                 break;
1296
1297 #ifndef MODPLUG_BASIC_SUPPORT
1298 #ifndef FASTSOUNDLIB
1299         // 8-bit interleaved stereo samples
1300         case RS_STIPCM8S:
1301         case RS_STIPCM8U:
1302                 {
1303                         int iadd = 0;
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++)
1310                         {
1311                                 pSample[j*2] = (signed char)(psrc[0] + iadd);
1312                                 pSample[j*2+1] = (signed char)(psrc[1] + iadd);
1313                                 psrc+=2;
1314                         }
1315                         len *= 2;
1316                 }
1317                 break;
1318
1319         // 16-bit interleaved stereo samples
1320         case RS_STIPCM16S:
1321         case RS_STIPCM16U:
1322                 {
1323                         int iadd = 0;
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++)
1330                         {
1331                                 pSample[j*2] = (short int)(bswapLE16(psrc[0]) + iadd);
1332                                 pSample[j*2+1] = (short int)(bswapLE16(psrc[1]) + iadd);
1333                                 psrc += 2;
1334                         }
1335                         len *= 4;
1336                 }
1337                 break;
1338
1339         // AMS compressed samples
1340         case RS_AMS8:
1341         case RS_AMS16:
1342                 len = 9;
1343                 if (dwMemLength > 9)
1344                 {
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);
1352                 }
1353                 break;
1354
1355         // PTM 8bit delta to 16-bit sample
1356         case RS_PTM8DTO16:
1357                 {
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++)
1363                         {
1364                                 delta8 += lpMemFile[j];
1365                                 *pSample++ = delta8;
1366                         }
1367                         WORD *pSampleW = (WORD *)pIns->pSample;
1368                         for (UINT j=0; j<len; j+=2)   // swaparoni!
1369                         {
1370                                 WORD s = bswapLE16(*pSampleW);
1371                                 *pSampleW++ = s;
1372                         }
1373                 }
1374                 break;
1375
1376         // Huffman MDL compressed samples
1377         case RS_MDL8:
1378         case RS_MDL16:
1379                 len = dwMemLength;
1380                 if (len >= 4)
1381                 {
1382                         LPBYTE pSample = (LPBYTE)pIns->pSample;
1383                         LPBYTE ibuf = (LPBYTE)lpMemFile;
1384                         DWORD bitbuf = bswapLE32(*((DWORD *)ibuf));
1385                         UINT bitnum = 32;
1386                         BYTE dlt = 0, lowbyte = 0;
1387                         ibuf += 4;
1388                         for (UINT j=0; j<pIns->nLength; j++)
1389                         {
1390                                 BYTE hibyte;
1391                                 BYTE sign;
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))
1395                                 {
1396                                         hibyte = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 3);
1397                                 } else
1398                                 {
1399                                         hibyte = 8;
1400                                         while (!MDLReadBits(bitbuf, bitnum, ibuf, 1)) hibyte += 0x10;
1401                                         hibyte += MDLReadBits(bitbuf, bitnum, ibuf, 4);
1402                                 }
1403                                 if (sign) hibyte = ~hibyte;
1404                                 dlt += hibyte;
1405                                 if (nFlags != RS_MDL16)
1406                                         pSample[j] = dlt;
1407                                 else
1408                                 {
1409                                         pSample[j<<1] = lowbyte;
1410                                         pSample[(j<<1)+1] = dlt;
1411                                 }
1412                         }
1413                 }
1414                 break;
1415
1416         case RS_DMF8:
1417         case RS_DMF16:
1418                 len = dwMemLength;
1419                 if (len >= 4)
1420                 {
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);
1425                 }
1426                 break;
1427
1428 #ifdef MODPLUG_TRACKER
1429         // PCM 24-bit signed -> load sample, and normalize it to 16-bit
1430         case RS_PCM24S:
1431         case RS_PCM32S:
1432                 len = pIns->nLength * 3;
1433                 if (nFlags == RS_PCM32S) len += pIns->nLength;
1434                 if (len > dwMemLength) break;
1435                 if (len > 4*8)
1436                 {
1437                         UINT slsize = (nFlags == RS_PCM32S) ? 4 : 3;
1438                         LPBYTE pSrc = (LPBYTE)lpMemFile;
1439                         LONG max = 255;
1440                         if (nFlags == RS_PCM32S) pSrc++;
1441                         for (UINT j=0; j<len; j+=slsize)
1442                         {
1443                                 LONG l = ((((pSrc[j+2] << 8) + pSrc[j+1]) << 8) + pSrc[j]) << 8;
1444                                 l /= 256;
1445                                 if (l > max) max = l;
1446                                 if (-l > max) max = -l;
1447                         }
1448                         max = (max / 128) + 1;
1449                         signed short *pDest = (signed short *)pIns->pSample;
1450                         for (UINT k=0; k<len; k+=slsize)
1451                         {
1452                                 LONG l = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8;
1453                                 *pDest++ = (signed short)(l / max);
1454                         }
1455                 }
1456                 break;
1457
1458         // Stereo PCM 24-bit signed -> load sample, and normalize it to 16-bit
1459         case RS_STIPCM24S:
1460         case RS_STIPCM32S:
1461                 len = pIns->nLength * 6;
1462                 if (nFlags == RS_STIPCM32S) len += pIns->nLength * 2;
1463                 if (len > dwMemLength) break;
1464                 if (len > 8*8)
1465                 {
1466                         UINT slsize = (nFlags == RS_STIPCM32S) ? 4 : 3;
1467                         LPBYTE pSrc = (LPBYTE)lpMemFile;
1468                         LONG max = 255;
1469                         if (nFlags == RS_STIPCM32S) pSrc++;
1470                         for (UINT j=0; j<len; j+=slsize)
1471                         {
1472                                 LONG l = ((((pSrc[j+2] << 8) + pSrc[j+1]) << 8) + pSrc[j]) << 8;
1473                                 l /= 256;
1474                                 if (l > max) max = l;
1475                                 if (-l > max) max = -l;
1476                         }
1477                         max = (max / 128) + 1;
1478                         signed short *pDest = (signed short *)pIns->pSample;
1479                         for (UINT k=0; k<len; k+=slsize)
1480                         {
1481                                 LONG lr = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8;
1482                                 k += slsize;
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;
1486                                 pDest += 2;
1487                         }
1488                 }
1489                 break;
1490
1491         // 16-bit signed big endian interleaved stereo
1492         case RS_STIPCM16M:
1493                 {
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++)
1499                         {
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]));
1502                                 psrc += 4;
1503                         }
1504                         len *= 4;
1505                 }
1506                 break;
1507
1508 #endif // MODPLUG_TRACKER
1509 #endif // !FASTSOUNDLIB
1510 #endif // !MODPLUG_BASIC_SUPPORT
1511
1512         // Default: 8-bit signed PCM data
1513         default:
1514                 len = pIns->nLength;
1515                 if (len > dwMemLength) len = pIns->nLength = dwMemLength;
1516                 memcpy(pIns->pSample, lpMemFile, len);
1517         }
1518         if (len > dwMemLength)
1519         {
1520                 if (pIns->pSample)
1521                 {
1522                         pIns->nLength = 0;
1523                         FreeSample(pIns->pSample);
1524                         pIns->pSample = NULL;
1525                 }
1526                 return 0;
1527         }
1528         AdjustSampleLoop(pIns);
1529         return len;
1530 }
1531
1532
1533 void CSoundFile::AdjustSampleLoop(MODINSTRUMENT *pIns)
1534 //----------------------------------------------------
1535 {
1536         if (!pIns->pSample) return;
1537         if (pIns->nLoopEnd > pIns->nLength) pIns->nLoopEnd = pIns->nLength;
1538         if (pIns->nLoopStart+2 >= pIns->nLoopEnd)
1539         {
1540                 pIns->nLoopStart = pIns->nLoopEnd = 0;
1541                 pIns->uFlags &= ~CHN_LOOP;
1542         }
1543         UINT len = pIns->nLength;
1544         if (pIns->uFlags & CHN_16BIT)
1545         {
1546                 short int *pSample = (short int *)pIns->pSample;
1547                 // Adjust end of sample
1548                 if (pIns->uFlags & CHN_STEREO)
1549                 {
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];
1552                 } else
1553                 {
1554                         pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1];
1555                 }
1556                 if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
1557                 {
1558                         // Fix bad loops
1559                         if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & MOD_TYPE_S3M))
1560                         {
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];
1566                         }
1567                 }
1568         } else
1569         {
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)))
1575                 {
1576                         int smpend = pSample[pIns->nLength-1], smpfix = 0, kscan;
1577                         for (kscan=pIns->nLength-1; kscan>0; kscan--)
1578                         {
1579                                 smpfix = pSample[kscan-1];
1580                                 if (smpfix != smpend) break;
1581                         }
1582                         int delta = smpfix - smpend;
1583                         if (((!(pIns->uFlags & CHN_LOOP)) || (kscan > (int)pIns->nLoopEnd))
1584                          && ((delta < -8) || (delta > 8)))
1585                         {
1586                                 while (kscan<(int)pIns->nLength)
1587                                 {
1588                                         if (!(kscan & 7))
1589                                         {
1590                                                 if (smpfix > 0) smpfix--;
1591                                                 if (smpfix < 0) smpfix++;
1592                                         }
1593                                         pSample[kscan] = (signed char)smpfix;
1594                                         kscan++;
1595                                 }
1596                         }
1597                 }
1598 #endif
1599                 // Adjust end of sample
1600                 if (pIns->uFlags & CHN_STEREO)
1601                 {
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];
1604                 } else
1605                 {
1606                         pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1];
1607                 }
1608                 if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
1609                 {
1610                         if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M)))
1611                         {
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];
1617                         }
1618                 }
1619         }
1620 }
1621
1622
1623 /////////////////////////////////////////////////////////////
1624 // Transpose <-> Frequency conversions
1625
1626 // returns 8363*2^((transp*128+ftune)/(12*128))
1627 DWORD CSoundFile::TransposeToFrequency(int transp, int ftune)
1628 //-----------------------------------------------------------
1629 {
1630         //---GCCFIX:  Removed assembly.
1631         return (DWORD)(8363*pow(2.0, (transp*128+ftune)/(1536)));
1632
1633 #ifdef MSC_VER
1634         const float _fbase = 8363;
1635         const float _factor = 1.0f/(12.0f*128.0f);
1636         int result;
1637         DWORD freq;
1638
1639         transp = (transp << 7) + ftune;
1640         _asm {
1641         fild transp
1642         fld _factor
1643         fmulp st(1), st(0)
1644         fist result
1645         fisub result
1646         f2xm1
1647         fild result
1648         fld _fbase
1649         fscale
1650         fstp st(1)
1651         fmul st(1), st(0)
1652         faddp st(1), st(0)
1653         fistp freq
1654         }
1655         UINT derr = freq % 11025;
1656         if (derr <= 8) freq -= derr;
1657         if (derr >= 11015) freq += 11025-derr;
1658         derr = freq % 1000;
1659         if (derr <= 5) freq -= derr;
1660         if (derr >= 995) freq += 1000-derr;
1661         return freq;
1662 #endif
1663 }
1664
1665
1666 // returns 12*128*log2(freq/8363)
1667 int CSoundFile::FrequencyToTranspose(DWORD freq)
1668 //----------------------------------------------
1669 {
1670         //---GCCFIX:  Removed assembly.
1671         return int(1536*(log(freq/8363.0)/log(2.0)));
1672
1673 #ifdef MSC_VER
1674         const float _f1_8363 = 1.0f / 8363.0f;
1675         const float _factor = 128 * 12;
1676         LONG result;
1677
1678         if (!freq) return 0;
1679         _asm {
1680         fld _factor
1681         fild freq
1682         fld _f1_8363
1683         fmulp st(1), st(0)
1684         fyl2x
1685         fistp result
1686         }
1687         return result;
1688 #endif
1689 }
1690
1691
1692 void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp)
1693 //--------------------------------------------------------
1694 {
1695         int f2t = FrequencyToTranspose(psmp->nC4Speed);
1696         int transp = f2t >> 7;
1697         int ftune = f2t & 0x7F;
1698         if (ftune > 80)
1699         {
1700                 transp++;
1701                 ftune -= 128;
1702         }
1703         if (transp > 127) transp = 127;
1704         if (transp < -127) transp = -127;
1705         psmp->RelativeTone = transp;
1706         psmp->nFineTune = ftune;
1707 }
1708
1709
1710 void CSoundFile::CheckCPUUsage(UINT nCPU)
1711 //---------------------------------------
1712 {
1713         if (nCPU > 100) nCPU = 100;
1714         gnCPUUsage = nCPU;
1715         if (nCPU < 90)
1716         {
1717                 m_dwSongFlags &= ~SONG_CPUVERYHIGH;
1718         } else
1719         if ((m_dwSongFlags & SONG_CPUVERYHIGH) && (nCPU >= 94))
1720         {
1721                 UINT i=MAX_CHANNELS;
1722                 while (i >= 8)
1723                 {
1724                         i--;
1725                         if (Chn[i].nLength)
1726                         {
1727                                 Chn[i].nLength = Chn[i].nPos = 0;
1728                                 nCPU -= 2;
1729                                 if (nCPU < 94) break;
1730                         }
1731                 }
1732         } else
1733         if (nCPU > 90)
1734         {
1735                 m_dwSongFlags |= SONG_CPUVERYHIGH;
1736         }
1737 }
1738
1739
1740 BOOL CSoundFile::SetPatternName(UINT nPat, LPCSTR lpszName)
1741 //---------------------------------------------------------
1742 {
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)
1749         {
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;
1754                 memset(p, 0, len);
1755                 if (m_lpszPatternNames)
1756                 {
1757                         memcpy(p, m_lpszPatternNames, m_nPatternNames * MAX_PATTERNNAME);
1758                         delete m_lpszPatternNames;
1759                         m_lpszPatternNames = NULL;
1760                 }
1761                 m_lpszPatternNames = p;
1762                 m_nPatternNames = nPat + 1;
1763         }
1764         memcpy(m_lpszPatternNames + nPat * MAX_PATTERNNAME, szName, MAX_PATTERNNAME);
1765         return TRUE;
1766 }
1767
1768
1769 BOOL CSoundFile::GetPatternName(UINT nPat, LPSTR lpszName, UINT cbSize) const
1770 //---------------------------------------------------------------------------
1771 {
1772         if ((!lpszName) || (!cbSize)) return FALSE;
1773         lpszName[0] = 0;
1774         if (cbSize > MAX_PATTERNNAME) cbSize = MAX_PATTERNNAME;
1775         if ((m_lpszPatternNames) && (nPat < m_nPatternNames))
1776         {
1777                 memcpy(lpszName, m_lpszPatternNames + nPat * MAX_PATTERNNAME, cbSize);
1778                 lpszName[cbSize-1] = 0;
1779                 return TRUE;
1780         }
1781         return FALSE;
1782 }
1783
1784
1785 #ifndef FASTSOUNDLIB
1786
1787 UINT CSoundFile::DetectUnusedSamples(BOOL *pbIns)
1788 //-----------------------------------------------
1789 {
1790         UINT nExt = 0;
1791
1792         if (!pbIns) return 0;
1793         if (m_nInstruments)
1794         {
1795                 memset(pbIns, 0, MAX_SAMPLES * sizeof(BOOL));
1796                 for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++)
1797                 {
1798                         MODCOMMAND *p = Patterns[ipat];
1799                         if (p)
1800                         {
1801                                 UINT jmax = PatternSize[ipat] * m_nChannels;
1802                                 for (UINT j=0; j<jmax; j++, p++)
1803                                 {
1804                                         if ((p->note) && (p->note <= 120))
1805                                         {
1806                                                 if ((p->instr) && (p->instr < MAX_INSTRUMENTS))
1807                                                 {
1808                                                         INSTRUMENTHEADER *penv = Headers[p->instr];
1809                                                         if (penv)
1810                                                         {
1811                                                                 UINT n = penv->Keyboard[p->note-1];
1812                                                                 if (n < MAX_SAMPLES) pbIns[n] = TRUE;
1813                                                         }
1814                                                 } else
1815                                                 {
1816                                                         for (UINT k=1; k<=m_nInstruments; k++)
1817                                                         {
1818                                                                 INSTRUMENTHEADER *penv = Headers[k];
1819                                                                 if (penv)
1820                                                                 {
1821                                                                         UINT n = penv->Keyboard[p->note-1];
1822                                                                         if (n < MAX_SAMPLES) pbIns[n] = TRUE;
1823                                                                 }
1824                                                         }
1825                                                 }
1826                                         }
1827                                 }
1828                         }
1829                 }
1830                 for (UINT ichk=1; ichk<=m_nSamples; ichk++)
1831                 {
1832                         if ((!pbIns[ichk]) && (Ins[ichk].pSample)) nExt++;
1833                 }
1834         }
1835         return nExt;
1836 }
1837
1838
1839 BOOL CSoundFile::RemoveSelectedSamples(BOOL *pbIns)
1840 //-------------------------------------------------
1841 {
1842         if (!pbIns) return FALSE;
1843         for (UINT j=1; j<MAX_SAMPLES; j++)
1844         {
1845                 if ((!pbIns[j]) && (Ins[j].pSample))
1846                 {
1847                         DestroySample(j);
1848                         if ((j == m_nSamples) && (j > 1)) m_nSamples--;
1849                 }
1850         }
1851         return TRUE;
1852 }
1853
1854
1855 BOOL CSoundFile::DestroySample(UINT nSample)
1856 //------------------------------------------
1857 {
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;
1863         pins->nLength = 0;
1864         pins->uFlags &= ~(CHN_16BIT);
1865         for (UINT i=0; i<MAX_CHANNELS; i++)
1866         {
1867                 if (Chn[i].pSample == pSample)
1868                 {
1869                         Chn[i].nPos = Chn[i].nLength = 0;
1870                         Chn[i].pSample = Chn[i].pCurrentSample = NULL;
1871                 }
1872         }
1873         FreeSample(pSample);
1874         return TRUE;
1875 }
1876
1877 #endif // FASTSOUNDLIB
1878