comparison src/modplug/sndmix.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 b24eda79942b
comparison
equal deleted inserted replaced
2336:ad45d65e9ae7 2337:107c1fed3d92
5 */ 5 */
6 6
7 #include "stdafx.h" 7 #include "stdafx.h"
8 #include "sndfile.h" 8 #include "sndfile.h"
9 9
10 #ifdef MODPLUG_TRACKER
11 #define ENABLE_STEREOVU
12 #endif
13 10
14 // Volume ramp length, in 1/10 ms 11 // Volume ramp length, in 1/10 ms
15 #define VOLUMERAMPLEN 146 // 1.46ms = 64 samples at 44.1kHz 12 #define VOLUMERAMPLEN 146 // 1.46ms = 64 samples at 44.1kHz
16 13
17 // VU-Meter 14 // VU-Meter
18 #define VUMETER_DECAY 4 15 #define VUMETER_DECAY 16
19 16
20 // SNDMIX: These are global flags for playback control 17 // SNDMIX: These are global flags for playback control
21 UINT CSoundFile::m_nStereoSeparation = 128;
22 LONG CSoundFile::m_nStreamVolume = 0x8000; 18 LONG CSoundFile::m_nStreamVolume = 0x8000;
23 UINT CSoundFile::m_nMaxMixChannels = 32; 19 UINT CSoundFile::m_nMaxMixChannels = 32;
24 // Mixing Configuration (SetWaveConfig) 20 // Mixing Configuration (SetWaveConfig)
25 DWORD CSoundFile::gdwSysInfo = 0; 21 DWORD CSoundFile::gdwSysInfo = 0;
26 DWORD CSoundFile::gnChannels = 1; 22 DWORD CSoundFile::gnChannels = 1;
28 DWORD CSoundFile::gdwMixingFreq = 44100; 24 DWORD CSoundFile::gdwMixingFreq = 44100;
29 DWORD CSoundFile::gnBitsPerSample = 16; 25 DWORD CSoundFile::gnBitsPerSample = 16;
30 // Mixing data initialized in 26 // Mixing data initialized in
31 UINT CSoundFile::gnAGC = AGC_UNITY; 27 UINT CSoundFile::gnAGC = AGC_UNITY;
32 UINT CSoundFile::gnVolumeRampSamples = 64; 28 UINT CSoundFile::gnVolumeRampSamples = 64;
33 UINT CSoundFile::gnVUMeter = 0; 29 UINT CSoundFile::gnVULeft = 0;
30 UINT CSoundFile::gnVURight = 0;
34 UINT CSoundFile::gnCPUUsage = 0; 31 UINT CSoundFile::gnCPUUsage = 0;
35 LPSNDMIXHOOKPROC CSoundFile::gpSndMixHook = NULL; 32 LPSNDMIXHOOKPROC CSoundFile::gpSndMixHook = NULL;
36 PMIXPLUGINCREATEPROC CSoundFile::gpMixPluginCreateProc = NULL; 33 PMIXPLUGINCREATEPROC CSoundFile::gpMixPluginCreateProc = NULL;
37 LONG gnDryROfsVol = 0; 34 LONG gnDryROfsVol = 0;
38 LONG gnDryLOfsVol = 0; 35 LONG gnDryLOfsVol = 0;
40 LONG gnRvbLOfsVol = 0; 37 LONG gnRvbLOfsVol = 0;
41 int gbInitPlugins = 0; 38 int gbInitPlugins = 0;
42 39
43 typedef DWORD (MPPASMCALL * LPCONVERTPROC)(LPVOID, int *, DWORD, LPLONG, LPLONG); 40 typedef DWORD (MPPASMCALL * LPCONVERTPROC)(LPVOID, int *, DWORD, LPLONG, LPLONG);
44 41
45 extern DWORD MPPASMCALL X86_Convert32To8(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG); 42 extern DWORD MPPASMCALL Convert32To8(LPVOID lpBuffer, int *, DWORD nSamples, LONG mins[2], LONG maxs[2]);
46 extern DWORD MPPASMCALL X86_Convert32To16(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG); 43 extern DWORD MPPASMCALL Convert32To16(LPVOID lpBuffer, int *, DWORD nSamples, LONG mins[2], LONG maxs[2]);
47 extern DWORD MPPASMCALL X86_Convert32To24(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG); 44 extern DWORD MPPASMCALL Convert32To24(LPVOID lpBuffer, int *, DWORD nSamples, LONG mins[2], LONG maxs[2]);
48 extern DWORD MPPASMCALL X86_Convert32To32(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG); 45 extern DWORD MPPASMCALL Convert32To32(LPVOID lpBuffer, int *, DWORD nSamples, LONG mins[2], LONG maxs[2]);
49 extern UINT MPPASMCALL X86_AGC(int *pBuffer, UINT nSamples, UINT nAGC); 46 extern UINT MPPASMCALL AGC(int *pBuffer, UINT nSamples, UINT nAGC);
50 extern VOID MPPASMCALL X86_Dither(int *pBuffer, UINT nSamples, UINT nBits); 47 extern VOID MPPASMCALL Dither(int *pBuffer, UINT nSamples, UINT nBits);
51 extern VOID MPPASMCALL X86_InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples); 48 extern VOID MPPASMCALL InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples);
52 extern VOID MPPASMCALL X86_StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs); 49 extern VOID MPPASMCALL StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs);
53 extern VOID MPPASMCALL X86_MonoFromStereo(int *pMixBuf, UINT nSamples); 50 extern VOID MPPASMCALL MonoFromStereo(int *pMixBuf, UINT nSamples);
54 51
55 extern short int ModSinusTable[64]; 52 extern short int ModSinusTable[64];
56 extern short int ModRampDownTable[64]; 53 extern short int ModRampDownTable[64];
57 extern short int ModSquareTable[64]; 54 extern short int ModSquareTable[64];
58 extern short int ModRandomTable[64]; 55 extern short int ModRandomTable[64];
83 0x84, 0x88, 0x8C, 0x90, 80 0x84, 0x88, 0x8C, 0x90,
84 0x94, 0x98, 0x9C, 0xA0, 81 0x94, 0x98, 0x9C, 0xA0,
85 }; 82 };
86 83
87 84
88 // Return (a*b)/c - no divide error
89 int _muldiv(long a, long b, long c)
90 {
91 #ifdef MSC_VER
92 int sign, result;
93 _asm {
94 mov eax, a
95 mov ebx, b
96 or eax, eax
97 mov edx, eax
98 jge aneg
99 neg eax
100 aneg:
101 xor edx, ebx
102 or ebx, ebx
103 mov ecx, c
104 jge bneg
105 neg ebx
106 bneg:
107 xor edx, ecx
108 or ecx, ecx
109 mov sign, edx
110 jge cneg
111 neg ecx
112 cneg:
113 mul ebx
114 cmp edx, ecx
115 jae diverr
116 div ecx
117 jmp ok
118 diverr:
119 mov eax, 0x7fffffff
120 ok:
121 mov edx, sign
122 or edx, edx
123 jge rneg
124 neg eax
125 rneg:
126 mov result, eax
127 }
128 return result;
129 #else
130 return ((unsigned long long) a * (unsigned long long) b ) / c;
131 #endif
132 }
133
134
135 // Return (a*b+c/2)/c - no divide error
136 int _muldivr(long a, long b, long c)
137 {
138 #ifdef MSC_VER
139 int sign, result;
140 _asm {
141 mov eax, a
142 mov ebx, b
143 or eax, eax
144 mov edx, eax
145 jge aneg
146 neg eax
147 aneg:
148 xor edx, ebx
149 or ebx, ebx
150 mov ecx, c
151 jge bneg
152 neg ebx
153 bneg:
154 xor edx, ecx
155 or ecx, ecx
156 mov sign, edx
157 jge cneg
158 neg ecx
159 cneg:
160 mul ebx
161 mov ebx, ecx
162 shr ebx, 1
163 add eax, ebx
164 adc edx, 0
165 cmp edx, ecx
166 jae diverr
167 div ecx
168 jmp ok
169 diverr:
170 mov eax, 0x7fffffff
171 ok:
172 mov edx, sign
173 or edx, edx
174 jge rneg
175 neg eax
176 rneg:
177 mov result, eax
178 }
179 return result;
180 #else
181 return ((unsigned long long) a * (unsigned long long) b + (c >> 1)) / c;
182 #endif
183 }
184
185
186 BOOL CSoundFile::InitPlayer(BOOL bReset) 85 BOOL CSoundFile::InitPlayer(BOOL bReset)
187 //-------------------------------------- 86 //--------------------------------------
188 { 87 {
189 if (m_nMaxMixChannels > MAX_CHANNELS) m_nMaxMixChannels = MAX_CHANNELS; 88 if (m_nMaxMixChannels > MAX_CHANNELS) m_nMaxMixChannels = MAX_CHANNELS;
190 if (gdwMixingFreq < 4000) gdwMixingFreq = 4000; 89 if (gdwMixingFreq < 4000) gdwMixingFreq = 4000;
193 if (gnVolumeRampSamples < 8) gnVolumeRampSamples = 8; 92 if (gnVolumeRampSamples < 8) gnVolumeRampSamples = 8;
194 gnDryROfsVol = gnDryLOfsVol = 0; 93 gnDryROfsVol = gnDryLOfsVol = 0;
195 gnRvbROfsVol = gnRvbLOfsVol = 0; 94 gnRvbROfsVol = gnRvbLOfsVol = 0;
196 if (bReset) 95 if (bReset)
197 { 96 {
198 gnVUMeter = 0; 97 gnVULeft = 0;
98 gnVURight = 0;
199 gnCPUUsage = 0; 99 gnCPUUsage = 0;
200 } 100 }
201 gbInitPlugins = (bReset) ? 3 : 1; 101 gbInitPlugins = (bReset) ? 3 : 1;
202 InitializeDSP(bReset); 102 InitializeDSP(bReset);
103 InitializeEQ(bReset);
203 return TRUE; 104 return TRUE;
204 } 105 }
205 106
206 107
207 BOOL CSoundFile::FadeSong(UINT msec) 108 BOOL CSoundFile::FadeSong(UINT msec)
243 144
244 UINT CSoundFile::Read(LPVOID lpDestBuffer, UINT cbBuffer) 145 UINT CSoundFile::Read(LPVOID lpDestBuffer, UINT cbBuffer)
245 //------------------------------------------------------- 146 //-------------------------------------------------------
246 { 147 {
247 LPBYTE lpBuffer = (LPBYTE)lpDestBuffer; 148 LPBYTE lpBuffer = (LPBYTE)lpDestBuffer;
248 LPCONVERTPROC pCvt = X86_Convert32To8; 149 LPCONVERTPROC pCvt = Convert32To8;
150 LONG vu_min[2];
151 LONG vu_max[2];
249 UINT lRead, lMax, lSampleSize, lCount, lSampleCount, nStat=0; 152 UINT lRead, lMax, lSampleSize, lCount, lSampleCount, nStat=0;
250 LONG nVUMeterMin = 0x7FFFFFFF, nVUMeterMax = -0x7FFFFFFF; 153 #if 0
251 UINT nMaxPlugins; 154 UINT nMaxPlugins;
252 155 #endif
156
157 vu_min[0] = vu_min[1] = 0x7FFFFFFF;
158 vu_max[0] = vu_max[1] = -0x7FFFFFFF;
159
160 #if 0
253 { 161 {
254 nMaxPlugins = MAX_MIXPLUGINS; 162 nMaxPlugins = MAX_MIXPLUGINS;
255 while ((nMaxPlugins > 0) && (!m_MixPlugins[nMaxPlugins-1].pMixPlugin)) nMaxPlugins--; 163 while ((nMaxPlugins > 0) && (!m_MixPlugins[nMaxPlugins-1].pMixPlugin)) nMaxPlugins--;
256 } 164 }
165 #endif
257 m_nMixStat = 0; 166 m_nMixStat = 0;
258 lSampleSize = gnChannels; 167 lSampleSize = gnChannels;
259 if (gnBitsPerSample == 16) { lSampleSize *= 2; pCvt = X86_Convert32To16; } 168 if (gnBitsPerSample == 16) { lSampleSize *= 2; pCvt = Convert32To16; }
260 #ifndef MODPLUG_FASTSOUNDLIB 169 else if (gnBitsPerSample == 24) { lSampleSize *= 3; pCvt = Convert32To24; }
261 else if (gnBitsPerSample == 24) { lSampleSize *= 3; pCvt = X86_Convert32To24; } 170 else if (gnBitsPerSample == 32) { lSampleSize *= 4; pCvt = Convert32To32; }
262 else if (gnBitsPerSample == 32) { lSampleSize *= 4; pCvt = X86_Convert32To32; }
263 #endif
264 lMax = cbBuffer / lSampleSize; 171 lMax = cbBuffer / lSampleSize;
265 if ((!lMax) || (!lpBuffer) || (!m_nChannels)) return 0; 172 if ((!lMax) || (!lpBuffer) || (!m_nChannels)) return 0;
266 lRead = lMax; 173 lRead = lMax;
267 if (m_dwSongFlags & SONG_ENDREACHED) goto MixDone; 174 if (m_dwSongFlags & SONG_ENDREACHED) goto MixDone;
268 while (lRead > 0) 175 while (lRead > 0)
269 { 176 {
270 // Update Channel Data 177 // Update Channel Data
178 UINT lTotalSampleCount;
271 if (!m_nBufferCount) 179 if (!m_nBufferCount)
272 { 180 {
273 #ifndef MODPLUG_FASTSOUNDLIB 181 if (!(gdwSoundSetup & SNDMIX_DIRECTTODISK))
274 if (m_dwSongFlags & SONG_FADINGSONG) 182 m_nBufferCount = lRead;
275 { 183 if (!ReadNote()) {
276 m_dwSongFlags |= SONG_ENDREACHED; 184 m_dwSongFlags |= SONG_ENDREACHED;
277 m_nBufferCount = lRead; 185 if (lRead == lMax) goto MixDone;
278 } else 186 if (!(gdwSoundSetup & SNDMIX_DIRECTTODISK))
279 #endif
280 if (!ReadNote())
281 {
282 #ifndef MODPLUG_FASTSOUNDLIB
283 if (!FadeSong(FADESONGDELAY))
284 #endif
285 {
286 m_dwSongFlags |= SONG_ENDREACHED;
287 if (lRead == lMax) goto MixDone;
288 m_nBufferCount = lRead; 187 m_nBufferCount = lRead;
289 } 188 }
290 } 189 if (!m_nBufferCount) goto MixDone;
291 } 190 }
292 lCount = m_nBufferCount; 191 lCount = m_nBufferCount;
293 if (lCount > MIXBUFFERSIZE) lCount = MIXBUFFERSIZE; 192 if (lCount > MIXBUFFERSIZE) lCount = MIXBUFFERSIZE;
294 if (lCount > lRead) lCount = lRead; 193 if (lCount > lRead) lCount = lRead;
295 if (!lCount) break; 194 if (!lCount) break;
296 lSampleCount = lCount; 195 lSampleCount = lCount;
297 #ifndef MODPLUG_NO_REVERB 196 #ifndef MODPLUG_NO_REVERB
298 gnReverbSend = 0; 197 gnReverbSend = 0;
299 #endif 198 #endif
199
300 // Resetting sound buffer 200 // Resetting sound buffer
301 X86_StereoFill(MixSoundBuffer, lSampleCount, &gnDryROfsVol, &gnDryLOfsVol); 201 StereoFill(MixSoundBuffer, lSampleCount, &gnDryROfsVol, &gnDryLOfsVol);
302 if (gnChannels >= 2) 202 if (gnChannels >= 2)
303 { 203 {
304 lSampleCount *= 2; 204 lSampleCount *= 2;
305 m_nMixStat += CreateStereoMix(lCount); 205 m_nMixStat += CreateStereoMix(lCount);
206 #if 0
207 if (nMaxPlugins) ProcessPlugins(lCount);
208 #endif
306 ProcessStereoDSP(lCount); 209 ProcessStereoDSP(lCount);
307 } else 210 } else
308 { 211 {
309 m_nMixStat += CreateStereoMix(lCount); 212 m_nMixStat += CreateStereoMix(lCount);
310 ProcessStereoDSP(lCount); 213 #if 0
311 X86_MonoFromStereo(MixSoundBuffer, lCount); 214 if (nMaxPlugins) ProcessPlugins(lCount);
312 } 215 #endif
216 MonoFromStereo(MixSoundBuffer, lCount);
217 ProcessMonoDSP(lCount);
218 }
219
220 if (gdwSoundSetup & SNDMIX_EQ)
221 {
222 if (gnChannels >= 2)
223 EQStereo(MixSoundBuffer, lCount);
224 else
225 EQMono(MixSoundBuffer, lCount);
226 }
227
228
313 nStat++; 229 nStat++;
314 #ifndef NO_AGC 230 #ifndef NO_AGC
315 // Automatic Gain Control 231 // Automatic Gain Control
316 if (gdwSoundSetup & SNDMIX_AGC) ProcessAGC(lSampleCount); 232 if (gdwSoundSetup & SNDMIX_AGC) ProcessAGC(lSampleCount);
317 #endif 233 #endif
318 UINT lTotalSampleCount = lSampleCount; 234 lTotalSampleCount = lSampleCount;
319 #ifndef MODPLUG_FASTSOUNDLIB
320 // Multichannel 235 // Multichannel
321 if (gnChannels > 2) 236 if (gnChannels > 2)
322 { 237 {
323 X86_InterleaveFrontRear(MixSoundBuffer, MixRearBuffer, lSampleCount); 238 InterleaveFrontRear(MixSoundBuffer, MixRearBuffer, lSampleCount);
324 lTotalSampleCount *= 2; 239 lTotalSampleCount *= 2;
325 } 240 }
326 // Hook Function 241 // Hook Function
327 if (gpSndMixHook) 242 if (gpSndMixHook)
328 { 243 {
329 gpSndMixHook(MixSoundBuffer, lTotalSampleCount, gnChannels); 244 gpSndMixHook(MixSoundBuffer, lTotalSampleCount, gnChannels);
330 } 245 }
331 #endif
332 // Perform clipping + VU-Meter 246 // Perform clipping + VU-Meter
333 lpBuffer += pCvt(lpBuffer, MixSoundBuffer, lTotalSampleCount, &nVUMeterMin, &nVUMeterMax); 247 lpBuffer += pCvt(lpBuffer, MixSoundBuffer, lTotalSampleCount, vu_min, vu_max);
334 // Buffer ready 248 // Buffer ready
335 lRead -= lCount; 249 lRead -= lCount;
336 m_nBufferCount -= lCount; 250 m_nBufferCount -= lCount;
337 } 251 }
338 MixDone: 252 MixDone:
339 if (lRead) memset(lpBuffer, (gnBitsPerSample == 8) ? 0x80 : 0, lRead * lSampleSize); 253 if (lRead) memset(lpBuffer, (gnBitsPerSample == 8) ? 0x80 : 0, lRead * lSampleSize);
340 // VU-Meter 254 // VU-Meter
341 nVUMeterMin >>= (24-MIXING_ATTENUATION); 255 vu_min[0] >>= 18;
342 nVUMeterMax >>= (24-MIXING_ATTENUATION); 256 vu_min[1] >>= 18;
343 if (nVUMeterMax < nVUMeterMin) nVUMeterMax = nVUMeterMin; 257 vu_max[0] >>= 18;
344 if ((gnVUMeter = (UINT)(nVUMeterMax - nVUMeterMin)) > 0xFF) gnVUMeter = 0xFF; 258 vu_max[1] >>= 18;
259 if (vu_max[0] < vu_min[0]) vu_max[0] = vu_min[0];
260 if (vu_max[1] < vu_min[1]) vu_max[1] = vu_min[1];
261 if ((gnVULeft = (UINT)(vu_max[0] - vu_min[0])) > 0xFF)
262 gnVULeft = 0xFF;
263 if ((gnVURight = (UINT)(vu_max[1] - vu_min[1])) > 0xFF)
264 gnVURight = 0xFF;
345 if (nStat) { m_nMixStat += nStat-1; m_nMixStat /= nStat; } 265 if (nStat) { m_nMixStat += nStat-1; m_nMixStat /= nStat; }
346 return lMax - lRead; 266 return lMax - lRead;
347 } 267 }
348 268
349 269
353 273
354 BOOL CSoundFile::ProcessRow() 274 BOOL CSoundFile::ProcessRow()
355 //--------------------------- 275 //---------------------------
356 { 276 {
357 if (++m_nTickCount >= m_nMusicSpeed * (m_nPatternDelay+1) + m_nFrameDelay) 277 if (++m_nTickCount >= m_nMusicSpeed * (m_nPatternDelay+1) + m_nFrameDelay)
358 { 278 {
359 m_nPatternDelay = 0; 279 m_nPatternDelay = 0;
360 m_nFrameDelay = 0; 280 m_nFrameDelay = 0;
361 m_nTickCount = 0; 281 m_nTickCount = 0;
362 m_nRow = m_nNextRow; 282 m_nRow = m_nNextRow;
283
363 // Reset Pattern Loop Effect 284 // Reset Pattern Loop Effect
364 if (m_nCurrentPattern != m_nNextPattern) m_nCurrentPattern = m_nNextPattern; 285 if (m_nCurrentPattern != m_nNextPattern) {
365 // Check if pattern is valid 286 if (m_nLockedPattern < MAX_ORDERS) {
366 if (!(m_dwSongFlags & SONG_PATTERNLOOP)) 287 m_nCurrentPattern = m_nLockedPattern;
367 { 288 if (!(m_dwSongFlags & SONG_ORDERLOCKED))
368 m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF; 289 m_nLockedPattern = MAX_ORDERS;
369 if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE; 290 } else {
370 while (m_nPattern >= MAX_PATTERNS) 291 m_nCurrentPattern = m_nNextPattern;
371 { 292 }
372 // End of song ? 293
373 if ((m_nPattern == 0xFF) || (m_nCurrentPattern >= MAX_ORDERS)) 294 // Check if pattern is valid
374 { 295 if (!(m_dwSongFlags & SONG_PATTERNLOOP))
375 //if (!m_nRepeatCount) 296 {
376 return FALSE; //never repeat entire song
377 if (!m_nRestartPos)
378 {
379 m_nMusicSpeed = m_nDefaultSpeed;
380 m_nMusicTempo = m_nDefaultTempo;
381 m_nGlobalVolume = m_nDefaultGlobalVolume;
382 for (UINT i=0; i<MAX_CHANNELS; i++)
383 {
384 Chn[i].dwFlags |= CHN_NOTEFADE | CHN_KEYOFF;
385 Chn[i].nFadeOutVol = 0;
386 if (i < m_nChannels)
387 {
388 Chn[i].nGlobalVol = ChnSettings[i].nVolume;
389 Chn[i].nVolume = ChnSettings[i].nVolume;
390 Chn[i].nPan = ChnSettings[i].nPan;
391 Chn[i].nPanSwing = Chn[i].nVolSwing = 0;
392 Chn[i].nOldVolParam = 0;
393 Chn[i].nOldOffset = 0;
394 Chn[i].nOldHiOffset = 0;
395 Chn[i].nPortamentoDest = 0;
396 if (!Chn[i].nLength)
397 {
398 Chn[i].dwFlags = ChnSettings[i].dwFlags;
399 Chn[i].nLoopStart = 0;
400 Chn[i].nLoopEnd = 0;
401 Chn[i].pHeader = NULL;
402 Chn[i].pSample = NULL;
403 Chn[i].pInstrument = NULL;
404 }
405 }
406 }
407 }
408 // if (m_nRepeatCount > 0) m_nRepeatCount--;
409 m_nCurrentPattern = m_nRestartPos;
410 m_nRow = 0;
411 if ((Order[m_nCurrentPattern] >= MAX_PATTERNS) || (!Patterns[Order[m_nCurrentPattern]])) return FALSE;
412 } else
413 {
414 m_nCurrentPattern++;
415 }
416 m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF; 297 m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF;
417 if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE; 298 if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE;
418 } 299 while (m_nPattern >= MAX_PATTERNS)
419 m_nNextPattern = m_nCurrentPattern; 300 {
301 // End of song ?
302 if ((m_nPattern == 0xFF) || (m_nCurrentPattern >= MAX_ORDERS))
303 {
304 if (m_nRepeatCount > 0) m_nRepeatCount--;
305 if (!m_nRepeatCount) return FALSE;
306 m_nCurrentPattern = m_nRestartPos;
307 if ((Order[m_nCurrentPattern] >= MAX_PATTERNS)
308 || (!Patterns[Order[m_nCurrentPattern]]))
309 return FALSE;
310 } else {
311 m_nCurrentPattern++;
312 }
313 m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF;
314 if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE;
315 }
316 m_nNextPattern = m_nCurrentPattern;
317 } else if (m_nCurrentPattern < 255) {
318 if (m_nRepeatCount > 0) m_nRepeatCount--;
319 if (!m_nRepeatCount) return FALSE;
320 }
321 }
322 #ifdef MODPLUG_TRACKER
323 if (m_dwSongFlags & SONG_STEP)
324 {
325 m_dwSongFlags &= ~SONG_STEP;
326 m_dwSongFlags |= SONG_PAUSED;
327 }
328 #endif // MODPLUG_TRACKER
329 if (!PatternSize[m_nPattern] || !Patterns[m_nPattern]) {
330 /* okay, this is wrong. allocate the pattern _NOW_ */
331 Patterns[m_nPattern] = AllocatePattern(64,64);
332 PatternSize[m_nPattern] = 64;
333 PatternAllocSize[m_nPattern] = 64;
420 } 334 }
421 // Weird stuff? 335 // Weird stuff?
422 if ((m_nPattern >= MAX_PATTERNS) || (!Patterns[m_nPattern])) return FALSE; 336 if (m_nPattern >= MAX_PATTERNS) return FALSE;
423 // Should never happen 337 // Should never happen
338 // ... sure it should: suppose there's a C70 effect before a 64-row pattern.
339 // It's in fact very easy to make this happen ;)
340 // - chisel
424 if (m_nRow >= PatternSize[m_nPattern]) m_nRow = 0; 341 if (m_nRow >= PatternSize[m_nPattern]) m_nRow = 0;
425 m_nNextRow = m_nRow + 1; 342 m_nNextRow = m_nRow + 1;
426 if (m_nNextRow >= PatternSize[m_nPattern]) 343 if (m_nNextRow >= PatternSize[m_nPattern])
427 { 344 {
428 if (!(m_dwSongFlags & SONG_PATTERNLOOP)) m_nNextPattern = m_nCurrentPattern + 1; 345 if (!(m_dwSongFlags & SONG_PATTERNLOOP)) m_nNextPattern = m_nCurrentPattern + 1;
346 else if (m_nRepeatCount > 0) return FALSE;
429 m_nNextRow = 0; 347 m_nNextRow = 0;
430 } 348 }
431 // Reset channel values 349 // Reset channel values
432 MODCHANNEL *pChn = Chn; 350 MODCHANNEL *pChn = Chn;
433 MODCOMMAND *m = Patterns[m_nPattern] + m_nRow * m_nChannels; 351 MODCOMMAND *m = Patterns[m_nPattern] + m_nRow * m_nChannels;
434 for (UINT nChn=0; nChn<m_nChannels; pChn++, nChn++, m++) 352 for (UINT nChn=0; nChn<m_nChannels; pChn++, nChn++, m++)
435 { 353 {
354 /* skip realtime copyin */
355 if (pChn->nRealtime) continue;
356
357 // this is where we're going to spit out our midi
358 // commands... ALL WE DO is dump raw midi data to
359 // our super-secret "midi buffer"
360 // -mrsb
361 if (_midi_out_note)
362 _midi_out_note(nChn, m);
363
436 pChn->nRowNote = m->note; 364 pChn->nRowNote = m->note;
365 if (m->instr) pChn->nLastInstr = m->instr;
437 pChn->nRowInstr = m->instr; 366 pChn->nRowInstr = m->instr;
438 pChn->nRowVolCmd = m->volcmd; 367 pChn->nRowVolCmd = m->volcmd;
439 pChn->nRowVolume = m->vol; 368 pChn->nRowVolume = m->vol;
440 pChn->nRowCommand = m->command; 369 pChn->nRowCommand = m->command;
441 pChn->nRowParam = m->param; 370 pChn->nRowParam = m->param;
442 371
443 pChn->nLeftVol = pChn->nNewLeftVol; 372 pChn->nLeftVol = pChn->nNewLeftVol;
444 pChn->nRightVol = pChn->nNewRightVol; 373 pChn->nRightVol = pChn->nNewRightVol;
445 pChn->dwFlags &= ~(CHN_PORTAMENTO | CHN_VIBRATO | CHN_TREMOLO | CHN_PANBRELLO); 374 pChn->dwFlags &= ~(CHN_PORTAMENTO | CHN_VIBRATO | CHN_TREMOLO | CHN_PANBRELLO);
446 pChn->nCommand = 0; 375 pChn->nCommand = 0;
376 }
377
378 } else if (_midi_out_note) {
379 MODCOMMAND *m = Patterns[m_nPattern] + m_nRow * m_nChannels;
380 for (UINT nChn=0; nChn<m_nChannels; nChn++, m++)
381 {
382 /* m==NULL allows schism to receive notification of SDx and Scx commands */
383 _midi_out_note(nChn, 0);
447 } 384 }
448 } 385 }
449 // Should we process tick0 effects? 386 // Should we process tick0 effects?
450 if (!m_nMusicSpeed) m_nMusicSpeed = 1; 387 if (!m_nMusicSpeed) m_nMusicSpeed = 1;
451 m_dwSongFlags |= SONG_FIRSTTICK; 388 m_dwSongFlags |= SONG_FIRSTTICK;
467 // Handles envelopes & mixer setup 404 // Handles envelopes & mixer setup
468 405
469 BOOL CSoundFile::ReadNote() 406 BOOL CSoundFile::ReadNote()
470 //------------------------- 407 //-------------------------
471 { 408 {
472 if (!ProcessRow()) return FALSE; 409 // Checking end of row ?
410 if (m_dwSongFlags & SONG_PAUSED)
411 {
412 /*m_nTickCount = 0;*/
413 if (!m_nMusicSpeed) m_nMusicSpeed = 6;
414 if (!m_nMusicTempo) m_nMusicTempo = 125;
415 m_nPatternDelay = 0;
416 m_nFrameDelay = 0;
417
418 m_dwSongFlags |= SONG_FIRSTTICK;
419 if (m_nTickCount) {
420 m_dwSongFlags &= ~SONG_FIRSTTICK;
421 }
422
423 ProcessEffects();
424 m_nTickCount++;
425 if (m_nTickCount >= m_nMusicSpeed) {
426 m_nTickCount = 0;
427 }
428 if (!ProcessEffects()) return FALSE;
429 } else
430 {
431 if (!ProcessRow()) return FALSE;
432 }
433
434 { /* handle realtime closures */
435 MODCHANNEL *pChn = Chn;
436 for (UINT nChn=0; nChn<m_nChannels; pChn++, nChn++) {
437 /* reset end of "row" */
438 if (pChn->nRealtime && pChn->nRowNote && (pChn->nTickStart % m_nMusicSpeed) == (m_nTickCount % m_nMusicSpeed)) {
439 pChn->nRealtime = 0;
440 pChn->nRowNote = 0;
441 pChn->nRowInstr = 0;
442 //pChn->nMaster
443 pChn->nRowVolCmd = 0;
444 pChn->nRowVolume = 0;
445 pChn->nRowCommand = 0;
446 pChn->nRowParam = 0;
447 pChn->nTickStart = 0;
448 }
449 }
450 };
451
473 //////////////////////////////////////////////////////////////////////////////////// 452 ////////////////////////////////////////////////////////////////////////////////////
474 m_nTotalCount++; 453 m_nTotalCount++;
475 if (!m_nMusicTempo) return FALSE; 454 if (!m_nMusicTempo) return FALSE;
476 m_nBufferCount = (gdwMixingFreq * 5 * m_nTempoFactor) / (m_nMusicTempo << 8); 455 m_nBufferCount = (gdwMixingFreq * 5 * m_nTempoFactor) / (m_nMusicTempo << 8);
456 #ifdef MODPLUG_TRACKER
457 if (m_dwSongFlags & SONG_PAUSED)
458 {
459 m_nBufferCount = gdwMixingFreq / 64; // 1/64 seconds
460 }
461 #endif
462
477 // Master Volume + Pre-Amplification / Attenuation setup 463 // Master Volume + Pre-Amplification / Attenuation setup
478 DWORD nMasterVol; 464 DWORD nMasterVol;
479 { 465 {
480 int nchn32 = (m_nChannels < 32) ? m_nChannels : 31; 466 int nchn32 = 0;
481 if ((m_nType & MOD_TYPE_IT) && (m_nInstruments) && (nchn32 < 6)) nchn32 = 6; 467 MODCHANNEL *pChn = Chn;
468 for (UINT nChn=0; nChn<m_nChannels; nChn++, pChn++) {
469 nchn32++;
470 }
471 if (nchn32 < 1) nchn32 = 1;
472 if (nchn32 > 31) nchn32 = 31;
473
482 int realmastervol = m_nMasterVolume; 474 int realmastervol = m_nMasterVolume;
483 if (realmastervol > 0x80) 475 if (realmastervol > 0x80)
484 { 476 {
485 realmastervol = 0x80 + ((realmastervol - 0x80) * (nchn32+4)) / 16; 477 realmastervol = 0x80 + ((realmastervol - 0x80) * (nchn32+4)) / 16;
486 } 478 }
479
480 DWORD mastervol = (realmastervol * (m_nSongPreAmp)) >> 6;
481 // if (mastervol > 0x200) mastervol = 0x200;
482 if ((m_dwSongFlags & SONG_GLOBALFADE) && (m_nGlobalFadeMaxSamples))
483 {
484 mastervol = _muldiv(mastervol, m_nGlobalFadeSamples, m_nGlobalFadeMaxSamples);
485 }
486
487 UINT attenuation = (gdwSoundSetup & SNDMIX_AGC) ? PreAmpAGCTable[nchn32>>1] : PreAmpTable[nchn32>>1]; 487 UINT attenuation = (gdwSoundSetup & SNDMIX_AGC) ? PreAmpAGCTable[nchn32>>1] : PreAmpTable[nchn32>>1];
488 DWORD mastervol = (realmastervol * (m_nSongPreAmp + 0x10)) >> 6; 488 if (attenuation < 1) attenuation = 1;
489 if (mastervol > 0x200) mastervol = 0x200; 489
490 if ((m_dwSongFlags & SONG_GLOBALFADE) && (m_nGlobalFadeMaxSamples))
491 {
492 mastervol = _muldiv(mastervol, m_nGlobalFadeSamples, m_nGlobalFadeMaxSamples);
493 }
494 nMasterVol = (mastervol << 7) / attenuation; 490 nMasterVol = (mastervol << 7) / attenuation;
495 if (nMasterVol > 0x180) nMasterVol = 0x180; 491 if (nMasterVol > 0x180) nMasterVol = 0x180;
496 } 492 }
497 //////////////////////////////////////////////////////////////////////////////////// 493 ////////////////////////////////////////////////////////////////////////////////////
498 // Update channels data 494 // Update channels data
495 if (CSoundFile::gdwSoundSetup & SNDMIX_NOMIXING) return TRUE;
499 m_nMixChannels = 0; 496 m_nMixChannels = 0;
500 MODCHANNEL *pChn = Chn; 497 MODCHANNEL *pChn = Chn;
501 for (UINT nChn=0; nChn<MAX_CHANNELS; nChn++,pChn++) 498 for (UINT nChn=0; nChn<MAX_CHANNELS; nChn++,pChn++)
502 { 499 {
503 if ((pChn->dwFlags & CHN_NOTEFADE) && (!(pChn->nFadeOutVol|pChn->nRightVol|pChn->nLeftVol))) 500 if ((pChn->dwFlags & CHN_NOTEFADE) && (!(pChn->nFadeOutVol|pChn->nRightVol|pChn->nLeftVol)))
504 { 501 {
505 pChn->nLength = 0; 502 pChn->nLength = 0;
506 pChn->nROfs = pChn->nLOfs = 0; 503 pChn->nROfs = pChn->nLOfs = 0;
507 } 504 }
508 // Check for unused channel 505 // Check for unused channel
509 if ((pChn->dwFlags & CHN_MUTE) || ((nChn >= m_nChannels) && (!pChn->nLength))) 506 if ((nChn >= m_nChannels) && (!pChn->nLength))
510 { 507 {
511 pChn->nVUMeter = 0;
512 #ifdef ENABLE_STEREOVU
513 pChn->nLeftVU = pChn->nRightVU = 0; 508 pChn->nLeftVU = pChn->nRightVU = 0;
514 #endif
515 continue; 509 continue;
516 } 510 }
517 // Reset channel data 511 // Reset channel data
518 pChn->nInc = 0; 512 pChn->nInc = 0;
519 pChn->nRealVolume = 0; 513 pChn->nRealVolume = 0;
573 // Clip volume 567 // Clip volume
574 if (vol < 0) vol = 0; 568 if (vol < 0) vol = 0;
575 if (vol > 0x100) vol = 0x100; 569 if (vol > 0x100) vol = 0x100;
576 vol <<= 6; 570 vol <<= 6;
577 // Process Envelopes 571 // Process Envelopes
578 if (pChn->pHeader) 572 if ((m_dwSongFlags & SONG_INSTRUMENTMODE) && pChn->pHeader)
579 { 573 {
580 INSTRUMENTHEADER *penv = pChn->pHeader; 574 INSTRUMENTHEADER *penv = pChn->pHeader;
581 // Volume Envelope 575 // Volume Envelope
582 if ((pChn->dwFlags & CHN_VOLENV) && (penv->nVolEnv)) 576 if ((pChn->dwFlags & CHN_VOLENV) && (penv->VolEnv.nNodes))
583 { 577 {
584 int envpos = pChn->nVolEnvPosition; 578 int envpos = pChn->nVolEnvPosition;
585 UINT pt = penv->nVolEnv - 1; 579 UINT pt = penv->VolEnv.nNodes - 1;
586 for (UINT i=0; i<(UINT)(penv->nVolEnv-1); i++) 580 for (UINT i=0; i<(UINT)(penv->VolEnv.nNodes-1); i++)
587 { 581 {
588 if (envpos <= penv->VolPoints[i]) 582 if (envpos <= penv->VolEnv.Ticks[i])
589 { 583 {
590 pt = i; 584 pt = i;
591 break; 585 break;
592 } 586 }
593 } 587 }
594 int x2 = penv->VolPoints[pt]; 588 int x2 = penv->VolEnv.Ticks[pt];
595 int x1, envvol; 589 int x1, envvol;
596 if (envpos >= x2) 590 if (envpos >= x2)
597 { 591 {
598 envvol = penv->VolEnv[pt] << 2; 592 envvol = penv->VolEnv.Values[pt] << 2;
599 x1 = x2; 593 x1 = x2;
600 } else 594 } else
601 if (pt) 595 if (pt)
602 { 596 {
603 envvol = penv->VolEnv[pt-1] << 2; 597 envvol = penv->VolEnv.Values[pt-1] << 2;
604 x1 = penv->VolPoints[pt-1]; 598 x1 = penv->VolEnv.Ticks[pt-1];
605 } else 599 } else
606 { 600 {
607 envvol = 0; 601 envvol = 0;
608 x1 = 0; 602 x1 = 0;
609 } 603 }
610 if (envpos > x2) envpos = x2; 604 if (envpos > x2) envpos = x2;
611 if ((x2 > x1) && (envpos > x1)) 605 if ((x2 > x1) && (envpos > x1))
612 { 606 {
613 envvol += ((envpos - x1) * (((int)penv->VolEnv[pt]<<2) - envvol)) / (x2 - x1); 607 envvol += ((envpos - x1) * (((int)penv->VolEnv.Values[pt]<<2) - envvol)) / (x2 - x1);
614 } 608 }
615 if (envvol < 0) envvol = 0; 609 if (envvol < 0) envvol = 0;
616 if (envvol > 256) envvol = 256; 610 if (envvol > 256) envvol = 256;
617 vol = (vol * envvol) >> 8; 611 vol = (vol * envvol) >> 8;
618 } 612 }
619 // Panning Envelope 613 // Panning Envelope
620 if ((pChn->dwFlags & CHN_PANENV) && (penv->nPanEnv)) 614 if ((pChn->dwFlags & CHN_PANENV) && (penv->PanEnv.nNodes))
621 { 615 {
622 int envpos = pChn->nPanEnvPosition; 616 int envpos = pChn->nPanEnvPosition;
623 UINT pt = penv->nPanEnv - 1; 617 UINT pt = penv->PanEnv.nNodes - 1;
624 for (UINT i=0; i<(UINT)(penv->nPanEnv-1); i++) 618 for (UINT i=0; i<(UINT)(penv->PanEnv.nNodes-1); i++)
625 { 619 {
626 if (envpos <= penv->PanPoints[i]) 620 if (envpos <= penv->PanEnv.Ticks[i])
627 { 621 {
628 pt = i; 622 pt = i;
629 break; 623 break;
630 } 624 }
631 } 625 }
632 int x2 = penv->PanPoints[pt], y2 = penv->PanEnv[pt]; 626 int x2 = penv->PanEnv.Ticks[pt], y2 = penv->PanEnv.Values[pt];
633 int x1, envpan; 627 int x1, envpan;
634 if (envpos >= x2) 628 if (envpos >= x2)
635 { 629 {
636 envpan = y2; 630 envpan = y2;
637 x1 = x2; 631 x1 = x2;
638 } else 632 } else
639 if (pt) 633 if (pt)
640 { 634 {
641 envpan = penv->PanEnv[pt-1]; 635 envpan = penv->PanEnv.Values[pt-1];
642 x1 = penv->PanPoints[pt-1]; 636 x1 = penv->PanEnv.Ticks[pt-1];
643 } else 637 } else
644 { 638 {
645 envpan = 128; 639 envpan = 128;
646 x1 = 0; 640 x1 = 0;
647 } 641 }
712 // Arpeggio ? 706 // Arpeggio ?
713 if (pChn->nCommand == CMD_ARPEGGIO) 707 if (pChn->nCommand == CMD_ARPEGGIO)
714 { 708 {
715 switch(m_nTickCount % 3) 709 switch(m_nTickCount % 3)
716 { 710 {
711 #if 0
717 case 1: period = GetPeriodFromNote(pChn->nNote + (pChn->nArpeggio >> 4), pChn->nFineTune, pChn->nC4Speed); break; 712 case 1: period = GetPeriodFromNote(pChn->nNote + (pChn->nArpeggio >> 4), pChn->nFineTune, pChn->nC4Speed); break;
718 case 2: period = GetPeriodFromNote(pChn->nNote + (pChn->nArpeggio & 0x0F), pChn->nFineTune, pChn->nC4Speed); break; 713 case 2: period = GetPeriodFromNote(pChn->nNote + (pChn->nArpeggio & 0x0F), pChn->nFineTune, pChn->nC4Speed); break;
714 #else
715 case 1: period = GetLinearPeriodFromNote(GetNoteFromPeriod(period) + (pChn->nArpeggio >> 4), pChn->nFineTune, pChn->nC4Speed); break;
716 case 2: period = GetLinearPeriodFromNote(GetNoteFromPeriod(period) + (pChn->nArpeggio & 0x0F), pChn->nFineTune, pChn->nC4Speed); break;
717 #endif
719 } 718 }
720 } 719 }
721 720
722 if (m_dwSongFlags & SONG_AMIGALIMITS) 721 if (m_dwSongFlags & SONG_AMIGALIMITS)
723 { 722 {
724 if (period < 113*4) period = 113*4; 723 if (period < 113*4) period = 113*4;
725 if (period > 856*4) period = 856*4; 724 if (period > 856*4) period = 856*4;
726 } 725 }
727 726
728 // Pitch/Filter Envelope 727 // Pitch/Filter Envelope
729 if ((pChn->pHeader) && (pChn->dwFlags & CHN_PITCHENV) && (pChn->pHeader->nPitchEnv)) 728 int envpitch = 0;
729 if ((m_dwSongFlags & SONG_INSTRUMENTMODE) && (pChn->pHeader)
730 && (pChn->dwFlags & CHN_PITCHENV) && (pChn->pHeader->PitchEnv.nNodes))
730 { 731 {
731 INSTRUMENTHEADER *penv = pChn->pHeader; 732 INSTRUMENTHEADER *penv = pChn->pHeader;
732 int envpos = pChn->nPitchEnvPosition; 733 int envpos = pChn->nPitchEnvPosition;
733 UINT pt = penv->nPitchEnv - 1; 734 UINT pt = penv->PitchEnv.nNodes - 1;
734 for (UINT i=0; i<(UINT)(penv->nPitchEnv-1); i++) 735 for (UINT i=0; i<(UINT)(penv->PitchEnv.nNodes-1); i++)
735 { 736 {
736 if (envpos <= penv->PitchPoints[i]) 737 if (envpos <= penv->PitchEnv.Ticks[i])
737 { 738 {
738 pt = i; 739 pt = i;
739 break; 740 break;
740 } 741 }
741 } 742 }
742 int x2 = penv->PitchPoints[pt]; 743 int x2 = penv->PitchEnv.Ticks[pt];
743 int x1, envpitch; 744 int x1;
744 if (envpos >= x2) 745 if (envpos >= x2)
745 { 746 {
746 envpitch = (((int)penv->PitchEnv[pt]) - 32) * 8; 747 envpitch = (((int)penv->PitchEnv.Values[pt]) - 32) * 8;
747 x1 = x2; 748 x1 = x2;
748 } else 749 } else
749 if (pt) 750 if (pt)
750 { 751 {
751 envpitch = (((int)penv->PitchEnv[pt-1]) - 32) * 8; 752 envpitch = (((int)penv->PitchEnv.Values[pt-1]) - 32) * 8;
752 x1 = penv->PitchPoints[pt-1]; 753 x1 = penv->PitchEnv.Ticks[pt-1];
753 } else 754 } else
754 { 755 {
755 envpitch = 0; 756 envpitch = 0;
756 x1 = 0; 757 x1 = 0;
757 } 758 }
758 if (envpos > x2) envpos = x2; 759 if (envpos > x2) envpos = x2;
759 if ((x2 > x1) && (envpos > x1)) 760 if ((x2 > x1) && (envpos > x1))
760 { 761 {
761 int envpitchdest = (((int)penv->PitchEnv[pt]) - 32) * 8; 762 int envpitchdest = (((int)penv->PitchEnv.Values[pt]) - 32) * 8;
762 envpitch += ((envpos - x1) * (envpitchdest - envpitch)) / (x2 - x1); 763 envpitch += ((envpos - x1) * (envpitchdest - envpitch)) / (x2 - x1);
763 } 764 }
764 if (envpitch < -256) envpitch = -256; 765 if (envpitch < -256) envpitch = -256;
765 if (envpitch > 256) envpitch = 256; 766 if (envpitch > 256) envpitch = 256;
766 // Filter Envelope: controls cutoff frequency
767 if (penv->dwFlags & ENV_FILTER)
768 {
769 #ifndef NO_FILTER
770 SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? FALSE : TRUE, envpitch);
771 #endif // NO_FILTER
772 } else
773 // Pitch Envelope 767 // Pitch Envelope
768 if (!(penv->dwFlags & ENV_FILTER))
774 { 769 {
775 int l = envpitch; 770 int l = envpitch;
776 if (l < 0) 771 if (l < 0)
777 { 772 {
778 l = -l; 773 l = -l;
858 int nPeriodFrac = 0; 853 int nPeriodFrac = 0;
859 // Instrument Auto-Vibrato 854 // Instrument Auto-Vibrato
860 if ((pChn->pInstrument) && (pChn->pInstrument->nVibDepth)) 855 if ((pChn->pInstrument) && (pChn->pInstrument->nVibDepth))
861 { 856 {
862 MODINSTRUMENT *pins = pChn->pInstrument; 857 MODINSTRUMENT *pins = pChn->pInstrument;
858 /* this isn't correct, but its better... */
859
860 if (pins->nVibSweep == 0) {
861 pChn->nAutoVibDepth = pins->nVibDepth << 8;
862 } else {
863 pChn->nAutoVibDepth += pins->nVibSweep;
864 if ((pChn->nAutoVibDepth >> 8) > (int)pins->nVibDepth)
865 pChn->nAutoVibDepth = pins->nVibDepth << 8;
866 }
867 #if 0
863 if (pins->nVibSweep == 0) 868 if (pins->nVibSweep == 0)
864 { 869 {
865 pChn->nAutoVibDepth = pins->nVibDepth << 8; 870 pChn->nAutoVibDepth = pins->nVibDepth << 8;
866 } else 871 } else
867 { 872 {
868 if (m_nType & MOD_TYPE_IT) 873 if (m_nType & MOD_TYPE_IT)
869 { 874 {
870 pChn->nAutoVibDepth += pins->nVibSweep << 3; 875 pChn->nAutoVibDepth += pins->nVibSweep;
871 } else 876 } else
872 if (!(pChn->dwFlags & CHN_KEYOFF)) 877 if (!(pChn->dwFlags & CHN_KEYOFF))
873 { 878 {
874 pChn->nAutoVibDepth += (pins->nVibDepth << 8) / pins->nVibSweep; 879 pChn->nAutoVibDepth += (pins->nVibDepth << 8) / pins->nVibSweep;
875 } 880 }
876 if ((pChn->nAutoVibDepth >> 8) > pins->nVibDepth) 881 if ((pChn->nAutoVibDepth >> 8) > pins->nVibDepth)
877 pChn->nAutoVibDepth = pins->nVibDepth << 8; 882 pChn->nAutoVibDepth = pins->nVibDepth << 8;
878 } 883 }
879 pChn->nAutoVibPos += pins->nVibRate; 884 #endif
885 pChn->nAutoVibPos += ((int)pins->nVibRate);
880 int val; 886 int val;
881 switch(pins->nVibType) 887 switch(pins->nVibType)
882 { 888 {
883 case 4: // Random 889 case 4: // Random
884 val = ModRandomTable[pChn->nAutoVibPos & 0x3F]; 890 val = ModRandomTable[pChn->nAutoVibPos & 0x3F];
895 break; 901 break;
896 default: // Sine 902 default: // Sine
897 val = ft2VibratoTable[pChn->nAutoVibPos & 255]; 903 val = ft2VibratoTable[pChn->nAutoVibPos & 255];
898 } 904 }
899 int n = ((val * pChn->nAutoVibDepth) >> 8); 905 int n = ((val * pChn->nAutoVibDepth) >> 8);
906 // is this right? -mrsb
907 if (!(m_dwSongFlags & SONG_ITOLDEFFECTS))
908 n >>= 1;
909
900 if (m_nType & MOD_TYPE_IT) 910 if (m_nType & MOD_TYPE_IT)
901 { 911 {
902 int df1, df2; 912 int df1, df2;
903 if (n < 0) 913 if (n < 0)
904 { 914 {
937 } 947 }
938 period = m_nMaxPeriod; 948 period = m_nMaxPeriod;
939 nPeriodFrac = 0; 949 nPeriodFrac = 0;
940 } 950 }
941 UINT freq = GetFreqFromPeriod(period, pChn->nC4Speed, nPeriodFrac); 951 UINT freq = GetFreqFromPeriod(period, pChn->nC4Speed, nPeriodFrac);
952
953 // Filter Envelope: controls cutoff frequency
954 if (pChn && pChn->pHeader && pChn->pHeader->dwFlags & ENV_FILTER)
955 {
956 #ifndef NO_FILTER
957 SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? FALSE : TRUE, envpitch);
958 #endif // NO_FILTER
959 }
960
961 #if 0
942 if ((m_nType & MOD_TYPE_IT) && (freq < 256)) 962 if ((m_nType & MOD_TYPE_IT) && (freq < 256))
943 { 963 {
944 pChn->nFadeOutVol = 0; 964 pChn->nFadeOutVol = 0;
945 pChn->dwFlags |= CHN_NOTEFADE; 965 pChn->dwFlags |= CHN_NOTEFADE;
946 pChn->nRealVolume = 0; 966 pChn->nRealVolume = 0;
947 } 967 }
968 #endif
969 pChn->sample_freq = freq;
970
948 UINT ninc = _muldiv(freq, 0x10000, gdwMixingFreq); 971 UINT ninc = _muldiv(freq, 0x10000, gdwMixingFreq);
949 if ((ninc >= 0xFFB0) && (ninc <= 0x10090)) ninc = 0x10000; 972 if ((ninc >= 0xFFB0) && (ninc <= 0x10090)) ninc = 0x10000;
950 if (m_nFreqFactor != 128) ninc = (ninc * m_nFreqFactor) >> 7; 973 if (m_nFreqFactor != 128) ninc = (ninc * m_nFreqFactor) >> 7;
951 if (ninc > 0xFF0000) ninc = 0xFF0000; 974 if (ninc > 0xFF0000) ninc = 0xFF0000;
952 pChn->nInc = (ninc+1) & ~3; 975 pChn->nInc = (ninc+1) & ~3;
953 } 976 }
954 977
955 // Increment envelope position 978 // Increment envelope position
956 if (pChn->pHeader) 979 if ((m_dwSongFlags & SONG_INSTRUMENTMODE) && pChn->pHeader)
957 { 980 {
958 INSTRUMENTHEADER *penv = pChn->pHeader; 981 INSTRUMENTHEADER *penv = pChn->pHeader;
959 // Volume Envelope 982 // Volume Envelope
960 if (pChn->dwFlags & CHN_VOLENV) 983 if (pChn->dwFlags & CHN_VOLENV)
961 { 984 {
962 // Increase position 985 // Increase position
963 pChn->nVolEnvPosition++; 986 pChn->nVolEnvPosition++;
964 // Volume Loop ? 987 // Volume Loop ?
965 if (penv->dwFlags & ENV_VOLLOOP) 988 if (penv->dwFlags & ENV_VOLLOOP)
966 { 989 {
967 UINT volloopend = penv->VolPoints[penv->nVolLoopEnd]; 990 int volloopend = penv->VolEnv.Ticks[penv->VolEnv.nLoopEnd];
968 if (m_nType != MOD_TYPE_XM) volloopend++; 991 if (m_nType != MOD_TYPE_XM) volloopend++;
969 if (pChn->nVolEnvPosition == volloopend) 992 if (pChn->nVolEnvPosition == volloopend)
970 { 993 {
971 pChn->nVolEnvPosition = penv->VolPoints[penv->nVolLoopStart]; 994 pChn->nVolEnvPosition = penv->VolEnv.Ticks[penv->VolEnv.nLoopStart];
972 if ((penv->nVolLoopEnd == penv->nVolLoopStart) && (!penv->VolEnv[penv->nVolLoopStart]) 995 if ((penv->VolEnv.nLoopEnd == penv->VolEnv.nLoopStart) && (!penv->VolEnv.Values[penv->VolEnv.nLoopStart])
973 && ((!(m_nType & MOD_TYPE_XM)) || (penv->nVolLoopEnd+1 == penv->nVolEnv))) 996 && ((!(m_nType & MOD_TYPE_XM)) || (penv->VolEnv.nLoopEnd+1 == penv->VolEnv.nNodes)))
974 { 997 {
975 pChn->dwFlags |= CHN_NOTEFADE; 998 pChn->dwFlags |= CHN_NOTEFADE;
976 pChn->nFadeOutVol = 0; 999 pChn->nFadeOutVol = 0;
977 } 1000 }
978 } 1001 }
979 } 1002 }
980 // Volume Sustain ? 1003 // Volume Sustain ?
981 if ((penv->dwFlags & ENV_VOLSUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF))) 1004 if ((penv->dwFlags & ENV_VOLSUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF)))
982 { 1005 {
983 if (pChn->nVolEnvPosition == (UINT)penv->VolPoints[penv->nVolSustainEnd]+1) 1006 if (pChn->nVolEnvPosition == (int)penv->VolEnv.Ticks[penv->VolEnv.nSustainEnd]+1)
984 pChn->nVolEnvPosition = penv->VolPoints[penv->nVolSustainBegin]; 1007 pChn->nVolEnvPosition = penv->VolEnv.Ticks[penv->VolEnv.nSustainStart];
985 } else 1008 } else
986 // End of Envelope ? 1009 // End of Envelope ?
987 if (pChn->nVolEnvPosition > penv->VolPoints[penv->nVolEnv - 1]) 1010 if (pChn->nVolEnvPosition > penv->VolEnv.Ticks[penv->VolEnv.nNodes - 1])
988 { 1011 {
989 if ((m_nType & MOD_TYPE_IT) || (pChn->dwFlags & CHN_KEYOFF)) pChn->dwFlags |= CHN_NOTEFADE; 1012 if ((m_nType & MOD_TYPE_IT) || (pChn->dwFlags & CHN_KEYOFF)) pChn->dwFlags |= CHN_NOTEFADE;
990 pChn->nVolEnvPosition = penv->VolPoints[penv->nVolEnv - 1]; 1013 pChn->nVolEnvPosition = penv->VolEnv.Ticks[penv->VolEnv.nNodes - 1];
991 if ((!penv->VolEnv[penv->nVolEnv-1]) && ((nChn >= m_nChannels) || (m_nType & MOD_TYPE_IT))) 1014 if ((!penv->VolEnv.Values[penv->VolEnv.nNodes-1]) && ((nChn >= m_nChannels) || (m_nType & MOD_TYPE_IT)))
992 { 1015 {
993 pChn->dwFlags |= CHN_NOTEFADE; 1016 pChn->dwFlags |= CHN_NOTEFADE;
994 pChn->nFadeOutVol = 0; 1017 pChn->nFadeOutVol = 0;
995 1018
996 pChn->nRealVolume = 0; 1019 pChn->nRealVolume = 0;
1001 if (pChn->dwFlags & CHN_PANENV) 1024 if (pChn->dwFlags & CHN_PANENV)
1002 { 1025 {
1003 pChn->nPanEnvPosition++; 1026 pChn->nPanEnvPosition++;
1004 if (penv->dwFlags & ENV_PANLOOP) 1027 if (penv->dwFlags & ENV_PANLOOP)
1005 { 1028 {
1006 UINT panloopend = penv->PanPoints[penv->nPanLoopEnd]; 1029 int panloopend = penv->PanEnv.Ticks[penv->PanEnv.nLoopEnd];
1007 if (m_nType != MOD_TYPE_XM) panloopend++; 1030 if (m_nType != MOD_TYPE_XM) panloopend++;
1008 if (pChn->nPanEnvPosition == panloopend) 1031 if (pChn->nPanEnvPosition == panloopend)
1009 pChn->nPanEnvPosition = penv->PanPoints[penv->nPanLoopStart]; 1032 pChn->nPanEnvPosition = penv->PanEnv.Ticks[penv->PanEnv.nLoopStart];
1010 } 1033 }
1011 // Panning Sustain ? 1034 // Panning Sustain ?
1012 if ((penv->dwFlags & ENV_PANSUSTAIN) && (pChn->nPanEnvPosition == (UINT)penv->PanPoints[penv->nPanSustainEnd]+1) 1035 if ((penv->dwFlags & ENV_PANSUSTAIN) && (pChn->nPanEnvPosition == (int)penv->PanEnv.Ticks[penv->PanEnv.nSustainEnd]+1)
1013 && (!(pChn->dwFlags & CHN_KEYOFF))) 1036 && (!(pChn->dwFlags & CHN_KEYOFF)))
1014 { 1037 {
1015 // Panning sustained 1038 // Panning sustained
1016 pChn->nPanEnvPosition = penv->PanPoints[penv->nPanSustainBegin]; 1039 pChn->nPanEnvPosition = penv->PanEnv.Ticks[penv->PanEnv.nSustainStart];
1017 } else 1040 } else
1018 { 1041 {
1019 if (pChn->nPanEnvPosition > penv->PanPoints[penv->nPanEnv - 1]) 1042 if (pChn->nPanEnvPosition > penv->PanEnv.Ticks[penv->PanEnv.nNodes - 1])
1020 pChn->nPanEnvPosition = penv->PanPoints[penv->nPanEnv - 1]; 1043 pChn->nPanEnvPosition = penv->PanEnv.Ticks[penv->PanEnv.nNodes - 1];
1021 } 1044 }
1022 } 1045 }
1023 // Pitch Envelope 1046 // Pitch Envelope
1024 if (pChn->dwFlags & CHN_PITCHENV) 1047 if (pChn->dwFlags & CHN_PITCHENV)
1025 { 1048 {
1026 // Increase position 1049 // Increase position
1027 pChn->nPitchEnvPosition++; 1050 pChn->nPitchEnvPosition++;
1028 // Pitch Loop ? 1051 // Pitch Loop ?
1029 if (penv->dwFlags & ENV_PITCHLOOP) 1052 if (penv->dwFlags & ENV_PITCHLOOP)
1030 { 1053 {
1031 if (pChn->nPitchEnvPosition >= penv->PitchPoints[penv->nPitchLoopEnd]) 1054 if (pChn->nPitchEnvPosition >= penv->PitchEnv.Ticks[penv->PitchEnv.nLoopEnd])
1032 pChn->nPitchEnvPosition = penv->PitchPoints[penv->nPitchLoopStart]; 1055 pChn->nPitchEnvPosition = penv->PitchEnv.Ticks[penv->PitchEnv.nLoopStart];
1033 } 1056 }
1034 // Pitch Sustain ? 1057 // Pitch Sustain ?
1035 if ((penv->dwFlags & ENV_PITCHSUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF))) 1058 if ((penv->dwFlags & ENV_PITCHSUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF)))
1036 { 1059 {
1037 if (pChn->nPitchEnvPosition == (UINT)penv->PitchPoints[penv->nPitchSustainEnd]+1) 1060 if (pChn->nPitchEnvPosition == (int)penv->PitchEnv.Ticks[penv->PitchEnv.nSustainEnd]+1)
1038 pChn->nPitchEnvPosition = penv->PitchPoints[penv->nPitchSustainBegin]; 1061 pChn->nPitchEnvPosition = penv->PitchEnv.Ticks[penv->PitchEnv.nSustainStart];
1039 } else 1062 } else
1040 { 1063 {
1041 if (pChn->nPitchEnvPosition > penv->PitchPoints[penv->nPitchEnv - 1]) 1064 if (pChn->nPitchEnvPosition > penv->PitchEnv.Ticks[penv->PitchEnv.nNodes - 1])
1042 pChn->nPitchEnvPosition = penv->PitchPoints[penv->nPitchEnv - 1]; 1065 pChn->nPitchEnvPosition = penv->PitchEnv.Ticks[penv->PitchEnv.nNodes - 1];
1043 } 1066 }
1044 } 1067 }
1045 } 1068 }
1046 #ifdef MODPLUG_PLAYER 1069 #if 0
1047 // Limit CPU -> > 80% -> don't ramp 1070 // Limit CPU -> > 80% -> don't ramp
1048 if ((gnCPUUsage >= 80) && (!pChn->nRealVolume)) 1071 if ((gnCPUUsage >= 80) && (!pChn->nRealVolume))
1049 { 1072 {
1050 pChn->nLeftVol = pChn->nRightVol = 0; 1073 pChn->nLeftVol = pChn->nRightVol = 0;
1051 } 1074 }
1052 #endif // MODPLUG_PLAYER 1075 #endif // MODPLUG_PLAYER
1053 // Volume ramping 1076 // Volume ramping
1054 pChn->dwFlags &= ~CHN_VOLUMERAMP; 1077 pChn->dwFlags &= ~CHN_VOLUMERAMP;
1055 if ((pChn->nRealVolume) || (pChn->nLeftVol) || (pChn->nRightVol)) 1078 if ((pChn->nRealVolume) || (pChn->nLeftVol) || (pChn->nRightVol))
1056 pChn->dwFlags |= CHN_VOLUMERAMP; 1079 pChn->dwFlags |= CHN_VOLUMERAMP;
1057 #ifdef MODPLUG_PLAYER
1058 // Decrease VU-Meter 1080 // Decrease VU-Meter
1059 if (pChn->nVUMeter > VUMETER_DECAY) pChn->nVUMeter -= VUMETER_DECAY; else pChn->nVUMeter = 0; 1081 if (pChn->nVUMeter > VUMETER_DECAY) pChn->nVUMeter -= VUMETER_DECAY; else pChn->nVUMeter = 0;
1060 #endif // MODPLUG_PLAYER
1061 #ifdef ENABLE_STEREOVU
1062 if (pChn->nLeftVU > VUMETER_DECAY) pChn->nLeftVU -= VUMETER_DECAY; else pChn->nLeftVU = 0; 1082 if (pChn->nLeftVU > VUMETER_DECAY) pChn->nLeftVU -= VUMETER_DECAY; else pChn->nLeftVU = 0;
1063 if (pChn->nRightVU > VUMETER_DECAY) pChn->nRightVU -= VUMETER_DECAY; else pChn->nRightVU = 0; 1083 if (pChn->nRightVU > VUMETER_DECAY) pChn->nRightVU -= VUMETER_DECAY; else pChn->nRightVU = 0;
1064 #endif
1065 // Check for too big nInc 1084 // Check for too big nInc
1066 if (((pChn->nInc >> 16) + 1) >= (LONG)(pChn->nLoopEnd - pChn->nLoopStart)) pChn->dwFlags &= ~CHN_LOOP; 1085 if (((pChn->nInc >> 16) + 1) >= (LONG)(pChn->nLoopEnd - pChn->nLoopStart)) pChn->dwFlags &= ~CHN_LOOP;
1067 pChn->nNewRightVol = pChn->nNewLeftVol = 0; 1086 pChn->nNewRightVol = pChn->nNewLeftVol = 0;
1068 pChn->pCurrentSample = ((pChn->pSample) && (pChn->nLength) && (pChn->nInc)) ? pChn->pSample : NULL; 1087 pChn->pCurrentSample = ((pChn->pSample) && (pChn->nLength) && (pChn->nInc)) ? pChn->pSample : NULL;
1069 if (pChn->pCurrentSample) 1088 if (pChn->pCurrentSample)
1070 { 1089 {
1071 // Update VU-Meter (nRealVolume is 14-bit) 1090 // Update VU-Meter (nRealVolume is 14-bit)
1072 #ifdef MODPLUG_PLAYER
1073 UINT vutmp = pChn->nRealVolume >> (14 - 8); 1091 UINT vutmp = pChn->nRealVolume >> (14 - 8);
1074 if (vutmp > 0xFF) vutmp = 0xFF; 1092 if (vutmp > 0xFF) vutmp = 0xFF;
1075 if (pChn->nVUMeter >= 0x100) pChn->nVUMeter = vutmp; 1093 if (pChn->nVUMeter >= 0x100) pChn->nVUMeter = vutmp;
1076 vutmp >>= 1; 1094 vutmp >>= 1;
1077 if (pChn->nVUMeter < vutmp) pChn->nVUMeter = vutmp; 1095 if (pChn->nVUMeter < vutmp) pChn->nVUMeter = vutmp;
1078 #endif // MODPLUG_PLAYER
1079 #ifdef ENABLE_STEREOVU
1080 UINT vul = (pChn->nRealVolume * pChn->nRealPan) >> 14; 1096 UINT vul = (pChn->nRealVolume * pChn->nRealPan) >> 14;
1081 if (vul > 127) vul = 127; 1097 if (vul > 127) vul = 127;
1082 if (pChn->nLeftVU > 127) pChn->nLeftVU = (BYTE)vul; 1098 if (pChn->nLeftVU > 127) pChn->nLeftVU = (BYTE)vul;
1083 vul >>= 1; 1099 vul >>= 1;
1084 if (pChn->nLeftVU < vul) pChn->nLeftVU = (BYTE)vul; 1100 if (pChn->nLeftVU < vul) pChn->nLeftVU = (BYTE)vul;
1085 UINT vur = (pChn->nRealVolume * (256-pChn->nRealPan)) >> 14; 1101 UINT vur = (pChn->nRealVolume * (256-pChn->nRealPan)) >> 14;
1086 if (vur > 127) vur = 127; 1102 if (vur > 127) vur = 127;
1087 if (pChn->nRightVU > 127) pChn->nRightVU = (BYTE)vur; 1103 if (pChn->nRightVU > 127) pChn->nRightVU = (BYTE)vur;
1088 vur >>= 1; 1104 vur >>= 1;
1089 if (pChn->nRightVU < vur) pChn->nRightVU = (BYTE)vur; 1105 if (pChn->nRightVU < vur) pChn->nRightVU = (BYTE)vur;
1090 #endif
1091 #ifdef MODPLUG_TRACKER 1106 #ifdef MODPLUG_TRACKER
1092 UINT kChnMasterVol = (pChn->dwFlags & CHN_EXTRALOUD) ? 0x100 : nMasterVol; 1107 UINT kChnMasterVol = (pChn->dwFlags & CHN_EXTRALOUD) ? 0x100 : nMasterVol;
1093 #else 1108 #else
1094 #define kChnMasterVol nMasterVol 1109 #define kChnMasterVol nMasterVol
1095 #endif // MODPLUG_TRACKER 1110 #endif // MODPLUG_TRACKER
1101 pan /= 128; 1116 pan /= 128;
1102 pan += 128; 1117 pan += 128;
1103 1118
1104 if (pan < 0) pan = 0; 1119 if (pan < 0) pan = 0;
1105 if (pan > 256) pan = 256; 1120 if (pan > 256) pan = 256;
1106 #ifndef MODPLUG_FASTSOUNDLIB
1107 if (gdwSoundSetup & SNDMIX_REVERSESTEREO) pan = 256 - pan; 1121 if (gdwSoundSetup & SNDMIX_REVERSESTEREO) pan = 256 - pan;
1108 #endif 1122 if (m_dwSongFlags & SONG_NOSTEREO) pan = 128;
1109 LONG realvol = (pChn->nRealVolume * kChnMasterVol) >> (8-1); 1123 LONG realvol = (pChn->nRealVolume * kChnMasterVol) >> (8-1);
1110 if (gdwSoundSetup & SNDMIX_SOFTPANNING) 1124 if (gdwSoundSetup & SNDMIX_SOFTPANNING)
1111 { 1125 {
1112 if (pan < 128) 1126 if (pan < 128)
1113 { 1127 {
1132 if (pChn->nNewRightVol > 0xFFFF) pChn->nNewRightVol = 0xFFFF; 1146 if (pChn->nNewRightVol > 0xFFFF) pChn->nNewRightVol = 0xFFFF;
1133 if (pChn->nNewLeftVol > 0xFFFF) pChn->nNewLeftVol = 0xFFFF; 1147 if (pChn->nNewLeftVol > 0xFFFF) pChn->nNewLeftVol = 0xFFFF;
1134 // Check IDO 1148 // Check IDO
1135 if (gdwSoundSetup & SNDMIX_NORESAMPLING) 1149 if (gdwSoundSetup & SNDMIX_NORESAMPLING)
1136 { 1150 {
1151 pChn->dwFlags &= ~(CHN_HQSRC);
1137 pChn->dwFlags |= CHN_NOIDO; 1152 pChn->dwFlags |= CHN_NOIDO;
1138 } else 1153 } else
1139 { 1154 {
1140 pChn->dwFlags &= ~(CHN_NOIDO|CHN_HQSRC); 1155 pChn->dwFlags &= ~(CHN_NOIDO|CHN_HQSRC);
1141 if( pChn->nInc == 0x10000 ) 1156 if( pChn->nInc == 0x10000 )
1149 } 1164 }
1150 pChn->nNewRightVol >>= MIXING_ATTENUATION; 1165 pChn->nNewRightVol >>= MIXING_ATTENUATION;
1151 pChn->nNewLeftVol >>= MIXING_ATTENUATION; 1166 pChn->nNewLeftVol >>= MIXING_ATTENUATION;
1152 pChn->nRightRamp = pChn->nLeftRamp = 0; 1167 pChn->nRightRamp = pChn->nLeftRamp = 0;
1153 // Dolby Pro-Logic Surround 1168 // Dolby Pro-Logic Surround
1154 if ((pChn->dwFlags & CHN_SURROUND) && (gnChannels <= 2)) pChn->nNewLeftVol = - pChn->nNewLeftVol; 1169 if ((pChn->dwFlags & CHN_SURROUND) && (gnChannels <= 2) && (gdwSoundSetup & SNDMIX_NOSURROUND) == 0)
1170 pChn->nNewLeftVol = -pChn->nNewLeftVol;
1155 // Checking Ping-Pong Loops 1171 // Checking Ping-Pong Loops
1156 if (pChn->dwFlags & CHN_PINGPONGFLAG) pChn->nInc = -pChn->nInc; 1172 if (pChn->dwFlags & CHN_PINGPONGFLAG) pChn->nInc = -pChn->nInc;
1157 // Setting up volume ramp 1173 // Setting up volume ramp
1158 if ((pChn->dwFlags & CHN_VOLUMERAMP) 1174 if (!(gdwSoundSetup & SNDMIX_NORAMPING)
1175 && (pChn->dwFlags & CHN_VOLUMERAMP)
1159 && ((pChn->nRightVol != pChn->nNewRightVol) 1176 && ((pChn->nRightVol != pChn->nNewRightVol)
1160 || (pChn->nLeftVol != pChn->nNewLeftVol))) 1177 || (pChn->nLeftVol != pChn->nNewLeftVol)))
1161 { 1178 {
1162 LONG nRampLength = gnVolumeRampSamples; 1179 LONG nRampLength = gnVolumeRampSamples;
1163 LONG nRightDelta = ((pChn->nNewRightVol - pChn->nRightVol) << VOLUMERAMPPRECISION); 1180 LONG nRightDelta = ((pChn->nNewRightVol - pChn->nRightVol) << VOLUMERAMPPRECISION);
1164 LONG nLeftDelta = ((pChn->nNewLeftVol - pChn->nLeftVol) << VOLUMERAMPPRECISION); 1181 LONG nLeftDelta = ((pChn->nNewLeftVol - pChn->nLeftVol) << VOLUMERAMPPRECISION);
1165 #ifndef MODPLUG_FASTSOUNDLIB 1182 #if 0
1166 if ((gdwSoundSetup & SNDMIX_DIRECTTODISK) 1183 if ((gdwSoundSetup & SNDMIX_DIRECTTODISK)
1167 || ((gdwSysInfo & (SYSMIX_ENABLEMMX|SYSMIX_FASTCPU)) 1184 || ((gdwSysInfo & (SYSMIX_ENABLEMMX|SYSMIX_FASTCPU))
1168 && (gdwSoundSetup & SNDMIX_HQRESAMPLER) && (gnCPUUsage <= 20))) 1185 && (gdwSoundSetup & SNDMIX_HQRESAMPLER) && (gnCPUUsage <= 20)))
1186 #else
1187 if (gdwSoundSetup & SNDMIX_HQRESAMPLER)
1188 #endif
1169 { 1189 {
1170 if ((pChn->nRightVol|pChn->nLeftVol) && (pChn->nNewRightVol|pChn->nNewLeftVol) && (!(pChn->dwFlags & CHN_FASTVOLRAMP))) 1190 if ((pChn->nRightVol|pChn->nLeftVol) && (pChn->nNewRightVol|pChn->nNewLeftVol) && (!(pChn->dwFlags & CHN_FASTVOLRAMP)))
1171 { 1191 {
1172 nRampLength = m_nBufferCount; 1192 nRampLength = m_nBufferCount;
1173 if (nRampLength > (1 << (VOLUMERAMPPRECISION-1))) nRampLength = (1 << (VOLUMERAMPPRECISION-1)); 1193 if (nRampLength > (1 << (VOLUMERAMPPRECISION-1))) nRampLength = (1 << (VOLUMERAMPPRECISION-1));
1174 if (nRampLength < (LONG)gnVolumeRampSamples) nRampLength = gnVolumeRampSamples; 1194 if (nRampLength < (LONG)gnVolumeRampSamples) nRampLength = gnVolumeRampSamples;
1175 } 1195 }
1176 } 1196 }
1177 #endif
1178 pChn->nRightRamp = nRightDelta / nRampLength; 1197 pChn->nRightRamp = nRightDelta / nRampLength;
1179 pChn->nLeftRamp = nLeftDelta / nRampLength; 1198 pChn->nLeftRamp = nLeftDelta / nRampLength;
1180 pChn->nRightVol = pChn->nNewRightVol - ((pChn->nRightRamp * nRampLength) >> VOLUMERAMPPRECISION); 1199 pChn->nRightVol = pChn->nNewRightVol - ((pChn->nRightRamp * nRampLength) >> VOLUMERAMPPRECISION);
1181 pChn->nLeftVol = pChn->nNewLeftVol - ((pChn->nLeftRamp * nRampLength) >> VOLUMERAMPPRECISION); 1200 pChn->nLeftVol = pChn->nNewLeftVol - ((pChn->nLeftRamp * nRampLength) >> VOLUMERAMPPRECISION);
1182 if (pChn->nRightRamp|pChn->nLeftRamp) 1201 if (pChn->nRightRamp|pChn->nLeftRamp)
1195 pChn->nLeftVol = pChn->nNewLeftVol; 1214 pChn->nLeftVol = pChn->nNewLeftVol;
1196 } 1215 }
1197 pChn->nRampRightVol = pChn->nRightVol << VOLUMERAMPPRECISION; 1216 pChn->nRampRightVol = pChn->nRightVol << VOLUMERAMPPRECISION;
1198 pChn->nRampLeftVol = pChn->nLeftVol << VOLUMERAMPPRECISION; 1217 pChn->nRampLeftVol = pChn->nLeftVol << VOLUMERAMPPRECISION;
1199 // Adding the channel in the channel list 1218 // Adding the channel in the channel list
1200 ChnMix[m_nMixChannels++] = nChn; 1219 if (!(pChn->dwFlags & CHN_MUTE)) {
1201 if (m_nMixChannels >= MAX_CHANNELS) break; 1220 ChnMix[m_nMixChannels++] = nChn;
1221 if (m_nMixChannels >= MAX_CHANNELS) break;
1222 }
1202 } else 1223 } else
1203 { 1224 {
1204 #ifdef ENABLE_STEREOVU
1205 // Note change but no sample 1225 // Note change but no sample
1206 if (pChn->nLeftVU > 128) pChn->nLeftVU = 0; 1226 if (pChn->nLeftVU > 128) pChn->nLeftVU = 0;
1207 if (pChn->nRightVU > 128) pChn->nRightVU = 0; 1227 if (pChn->nRightVU > 128) pChn->nRightVU = 0;
1208 #endif
1209 if (pChn->nVUMeter > 0xFF) pChn->nVUMeter = 0; 1228 if (pChn->nVUMeter > 0xFF) pChn->nVUMeter = 0;
1210 pChn->nLeftVol = pChn->nRightVol = 0; 1229 pChn->nLeftVol = pChn->nRightVol = 0;
1211 pChn->nLength = 0; 1230 pChn->nLength = 0;
1212 } 1231 }
1213 } 1232 }