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