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];