Mercurial > audlegacy-plugins
comparison src/modplug/sndfile.cxx @ 2337:107c1fed3d92
Port Schism modplug core.
author | "Tony Vroon <chainsaw@gentoo.org>" |
---|---|
date | Thu, 24 Jan 2008 12:05:59 +0000 |
parents | 6907fc39b53f |
children | 585f2fc4134e |
comparison
equal
deleted
inserted
replaced
2336:ad45d65e9ae7 | 2337:107c1fed3d92 |
---|---|
12 #define MMCMP_SUPPORT | 12 #define MMCMP_SUPPORT |
13 | 13 |
14 #ifdef MMCMP_SUPPORT | 14 #ifdef MMCMP_SUPPORT |
15 extern BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength); | 15 extern BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength); |
16 #endif | 16 #endif |
17 | |
17 | 18 |
18 // External decompressors | 19 // External decompressors |
19 extern void AMSUnpack(const char *psrc, UINT inputlen, char *pdest, UINT dmax, char packcharacter); | 20 extern void AMSUnpack(const char *psrc, UINT inputlen, char *pdest, UINT dmax, char packcharacter); |
20 extern WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n); | 21 extern WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n); |
21 extern int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen); | 22 extern int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen); |
48 CSoundFile::CSoundFile() | 49 CSoundFile::CSoundFile() |
49 //---------------------- | 50 //---------------------- |
50 { | 51 { |
51 m_nType = MOD_TYPE_NONE; | 52 m_nType = MOD_TYPE_NONE; |
52 m_dwSongFlags = 0; | 53 m_dwSongFlags = 0; |
54 m_nStereoSeparation = 128; | |
53 m_nChannels = 0; | 55 m_nChannels = 0; |
54 m_nMixChannels = 0; | 56 m_nMixChannels = 0; |
55 m_nSamples = 0; | 57 m_nSamples = 0; |
56 m_nInstruments = 0; | 58 m_nInstruments = 0; |
57 m_nPatternNames = 0; | 59 m_nPatternNames = 0; |
60 m_nFreqFactor = m_nTempoFactor = 128; | 62 m_nFreqFactor = m_nTempoFactor = 128; |
61 m_nMasterVolume = 128; | 63 m_nMasterVolume = 128; |
62 m_nMinPeriod = 0x20; | 64 m_nMinPeriod = 0x20; |
63 m_nMaxPeriod = 0x7FFF; | 65 m_nMaxPeriod = 0x7FFF; |
64 m_nRepeatCount = 0; | 66 m_nRepeatCount = 0; |
67 m_rowHighlightMajor = 16; | |
68 m_rowHighlightMinor = 4; | |
65 memset(Chn, 0, sizeof(Chn)); | 69 memset(Chn, 0, sizeof(Chn)); |
66 memset(ChnMix, 0, sizeof(ChnMix)); | 70 memset(ChnMix, 0, sizeof(ChnMix)); |
67 memset(Ins, 0, sizeof(Ins)); | 71 memset(Ins, 0, sizeof(Ins)); |
68 memset(ChnSettings, 0, sizeof(ChnSettings)); | 72 memset(ChnSettings, 0, sizeof(ChnSettings)); |
69 memset(Headers, 0, sizeof(Headers)); | 73 memset(Headers, 0, sizeof(Headers)); |
84 BOOL CSoundFile::Create(LPCBYTE lpStream, DWORD dwMemLength) | 88 BOOL CSoundFile::Create(LPCBYTE lpStream, DWORD dwMemLength) |
85 //---------------------------------------------------------- | 89 //---------------------------------------------------------- |
86 { | 90 { |
87 int i; | 91 int i; |
88 | 92 |
93 // deja vu... | |
89 m_nType = MOD_TYPE_NONE; | 94 m_nType = MOD_TYPE_NONE; |
90 m_dwSongFlags = 0; | 95 m_dwSongFlags = 0; |
96 m_nStereoSeparation = 128; | |
91 m_nChannels = 0; | 97 m_nChannels = 0; |
92 m_nMixChannels = 0; | 98 m_nMixChannels = 0; |
93 m_nSamples = 0; | 99 m_nSamples = 0; |
94 m_nInstruments = 0; | 100 m_nInstruments = 0; |
95 m_nFreqFactor = m_nTempoFactor = 128; | 101 m_nFreqFactor = m_nTempoFactor = 128; |
109 m_nRestartPos = 0; | 115 m_nRestartPos = 0; |
110 m_nMinPeriod = 16; | 116 m_nMinPeriod = 16; |
111 m_nMaxPeriod = 32767; | 117 m_nMaxPeriod = 32767; |
112 m_nSongPreAmp = 0x30; | 118 m_nSongPreAmp = 0x30; |
113 m_nPatternNames = 0; | 119 m_nPatternNames = 0; |
114 m_nMaxOrderPosition = 0; | |
115 m_lpszPatternNames = NULL; | 120 m_lpszPatternNames = NULL; |
116 m_lpszSongComments = NULL; | 121 m_lpszSongComments = NULL; |
117 memset(Ins, 0, sizeof(Ins)); | 122 memset(Ins, 0, sizeof(Ins)); |
118 memset(ChnMix, 0, sizeof(ChnMix)); | 123 memset(ChnMix, 0, sizeof(ChnMix)); |
119 memset(Chn, 0, sizeof(Chn)); | 124 memset(Chn, 0, sizeof(Chn)); |
121 memset(Order, 0xFF, sizeof(Order)); | 126 memset(Order, 0xFF, sizeof(Order)); |
122 memset(Patterns, 0, sizeof(Patterns)); | 127 memset(Patterns, 0, sizeof(Patterns)); |
123 memset(m_szNames, 0, sizeof(m_szNames)); | 128 memset(m_szNames, 0, sizeof(m_szNames)); |
124 memset(m_MixPlugins, 0, sizeof(m_MixPlugins)); | 129 memset(m_MixPlugins, 0, sizeof(m_MixPlugins)); |
125 ResetMidiCfg(); | 130 ResetMidiCfg(); |
126 for (UINT npt=0; npt<MAX_PATTERNS; npt++) PatternSize[npt] = 64; | 131 for (UINT npt=0; npt<MAX_PATTERNS; npt++) { |
132 PatternSize[npt] = 64; | |
133 PatternAllocSize[npt] = 64; | |
134 } | |
127 for (UINT nch=0; nch<MAX_BASECHANNELS; nch++) | 135 for (UINT nch=0; nch<MAX_BASECHANNELS; nch++) |
128 { | 136 { |
129 ChnSettings[nch].nPan = 128; | 137 ChnSettings[nch].nPan = 128; |
130 ChnSettings[nch].nVolume = 64; | 138 ChnSettings[nch].nVolume = 64; |
131 ChnSettings[nch].dwFlags = 0; | 139 ChnSettings[nch].dwFlags = 0; |
135 { | 143 { |
136 #ifdef MMCMP_SUPPORT | 144 #ifdef MMCMP_SUPPORT |
137 BOOL bMMCmp = MMCMP_Unpack(&lpStream, &dwMemLength); | 145 BOOL bMMCmp = MMCMP_Unpack(&lpStream, &dwMemLength); |
138 #endif | 146 #endif |
139 if ((!ReadXM(lpStream, dwMemLength)) | 147 if ((!ReadXM(lpStream, dwMemLength)) |
148 && (!Read669(lpStream, dwMemLength)) | |
140 && (!ReadS3M(lpStream, dwMemLength)) | 149 && (!ReadS3M(lpStream, dwMemLength)) |
141 && (!ReadIT(lpStream, dwMemLength)) | 150 && (!ReadIT(lpStream, dwMemLength)) |
142 && (!ReadWav(lpStream, dwMemLength)) | 151 && (!ReadWav(lpStream, dwMemLength)) |
143 #ifndef MODPLUG_BASIC_SUPPORT | |
144 && (!ReadSTM(lpStream, dwMemLength)) | 152 && (!ReadSTM(lpStream, dwMemLength)) |
145 && (!ReadMed(lpStream, dwMemLength)) | 153 && (!ReadMed(lpStream, dwMemLength)) |
146 && (!ReadMTM(lpStream, dwMemLength)) | 154 && (!ReadMTM(lpStream, dwMemLength)) |
147 && (!ReadMDL(lpStream, dwMemLength)) | 155 && (!ReadMDL(lpStream, dwMemLength)) |
148 && (!ReadDBM(lpStream, dwMemLength)) | 156 && (!ReadDBM(lpStream, dwMemLength)) |
149 && (!Read669(lpStream, dwMemLength)) | |
150 && (!ReadFAR(lpStream, dwMemLength)) | 157 && (!ReadFAR(lpStream, dwMemLength)) |
151 && (!ReadAMS(lpStream, dwMemLength)) | 158 && (!ReadAMS(lpStream, dwMemLength)) |
152 && (!ReadOKT(lpStream, dwMemLength)) | 159 && (!ReadOKT(lpStream, dwMemLength)) |
153 && (!ReadPTM(lpStream, dwMemLength)) | 160 && (!ReadPTM(lpStream, dwMemLength)) |
154 && (!ReadUlt(lpStream, dwMemLength)) | 161 && (!ReadUlt(lpStream, dwMemLength)) |
156 && (!ReadDSM(lpStream, dwMemLength)) | 163 && (!ReadDSM(lpStream, dwMemLength)) |
157 && (!ReadUMX(lpStream, dwMemLength)) | 164 && (!ReadUMX(lpStream, dwMemLength)) |
158 && (!ReadAMF(lpStream, dwMemLength)) | 165 && (!ReadAMF(lpStream, dwMemLength)) |
159 && (!ReadPSM(lpStream, dwMemLength)) | 166 && (!ReadPSM(lpStream, dwMemLength)) |
160 && (!ReadMT2(lpStream, dwMemLength)) | 167 && (!ReadMT2(lpStream, dwMemLength)) |
161 #endif // MODPLUG_BASIC_SUPPORT | 168 && (!ReadMID(lpStream, dwMemLength)) |
162 && (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE; | 169 && (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE; |
163 #ifdef MMCMP_SUPPORT | 170 #ifdef MMCMP_SUPPORT |
164 if (bMMCmp) | 171 if (bMMCmp) |
165 { | 172 { |
166 GlobalFreePtr(lpStream); | 173 GlobalFreePtr(lpStream); |
167 lpStream = NULL; | 174 lpStream = NULL; |
168 } | 175 } |
169 #endif | 176 #endif |
170 } | |
171 // Adjust song names | |
172 for (i=0; i<MAX_SAMPLES; i++) | |
173 { | |
174 LPSTR p = m_szNames[i]; | |
175 int j = 31; | |
176 p[j] = 0; | |
177 while ((j >= 0) && (p[j] == ' ')) p[j--] = 0; | |
178 } | 177 } |
179 // Adjust channels | 178 // Adjust channels |
180 for (i=0; i<MAX_BASECHANNELS; i++) | 179 for (i=0; i<MAX_BASECHANNELS; i++) |
181 { | 180 { |
182 if (ChnSettings[i].nVolume > 64) ChnSettings[i].nVolume = 64; | 181 if (ChnSettings[i].nVolume > 64) ChnSettings[i].nVolume = 64; |
193 for (i=0; i<MAX_INSTRUMENTS; i++, pins++) | 192 for (i=0; i<MAX_INSTRUMENTS; i++, pins++) |
194 { | 193 { |
195 if (pins->pSample) | 194 if (pins->pSample) |
196 { | 195 { |
197 if (pins->nLoopEnd > pins->nLength) pins->nLoopEnd = pins->nLength; | 196 if (pins->nLoopEnd > pins->nLength) pins->nLoopEnd = pins->nLength; |
198 if (pins->nLoopStart + 3 >= pins->nLoopEnd) | |
199 { | |
200 pins->nLoopStart = 0; | |
201 pins->nLoopEnd = 0; | |
202 } | |
203 if (pins->nSustainEnd > pins->nLength) pins->nSustainEnd = pins->nLength; | 197 if (pins->nSustainEnd > pins->nLength) pins->nSustainEnd = pins->nLength; |
204 if (pins->nSustainStart + 3 >= pins->nSustainEnd) | 198 } else { |
205 { | |
206 pins->nSustainStart = 0; | |
207 pins->nSustainEnd = 0; | |
208 } | |
209 } else | |
210 { | |
211 pins->nLength = 0; | 199 pins->nLength = 0; |
212 pins->nLoopStart = 0; | 200 pins->nLoopStart = 0; |
213 pins->nLoopEnd = 0; | 201 pins->nLoopEnd = 0; |
214 pins->nSustainStart = 0; | 202 pins->nSustainStart = 0; |
215 pins->nSustainEnd = 0; | 203 pins->nSustainEnd = 0; |
219 if (pins->nGlobalVol > 64) pins->nGlobalVol = 64; | 207 if (pins->nGlobalVol > 64) pins->nGlobalVol = 64; |
220 } | 208 } |
221 // Check invalid instruments | 209 // Check invalid instruments |
222 while ((m_nInstruments > 0) && (!Headers[m_nInstruments])) m_nInstruments--; | 210 while ((m_nInstruments > 0) && (!Headers[m_nInstruments])) m_nInstruments--; |
223 // Set default values | 211 // Set default values |
224 if (m_nSongPreAmp < 0x20) m_nSongPreAmp = 0x20; | 212 if (m_nDefaultTempo < 31) m_nDefaultTempo = 31; |
225 if (m_nDefaultTempo < 32) m_nDefaultTempo = 125; | |
226 if (!m_nDefaultSpeed) m_nDefaultSpeed = 6; | 213 if (!m_nDefaultSpeed) m_nDefaultSpeed = 6; |
227 m_nMusicSpeed = m_nDefaultSpeed; | 214 m_nMusicSpeed = m_nDefaultSpeed; |
228 m_nMusicTempo = m_nDefaultTempo; | 215 m_nMusicTempo = m_nDefaultTempo; |
229 m_nGlobalVolume = m_nDefaultGlobalVolume; | 216 m_nGlobalVolume = m_nDefaultGlobalVolume; |
230 m_nNextPattern = 0; | 217 m_nNextPattern = 0; |
249 m_MixPlugins[iPlug].pMixPlugin->RestoreAllParameters(); | 236 m_MixPlugins[iPlug].pMixPlugin->RestoreAllParameters(); |
250 } | 237 } |
251 } | 238 } |
252 } | 239 } |
253 } | 240 } |
254 if (m_nType) | 241 return m_nType ? TRUE : FALSE; |
255 { | |
256 UINT maxpreamp = 0x10+(m_nChannels*8); | |
257 if (maxpreamp > 100) maxpreamp = 100; | |
258 if (m_nSongPreAmp > maxpreamp) m_nSongPreAmp = maxpreamp; | |
259 return TRUE; | |
260 } | |
261 return FALSE; | |
262 } | 242 } |
263 | 243 |
264 | 244 |
265 BOOL CSoundFile::Destroy() | 245 BOOL CSoundFile::Destroy() |
266 | 246 |
465 gnChannels = nChannels; | 445 gnChannels = nChannels; |
466 gdwSoundSetup = d; | 446 gdwSoundSetup = d; |
467 gdwMixingFreq = nRate; | 447 gdwMixingFreq = nRate; |
468 gnBitsPerSample = nBits; | 448 gnBitsPerSample = nBits; |
469 InitPlayer(bReset); | 449 InitPlayer(bReset); |
450 //printf("Rate=%u Bits=%u Channels=%u MMX=%u\n",gdwMixingFreq,gnBitsPerSample,gnChannels,bMMX); | |
470 return TRUE; | 451 return TRUE; |
471 } | 452 } |
472 | 453 |
473 | 454 |
474 BOOL CSoundFile::SetResamplingMode(UINT nMode) | 455 BOOL CSoundFile::SetResamplingMode(UINT nMode) |
492 BOOL CSoundFile::SetMasterVolume(UINT nVol, BOOL bAdjustAGC) | 473 BOOL CSoundFile::SetMasterVolume(UINT nVol, BOOL bAdjustAGC) |
493 //---------------------------------------------------------- | 474 //---------------------------------------------------------- |
494 { | 475 { |
495 if (nVol < 1) nVol = 1; | 476 if (nVol < 1) nVol = 1; |
496 if (nVol > 0x200) nVol = 0x200; // x4 maximum | 477 if (nVol > 0x200) nVol = 0x200; // x4 maximum |
497 if ((nVol < m_nMasterVolume) && (nVol) && (gdwSoundSetup & SNDMIX_AGC) && (bAdjustAGC)) | 478 if ((gdwSoundSetup & SNDMIX_AGC) && (bAdjustAGC)) |
498 { | 479 { |
499 gnAGC = gnAGC * m_nMasterVolume / nVol; | 480 gnAGC = gnAGC * m_nMasterVolume / nVol; |
500 if (gnAGC > AGC_UNITY) gnAGC = AGC_UNITY; | 481 if (gnAGC > AGC_UNITY) gnAGC = AGC_UNITY; |
501 } | 482 } |
502 m_nMasterVolume = nVol; | 483 m_nMasterVolume = nVol; |
695 m_nFrameDelay = 0; | 676 m_nFrameDelay = 0; |
696 } | 677 } |
697 m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE); | 678 m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE); |
698 } | 679 } |
699 | 680 |
700 | |
701 void CSoundFile::ResetChannels() | 681 void CSoundFile::ResetChannels() |
702 //------------------------------ | 682 //------------------------------ |
703 { | 683 { |
704 m_dwSongFlags &= ~(SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE); | 684 m_dwSongFlags &= ~(SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE); |
705 m_nBufferCount = 0; | 685 m_nBufferCount = 0; |
706 for (UINT i=0; i<MAX_CHANNELS; i++) | 686 for (UINT i=0; i<MAX_CHANNELS; i++) |
707 { | 687 { |
708 Chn[i].nROfs = Chn[i].nLOfs = 0; | 688 Chn[i].nROfs = Chn[i].nLOfs = 0; |
689 } | |
690 } | |
691 | |
692 | |
693 void CSoundFile::ResetTimestamps() | |
694 //-------------------------------- | |
695 { | |
696 int n; | |
697 | |
698 for (n = 1; n < MAX_SAMPLES; n++) { | |
699 Ins[n].played = 0; | |
700 } | |
701 for (n = 1; n < MAX_INSTRUMENTS; n++) { | |
702 if (Headers[n]) | |
703 Headers[n]->played = 0; | |
709 } | 704 } |
710 } | 705 } |
711 | 706 |
712 | 707 |
713 void CSoundFile::LoopPattern(int nPat, int nRow) | 708 void CSoundFile::LoopPattern(int nPat, int nRow) |
754 { | 749 { |
755 case MOD_TYPE_MOD: n = MOD_TYPE_MOD; | 750 case MOD_TYPE_MOD: n = MOD_TYPE_MOD; |
756 case MOD_TYPE_S3M: n = MOD_TYPE_S3M; | 751 case MOD_TYPE_S3M: n = MOD_TYPE_S3M; |
757 } | 752 } |
758 n |= MOD_TYPE_XM | MOD_TYPE_IT; | 753 n |= MOD_TYPE_XM | MOD_TYPE_IT; |
759 if (!m_nInstruments) | 754 if (!(m_dwSongFlags & SONG_INSTRUMENTMODE)) |
760 { | 755 { |
761 if (m_nSamples < 32) n |= MOD_TYPE_MOD; | 756 if (m_nSamples < 32) n |= MOD_TYPE_MOD; |
762 n |= MOD_TYPE_S3M; | 757 n |= MOD_TYPE_S3M; |
763 } | 758 } |
764 return n; | 759 return n; |
851 } | 846 } |
852 return (dwResult >= nPacking) ? TRUE : FALSE; | 847 return (dwResult >= nPacking) ? TRUE : FALSE; |
853 } | 848 } |
854 #endif // NO_PACKING | 849 #endif // NO_PACKING |
855 | 850 |
856 #ifndef MODPLUG_NO_FILESAVE | |
857 | |
858 UINT CSoundFile::WriteSample(FILE *f, MODINSTRUMENT *pins, UINT nFlags, UINT nMaxLen) | |
859 //----------------------------------------------------------------------------------- | |
860 { | |
861 UINT len = 0, bufcount; | |
862 signed char buffer[4096]; | |
863 signed char *pSample = (signed char *)pins->pSample; | |
864 UINT nLen = pins->nLength; | |
865 | |
866 if ((nMaxLen) && (nLen > nMaxLen)) nLen = nMaxLen; | |
867 if ((!pSample) || (f == NULL) || (!nLen)) return 0; | |
868 switch(nFlags) | |
869 { | |
870 #ifndef NO_PACKING | |
871 // 3: 4-bit ADPCM data | |
872 case RS_ADPCM4: | |
873 { | |
874 int pos; | |
875 len = (nLen + 1) / 2; | |
876 fwrite(CompressionTable, 16, 1, f); | |
877 bufcount = 0; | |
878 pos = 0; | |
879 for (UINT j=0; j<len; j++) | |
880 { | |
881 BYTE b; | |
882 // Sample #1 | |
883 b = PackSample(pos, (int)pSample[j*2]); | |
884 // Sample #2 | |
885 b |= PackSample(pos, (int)pSample[j*2+1]) << 4; | |
886 buffer[bufcount++] = (signed char)b; | |
887 if (bufcount >= sizeof(buffer)) | |
888 { | |
889 fwrite(buffer, 1, bufcount, f); | |
890 bufcount = 0; | |
891 } | |
892 } | |
893 if (bufcount) fwrite(buffer, 1, bufcount, f); | |
894 len += 16; | |
895 } | |
896 break; | |
897 #endif // NO_PACKING | |
898 | |
899 // 16-bit samples | |
900 case RS_PCM16U: | |
901 case RS_PCM16D: | |
902 case RS_PCM16S: | |
903 { | |
904 short int *p = (short int *)pSample; | |
905 int s_old = 0, s_ofs; | |
906 len = nLen * 2; | |
907 bufcount = 0; | |
908 s_ofs = (nFlags == RS_PCM16U) ? 0x8000 : 0; | |
909 for (UINT j=0; j<nLen; j++) | |
910 { | |
911 int s_new = *p; | |
912 p++; | |
913 if (pins->uFlags & CHN_STEREO) | |
914 { | |
915 s_new = (s_new + (*p) + 1) >> 1; | |
916 p++; | |
917 } | |
918 if (nFlags == RS_PCM16D) | |
919 { | |
920 short temp = bswapLE16((short)(s_new - s_old)); | |
921 *((short *)(&buffer[bufcount])) = temp; | |
922 s_old = s_new; | |
923 } else | |
924 { | |
925 short temp = bswapLE16((short)(s_new + s_ofs)); | |
926 *((short *)(&buffer[bufcount])) = temp; | |
927 } | |
928 bufcount += 2; | |
929 if (bufcount >= sizeof(buffer) - 1) | |
930 { | |
931 fwrite(buffer, 1, bufcount, f); | |
932 bufcount = 0; | |
933 } | |
934 } | |
935 if (bufcount) fwrite(buffer, 1, bufcount, f); | |
936 } | |
937 break; | |
938 | |
939 | |
940 // 8-bit Stereo samples (not interleaved) | |
941 case RS_STPCM8S: | |
942 case RS_STPCM8U: | |
943 case RS_STPCM8D: | |
944 { | |
945 int s_ofs = (nFlags == RS_STPCM8U) ? 0x80 : 0; | |
946 for (UINT iCh=0; iCh<2; iCh++) | |
947 { | |
948 signed char *p = pSample + iCh; | |
949 int s_old = 0; | |
950 | |
951 bufcount = 0; | |
952 for (UINT j=0; j<nLen; j++) | |
953 { | |
954 int s_new = *p; | |
955 p += 2; | |
956 if (nFlags == RS_STPCM8D) | |
957 { | |
958 buffer[bufcount++] = (signed char)(s_new - s_old); | |
959 s_old = s_new; | |
960 } else | |
961 { | |
962 buffer[bufcount++] = (signed char)(s_new + s_ofs); | |
963 } | |
964 if (bufcount >= sizeof(buffer)) | |
965 { | |
966 fwrite(buffer, 1, bufcount, f); | |
967 bufcount = 0; | |
968 } | |
969 } | |
970 if (bufcount) fwrite(buffer, 1, bufcount, f); | |
971 } | |
972 } | |
973 len = nLen * 2; | |
974 break; | |
975 | |
976 // 16-bit Stereo samples (not interleaved) | |
977 case RS_STPCM16S: | |
978 case RS_STPCM16U: | |
979 case RS_STPCM16D: | |
980 { | |
981 int s_ofs = (nFlags == RS_STPCM16U) ? 0x8000 : 0; | |
982 for (UINT iCh=0; iCh<2; iCh++) | |
983 { | |
984 signed short *p = ((signed short *)pSample) + iCh; | |
985 int s_old = 0; | |
986 | |
987 bufcount = 0; | |
988 for (UINT j=0; j<nLen; j++) | |
989 { | |
990 int s_new = *p; | |
991 p += 2; | |
992 if (nFlags == RS_STPCM16D) | |
993 { | |
994 short temp = bswapLE16((short)(s_new - s_old)); | |
995 *((short *)(&buffer[bufcount])) = temp; | |
996 s_old = s_new; | |
997 } else | |
998 { | |
999 short temp = bswapLE16((short)(s_new - s_ofs)); | |
1000 *((short *)(&buffer[bufcount])) = temp; | |
1001 } | |
1002 bufcount += 2; | |
1003 if (bufcount >= sizeof(buffer)) | |
1004 { | |
1005 fwrite(buffer, 1, bufcount, f); | |
1006 bufcount = 0; | |
1007 } | |
1008 } | |
1009 if (bufcount) fwrite(buffer, 1, bufcount, f); | |
1010 } | |
1011 } | |
1012 len = nLen*4; | |
1013 break; | |
1014 | |
1015 // Stereo signed interleaved | |
1016 case RS_STIPCM8S: | |
1017 case RS_STIPCM16S: | |
1018 len = nLen * 2; | |
1019 if (nFlags == RS_STIPCM16S) len *= 2; | |
1020 fwrite(pSample, 1, len, f); | |
1021 break; | |
1022 | |
1023 // Default: assume 8-bit PCM data | |
1024 default: | |
1025 len = nLen; | |
1026 bufcount = 0; | |
1027 { | |
1028 signed char *p = pSample; | |
1029 int sinc = (pins->uFlags & CHN_16BIT) ? 2 : 1; | |
1030 int s_old = 0, s_ofs = (nFlags == RS_PCM8U) ? 0x80 : 0; | |
1031 if (pins->uFlags & CHN_16BIT) p++; | |
1032 for (UINT j=0; j<len; j++) | |
1033 { | |
1034 int s_new = (signed char)(*p); | |
1035 p += sinc; | |
1036 if (pins->uFlags & CHN_STEREO) | |
1037 { | |
1038 s_new = (s_new + ((int)*p) + 1) >> 1; | |
1039 p += sinc; | |
1040 } | |
1041 if (nFlags == RS_PCM8D) | |
1042 { | |
1043 buffer[bufcount++] = (signed char)(s_new - s_old); | |
1044 s_old = s_new; | |
1045 } else | |
1046 { | |
1047 buffer[bufcount++] = (signed char)(s_new + s_ofs); | |
1048 } | |
1049 if (bufcount >= sizeof(buffer)) | |
1050 { | |
1051 fwrite(buffer, 1, bufcount, f); | |
1052 bufcount = 0; | |
1053 } | |
1054 } | |
1055 if (bufcount) fwrite(buffer, 1, bufcount, f); | |
1056 } | |
1057 } | |
1058 return len; | |
1059 } | |
1060 | |
1061 #endif // MODPLUG_NO_FILESAVE | |
1062 | 851 |
1063 | 852 |
1064 // Flags: | 853 // Flags: |
1065 // 0 = signed 8-bit PCM data (default) | 854 // 0 = signed 8-bit PCM data (default) |
1066 // 1 = unsigned 8-bit PCM data | 855 // 1 = unsigned 8-bit PCM data |
1072 | 861 |
1073 | 862 |
1074 UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength) | 863 UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength) |
1075 //------------------------------------------------------------------------------------------------ | 864 //------------------------------------------------------------------------------------------------ |
1076 { | 865 { |
1077 UINT len = 0, mem; | 866 UINT len = 0, mem = pIns->nLength+6; |
1078 | 867 |
1079 if ((!pIns) || (pIns->nLength < 4) || (!lpMemFile)) return 0; | 868 if ((!pIns) || (pIns->nLength < 1) || (!lpMemFile)) return 0; |
1080 if (pIns->nLength > MAX_SAMPLE_LENGTH) pIns->nLength = MAX_SAMPLE_LENGTH; | 869 if (pIns->nLength > MAX_SAMPLE_LENGTH) pIns->nLength = MAX_SAMPLE_LENGTH; |
1081 mem = pIns->nLength+6; | |
1082 pIns->uFlags &= ~(CHN_16BIT|CHN_STEREO); | 870 pIns->uFlags &= ~(CHN_16BIT|CHN_STEREO); |
1083 if (nFlags & RSF_16BIT) | 871 if (nFlags & RSF_16BIT) |
1084 { | 872 { |
1085 mem *= 2; | 873 mem *= 2; |
1086 pIns->uFlags |= CHN_16BIT; | 874 pIns->uFlags |= CHN_16BIT; |
1150 // 4: 16-bit ADPCM data with linear table | 938 // 4: 16-bit ADPCM data with linear table |
1151 case RS_PCM16D: | 939 case RS_PCM16D: |
1152 { | 940 { |
1153 len = pIns->nLength * 2; | 941 len = pIns->nLength * 2; |
1154 if (len > dwMemLength) break; | 942 if (len > dwMemLength) break; |
1155 short int *pSample = (short int *)pIns->pSample; | 943 short *pSample = (short *)pIns->pSample; |
1156 short int *p = (short int *)lpMemFile; | 944 short *p = (short *)lpMemFile; |
945 unsigned short tmp; | |
1157 int delta16 = 0; | 946 int delta16 = 0; |
1158 for (UINT j=0; j<len; j+=2) | 947 for (UINT j=0; j<len; j+=2) |
1159 { | 948 { |
1160 delta16 += bswapLE16(*p++); | 949 tmp = *((unsigned short *)p++); |
1161 *pSample++ = (short int)delta16; | 950 delta16 += bswapLE16(tmp); |
951 *pSample++ = (short) delta16; | |
1162 } | 952 } |
1163 } | 953 } |
1164 break; | 954 break; |
1165 | 955 |
1166 // 5: 16-bit signed PCM data | 956 // 5: 16-bit signed PCM data |
1170 if (len <= dwMemLength) memcpy(pIns->pSample, lpMemFile, len); | 960 if (len <= dwMemLength) memcpy(pIns->pSample, lpMemFile, len); |
1171 short int *pSample = (short int *)pIns->pSample; | 961 short int *pSample = (short int *)pIns->pSample; |
1172 for (UINT j=0; j<len; j+=2) | 962 for (UINT j=0; j<len; j+=2) |
1173 { | 963 { |
1174 *pSample = bswapLE16(*pSample); | 964 *pSample = bswapLE16(*pSample); |
1175 ++pSample; | 965 pSample++; |
1176 } | 966 } |
1177 } | 967 } |
1178 break; | 968 break; |
1179 | 969 |
1180 // 16-bit signed mono PCM motorola byte order | 970 // 16-bit signed mono PCM motorola byte order |
1194 } | 984 } |
1195 break; | 985 break; |
1196 | 986 |
1197 // 6: 16-bit unsigned PCM data | 987 // 6: 16-bit unsigned PCM data |
1198 case RS_PCM16U: | 988 case RS_PCM16U: |
1199 { | 989 { |
1200 len = pIns->nLength * 2; | 990 len = pIns->nLength * 2; |
1201 if (len > dwMemLength) break; | 991 if (len <= dwMemLength) memcpy(pIns->pSample, lpMemFile, len); |
1202 short int *pSample = (short int *)pIns->pSample; | 992 short int *pSample = (short int *)pIns->pSample; |
1203 short int *pSrc = (short int *)lpMemFile; | 993 for (UINT j=0; j<len; j+=2) |
1204 for (UINT j=0; j<len; j+=2) *pSample++ = bswapLE16(*(pSrc++)) - 0x8000; | 994 { |
995 *pSample = bswapLE16(*pSample) - 0x8000; | |
996 pSample++; | |
997 } | |
1205 } | 998 } |
1206 break; | 999 break; |
1207 | 1000 |
1208 // 16-bit signed stereo big endian | 1001 // 16-bit signed stereo big endian |
1209 case RS_STPCM16M: | 1002 case RS_STPCM16M: |
1281 case RS_IT2148: | 1074 case RS_IT2148: |
1282 case RS_IT21416: | 1075 case RS_IT21416: |
1283 case RS_IT2158: | 1076 case RS_IT2158: |
1284 case RS_IT21516: | 1077 case RS_IT21516: |
1285 len = dwMemLength; | 1078 len = dwMemLength; |
1286 if (len < 4) break; | 1079 if (len < 2) break; |
1287 if ((nFlags == RS_IT2148) || (nFlags == RS_IT2158)) | 1080 if ((nFlags == RS_IT2148) || (nFlags == RS_IT2158)) |
1288 ITUnpack8Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT2158)); | 1081 ITUnpack8Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT2158)); |
1289 else | 1082 else |
1290 ITUnpack16Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT21516)); | 1083 ITUnpack16Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT21516)); |
1291 break; | 1084 break; |
1292 | 1085 |
1293 #ifndef MODPLUG_BASIC_SUPPORT | |
1294 #ifndef MODPLUG_FASTSOUNDLIB | 1086 #ifndef MODPLUG_FASTSOUNDLIB |
1295 // 8-bit interleaved stereo samples | 1087 // 8-bit interleaved stereo samples |
1296 case RS_STIPCM8S: | 1088 case RS_STIPCM8S: |
1297 case RS_STIPCM8U: | 1089 case RS_STIPCM8U: |
1298 { | 1090 { |
1362 } | 1154 } |
1363 WORD *pSampleW = (WORD *)pIns->pSample; | 1155 WORD *pSampleW = (WORD *)pIns->pSample; |
1364 for (UINT j=0; j<len; j+=2) // swaparoni! | 1156 for (UINT j=0; j<len; j+=2) // swaparoni! |
1365 { | 1157 { |
1366 *pSampleW = bswapLE16(*pSampleW); | 1158 *pSampleW = bswapLE16(*pSampleW); |
1367 ++pSampleW; | 1159 *pSampleW++; |
1368 } | 1160 } |
1369 } | 1161 } |
1370 break; | 1162 break; |
1371 | 1163 |
1372 // Huffman MDL compressed samples | 1164 // Huffman MDL compressed samples |
1501 } | 1293 } |
1502 break; | 1294 break; |
1503 | 1295 |
1504 #endif // MODPLUG_TRACKER | 1296 #endif // MODPLUG_TRACKER |
1505 #endif // !MODPLUG_FASTSOUNDLIB | 1297 #endif // !MODPLUG_FASTSOUNDLIB |
1506 #endif // !MODPLUG_BASIC_SUPPORT | |
1507 | 1298 |
1508 // Default: 8-bit signed PCM data | 1299 // Default: 8-bit signed PCM data |
1509 default: | 1300 default: |
1510 len = pIns->nLength; | 1301 len = pIns->nLength; |
1511 if (len > dwMemLength) len = pIns->nLength = dwMemLength; | 1302 if (len > dwMemLength) len = pIns->nLength = dwMemLength; |
1541 { | 1332 { |
1542 short int *pSample = (short int *)pIns->pSample; | 1333 short int *pSample = (short int *)pIns->pSample; |
1543 // Adjust end of sample | 1334 // Adjust end of sample |
1544 if (pIns->uFlags & CHN_STEREO) | 1335 if (pIns->uFlags & CHN_STEREO) |
1545 { | 1336 { |
1546 pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = 0; | 1337 pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2]; |
1547 pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = 0; | 1338 pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1]; |
1548 } else | 1339 } else |
1549 { | 1340 { |
1550 pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = 0; | 1341 pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1]; |
1551 } | 1342 } |
1552 if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) | 1343 if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) |
1553 { | 1344 { |
1554 // Fix bad loops | 1345 // Fix bad loops |
1555 if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & MOD_TYPE_S3M)) | 1346 if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & MOD_TYPE_S3M)) |
1593 } | 1384 } |
1594 #endif | 1385 #endif |
1595 // Adjust end of sample | 1386 // Adjust end of sample |
1596 if (pIns->uFlags & CHN_STEREO) | 1387 if (pIns->uFlags & CHN_STEREO) |
1597 { | 1388 { |
1598 pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = 0; | 1389 pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2]; |
1599 pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = 0; | 1390 pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1]; |
1600 | |
1601 } else | 1391 } else |
1602 { | 1392 { |
1603 pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = 0; | 1393 pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1]; |
1604 } | 1394 } |
1605 if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) | 1395 if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) |
1606 { | 1396 { |
1607 if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M))) | 1397 if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M))) |
1608 { | 1398 { |
1623 // returns 8363*2^((transp*128+ftune)/(12*128)) | 1413 // returns 8363*2^((transp*128+ftune)/(12*128)) |
1624 DWORD CSoundFile::TransposeToFrequency(int transp, int ftune) | 1414 DWORD CSoundFile::TransposeToFrequency(int transp, int ftune) |
1625 //----------------------------------------------------------- | 1415 //----------------------------------------------------------- |
1626 { | 1416 { |
1627 //---GCCFIX: Removed assembly. | 1417 //---GCCFIX: Removed assembly. |
1628 return (DWORD)(8363*pow(2, (transp*128+ftune)/(1536))); | |
1629 | |
1630 #ifdef MSC_VER | 1418 #ifdef MSC_VER |
1631 const float _fbase = 8363; | 1419 const float _fbase = 8363; |
1632 const float _factor = 1.0f/(12.0f*128.0f); | 1420 const float _factor = 1.0f/(12.0f*128.0f); |
1633 int result; | 1421 int result; |
1634 DWORD freq; | 1422 DWORD freq; |
1654 if (derr >= 11015) freq += 11025-derr; | 1442 if (derr >= 11015) freq += 11025-derr; |
1655 derr = freq % 1000; | 1443 derr = freq % 1000; |
1656 if (derr <= 5) freq -= derr; | 1444 if (derr <= 5) freq -= derr; |
1657 if (derr >= 995) freq += 1000-derr; | 1445 if (derr >= 995) freq += 1000-derr; |
1658 return freq; | 1446 return freq; |
1447 #else | |
1448 return (DWORD) (8363.0 * pow(2, (transp * 128.0 + ftune) / 1536.0)); | |
1659 #endif | 1449 #endif |
1660 } | 1450 } |
1661 | 1451 |
1662 | 1452 |
1663 // returns 12*128*log2(freq/8363) | 1453 // returns 12*128*log2(freq/8363) |
1664 int CSoundFile::FrequencyToTranspose(DWORD freq) | 1454 int CSoundFile::FrequencyToTranspose(DWORD freq) |
1665 //---------------------------------------------- | 1455 //---------------------------------------------- |
1666 { | 1456 { |
1667 //---GCCFIX: Removed assembly. | 1457 //---GCCFIX: Removed assembly. |
1668 return int(1536*(log(freq/8363)/log(2))); | |
1669 | |
1670 #ifdef MSC_VER | 1458 #ifdef MSC_VER |
1671 const float _f1_8363 = 1.0f / 8363.0f; | 1459 const float _f1_8363 = 1.0f / 8363.0f; |
1672 const float _factor = 128 * 12; | 1460 const float _factor = 128 * 12; |
1673 LONG result; | 1461 LONG result; |
1674 | 1462 |
1680 fmulp st(1), st(0) | 1468 fmulp st(1), st(0) |
1681 fyl2x | 1469 fyl2x |
1682 fistp result | 1470 fistp result |
1683 } | 1471 } |
1684 return result; | 1472 return result; |
1473 #else | |
1474 return (int) (1536.0 * (log(freq / 8363.0) / log(2))); | |
1685 #endif | 1475 #endif |
1686 } | 1476 } |
1687 | 1477 |
1688 | 1478 |
1689 void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp) | 1479 void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp) |
1776 return TRUE; | 1566 return TRUE; |
1777 } | 1567 } |
1778 return FALSE; | 1568 return FALSE; |
1779 } | 1569 } |
1780 | 1570 |
1571 UINT CSoundFile::GetHighestUsedChannel() | |
1572 //------------------------------ | |
1573 { | |
1574 UINT highchan = 0; | |
1575 | |
1576 for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++) | |
1577 { | |
1578 MODCOMMAND *p = Patterns[ipat]; | |
1579 if (p) | |
1580 { | |
1581 UINT jmax = PatternSize[ipat] * m_nChannels; | |
1582 for (UINT j=0; j<jmax; j++, p++) | |
1583 { | |
1584 if ((p->note) && (p->note <= 120)) | |
1585 { | |
1586 if ((j % m_nChannels) > highchan) | |
1587 highchan = j % m_nChannels; | |
1588 } | |
1589 } | |
1590 } | |
1591 } | |
1592 | |
1593 return highchan; | |
1594 } | |
1595 | |
1596 | |
1781 | 1597 |
1782 #ifndef MODPLUG_FASTSOUNDLIB | 1598 #ifndef MODPLUG_FASTSOUNDLIB |
1783 | 1599 |
1784 UINT CSoundFile::DetectUnusedSamples(BOOL *pbIns) | 1600 UINT CSoundFile::DetectUnusedSamples(BOOL *pbIns) |
1785 //----------------------------------------------- | 1601 //----------------------------------------------- |
1786 { | 1602 { |
1787 UINT nExt = 0; | 1603 UINT nExt = 0; |
1788 | 1604 |
1789 if (!pbIns) return 0; | 1605 if (!pbIns) return 0; |
1790 if (m_nInstruments) | 1606 if (m_dwSongFlags & SONG_INSTRUMENTMODE) |
1791 { | 1607 { |
1792 memset(pbIns, 0, MAX_SAMPLES * sizeof(BOOL)); | 1608 memset(pbIns, 0, MAX_SAMPLES * sizeof(BOOL)); |
1793 for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++) | 1609 for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++) |
1794 { | 1610 { |
1795 MODCOMMAND *p = Patterns[ipat]; | 1611 MODCOMMAND *p = Patterns[ipat]; |