1 /*
2  * This source code is public domain.
3  *
4  * Authors: Olivier Lapicque <olivierl@jps.net>
5 */
6 
7 #include "libmodplug/stdafx.h"
8 #include "libmodplug/sndfile.h"
9 #include "tables.h"
10 
11 #ifdef MODPLUG_TRACKER
12 #define ENABLE_STEREOVU
13 #endif
14 
15 // Volume ramp length, in 1/10 ms
16 #define VOLUMERAMPLEN	146	// 1.46ms = 64 samples at 44.1kHz
17 
18 // VU-Meter
19 #define VUMETER_DECAY		4
20 
21 // SNDMIX: These are global flags for playback control (first two configurable via SetMixConfig)
22 UINT CSoundFile::m_nStereoSeparation = 128;
23 UINT CSoundFile::m_nMaxMixChannels = 32;
24 LONG CSoundFile::m_nStreamVolume = 0x8000;
25 // Mixing Configuration (SetWaveConfig)
26 DWORD CSoundFile::gdwSysInfo = 0;
27 DWORD CSoundFile::gnChannels = 1;
28 DWORD CSoundFile::gdwSoundSetup = 0;
29 DWORD CSoundFile::gdwMixingFreq = 44100;
30 DWORD CSoundFile::gnBitsPerSample = 16;
31 // Mixing data initialized in
32 UINT CSoundFile::gnAGC = AGC_UNITY;
33 UINT CSoundFile::gnVolumeRampSamples = 64;
34 UINT CSoundFile::gnVUMeter = 0;
35 UINT CSoundFile::gnCPUUsage = 0;
36 LPSNDMIXHOOKPROC CSoundFile::gpSndMixHook = NULL;
37 PMIXPLUGINCREATEPROC CSoundFile::gpMixPluginCreateProc = NULL;
38 LONG gnDryROfsVol = 0;
39 LONG gnDryLOfsVol = 0;
40 LONG gnRvbROfsVol = 0;
41 LONG gnRvbLOfsVol = 0;
42 int gbInitPlugins = 0;
43 
44 typedef DWORD (MPPASMCALL * LPCONVERTPROC)(LPVOID, int *, DWORD, LPLONG, LPLONG);
45 
46 extern DWORD MPPASMCALL X86_Convert32To8(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG);
47 extern DWORD MPPASMCALL X86_Convert32To16(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG);
48 extern DWORD MPPASMCALL X86_Convert32To24(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG);
49 extern DWORD MPPASMCALL X86_Convert32To32(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG);
50 extern UINT MPPASMCALL X86_AGC(int *pBuffer, UINT nSamples, UINT nAGC);
51 extern VOID MPPASMCALL X86_Dither(int *pBuffer, UINT nSamples, UINT nBits);
52 extern VOID MPPASMCALL X86_InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples);
53 extern VOID MPPASMCALL X86_StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs);
54 extern VOID MPPASMCALL X86_MonoFromStereo(int *pMixBuf, UINT nSamples);
55 
56 extern int MixSoundBuffer[MIXBUFFERSIZE*4];
57 extern int MixRearBuffer[MIXBUFFERSIZE*2];
58 UINT gnReverbSend;
59 
60 
61 // Log tables for pre-amp
62 // We don't want the tracker to get too loud
63 const UINT PreAmpTable[16] =
64 {
65 	0x60, 0x60, 0x60, 0x70,	// 0-7
66 	0x80, 0x88, 0x90, 0x98,	// 8-15
67 	0xA0, 0xA4, 0xA8, 0xB0,	// 16-23
68 	0xB4, 0xB8, 0xBC, 0xC0,	// 24-31
69 };
70 
71 const UINT PreAmpAGCTable[16] =
72 {
73 	0x60, 0x60, 0x60, 0x60,
74 	0x68, 0x70, 0x78, 0x80,
75 	0x84, 0x88, 0x8C, 0x90,
76 	0x94, 0x98, 0x9C, 0xA0,
77 };
78 
79 
80 // Return (a*b)/c - no divide error
_muldiv(long a,long b,long c)81 int _muldiv(long a, long b, long c)
82 {
83 #ifdef MSC_VER
84 	int sign, result;
85 	_asm {
86 	mov eax, a
87 	mov ebx, b
88 	or eax, eax
89 	mov edx, eax
90 	jge aneg
91 	neg eax
92 aneg:
93 	xor edx, ebx
94 	or ebx, ebx
95 	mov ecx, c
96 	jge bneg
97 	neg ebx
98 bneg:
99 	xor edx, ecx
100 	or ecx, ecx
101 	mov sign, edx
102 	jge cneg
103 	neg ecx
104 cneg:
105 	mul ebx
106 	cmp edx, ecx
107 	jae diverr
108 	div ecx
109 	jmp ok
110 diverr:
111 	mov eax, 0x7fffffff
112 ok:
113 	mov edx, sign
114 	or edx, edx
115 	jge rneg
116 	neg eax
117 rneg:
118 	mov result, eax
119 	}
120 	return result;
121 #else
122 	return ((uint64_t) a * (uint64_t) b ) / c;
123 #endif
124 }
125 
126 
127 // Return (a*b+c/2)/c - no divide error
_muldivr(long a,long b,long c)128 int _muldivr(long a, long b, long c)
129 {
130 #ifdef MSC_VER
131 	int sign, result;
132 	_asm {
133 	mov eax, a
134 	mov ebx, b
135 	or eax, eax
136 	mov edx, eax
137 	jge aneg
138 	neg eax
139 aneg:
140 	xor edx, ebx
141 	or ebx, ebx
142 	mov ecx, c
143 	jge bneg
144 	neg ebx
145 bneg:
146 	xor edx, ecx
147 	or ecx, ecx
148 	mov sign, edx
149 	jge cneg
150 	neg ecx
151 cneg:
152 	mul ebx
153 	mov ebx, ecx
154 	shr ebx, 1
155 	add eax, ebx
156 	adc edx, 0
157 	cmp edx, ecx
158 	jae diverr
159 	div ecx
160 	jmp ok
161 diverr:
162 	mov eax, 0x7fffffff
163 ok:
164 	mov edx, sign
165 	or edx, edx
166 	jge rneg
167 	neg eax
168 rneg:
169 	mov result, eax
170 	}
171 	return result;
172 #else
173 	return ((uint64_t) a * (uint64_t) b + (c >> 1)) / c;
174 #endif
175 }
176 
177 
InitPlayer(BOOL bReset)178 BOOL CSoundFile::InitPlayer(BOOL bReset)
179 //--------------------------------------
180 {
181 	if (m_nMaxMixChannels > MAX_CHANNELS) m_nMaxMixChannels = MAX_CHANNELS;
182 	if (gdwMixingFreq < 4000) gdwMixingFreq = 4000;
183 	if (gdwMixingFreq > MAX_SAMPLE_RATE) gdwMixingFreq = MAX_SAMPLE_RATE;
184 	gnVolumeRampSamples = (gdwMixingFreq * VOLUMERAMPLEN) / 100000;
185 	if (gnVolumeRampSamples < 8) gnVolumeRampSamples = 8;
186 	gnDryROfsVol = gnDryLOfsVol = 0;
187 	gnRvbROfsVol = gnRvbLOfsVol = 0;
188 	if (bReset)
189 	{
190 		gnVUMeter = 0;
191 		gnCPUUsage = 0;
192 	}
193 	gbInitPlugins = (bReset) ? 3 : 1;
194 	InitializeDSP(bReset);
195 	return TRUE;
196 }
197 
198 
FadeSong(UINT msec)199 BOOL CSoundFile::FadeSong(UINT msec)
200 //----------------------------------
201 {
202 	LONG nsamples = _muldiv(msec, gdwMixingFreq, 1000);
203 	if (nsamples <= 0) return FALSE;
204 	if (nsamples > 0x100000) nsamples = 0x100000;
205 	m_nBufferCount = nsamples;
206 	LONG nRampLength = m_nBufferCount;
207 	// Ramp everything down
208 	for (UINT noff=0; noff < m_nMixChannels; noff++)
209 	{
210 		MODCHANNEL *pramp = &Chn[ChnMix[noff]];
211 		if (!pramp) continue;
212 		pramp->nNewLeftVol = pramp->nNewRightVol = 0;
213 		pramp->nRightRamp = (-pramp->nRightVol << VOLUMERAMPPRECISION) / nRampLength;
214 		pramp->nLeftRamp = (-pramp->nLeftVol << VOLUMERAMPPRECISION) / nRampLength;
215 		pramp->nRampRightVol = pramp->nRightVol << VOLUMERAMPPRECISION;
216 		pramp->nRampLeftVol = pramp->nLeftVol << VOLUMERAMPPRECISION;
217 		pramp->nRampLength = nRampLength;
218 		pramp->dwFlags |= CHN_VOLUMERAMP;
219 	}
220 	m_dwSongFlags |= SONG_FADINGSONG;
221 	return TRUE;
222 }
223 
224 
GlobalFadeSong(UINT msec)225 BOOL CSoundFile::GlobalFadeSong(UINT msec)
226 //----------------------------------------
227 {
228 	if (m_dwSongFlags & SONG_GLOBALFADE) return FALSE;
229 	m_nGlobalFadeMaxSamples = _muldiv(msec, gdwMixingFreq, 1000);
230 	m_nGlobalFadeSamples = m_nGlobalFadeMaxSamples;
231 	m_dwSongFlags |= SONG_GLOBALFADE;
232 	return TRUE;
233 }
234 
235 
Read(LPVOID lpDestBuffer,UINT cbBuffer)236 UINT CSoundFile::Read(LPVOID lpDestBuffer, UINT cbBuffer)
237 //-------------------------------------------------------
238 {
239 	LPBYTE lpBuffer = (LPBYTE)lpDestBuffer;
240 	LPCONVERTPROC pCvt = X86_Convert32To8;
241 	UINT lRead, lMax, lSampleSize, lCount, lSampleCount, nStat=0;
242 	LONG nVUMeterMin = 0x7FFFFFFF, nVUMeterMax = -0x7FFFFFFF;
243 	UINT nMaxPlugins;
244 
245 	{
246 		nMaxPlugins = MAX_MIXPLUGINS;
247 		while ((nMaxPlugins > 0) && (!m_MixPlugins[nMaxPlugins-1].pMixPlugin)) nMaxPlugins--;
248 	}
249 	m_nMixStat = 0;
250 	lSampleSize = gnChannels;
251 	if (gnBitsPerSample == 16) { lSampleSize *= 2; pCvt = X86_Convert32To16; }
252 #ifndef MODPLUG_FASTSOUNDLIB
253 	else if (gnBitsPerSample == 24) { lSampleSize *= 3; pCvt = X86_Convert32To24; }
254 	else if (gnBitsPerSample == 32) { lSampleSize *= 4; pCvt = X86_Convert32To32; }
255 #endif
256 	lMax = cbBuffer / lSampleSize;
257 	if ((!lMax) || (!lpBuffer) || (!m_nChannels)) return 0;
258 	lRead = lMax;
259 	if (m_dwSongFlags & SONG_ENDREACHED) goto MixDone;
260 	while (lRead > 0)
261 	{
262 		// Update Channel Data
263 		if (!m_nBufferCount)
264 		{
265 #ifndef MODPLUG_FASTSOUNDLIB
266 			if (m_dwSongFlags & SONG_FADINGSONG)
267 			{
268 				m_dwSongFlags |= SONG_ENDREACHED;
269 				m_nBufferCount = lRead;
270 			} else
271 #endif
272 			if (!ReadNote())
273 			{
274 #ifndef MODPLUG_FASTSOUNDLIB
275 				if (!FadeSong(FADESONGDELAY))
276 #endif
277 				{
278 					m_dwSongFlags |= SONG_ENDREACHED;
279 					if (lRead == lMax) goto MixDone;
280 					m_nBufferCount = lRead;
281 				}
282 			}
283 		}
284 		lCount = m_nBufferCount;
285 		if (lCount > MIXBUFFERSIZE) lCount = MIXBUFFERSIZE;
286 		if (lCount > lRead) lCount = lRead;
287 		if (!lCount) break;
288 		lSampleCount = lCount;
289 #ifndef MODPLUG_NO_REVERB
290 		gnReverbSend = 0;
291 #endif
292 		// Resetting sound buffer
293 		X86_StereoFill(MixSoundBuffer, lSampleCount, &gnDryROfsVol, &gnDryLOfsVol);
294 		if (gnChannels >= 2)
295 		{
296 			lSampleCount *= 2;
297 			m_nMixStat += CreateStereoMix(lCount);
298 			ProcessStereoDSP(lCount);
299 		} else
300 		{
301 			m_nMixStat += CreateStereoMix(lCount);
302 			if (nMaxPlugins) ProcessPlugins(lCount);
303 			ProcessStereoDSP(lCount);
304 			X86_MonoFromStereo(MixSoundBuffer, lCount);
305 		}
306 		nStat++;
307 #ifndef NO_AGC
308 		// Automatic Gain Control
309 		if (gdwSoundSetup & SNDMIX_AGC) ProcessAGC(lSampleCount);
310 #endif
311 		UINT lTotalSampleCount = lSampleCount;
312 #ifndef MODPLUG_FASTSOUNDLIB
313 		// Multichannel
314 		if (gnChannels > 2)
315 		{
316 			X86_InterleaveFrontRear(MixSoundBuffer, MixRearBuffer, lSampleCount);
317 			lTotalSampleCount *= 2;
318 		}
319 		// Hook Function
320 		if (gpSndMixHook)
321 		{
322 			gpSndMixHook(MixSoundBuffer, lTotalSampleCount, gnChannels);
323 		}
324 #endif
325 		// Perform clipping + VU-Meter
326 		lpBuffer += pCvt(lpBuffer, MixSoundBuffer, lTotalSampleCount, &nVUMeterMin, &nVUMeterMax);
327 		// Buffer ready
328 		lRead -= lCount;
329 		m_nBufferCount -= lCount;
330 	}
331 MixDone:
332 	if (lRead) memset(lpBuffer, (gnBitsPerSample == 8) ? 0x80 : 0, lRead * lSampleSize);
333 	// VU-Meter
334 	nVUMeterMin >>= (24-MIXING_ATTENUATION);
335 	nVUMeterMax >>= (24-MIXING_ATTENUATION);
336 	if (nVUMeterMax < nVUMeterMin) nVUMeterMax = nVUMeterMin;
337 	if ((gnVUMeter = (UINT)(nVUMeterMax - nVUMeterMin)) > 0xFF) gnVUMeter = 0xFF;
338 	if (nStat) { m_nMixStat += nStat-1; m_nMixStat /= nStat; }
339 	return lMax - lRead;
340 }
341 
342 
343 
344 /////////////////////////////////////////////////////////////////////////////
345 // Handles navigation/effects
346 
ProcessRow()347 BOOL CSoundFile::ProcessRow()
348 //---------------------------
349 {
350 	if (++m_nTickCount >= m_nMusicSpeed * (m_nPatternDelay+1) + m_nFrameDelay)
351 	{
352 		m_nPatternDelay = 0;
353 		m_nFrameDelay = 0;
354 		m_nTickCount = 0;
355 		m_nRow = m_nNextRow;
356 		// Reset Pattern Loop Effect
357 		if (m_nCurrentPattern != m_nNextPattern) m_nCurrentPattern = m_nNextPattern;
358 		// Check if pattern is valid
359 		if (!(m_dwSongFlags & SONG_PATTERNLOOP))
360 		{
361 			m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF;
362 			if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE;
363 			while (m_nPattern >= MAX_PATTERNS)
364 			{
365 				// End of song ?
366 				if ((m_nPattern == 0xFF) || (m_nCurrentPattern >= MAX_ORDERS))
367 				{
368 					//if (!m_nRepeatCount)
369 						return FALSE;     //never repeat entire song
370 					if (!m_nRestartPos)
371 					{
372 						m_nMusicSpeed = m_nDefaultSpeed;
373 						m_nMusicTempo = m_nDefaultTempo;
374 						m_nGlobalVolume = m_nDefaultGlobalVolume;
375 						for (UINT i=0; i<MAX_CHANNELS; i++)
376 						{
377 							Chn[i].dwFlags |= CHN_NOTEFADE | CHN_KEYOFF;
378 							Chn[i].nFadeOutVol = 0;
379 							if (i < m_nChannels)
380 							{
381 								Chn[i].nGlobalVol = ChnSettings[i].nVolume;
382 								Chn[i].nVolume = ChnSettings[i].nVolume;
383 								Chn[i].nPan = ChnSettings[i].nPan;
384 								Chn[i].nPanSwing = Chn[i].nVolSwing = 0;
385 								Chn[i].nOldVolParam = 0;
386 								Chn[i].nOldOffset = 0;
387 								Chn[i].nOldHiOffset = 0;
388 								Chn[i].nPortamentoDest = 0;
389 								if (!Chn[i].nLength)
390 								{
391 									Chn[i].dwFlags = ChnSettings[i].dwFlags;
392 									Chn[i].nLoopStart = 0;
393 									Chn[i].nLoopEnd = 0;
394 									Chn[i].pHeader = NULL;
395 									Chn[i].pSample = NULL;
396 									Chn[i].pInstrument = NULL;
397 								}
398 							}
399 						}
400 					}
401 //					if (m_nRepeatCount > 0) m_nRepeatCount--;
402 					m_nCurrentPattern = m_nRestartPos;
403 					m_nRow = 0;
404 					if ((Order[m_nCurrentPattern] >= MAX_PATTERNS) || (!Patterns[Order[m_nCurrentPattern]])) return FALSE;
405 				} else
406 				{
407 					m_nCurrentPattern++;
408 				}
409 				m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF;
410 				if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE;
411 			}
412 			m_nNextPattern = m_nCurrentPattern;
413 		}
414 		// Weird stuff?
415 		if ((m_nPattern >= MAX_PATTERNS) || (!Patterns[m_nPattern]) ||
416 			PatternSize[m_nPattern] == 0) return FALSE;
417 		// Should never happen
418 		if (m_nRow >= PatternSize[m_nPattern]) m_nRow = 0;
419 		m_nNextRow = m_nRow + 1;
420 		if (m_nNextRow >= PatternSize[m_nPattern])
421 		{
422 			if (!(m_dwSongFlags & SONG_PATTERNLOOP)) m_nNextPattern = m_nCurrentPattern + 1;
423 			m_nNextRow = m_nNextStartRow;
424 			m_nNextStartRow = 0;
425 		}
426 		// Reset channel values
427 		MODCHANNEL *pChn = Chn;
428 		MODCOMMAND *m = Patterns[m_nPattern] + m_nRow * m_nChannels;
429 		for (UINT nChn=0; nChn<m_nChannels; pChn++, nChn++, m++)
430 		{
431 			pChn->nRowNote = m->note;
432 			pChn->nRowInstr = m->instr;
433 			pChn->nRowVolCmd = m->volcmd;
434 			pChn->nRowVolume = m->vol;
435 			pChn->nRowCommand = m->command;
436 			pChn->nRowParam = m->param;
437 
438 			pChn->nLeftVol = pChn->nNewLeftVol;
439 			pChn->nRightVol = pChn->nNewRightVol;
440 			pChn->dwFlags &= ~(CHN_PORTAMENTO | CHN_VIBRATO | CHN_TREMOLO | CHN_PANBRELLO);
441 			pChn->nCommand = 0;
442 		}
443 	}
444 	// Should we process tick0 effects?
445 	if (!m_nMusicSpeed) m_nMusicSpeed = 1;
446 	m_dwSongFlags |= SONG_FIRSTTICK;
447 	if (m_nTickCount)
448 	{
449 		m_dwSongFlags &= ~SONG_FIRSTTICK;
450 		if ((!(m_nType & MOD_TYPE_XM)) && (m_nTickCount < m_nMusicSpeed * (1 + m_nPatternDelay)))
451 		{
452 			if (!(m_nTickCount % m_nMusicSpeed)) m_dwSongFlags |= SONG_FIRSTTICK;
453 		}
454 
455 	}
456 	// Update Effects
457 	return ProcessEffects();
458 }
459 
460 
461 ////////////////////////////////////////////////////////////////////////////////////////////
462 // Handles envelopes & mixer setup
463 
ReadNote()464 BOOL CSoundFile::ReadNote()
465 //-------------------------
466 {
467 	if (!ProcessRow()) return FALSE;
468 	////////////////////////////////////////////////////////////////////////////////////
469 	m_nTotalCount++;
470 	if (!m_nMusicTempo) return FALSE;
471 	m_nBufferCount = (gdwMixingFreq * 5 * m_nTempoFactor) / (m_nMusicTempo << 8);
472 	// Master Volume + Pre-Amplification / Attenuation setup
473 	DWORD nMasterVol;
474 	{
475 		int nchn32 = (m_nChannels < 32) ? m_nChannels : 31;
476 		if ((m_nType & MOD_TYPE_IT) && (m_nInstruments) && (nchn32 < 6)) nchn32 = 6;
477 		int realmastervol = m_nMasterVolume;
478 		if (realmastervol > 0x80)
479 		{
480 			realmastervol = 0x80 + ((realmastervol - 0x80) * (nchn32+4)) / 16;
481 		}
482 		UINT attenuation = (gdwSoundSetup & SNDMIX_AGC) ? PreAmpAGCTable[nchn32>>1] : PreAmpTable[nchn32>>1];
483 		DWORD mastervol = (realmastervol * (m_nSongPreAmp + 0x10)) >> 6;
484 		if (mastervol > 0x200) mastervol = 0x200;
485 		if ((m_dwSongFlags & SONG_GLOBALFADE) && (m_nGlobalFadeMaxSamples))
486 		{
487 			mastervol = _muldiv(mastervol, m_nGlobalFadeSamples, m_nGlobalFadeMaxSamples);
488 		}
489 		nMasterVol = (mastervol << 7) / attenuation;
490 		if (nMasterVol > 0x180) nMasterVol = 0x180;
491 	}
492 	////////////////////////////////////////////////////////////////////////////////////
493 	// Update channels data
494 	m_nMixChannels = 0;
495 	MODCHANNEL *pChn = Chn;
496 	for (UINT nChn=0; nChn<MAX_CHANNELS; nChn++,pChn++)
497 	{
498 		if ((pChn->dwFlags & CHN_NOTEFADE) && (!(pChn->nFadeOutVol|pChn->nRightVol|pChn->nLeftVol)))
499 		{
500 			pChn->nLength = 0;
501 			pChn->nROfs = pChn->nLOfs = 0;
502 		}
503 		// Check for unused channel
504 		if ((pChn->dwFlags & CHN_MUTE) || ((nChn >= m_nChannels) && (!pChn->nLength)))
505 		{
506 			pChn->nVUMeter = 0;
507 #ifdef ENABLE_STEREOVU
508 			pChn->nLeftVU = pChn->nRightVU = 0;
509 #endif
510 			continue;
511 		}
512 		// Reset channel data
513 		pChn->nInc = 0;
514 		pChn->nRealVolume = 0;
515 		pChn->nRealPan = pChn->nPan + pChn->nPanSwing;
516 		if (pChn->nRealPan < 0) pChn->nRealPan = 0;
517 		if (pChn->nRealPan > 256) pChn->nRealPan = 256;
518 		pChn->nRampLength = 0;
519 		// Calc Frequency
520 		if ((pChn->nPeriod)	&& (pChn->nLength))
521 		{
522 			int vol = pChn->nVolume + pChn->nVolSwing;
523 
524 			if (vol < 0) vol = 0;
525 			if (vol > 256) vol = 256;
526 			// Tremolo
527 			if (pChn->dwFlags & CHN_TREMOLO)
528 			{
529 				UINT trempos = pChn->nTremoloPos & 0x3F;
530 				if (vol > 0)
531 				{
532 					int tremattn = (m_nType & MOD_TYPE_XM) ? 5 : 6;
533 					switch (pChn->nTremoloType & 0x03)
534 					{
535 					case 1:
536 						vol += (ModRampDownTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
537 						break;
538 					case 2:
539 						vol += (ModSquareTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
540 						break;
541 					case 3:
542 						vol += (ModRandomTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
543 						break;
544 					default:
545 						vol += (ModSinusTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
546 					}
547 				}
548 				if ((m_nTickCount) || ((m_nType & (MOD_TYPE_STM|MOD_TYPE_S3M|MOD_TYPE_IT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
549 				{
550 					pChn->nTremoloPos = (trempos + pChn->nTremoloSpeed) & 0x3F;
551 				}
552 			}
553 			// Tremor
554 			if (pChn->nCommand == CMD_TREMOR)
555 			{
556 				UINT n = (pChn->nTremorParam >> 4) + (pChn->nTremorParam & 0x0F);
557 				UINT ontime = pChn->nTremorParam >> 4;
558 				if ((!(m_nType & MOD_TYPE_IT)) || (m_dwSongFlags & SONG_ITOLDEFFECTS)) { n += 2; ontime++; }
559 				UINT tremcount = (UINT)pChn->nTremorCount;
560 				if (tremcount >= n) tremcount = 0;
561 				if ((m_nTickCount) || (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT)))
562 				{
563 					if (tremcount >= ontime) vol = 0;
564 					pChn->nTremorCount = (BYTE)(tremcount + 1);
565 				}
566 				pChn->dwFlags |= CHN_FASTVOLRAMP;
567 			}
568 			// Clip volume
569 			if (vol < 0) vol = 0;
570 			if (vol > 0x100) vol = 0x100;
571 			vol <<= 6;
572 			// Process Envelopes
573 			if (pChn->pHeader)
574 			{
575 				INSTRUMENTHEADER *penv = pChn->pHeader;
576 				// Volume Envelope
577 				if ((pChn->dwFlags & CHN_VOLENV) && (penv->nVolEnv))
578 				{
579 					int envpos = pChn->nVolEnvPosition;
580 					UINT pt = penv->nVolEnv - 1;
581 					for (UINT i=0; i<(UINT)(penv->nVolEnv-1); i++)
582 					{
583 						if (envpos <= penv->VolPoints[i])
584 						{
585 							pt = i;
586 							break;
587 						}
588 					}
589 					int x2 = penv->VolPoints[pt];
590 					int x1, envvol;
591 					if (envpos >= x2)
592 					{
593 						envvol = penv->VolEnv[pt] << 2;
594 						x1 = x2;
595 					} else
596 					if (pt)
597 					{
598 						envvol = penv->VolEnv[pt-1] << 2;
599 						x1 = penv->VolPoints[pt-1];
600 					} else
601 					{
602 						envvol = 0;
603 						x1 = 0;
604 					}
605 					if (envpos > x2) envpos = x2;
606 					if ((x2 > x1) && (envpos > x1))
607 					{
608 						envvol += ((envpos - x1) * (((int)penv->VolEnv[pt]<<2) - envvol)) / (x2 - x1);
609 					}
610 					if (envvol < 0) envvol = 0;
611 					if (envvol > 256) envvol = 256;
612 					vol = (vol * envvol) >> 8;
613 				}
614 				// Panning Envelope
615 				if ((pChn->dwFlags & CHN_PANENV) && (penv->nPanEnv))
616 				{
617 					int envpos = pChn->nPanEnvPosition;
618 					UINT pt = penv->nPanEnv - 1;
619 					for (UINT i=0; i<(UINT)(penv->nPanEnv-1); i++)
620 					{
621 						if (envpos <= penv->PanPoints[i])
622 						{
623 							pt = i;
624 							break;
625 						}
626 					}
627 					int x2 = penv->PanPoints[pt], y2 = penv->PanEnv[pt];
628 					int x1, envpan;
629 					if (envpos >= x2)
630 					{
631 						envpan = y2;
632 						x1 = x2;
633 					} else
634 					if (pt)
635 					{
636 						envpan = penv->PanEnv[pt-1];
637 						x1 = penv->PanPoints[pt-1];
638 					} else
639 					{
640 						envpan = 128;
641 						x1 = 0;
642 					}
643 					if ((x2 > x1) && (envpos > x1))
644 					{
645 						envpan += ((envpos - x1) * (y2 - envpan)) / (x2 - x1);
646 					}
647 					if (envpan < 0) envpan = 0;
648 					if (envpan > 64) envpan = 64;
649 					int pan = pChn->nPan;
650 					if (pan >= 128)
651 					{
652 						pan += ((envpan - 32) * (256 - pan)) / 32;
653 					} else
654 					{
655 						pan += ((envpan - 32) * (pan)) / 32;
656 					}
657 					if (pan < 0) pan = 0;
658 					if (pan > 256) pan = 256;
659 					pChn->nRealPan = pan;
660 				}
661 				// FadeOut volume
662 				if (pChn->dwFlags & CHN_NOTEFADE)
663 				{
664 					UINT fadeout = penv->nFadeOut;
665 					if (fadeout)
666 					{
667 						pChn->nFadeOutVol -= fadeout << 1;
668 						if (pChn->nFadeOutVol <= 0) pChn->nFadeOutVol = 0;
669 						vol = (vol * pChn->nFadeOutVol) >> 16;
670 					} else
671 					if (!pChn->nFadeOutVol)
672 					{
673 						vol = 0;
674 					}
675 				}
676 				// Pitch/Pan separation
677 				if ((penv->nPPS) && (pChn->nRealPan) && (pChn->nNote))
678 				{
679 					int pandelta = (int)pChn->nRealPan + (int)((int)(pChn->nNote - penv->nPPC - 1) * (int)penv->nPPS) / (int)8;
680 					if (pandelta < 0) pandelta = 0;
681 					if (pandelta > 256) pandelta = 256;
682 					pChn->nRealPan = pandelta;
683 				}
684 			} else
685 			{
686 				// No Envelope: key off => note cut
687 				if (pChn->dwFlags & CHN_NOTEFADE) // 1.41-: CHN_KEYOFF|CHN_NOTEFADE
688 				{
689 					pChn->nFadeOutVol = 0;
690 					vol = 0;
691 				}
692 			}
693 			// vol is 14-bits
694 			if (vol)
695 			{
696 				// IMPORTANT: pChn->nRealVolume is 14 bits !!!
697 				// -> _muldiv( 14+8, 6+6, 18); => RealVolume: 14-bit result (22+12-20)
698 				pChn->nRealVolume = _muldiv(vol * m_nGlobalVolume, pChn->nGlobalVol * pChn->nInsVol, 1 << 20);
699 			}
700 			if (pChn->nPeriod < m_nMinPeriod) pChn->nPeriod = m_nMinPeriod;
701 			int period = pChn->nPeriod;
702 			if ((pChn->dwFlags & (CHN_GLISSANDO|CHN_PORTAMENTO)) ==	(CHN_GLISSANDO|CHN_PORTAMENTO))
703 			{
704 				period = GetPeriodFromNote(GetNoteFromPeriod(period), pChn->nFineTune, pChn->nC4Speed);
705 			}
706 
707 			// Arpeggio ?
708 			if (pChn->nCommand == CMD_ARPEGGIO)
709 			{
710 				switch(m_nTickCount % 3)
711 				{
712 				case 1:	period = GetPeriodFromNote(pChn->nNote + (pChn->nArpeggio >> 4), pChn->nFineTune, pChn->nC4Speed); break;
713 				case 2:	period = GetPeriodFromNote(pChn->nNote + (pChn->nArpeggio & 0x0F), pChn->nFineTune, pChn->nC4Speed); break;
714 				}
715 			}
716 
717 			if (m_dwSongFlags & SONG_AMIGALIMITS)
718 			{
719 				if (period < 113*4) period = 113*4;
720 				if (period > 856*4) period = 856*4;
721 			}
722 
723 			// Pitch/Filter Envelope
724 			if ((pChn->pHeader) && (pChn->dwFlags & CHN_PITCHENV) && (pChn->pHeader->nPitchEnv))
725 			{
726 				INSTRUMENTHEADER *penv = pChn->pHeader;
727 				int envpos = pChn->nPitchEnvPosition;
728 				UINT pt = penv->nPitchEnv - 1;
729 				for (UINT i=0; i<(UINT)(penv->nPitchEnv-1); i++)
730 				{
731 					if (envpos <= penv->PitchPoints[i])
732 					{
733 						pt = i;
734 						break;
735 					}
736 				}
737 				int x2 = penv->PitchPoints[pt];
738 				int x1, envpitch;
739 				if (envpos >= x2)
740 				{
741 					envpitch = (((int)penv->PitchEnv[pt]) - 32) * 8;
742 					x1 = x2;
743 				} else
744 				if (pt)
745 				{
746 					envpitch = (((int)penv->PitchEnv[pt-1]) - 32) * 8;
747 					x1 = penv->PitchPoints[pt-1];
748 				} else
749 				{
750 					envpitch = 0;
751 					x1 = 0;
752 				}
753 				if (envpos > x2) envpos = x2;
754 				if ((x2 > x1) && (envpos > x1))
755 				{
756 					int envpitchdest = (((int)penv->PitchEnv[pt]) - 32) * 8;
757 					envpitch += ((envpos - x1) * (envpitchdest - envpitch)) / (x2 - x1);
758 				}
759 				if (envpitch < -256) envpitch = -256;
760 				if (envpitch > 256) envpitch = 256;
761 				// Filter Envelope: controls cutoff frequency
762 				if (penv->dwFlags & ENV_FILTER)
763 				{
764 #ifndef NO_FILTER
765 					SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? FALSE : TRUE, envpitch);
766 #endif // NO_FILTER
767 				} else
768 				// Pitch Envelope
769 				{
770 					int l = envpitch;
771 					if (l < 0)
772 					{
773 						l = -l;
774 						if (l > 255) l = 255;
775 						period = _muldiv(period, LinearSlideUpTable[l], 0x10000);
776 					} else
777 					{
778 						if (l > 255) l = 255;
779 						period = _muldiv(period, LinearSlideDownTable[l], 0x10000);
780 					}
781 				}
782 			}
783 
784 			// Vibrato
785 			if (pChn->dwFlags & CHN_VIBRATO)
786 			{
787 				UINT vibpos = pChn->nVibratoPos;
788 				LONG vdelta;
789 				switch (pChn->nVibratoType & 0x03)
790 				{
791 				case 1:
792 					vdelta = ModRampDownTable[vibpos];
793 					break;
794 				case 2:
795 					vdelta = ModSquareTable[vibpos];
796 					break;
797 				case 3:
798 					vdelta = ModRandomTable[vibpos];
799 					break;
800 				default:
801 					vdelta = ModSinusTable[vibpos];
802 				}
803 				UINT vdepth = ((m_nType != MOD_TYPE_IT) || (m_dwSongFlags & SONG_ITOLDEFFECTS)) ? 6 : 7;
804 				vdelta = (vdelta * (int)pChn->nVibratoDepth) >> vdepth;
805 				if ((m_dwSongFlags & SONG_LINEARSLIDES) && (m_nType & MOD_TYPE_IT))
806 				{
807 					LONG l = vdelta;
808 					if (l < 0)
809 					{
810 						l = -l;
811 						vdelta = _muldiv(period, LinearSlideDownTable[l >> 2], 0x10000) - period;
812 						if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideDownTable[l & 0x03], 0x10000) - period;
813 
814 					} else
815 					{
816 						vdelta = _muldiv(period, LinearSlideUpTable[l >> 2], 0x10000) - period;
817 						if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideUpTable[l & 0x03], 0x10000) - period;
818 
819 					}
820 				}
821 				period += vdelta;
822 				if ((m_nTickCount) || ((m_nType & MOD_TYPE_IT) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
823 				{
824 					pChn->nVibratoPos = (vibpos + pChn->nVibratoSpeed) & 0x3F;
825 				}
826 			}
827 			// Panbrello
828 			if (pChn->dwFlags & CHN_PANBRELLO)
829 			{
830 				UINT panpos = ((pChn->nPanbrelloPos+0x10) >> 2) & 0x3F;
831 				LONG pdelta;
832 				switch (pChn->nPanbrelloType & 0x03)
833 				{
834 				case 1:
835 					pdelta = ModRampDownTable[panpos];
836 					break;
837 				case 2:
838 					pdelta = ModSquareTable[panpos];
839 					break;
840 				case 3:
841 					pdelta = ModRandomTable[panpos];
842 					break;
843 				default:
844 					pdelta = ModSinusTable[panpos];
845 				}
846 				pChn->nPanbrelloPos += pChn->nPanbrelloSpeed;
847 				pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> 3;
848 				pdelta += pChn->nRealPan;
849 				if (pdelta < 0) pdelta = 0;
850 				if (pdelta > 256) pdelta = 256;
851 				pChn->nRealPan = pdelta;
852 			}
853 			int nPeriodFrac = 0;
854 			// Instrument Auto-Vibrato
855 			if ((pChn->pInstrument) && (pChn->pInstrument->nVibDepth))
856 			{
857 				MODINSTRUMENT *pins = pChn->pInstrument;
858 				if (pins->nVibSweep == 0)
859 				{
860 					pChn->nAutoVibDepth = pins->nVibDepth << 8;
861 				} else
862 				{
863 					if (m_nType & MOD_TYPE_IT)
864 					{
865 						pChn->nAutoVibDepth += pins->nVibSweep << 3;
866 					} else
867 					if (!(pChn->dwFlags & CHN_KEYOFF))
868 					{
869 						pChn->nAutoVibDepth += (pins->nVibDepth << 8) /	pins->nVibSweep;
870 					}
871 					if ((pChn->nAutoVibDepth >> 8) > pins->nVibDepth)
872 						pChn->nAutoVibDepth = pins->nVibDepth << 8;
873 				}
874 				pChn->nAutoVibPos += pins->nVibRate;
875 				int val;
876 				switch(pins->nVibType)
877 				{
878 				case 4:	// Random
879 					val = ModRandomTable[pChn->nAutoVibPos & 0x3F];
880 					pChn->nAutoVibPos++;
881 					break;
882 				case 3:	// Ramp Down
883 					val = ((0x40 - (pChn->nAutoVibPos >> 1)) & 0x7F) - 0x40;
884 					break;
885 				case 2:	// Ramp Up
886 					val = ((0x40 + (pChn->nAutoVibPos >> 1)) & 0x7f) - 0x40;
887 					break;
888 				case 1:	// Square
889 					val = (pChn->nAutoVibPos & 128) ? +64 : -64;
890 					break;
891 				default:	// Sine
892 					val = ft2VibratoTable[pChn->nAutoVibPos & 255];
893 				}
894 				int n =	((val * pChn->nAutoVibDepth) >> 8);
895 				if (m_nType & MOD_TYPE_IT)
896 				{
897 					int df1, df2;
898 					if (n < 0)
899 					{
900 						n = -n;
901 						UINT n1 = n >> 8;
902 						df1 = LinearSlideUpTable[n1];
903 						df2 = LinearSlideUpTable[n1+1];
904 					} else
905 					{
906 						UINT n1 = n >> 8;
907 						df1 = LinearSlideDownTable[n1];
908 						df2 = LinearSlideDownTable[n1+1];
909 					}
910 					n >>= 2;
911 					period = _muldiv(period, df1 + ((df2-df1)*(n&0x3F)>>6), 256);
912 					nPeriodFrac = period & 0xFF;
913 					period >>= 8;
914 				} else
915 				{
916 					period += (n >> 6);
917 				}
918 			}
919 			// Final Period
920 			if (period <= m_nMinPeriod)
921 			{
922 				if (m_nType & MOD_TYPE_S3M) pChn->nLength = 0;
923 				period = m_nMinPeriod;
924 			}
925 			if (period > m_nMaxPeriod)
926 			{
927 				if ((m_nType & MOD_TYPE_IT) || (period >= 0x100000))
928 				{
929 					pChn->nFadeOutVol = 0;
930 					pChn->dwFlags |= CHN_NOTEFADE;
931 					pChn->nRealVolume = 0;
932 				}
933 				period = m_nMaxPeriod;
934 				nPeriodFrac = 0;
935 			}
936 			UINT freq = GetFreqFromPeriod(period, pChn->nC4Speed, nPeriodFrac);
937 			if ((m_nType & MOD_TYPE_IT) && (freq < 256))
938 			{
939 				pChn->nFadeOutVol = 0;
940 				pChn->dwFlags |= CHN_NOTEFADE;
941 				pChn->nRealVolume = 0;
942 			}
943 			UINT ninc = _muldiv(freq, 0x10000, gdwMixingFreq);
944 			if ((ninc >= 0xFFB0) && (ninc <= 0x10090)) ninc = 0x10000;
945 			if (m_nFreqFactor != 128) ninc = (ninc * m_nFreqFactor) >> 7;
946 			if (ninc > 0xFF0000) ninc = 0xFF0000;
947 			pChn->nInc = (ninc+1) & ~3;
948 		}
949 
950 		// Increment envelope position
951 		if (pChn->pHeader)
952 		{
953 			INSTRUMENTHEADER *penv = pChn->pHeader;
954 			// Volume Envelope
955 			if (pChn->dwFlags & CHN_VOLENV)
956 			{
957 				// Increase position
958 				pChn->nVolEnvPosition++;
959 				// Volume Loop ?
960 				if (penv->dwFlags & ENV_VOLLOOP)
961 				{
962 					UINT volloopend = penv->VolPoints[penv->nVolLoopEnd];
963 					if (m_nType != MOD_TYPE_XM) volloopend++;
964 					if (pChn->nVolEnvPosition == volloopend)
965 					{
966 						pChn->nVolEnvPosition = penv->VolPoints[penv->nVolLoopStart];
967 						if ((penv->nVolLoopEnd == penv->nVolLoopStart) && (!penv->VolEnv[penv->nVolLoopStart])
968 						 && ((!(m_nType & MOD_TYPE_XM)) || (penv->nVolLoopEnd+1 == penv->nVolEnv)))
969 						{
970 							pChn->dwFlags |= CHN_NOTEFADE;
971 							pChn->nFadeOutVol = 0;
972 						}
973 					}
974 				}
975 				// Volume Sustain ?
976 				if ((penv->dwFlags & ENV_VOLSUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF)))
977 				{
978 					if (pChn->nVolEnvPosition == (UINT)penv->VolPoints[penv->nVolSustainEnd]+1)
979 						pChn->nVolEnvPosition = penv->VolPoints[penv->nVolSustainBegin];
980 				} else
981 				// End of Envelope ?
982 				if (pChn->nVolEnvPosition > penv->VolPoints[penv->nVolEnv - 1])
983 				{
984 					if ((m_nType & MOD_TYPE_IT) || (pChn->dwFlags & CHN_KEYOFF)) pChn->dwFlags |= CHN_NOTEFADE;
985 					pChn->nVolEnvPosition = penv->VolPoints[penv->nVolEnv - 1];
986 					if ((!penv->VolEnv[penv->nVolEnv-1]) && ((nChn >= m_nChannels) || (m_nType & MOD_TYPE_IT)))
987 					{
988 						pChn->dwFlags |= CHN_NOTEFADE;
989 						pChn->nFadeOutVol = 0;
990 
991 						pChn->nRealVolume = 0;
992 					}
993 				}
994 			}
995 			// Panning Envelope
996 			if (pChn->dwFlags & CHN_PANENV)
997 			{
998 				pChn->nPanEnvPosition++;
999 				if (penv->dwFlags & ENV_PANLOOP)
1000 				{
1001 					UINT panloopend = penv->PanPoints[penv->nPanLoopEnd];
1002 					if (m_nType != MOD_TYPE_XM) panloopend++;
1003 					if (pChn->nPanEnvPosition == panloopend)
1004 						pChn->nPanEnvPosition = penv->PanPoints[penv->nPanLoopStart];
1005 				}
1006 				// Panning Sustain ?
1007 				if ((penv->dwFlags & ENV_PANSUSTAIN) && (pChn->nPanEnvPosition == (UINT)penv->PanPoints[penv->nPanSustainEnd]+1)
1008 				 && (!(pChn->dwFlags & CHN_KEYOFF)))
1009 				{
1010 					// Panning sustained
1011 					pChn->nPanEnvPosition = penv->PanPoints[penv->nPanSustainBegin];
1012 				} else
1013 				{
1014 					if (pChn->nPanEnvPosition > penv->PanPoints[penv->nPanEnv - 1])
1015 						pChn->nPanEnvPosition = penv->PanPoints[penv->nPanEnv - 1];
1016 				}
1017 			}
1018 			// Pitch Envelope
1019 			if (pChn->dwFlags & CHN_PITCHENV)
1020 			{
1021 				// Increase position
1022 				pChn->nPitchEnvPosition++;
1023 				// Pitch Loop ?
1024 				if (penv->dwFlags & ENV_PITCHLOOP)
1025 				{
1026 					if (pChn->nPitchEnvPosition >= penv->PitchPoints[penv->nPitchLoopEnd])
1027 						pChn->nPitchEnvPosition = penv->PitchPoints[penv->nPitchLoopStart];
1028 				}
1029 				// Pitch Sustain ?
1030 				if ((penv->dwFlags & ENV_PITCHSUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF)))
1031 				{
1032 					if (pChn->nPitchEnvPosition == (UINT)penv->PitchPoints[penv->nPitchSustainEnd]+1)
1033 						pChn->nPitchEnvPosition = penv->PitchPoints[penv->nPitchSustainBegin];
1034 				} else
1035 				{
1036 					if (pChn->nPitchEnvPosition > penv->PitchPoints[penv->nPitchEnv - 1])
1037 						pChn->nPitchEnvPosition = penv->PitchPoints[penv->nPitchEnv - 1];
1038 				}
1039 			}
1040 		}
1041 #ifdef MODPLUG_PLAYER
1042 		// Limit CPU -> > 80% -> don't ramp
1043 		if ((gnCPUUsage >= 80) && (!pChn->nRealVolume))
1044 		{
1045 			pChn->nLeftVol = pChn->nRightVol = 0;
1046 		}
1047 #endif // MODPLUG_PLAYER
1048 		// Volume ramping
1049 		pChn->dwFlags &= ~CHN_VOLUMERAMP;
1050 		if ((pChn->nRealVolume) || (pChn->nLeftVol) || (pChn->nRightVol))
1051 			pChn->dwFlags |= CHN_VOLUMERAMP;
1052 #ifdef MODPLUG_PLAYER
1053 		// Decrease VU-Meter
1054 		if (pChn->nVUMeter > VUMETER_DECAY)	pChn->nVUMeter -= VUMETER_DECAY; else pChn->nVUMeter = 0;
1055 #endif // MODPLUG_PLAYER
1056 #ifdef ENABLE_STEREOVU
1057 		if (pChn->nLeftVU > VUMETER_DECAY) pChn->nLeftVU -= VUMETER_DECAY; else pChn->nLeftVU = 0;
1058 		if (pChn->nRightVU > VUMETER_DECAY) pChn->nRightVU -= VUMETER_DECAY; else pChn->nRightVU = 0;
1059 #endif
1060 		// Check for too big nInc
1061 		if (((pChn->nInc >> 16) + 1) >= (LONG)(pChn->nLoopEnd - pChn->nLoopStart)) pChn->dwFlags &= ~CHN_LOOP;
1062 		pChn->nNewRightVol = pChn->nNewLeftVol = 0;
1063 		pChn->pCurrentSample = ((pChn->pSample) && (pChn->nLength) && (pChn->nInc)) ? pChn->pSample : NULL;
1064 		if (pChn->pCurrentSample)
1065 		{
1066 			// Update VU-Meter (nRealVolume is 14-bit)
1067 #ifdef MODPLUG_PLAYER
1068 			UINT vutmp = pChn->nRealVolume >> (14 - 8);
1069 			if (vutmp > 0xFF) vutmp = 0xFF;
1070 			if (pChn->nVUMeter >= 0x100) pChn->nVUMeter = vutmp;
1071 			vutmp >>= 1;
1072 			if (pChn->nVUMeter < vutmp)	pChn->nVUMeter = vutmp;
1073 #endif // MODPLUG_PLAYER
1074 #ifdef ENABLE_STEREOVU
1075 			UINT vul = (pChn->nRealVolume * pChn->nRealPan) >> 14;
1076 			if (vul > 127) vul = 127;
1077 			if (pChn->nLeftVU > 127) pChn->nLeftVU = (BYTE)vul;
1078 			vul >>= 1;
1079 			if (pChn->nLeftVU < vul) pChn->nLeftVU = (BYTE)vul;
1080 			UINT vur = (pChn->nRealVolume * (256-pChn->nRealPan)) >> 14;
1081 			if (vur > 127) vur = 127;
1082 			if (pChn->nRightVU > 127) pChn->nRightVU = (BYTE)vur;
1083 			vur >>= 1;
1084 			if (pChn->nRightVU < vur) pChn->nRightVU = (BYTE)vur;
1085 #endif
1086 #ifdef MODPLUG_TRACKER
1087 			UINT kChnMasterVol = (pChn->dwFlags & CHN_EXTRALOUD) ? 0x100 : nMasterVol;
1088 #else
1089 #define		kChnMasterVol	nMasterVol
1090 #endif // MODPLUG_TRACKER
1091 			// Adjusting volumes
1092 			if (gnChannels >= 2)
1093 			{
1094 				int pan = ((int)pChn->nRealPan) - 128;
1095 				pan *= (int)m_nStereoSeparation;
1096 				pan /= 128;
1097 				pan += 128;
1098 
1099 				if (pan < 0) pan = 0;
1100 				if (pan > 256) pan = 256;
1101 #ifndef MODPLUG_FASTSOUNDLIB
1102 				if (gdwSoundSetup & SNDMIX_REVERSESTEREO) pan = 256 - pan;
1103 #endif
1104 				LONG realvol = (pChn->nRealVolume * kChnMasterVol) >> (8-1);
1105 				if (gdwSoundSetup & SNDMIX_SOFTPANNING)
1106 				{
1107 					if (pan < 128)
1108 					{
1109 						pChn->nNewLeftVol = (realvol * pan) >> 8;
1110 						pChn->nNewRightVol = (realvol * 128) >> 8;
1111 					} else
1112 					{
1113 						pChn->nNewLeftVol = (realvol * 128) >> 8;
1114 						pChn->nNewRightVol = (realvol * (256 - pan)) >> 8;
1115 					}
1116 				} else
1117 				{
1118 					pChn->nNewLeftVol = (realvol * pan) >> 8;
1119 					pChn->nNewRightVol = (realvol * (256 - pan)) >> 8;
1120 				}
1121 			} else
1122 			{
1123 				pChn->nNewRightVol = (pChn->nRealVolume * kChnMasterVol) >> 8;
1124 				pChn->nNewLeftVol = pChn->nNewRightVol;
1125 			}
1126 			// Clipping volumes
1127 			if (pChn->nNewRightVol > 0xFFFF) pChn->nNewRightVol = 0xFFFF;
1128 			if (pChn->nNewLeftVol > 0xFFFF) pChn->nNewLeftVol = 0xFFFF;
1129 			// Check IDO
1130 			if (gdwSoundSetup & SNDMIX_NORESAMPLING)
1131 			{
1132 				pChn->dwFlags |= CHN_NOIDO;
1133 			} else
1134 			{
1135 				pChn->dwFlags &= ~(CHN_NOIDO|CHN_HQSRC);
1136 				if( pChn->nInc == 0x10000 )
1137 				{	pChn->dwFlags |= CHN_NOIDO;
1138 				}
1139 				else
1140 				{	if( ((gdwSoundSetup & SNDMIX_HQRESAMPLER) == 0) && ((gdwSoundSetup & SNDMIX_ULTRAHQSRCMODE) == 0) )
1141 					{	if (pChn->nInc >= 0xFF00) pChn->dwFlags |= CHN_NOIDO;
1142 					}
1143 				}
1144 			}
1145 			pChn->nNewRightVol >>= MIXING_ATTENUATION;
1146 			pChn->nNewLeftVol >>= MIXING_ATTENUATION;
1147 			pChn->nRightRamp = pChn->nLeftRamp = 0;
1148 			// Dolby Pro-Logic Surround
1149 			if ((pChn->dwFlags & CHN_SURROUND) && (gnChannels <= 2)) pChn->nNewLeftVol = - pChn->nNewLeftVol;
1150 			// Checking Ping-Pong Loops
1151 			if (pChn->dwFlags & CHN_PINGPONGFLAG) pChn->nInc = -pChn->nInc;
1152 			// Setting up volume ramp
1153 			if ((pChn->dwFlags & CHN_VOLUMERAMP)
1154 			 && ((pChn->nRightVol != pChn->nNewRightVol)
1155 			  || (pChn->nLeftVol != pChn->nNewLeftVol)))
1156 			{
1157 				LONG nRampLength = gnVolumeRampSamples;
1158 				LONG nRightDelta = ((pChn->nNewRightVol - pChn->nRightVol) << VOLUMERAMPPRECISION);
1159 				LONG nLeftDelta = ((pChn->nNewLeftVol - pChn->nLeftVol) << VOLUMERAMPPRECISION);
1160 #ifndef MODPLUG_FASTSOUNDLIB
1161 				if ((gdwSoundSetup & SNDMIX_DIRECTTODISK)
1162 				 || ((gdwSysInfo & (SYSMIX_ENABLEMMX|SYSMIX_FASTCPU))
1163 				  && (gdwSoundSetup & SNDMIX_HQRESAMPLER) && (gnCPUUsage <= 20)))
1164 				{
1165 					if ((pChn->nRightVol|pChn->nLeftVol) && (pChn->nNewRightVol|pChn->nNewLeftVol) && (!(pChn->dwFlags & CHN_FASTVOLRAMP)))
1166 					{
1167 						nRampLength = m_nBufferCount;
1168 						if (nRampLength > (1 << (VOLUMERAMPPRECISION-1))) nRampLength = (1 << (VOLUMERAMPPRECISION-1));
1169 						if (nRampLength < (LONG)gnVolumeRampSamples) nRampLength = gnVolumeRampSamples;
1170 					}
1171 				}
1172 #endif
1173 				pChn->nRightRamp = nRightDelta / nRampLength;
1174 				pChn->nLeftRamp = nLeftDelta / nRampLength;
1175 				pChn->nRightVol = pChn->nNewRightVol - ((pChn->nRightRamp * nRampLength) >> VOLUMERAMPPRECISION);
1176 				pChn->nLeftVol = pChn->nNewLeftVol - ((pChn->nLeftRamp * nRampLength) >> VOLUMERAMPPRECISION);
1177 				if (pChn->nRightRamp|pChn->nLeftRamp)
1178 				{
1179 					pChn->nRampLength = nRampLength;
1180 				} else
1181 				{
1182 					pChn->dwFlags &= ~CHN_VOLUMERAMP;
1183 					pChn->nRightVol = pChn->nNewRightVol;
1184 					pChn->nLeftVol = pChn->nNewLeftVol;
1185 				}
1186 			} else
1187 			{
1188 				pChn->dwFlags &= ~CHN_VOLUMERAMP;
1189 				pChn->nRightVol = pChn->nNewRightVol;
1190 				pChn->nLeftVol = pChn->nNewLeftVol;
1191 			}
1192 			pChn->nRampRightVol = pChn->nRightVol << VOLUMERAMPPRECISION;
1193 			pChn->nRampLeftVol = pChn->nLeftVol << VOLUMERAMPPRECISION;
1194 			// Adding the channel in the channel list
1195 			ChnMix[m_nMixChannels++] = nChn;
1196 			if (m_nMixChannels >= MAX_CHANNELS) break;
1197 		} else
1198 		{
1199 #ifdef ENABLE_STEREOVU
1200 			// Note change but no sample
1201 			if (pChn->nLeftVU > 128) pChn->nLeftVU = 0;
1202 			if (pChn->nRightVU > 128) pChn->nRightVU = 0;
1203 #endif
1204 			if (pChn->nVUMeter > 0xFF) pChn->nVUMeter = 0;
1205 			pChn->nLeftVol = pChn->nRightVol = 0;
1206 			pChn->nLength = 0;
1207 		}
1208 	}
1209 	// Checking Max Mix Channels reached: ordering by volume
1210 	if ((m_nMixChannels >= m_nMaxMixChannels) && (!(gdwSoundSetup & SNDMIX_DIRECTTODISK)))
1211 	{
1212 		for (UINT i=0; i<m_nMixChannels; i++)
1213 		{
1214 			UINT j=i;
1215 			while ((j+1<m_nMixChannels) && (Chn[ChnMix[j]].nRealVolume < Chn[ChnMix[j+1]].nRealVolume))
1216 			{
1217 				UINT n = ChnMix[j];
1218 				ChnMix[j] = ChnMix[j+1];
1219 				ChnMix[j+1] = n;
1220 				j++;
1221 			}
1222 		}
1223 	}
1224 	if (m_dwSongFlags & SONG_GLOBALFADE)
1225 	{
1226 		if (!m_nGlobalFadeSamples)
1227 		{
1228 			m_dwSongFlags |= SONG_ENDREACHED;
1229 			return FALSE;
1230 		}
1231 		if (m_nGlobalFadeSamples > m_nBufferCount)
1232 			m_nGlobalFadeSamples -= m_nBufferCount;
1233 		else
1234 			m_nGlobalFadeSamples = 0;
1235 	}
1236 	return TRUE;
1237 }
1238