00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "stdafx.h"
00011 #include "sndfile.h"
00012
00013 #ifdef MODPLUG_TRACKER
00014 #define ENABLE_STEREOVU
00015 #endif
00016
00017
00018 #define VOLUMERAMPLEN 146 // 1.46ms = 64 samples at 44.1kHz
00019
00020
00021 #define VUMETER_DECAY 4
00022
00023
00024 UINT CSoundFile::m_nStereoSeparation = 128;
00025 LONG CSoundFile::m_nStreamVolume = 0x8000;
00026 UINT CSoundFile::m_nMaxMixChannels = 32;
00027
00028 DWORD CSoundFile::gdwSysInfo = 0;
00029 DWORD CSoundFile::gnChannels = 1;
00030 DWORD CSoundFile::gdwSoundSetup = 0;
00031 DWORD CSoundFile::gdwMixingFreq = 44100;
00032 DWORD CSoundFile::gnBitsPerSample = 16;
00033
00034 UINT CSoundFile::gnAGC = AGC_UNITY;
00035 UINT CSoundFile::gnVolumeRampSamples = 64;
00036 UINT CSoundFile::gnVUMeter = 0;
00037 UINT CSoundFile::gnCPUUsage = 0;
00038 LPSNDMIXHOOKPROC CSoundFile::gpSndMixHook = NULL;
00039 PMIXPLUGINCREATEPROC CSoundFile::gpMixPluginCreateProc = NULL;
00040 LONG gnDryROfsVol = 0;
00041 LONG gnDryLOfsVol = 0;
00042 LONG gnRvbROfsVol = 0;
00043 LONG gnRvbLOfsVol = 0;
00044 int gbInitPlugins = 0;
00045
00046 typedef DWORD (MPPASMCALL * LPCONVERTPROC)(LPVOID, int *, DWORD, LPLONG, LPLONG);
00047
00048 extern DWORD MPPASMCALL X86_Convert32To8(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG);
00049 extern DWORD MPPASMCALL X86_Convert32To16(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG);
00050 extern DWORD MPPASMCALL X86_Convert32To24(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG);
00051 extern DWORD MPPASMCALL X86_Convert32To32(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG);
00052 extern UINT MPPASMCALL X86_AGC(int *pBuffer, UINT nSamples, UINT nAGC);
00053 extern VOID MPPASMCALL X86_Dither(int *pBuffer, UINT nSamples, UINT nBits);
00054 extern VOID MPPASMCALL X86_InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples);
00055 extern VOID MPPASMCALL X86_StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs);
00056 extern VOID MPPASMCALL X86_MonoFromStereo(int *pMixBuf, UINT nSamples);
00057
00058 extern const short int ModSinusTable[64];
00059 extern const short int ModRampDownTable[64];
00060 extern const short int ModSquareTable[64];
00061 extern const short int ModRandomTable[64];
00062 extern const DWORD LinearSlideUpTable[256];
00063 extern const DWORD LinearSlideDownTable[256];
00064 extern const DWORD FineLinearSlideUpTable[16];
00065 extern const DWORD FineLinearSlideDownTable[16];
00066 extern const signed char ft2VibratoTable[256];
00067 extern int MixSoundBuffer[MIXBUFFERSIZE*4];
00068 extern int MixRearBuffer[MIXBUFFERSIZE*2];
00069 UINT gnReverbSend;
00070
00071
00072
00073
00074 const UINT PreAmpTable[16] =
00075 {
00076 0x60, 0x60, 0x60, 0x70,
00077 0x80, 0x88, 0x90, 0x98,
00078 0xA0, 0xA4, 0xA8, 0xB0,
00079 0xB4, 0xB8, 0xBC, 0xC0,
00080 };
00081
00082 const UINT PreAmpAGCTable[16] =
00083 {
00084 0x60, 0x60, 0x60, 0x60,
00085 0x68, 0x70, 0x78, 0x80,
00086 0x84, 0x88, 0x8C, 0x90,
00087 0x94, 0x98, 0x9C, 0xA0,
00088 };
00089
00090
00091
00092 int _muldiv(long a, long b, long c)
00093 {
00094 #ifdef WIN32
00095 int sign, result;
00096 _asm {
00097 mov eax, a
00098 mov ebx, b
00099 or eax, eax
00100 mov edx, eax
00101 jge aneg
00102 neg eax
00103 aneg:
00104 xor edx, ebx
00105 or ebx, ebx
00106 mov ecx, c
00107 jge bneg
00108 neg ebx
00109 bneg:
00110 xor edx, ecx
00111 or ecx, ecx
00112 mov sign, edx
00113 jge cneg
00114 neg ecx
00115 cneg:
00116 mul ebx
00117 cmp edx, ecx
00118 jae diverr
00119 div ecx
00120 jmp ok
00121 diverr:
00122 mov eax, 0x7fffffff
00123 ok:
00124 mov edx, sign
00125 or edx, edx
00126 jge rneg
00127 neg eax
00128 rneg:
00129 mov result, eax
00130 }
00131 return result;
00132 #else
00133 return ((unsigned long long) a * (unsigned long long) b ) / c;
00134 #endif
00135 }
00136
00137
00138
00139 int _muldivr(long a, long b, long c)
00140 {
00141 #ifdef WIN32
00142 int sign, result;
00143 _asm {
00144 mov eax, a
00145 mov ebx, b
00146 or eax, eax
00147 mov edx, eax
00148 jge aneg
00149 neg eax
00150 aneg:
00151 xor edx, ebx
00152 or ebx, ebx
00153 mov ecx, c
00154 jge bneg
00155 neg ebx
00156 bneg:
00157 xor edx, ecx
00158 or ecx, ecx
00159 mov sign, edx
00160 jge cneg
00161 neg ecx
00162 cneg:
00163 mul ebx
00164 mov ebx, ecx
00165 shr ebx, 1
00166 add eax, ebx
00167 adc edx, 0
00168 cmp edx, ecx
00169 jae diverr
00170 div ecx
00171 jmp ok
00172 diverr:
00173 mov eax, 0x7fffffff
00174 ok:
00175 mov edx, sign
00176 or edx, edx
00177 jge rneg
00178 neg eax
00179 rneg:
00180 mov result, eax
00181 }
00182 return result;
00183 #else
00184 return ((unsigned long long) a * (unsigned long long) b + (c >> 1)) / c;
00185 #endif
00186 }
00187
00188
00189 BOOL CSoundFile::InitPlayer(BOOL bReset)
00190
00191 {
00192 if (m_nMaxMixChannels > MAX_CHANNELS) m_nMaxMixChannels = MAX_CHANNELS;
00193 if (gdwMixingFreq < 4000) gdwMixingFreq = 4000;
00194 if (gdwMixingFreq > MAX_SAMPLE_RATE) gdwMixingFreq = MAX_SAMPLE_RATE;
00195 gnVolumeRampSamples = (gdwMixingFreq * VOLUMERAMPLEN) / 100000;
00196 if (gnVolumeRampSamples < 8) gnVolumeRampSamples = 8;
00197 gnDryROfsVol = gnDryLOfsVol = 0;
00198 gnRvbROfsVol = gnRvbLOfsVol = 0;
00199 if (bReset)
00200 {
00201 gnVUMeter = 0;
00202 gnCPUUsage = 0;
00203 }
00204 gbInitPlugins = (bReset) ? 3 : 1;
00205 InitializeDSP(bReset);
00206 return TRUE;
00207 }
00208
00209
00210 BOOL CSoundFile::FadeSong(UINT msec)
00211
00212 {
00213 LONG nsamples = _muldiv(msec, gdwMixingFreq, 1000);
00214 if (nsamples <= 0) return FALSE;
00215 if (nsamples > 0x100000) nsamples = 0x100000;
00216 m_nBufferCount = nsamples;
00217 LONG nRampLength = m_nBufferCount;
00218
00219 for (UINT noff=0; noff < m_nMixChannels; noff++)
00220 {
00221 MODCHANNEL *pramp = &Chn[ChnMix[noff]];
00222 if (!pramp) continue;
00223 pramp->nNewLeftVol = pramp->nNewRightVol = 0;
00224 pramp->nRightRamp = (-pramp->nRightVol << VOLUMERAMPPRECISION) / nRampLength;
00225 pramp->nLeftRamp = (-pramp->nLeftVol << VOLUMERAMPPRECISION) / nRampLength;
00226 pramp->nRampRightVol = pramp->nRightVol << VOLUMERAMPPRECISION;
00227 pramp->nRampLeftVol = pramp->nLeftVol << VOLUMERAMPPRECISION;
00228 pramp->nRampLength = nRampLength;
00229 pramp->dwFlags |= CHN_VOLUMERAMP;
00230 }
00231 m_dwSongFlags |= SONG_FADINGSONG;
00232 return TRUE;
00233 }
00234
00235
00236 BOOL CSoundFile::GlobalFadeSong(UINT msec)
00237
00238 {
00239 if (m_dwSongFlags & SONG_GLOBALFADE) return FALSE;
00240 m_nGlobalFadeMaxSamples = _muldiv(msec, gdwMixingFreq, 1000);
00241 m_nGlobalFadeSamples = m_nGlobalFadeMaxSamples;
00242 m_dwSongFlags |= SONG_GLOBALFADE;
00243 return TRUE;
00244 }
00245
00246
00247 UINT CSoundFile::Read(LPVOID lpDestBuffer, UINT cbBuffer)
00248
00249 {
00250 LPBYTE lpBuffer = (LPBYTE)lpDestBuffer;
00251 LPCONVERTPROC pCvt = X86_Convert32To8;
00252 UINT lRead, lMax, lSampleSize, lCount, lSampleCount, nStat=0;
00253 LONG nVUMeterMin = 0x7FFFFFFF, nVUMeterMax = -0x7FFFFFFF;
00254 UINT nMaxPlugins;
00255
00256 {
00257 nMaxPlugins = MAX_MIXPLUGINS;
00258 while ((nMaxPlugins > 0) && (!m_MixPlugins[nMaxPlugins-1].pMixPlugin)) nMaxPlugins--;
00259 }
00260 m_nMixStat = 0;
00261 lSampleSize = gnChannels;
00262 if (gnBitsPerSample == 16) { lSampleSize *= 2; pCvt = X86_Convert32To16; }
00263 #ifndef FASTSOUNDLIB
00264 else if (gnBitsPerSample == 24) { lSampleSize *= 3; pCvt = X86_Convert32To24; }
00265 else if (gnBitsPerSample == 32) { lSampleSize *= 4; pCvt = X86_Convert32To32; }
00266 #endif
00267 lMax = cbBuffer / lSampleSize;
00268 if ((!lMax) || (!lpBuffer) || (!m_nChannels)) return 0;
00269 lRead = lMax;
00270 if (m_dwSongFlags & SONG_ENDREACHED) goto MixDone;
00271 while (lRead > 0)
00272 {
00273
00274 if (!m_nBufferCount)
00275 {
00276 #ifndef FASTSOUNDLIB
00277 if (m_dwSongFlags & SONG_FADINGSONG)
00278 {
00279 m_dwSongFlags |= SONG_ENDREACHED;
00280 m_nBufferCount = lRead;
00281 } else
00282 #endif
00283 if (!ReadNote())
00284 {
00285 #ifndef FASTSOUNDLIB
00286 if (!FadeSong(FADESONGDELAY))
00287 #endif
00288 {
00289 m_dwSongFlags |= SONG_ENDREACHED;
00290 if (lRead == lMax) goto MixDone;
00291 m_nBufferCount = lRead;
00292 }
00293 }
00294 }
00295 lCount = m_nBufferCount;
00296 if (lCount > MIXBUFFERSIZE) lCount = MIXBUFFERSIZE;
00297 if (lCount > lRead) lCount = lRead;
00298 if (!lCount) break;
00299 lSampleCount = lCount;
00300 #ifndef NO_REVERB
00301 gnReverbSend = 0;
00302 #endif
00303
00304 X86_StereoFill(MixSoundBuffer, lSampleCount, &gnDryROfsVol, &gnDryLOfsVol);
00305 if (gnChannels >= 2)
00306 {
00307 lSampleCount *= 2;
00308 m_nMixStat += CreateStereoMix(lCount);
00309 ProcessStereoDSP(lCount);
00310 } else
00311 {
00312 m_nMixStat += CreateStereoMix(lCount);
00313 if (nMaxPlugins) ProcessPlugins(lCount);
00314 ProcessStereoDSP(lCount);
00315 X86_MonoFromStereo(MixSoundBuffer, lCount);
00316 }
00317 nStat++;
00318 #ifndef NO_AGC
00319
00320 if (gdwSoundSetup & SNDMIX_AGC) ProcessAGC(lSampleCount);
00321 #endif
00322 UINT lTotalSampleCount = lSampleCount;
00323 #ifndef FASTSOUNDLIB
00324
00325 if (gnChannels > 2)
00326 {
00327 X86_InterleaveFrontRear(MixSoundBuffer, MixRearBuffer, lSampleCount);
00328 lTotalSampleCount *= 2;
00329 }
00330
00331 if (gpSndMixHook)
00332 {
00333 gpSndMixHook(MixSoundBuffer, lTotalSampleCount, gnChannels);
00334 }
00335 #endif
00336
00337 lpBuffer += pCvt(lpBuffer, MixSoundBuffer, lTotalSampleCount, &nVUMeterMin, &nVUMeterMax);
00338
00339 lRead -= lCount;
00340 m_nBufferCount -= lCount;
00341 }
00342 MixDone:
00343 if (lRead) memset(lpBuffer, (gnBitsPerSample == 8) ? 0x80 : 0, lRead * lSampleSize);
00344
00345 nVUMeterMin >>= (24-MIXING_ATTENUATION);
00346 nVUMeterMax >>= (24-MIXING_ATTENUATION);
00347 if (nVUMeterMax < nVUMeterMin) nVUMeterMax = nVUMeterMin;
00348 if ((gnVUMeter = (UINT)(nVUMeterMax - nVUMeterMin)) > 0xFF) gnVUMeter = 0xFF;
00349 if (nStat) { m_nMixStat += nStat-1; m_nMixStat /= nStat; }
00350 return lMax - lRead;
00351 }
00352
00353
00354
00356
00357
00358 BOOL CSoundFile::ProcessRow()
00359
00360 {
00361 if (++m_nTickCount >= m_nMusicSpeed * (m_nPatternDelay+1) + m_nFrameDelay)
00362 {
00363 m_nPatternDelay = 0;
00364 m_nFrameDelay = 0;
00365 m_nTickCount = 0;
00366 m_nRow = m_nNextRow;
00367
00368 if (m_nCurrentPattern != m_nNextPattern) m_nCurrentPattern = m_nNextPattern;
00369
00370 if (!(m_dwSongFlags & SONG_PATTERNLOOP))
00371 {
00372 m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF;
00373 if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE;
00374 while (m_nPattern >= MAX_PATTERNS)
00375 {
00376
00377 if ((m_nPattern == 0xFF) || (m_nCurrentPattern >= MAX_ORDERS))
00378 {
00379
00380 return FALSE;
00381 if (!m_nRestartPos)
00382 {
00383 m_nMusicSpeed = m_nDefaultSpeed;
00384 m_nMusicTempo = m_nDefaultTempo;
00385 m_nGlobalVolume = m_nDefaultGlobalVolume;
00386 for (UINT i=0; i<MAX_CHANNELS; i++)
00387 {
00388 Chn[i].dwFlags |= CHN_NOTEFADE | CHN_KEYOFF;
00389 Chn[i].nFadeOutVol = 0;
00390 if (i < m_nChannels)
00391 {
00392 Chn[i].nGlobalVol = ChnSettings[i].nVolume;
00393 Chn[i].nVolume = ChnSettings[i].nVolume;
00394 Chn[i].nPan = ChnSettings[i].nPan;
00395 Chn[i].nPanSwing = Chn[i].nVolSwing = 0;
00396 Chn[i].nOldVolParam = 0;
00397 Chn[i].nOldOffset = 0;
00398 Chn[i].nOldHiOffset = 0;
00399 Chn[i].nPortamentoDest = 0;
00400 if (!Chn[i].nLength)
00401 {
00402 Chn[i].dwFlags = ChnSettings[i].dwFlags;
00403 Chn[i].nLoopStart = 0;
00404 Chn[i].nLoopEnd = 0;
00405 Chn[i].pHeader = NULL;
00406 Chn[i].pSample = NULL;
00407 Chn[i].pInstrument = NULL;
00408 }
00409 }
00410 }
00411 }
00412
00413 m_nCurrentPattern = m_nRestartPos;
00414 m_nRow = 0;
00415 if ((Order[m_nCurrentPattern] >= MAX_PATTERNS) || (!Patterns[Order[m_nCurrentPattern]])) return FALSE;
00416 } else
00417 {
00418 m_nCurrentPattern++;
00419 }
00420 m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF;
00421 if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE;
00422 }
00423 m_nNextPattern = m_nCurrentPattern;
00424 }
00425
00426 if ((m_nPattern >= MAX_PATTERNS) || (!Patterns[m_nPattern])) return FALSE;
00427
00428 if (m_nRow >= PatternSize[m_nPattern]) m_nRow = 0;
00429 m_nNextRow = m_nRow + 1;
00430 if (m_nNextRow >= PatternSize[m_nPattern])
00431 {
00432 if (!(m_dwSongFlags & SONG_PATTERNLOOP)) m_nNextPattern = m_nCurrentPattern + 1;
00433 m_nNextRow = 0;
00434 }
00435
00436 MODCHANNEL *pChn = Chn;
00437 MODCOMMAND *m = Patterns[m_nPattern] + m_nRow * m_nChannels;
00438 for (UINT nChn=0; nChn<m_nChannels; pChn++, nChn++, m++)
00439 {
00440 pChn->nRowNote = m->note;
00441 pChn->nRowInstr = m->instr;
00442 pChn->nRowVolCmd = m->volcmd;
00443 pChn->nRowVolume = m->vol;
00444 pChn->nRowCommand = m->command;
00445 pChn->nRowParam = m->param;
00446
00447 pChn->nLeftVol = pChn->nNewLeftVol;
00448 pChn->nRightVol = pChn->nNewRightVol;
00449 pChn->dwFlags &= ~(CHN_PORTAMENTO | CHN_VIBRATO | CHN_TREMOLO | CHN_PANBRELLO);
00450 pChn->nCommand = 0;
00451 }
00452 }
00453
00454 if (!m_nMusicSpeed) m_nMusicSpeed = 1;
00455 m_dwSongFlags |= SONG_FIRSTTICK;
00456 if (m_nTickCount)
00457 {
00458 m_dwSongFlags &= ~SONG_FIRSTTICK;
00459 if ((!(m_nType & MOD_TYPE_XM)) && (m_nTickCount < m_nMusicSpeed * (1 + m_nPatternDelay)))
00460 {
00461 if (!(m_nTickCount % m_nMusicSpeed)) m_dwSongFlags |= SONG_FIRSTTICK;
00462 }
00463
00464 }
00465
00466 return ProcessEffects();
00467 }
00468
00469
00471
00472
00473 BOOL CSoundFile::ReadNote()
00474
00475 {
00476 if (!ProcessRow()) return FALSE;
00478 m_nTotalCount++;
00479 if (!m_nMusicTempo) return FALSE;
00480 m_nBufferCount = (gdwMixingFreq * 5 * m_nTempoFactor) / (m_nMusicTempo << 8);
00481
00482 DWORD nMasterVol;
00483 {
00484 int nchn32 = (m_nChannels < 32) ? m_nChannels : 31;
00485 if ((m_nType & MOD_TYPE_IT) && (m_nInstruments) && (nchn32 < 6)) nchn32 = 6;
00486 int realmastervol = m_nMasterVolume;
00487 if (realmastervol > 0x80)
00488 {
00489 realmastervol = 0x80 + ((realmastervol - 0x80) * (nchn32+4)) / 16;
00490 }
00491 UINT attenuation = (gdwSoundSetup & SNDMIX_AGC) ? PreAmpAGCTable[nchn32>>1] : PreAmpTable[nchn32>>1];
00492 DWORD mastervol = (realmastervol * (m_nSongPreAmp + 0x10)) >> 6;
00493 if (mastervol > 0x200) mastervol = 0x200;
00494 if ((m_dwSongFlags & SONG_GLOBALFADE) && (m_nGlobalFadeMaxSamples))
00495 {
00496 mastervol = _muldiv(mastervol, m_nGlobalFadeSamples, m_nGlobalFadeMaxSamples);
00497 }
00498 nMasterVol = (mastervol << 7) / attenuation;
00499 if (nMasterVol > 0x180) nMasterVol = 0x180;
00500 }
00502
00503 m_nMixChannels = 0;
00504 MODCHANNEL *pChn = Chn;
00505 for (UINT nChn=0; nChn<MAX_CHANNELS; nChn++,pChn++)
00506 {
00507 if ((pChn->dwFlags & CHN_NOTEFADE) && (!(pChn->nFadeOutVol|pChn->nRightVol|pChn->nLeftVol)))
00508 {
00509 pChn->nLength = 0;
00510 pChn->nROfs = pChn->nLOfs = 0;
00511 }
00512
00513 if ((pChn->dwFlags & CHN_MUTE) || ((nChn >= m_nChannels) && (!pChn->nLength)))
00514 {
00515 pChn->nVUMeter = 0;
00516 #ifdef ENABLE_STEREOVU
00517 pChn->nLeftVU = pChn->nRightVU = 0;
00518 #endif
00519 continue;
00520 }
00521
00522 pChn->nInc = 0;
00523 pChn->nRealVolume = 0;
00524 pChn->nRealPan = pChn->nPan + pChn->nPanSwing;
00525 if (pChn->nRealPan < 0) pChn->nRealPan = 0;
00526 if (pChn->nRealPan > 256) pChn->nRealPan = 256;
00527 pChn->nRampLength = 0;
00528
00529 if ((pChn->nPeriod) && (pChn->nLength))
00530 {
00531 int vol = pChn->nVolume + pChn->nVolSwing;
00532
00533 if (vol < 0) vol = 0;
00534 if (vol > 256) vol = 256;
00535
00536 if (pChn->dwFlags & CHN_TREMOLO)
00537 {
00538 UINT trempos = pChn->nTremoloPos & 0x3F;
00539 if (vol > 0)
00540 {
00541 int tremattn = (m_nType & MOD_TYPE_XM) ? 5 : 6;
00542 switch (pChn->nTremoloType & 0x03)
00543 {
00544 case 1:
00545 vol += (ModRampDownTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
00546 break;
00547 case 2:
00548 vol += (ModSquareTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
00549 break;
00550 case 3:
00551 vol += (ModRandomTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
00552 break;
00553 default:
00554 vol += (ModSinusTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
00555 }
00556 }
00557 if ((m_nTickCount) || ((m_nType & (MOD_TYPE_STM|MOD_TYPE_S3M|MOD_TYPE_IT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
00558 {
00559 pChn->nTremoloPos = (trempos + pChn->nTremoloSpeed) & 0x3F;
00560 }
00561 }
00562
00563 if (pChn->nCommand == CMD_TREMOR)
00564 {
00565 UINT n = (pChn->nTremorParam >> 4) + (pChn->nTremorParam & 0x0F);
00566 UINT ontime = pChn->nTremorParam >> 4;
00567 if ((!(m_nType & MOD_TYPE_IT)) || (m_dwSongFlags & SONG_ITOLDEFFECTS)) { n += 2; ontime++; }
00568 UINT tremcount = (UINT)pChn->nTremorCount;
00569 if (tremcount >= n) tremcount = 0;
00570 if ((m_nTickCount) || (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT)))
00571 {
00572 if (tremcount >= ontime) vol = 0;
00573 pChn->nTremorCount = (BYTE)(tremcount + 1);
00574 }
00575 pChn->dwFlags |= CHN_FASTVOLRAMP;
00576 }
00577
00578 if (vol < 0) vol = 0;
00579 if (vol > 0x100) vol = 0x100;
00580 vol <<= 6;
00581
00582 if (pChn->pHeader)
00583 {
00584 INSTRUMENTHEADER *penv = pChn->pHeader;
00585
00586 if ((pChn->dwFlags & CHN_VOLENV) && (penv->nVolEnv))
00587 {
00588 int envpos = pChn->nVolEnvPosition;
00589 UINT pt = penv->nVolEnv - 1;
00590 for (UINT i=0; i<(UINT)(penv->nVolEnv-1); i++)
00591 {
00592 if (envpos <= penv->VolPoints[i])
00593 {
00594 pt = i;
00595 break;
00596 }
00597 }
00598 int x2 = penv->VolPoints[pt];
00599 int x1, envvol;
00600 if (envpos >= x2)
00601 {
00602 envvol = penv->VolEnv[pt] << 2;
00603 x1 = x2;
00604 } else
00605 if (pt)
00606 {
00607 envvol = penv->VolEnv[pt-1] << 2;
00608 x1 = penv->VolPoints[pt-1];
00609 } else
00610 {
00611 envvol = 0;
00612 x1 = 0;
00613 }
00614 if (envpos > x2) envpos = x2;
00615 if ((x2 > x1) && (envpos > x1))
00616 {
00617 envvol += ((envpos - x1) * (((int)penv->VolEnv[pt]<<2) - envvol)) / (x2 - x1);
00618 }
00619 if (envvol < 0) envvol = 0;
00620 if (envvol > 256) envvol = 256;
00621 vol = (vol * envvol) >> 8;
00622 }
00623
00624 if ((pChn->dwFlags & CHN_PANENV) && (penv->nPanEnv))
00625 {
00626 int envpos = pChn->nPanEnvPosition;
00627 UINT pt = penv->nPanEnv - 1;
00628 for (UINT i=0; i<(UINT)(penv->nPanEnv-1); i++)
00629 {
00630 if (envpos <= penv->PanPoints[i])
00631 {
00632 pt = i;
00633 break;
00634 }
00635 }
00636 int x2 = penv->PanPoints[pt], y2 = penv->PanEnv[pt];
00637 int x1, envpan;
00638 if (envpos >= x2)
00639 {
00640 envpan = y2;
00641 x1 = x2;
00642 } else
00643 if (pt)
00644 {
00645 envpan = penv->PanEnv[pt-1];
00646 x1 = penv->PanPoints[pt-1];
00647 } else
00648 {
00649 envpan = 128;
00650 x1 = 0;
00651 }
00652 if ((x2 > x1) && (envpos > x1))
00653 {
00654 envpan += ((envpos - x1) * (y2 - envpan)) / (x2 - x1);
00655 }
00656 if (envpan < 0) envpan = 0;
00657 if (envpan > 64) envpan = 64;
00658 int pan = pChn->nPan;
00659 if (pan >= 128)
00660 {
00661 pan += ((envpan - 32) * (256 - pan)) / 32;
00662 } else
00663 {
00664 pan += ((envpan - 32) * (pan)) / 32;
00665 }
00666 if (pan < 0) pan = 0;
00667 if (pan > 256) pan = 256;
00668 pChn->nRealPan = pan;
00669 }
00670
00671 if (pChn->dwFlags & CHN_NOTEFADE)
00672 {
00673 UINT fadeout = penv->nFadeOut;
00674 if (fadeout)
00675 {
00676 pChn->nFadeOutVol -= fadeout << 1;
00677 if (pChn->nFadeOutVol <= 0) pChn->nFadeOutVol = 0;
00678 vol = (vol * pChn->nFadeOutVol) >> 16;
00679 } else
00680 if (!pChn->nFadeOutVol)
00681 {
00682 vol = 0;
00683 }
00684 }
00685
00686 if ((penv->nPPS) && (pChn->nRealPan) && (pChn->nNote))
00687 {
00688 int pandelta = (int)pChn->nRealPan + (int)((int)(pChn->nNote - penv->nPPC - 1) * (int)penv->nPPS) / (int)8;
00689 if (pandelta < 0) pandelta = 0;
00690 if (pandelta > 256) pandelta = 256;
00691 pChn->nRealPan = pandelta;
00692 }
00693 } else
00694 {
00695
00696 if (pChn->dwFlags & CHN_NOTEFADE)
00697 {
00698 pChn->nFadeOutVol = 0;
00699 vol = 0;
00700 }
00701 }
00702
00703 if (vol)
00704 {
00705
00706
00707 pChn->nRealVolume = _muldiv(vol * m_nGlobalVolume, pChn->nGlobalVol * pChn->nInsVol, 1 << 20);
00708 }
00709 if (pChn->nPeriod < m_nMinPeriod) pChn->nPeriod = m_nMinPeriod;
00710 int period = pChn->nPeriod;
00711 if ((pChn->dwFlags & (CHN_GLISSANDO|CHN_PORTAMENTO)) == (CHN_GLISSANDO|CHN_PORTAMENTO))
00712 {
00713 period = GetPeriodFromNote(GetNoteFromPeriod(period), pChn->nFineTune, pChn->nC4Speed);
00714 }
00715
00716
00717 if (pChn->nCommand == CMD_ARPEGGIO)
00718 {
00719 switch(m_nTickCount % 3)
00720 {
00721 case 1: period = GetPeriodFromNote(pChn->nNote + (pChn->nArpeggio >> 4), pChn->nFineTune, pChn->nC4Speed); break;
00722 case 2: period = GetPeriodFromNote(pChn->nNote + (pChn->nArpeggio & 0x0F), pChn->nFineTune, pChn->nC4Speed); break;
00723 }
00724 }
00725
00726 if (m_dwSongFlags & SONG_AMIGALIMITS)
00727 {
00728 if (period < 113*4) period = 113*4;
00729 if (period > 856*4) period = 856*4;
00730 }
00731
00732
00733 if ((pChn->pHeader) && (pChn->dwFlags & CHN_PITCHENV) && (pChn->pHeader->nPitchEnv))
00734 {
00735 INSTRUMENTHEADER *penv = pChn->pHeader;
00736 int envpos = pChn->nPitchEnvPosition;
00737 UINT pt = penv->nPitchEnv - 1;
00738 for (UINT i=0; i<(UINT)(penv->nPitchEnv-1); i++)
00739 {
00740 if (envpos <= penv->PitchPoints[i])
00741 {
00742 pt = i;
00743 break;
00744 }
00745 }
00746 int x2 = penv->PitchPoints[pt];
00747 int x1, envpitch;
00748 if (envpos >= x2)
00749 {
00750 envpitch = (((int)penv->PitchEnv[pt]) - 32) * 8;
00751 x1 = x2;
00752 } else
00753 if (pt)
00754 {
00755 envpitch = (((int)penv->PitchEnv[pt-1]) - 32) * 8;
00756 x1 = penv->PitchPoints[pt-1];
00757 } else
00758 {
00759 envpitch = 0;
00760 x1 = 0;
00761 }
00762 if (envpos > x2) envpos = x2;
00763 if ((x2 > x1) && (envpos > x1))
00764 {
00765 int envpitchdest = (((int)penv->PitchEnv[pt]) - 32) * 8;
00766 envpitch += ((envpos - x1) * (envpitchdest - envpitch)) / (x2 - x1);
00767 }
00768 if (envpitch < -256) envpitch = -256;
00769 if (envpitch > 256) envpitch = 256;
00770
00771 if (penv->dwFlags & ENV_FILTER)
00772 {
00773 #ifndef NO_FILTER
00774 SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? FALSE : TRUE, envpitch);
00775 #endif // NO_FILTER
00776 } else
00777
00778 {
00779 int l = envpitch;
00780 if (l < 0)
00781 {
00782 l = -l;
00783 if (l > 255) l = 255;
00784 period = _muldiv(period, LinearSlideUpTable[l], 0x10000);
00785 } else
00786 {
00787 if (l > 255) l = 255;
00788 period = _muldiv(period, LinearSlideDownTable[l], 0x10000);
00789 }
00790 }
00791 }
00792
00793
00794 if (pChn->dwFlags & CHN_VIBRATO)
00795 {
00796 UINT vibpos = pChn->nVibratoPos;
00797 LONG vdelta;
00798 switch (pChn->nVibratoType & 0x03)
00799 {
00800 case 1:
00801 vdelta = ModRampDownTable[vibpos];
00802 break;
00803 case 2:
00804 vdelta = ModSquareTable[vibpos];
00805 break;
00806 case 3:
00807 vdelta = ModRandomTable[vibpos];
00808 break;
00809 default:
00810 vdelta = ModSinusTable[vibpos];
00811 }
00812 UINT vdepth = ((m_nType != MOD_TYPE_IT) || (m_dwSongFlags & SONG_ITOLDEFFECTS)) ? 6 : 7;
00813 vdelta = (vdelta * (int)pChn->nVibratoDepth) >> vdepth;
00814 if ((m_dwSongFlags & SONG_LINEARSLIDES) && (m_nType & MOD_TYPE_IT))
00815 {
00816 LONG l = vdelta;
00817 if (l < 0)
00818 {
00819 l = -l;
00820 vdelta = _muldiv(period, LinearSlideDownTable[l >> 2], 0x10000) - period;
00821 if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideDownTable[l & 0x03], 0x10000) - period;
00822
00823 } else
00824 {
00825 vdelta = _muldiv(period, LinearSlideUpTable[l >> 2], 0x10000) - period;
00826 if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideUpTable[l & 0x03], 0x10000) - period;
00827
00828 }
00829 }
00830 period += vdelta;
00831 if ((m_nTickCount) || ((m_nType & MOD_TYPE_IT) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
00832 {
00833 pChn->nVibratoPos = (vibpos + pChn->nVibratoSpeed) & 0x3F;
00834 }
00835 }
00836
00837 if (pChn->dwFlags & CHN_PANBRELLO)
00838 {
00839 UINT panpos = ((pChn->nPanbrelloPos+0x10) >> 2) & 0x3F;
00840 LONG pdelta;
00841 switch (pChn->nPanbrelloType & 0x03)
00842 {
00843 case 1:
00844 pdelta = ModRampDownTable[panpos];
00845 break;
00846 case 2:
00847 pdelta = ModSquareTable[panpos];
00848 break;
00849 case 3:
00850 pdelta = ModRandomTable[panpos];
00851 break;
00852 default:
00853 pdelta = ModSinusTable[panpos];
00854 }
00855 pChn->nPanbrelloPos += pChn->nPanbrelloSpeed;
00856 pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> 3;
00857 pdelta += pChn->nRealPan;
00858 if (pdelta < 0) pdelta = 0;
00859 if (pdelta > 256) pdelta = 256;
00860 pChn->nRealPan = pdelta;
00861 }
00862 int nPeriodFrac = 0;
00863
00864 if ((pChn->pInstrument) && (pChn->pInstrument->nVibDepth))
00865 {
00866 MODINSTRUMENT *pins = pChn->pInstrument;
00867 if (pins->nVibSweep == 0)
00868 {
00869 pChn->nAutoVibDepth = pins->nVibDepth << 8;
00870 } else
00871 {
00872 if (m_nType & MOD_TYPE_IT)
00873 {
00874 pChn->nAutoVibDepth += pins->nVibSweep << 3;
00875 } else
00876 if (!(pChn->dwFlags & CHN_KEYOFF))
00877 {
00878 pChn->nAutoVibDepth += (pins->nVibDepth << 8) / pins->nVibSweep;
00879 }
00880 if ((pChn->nAutoVibDepth >> 8) > pins->nVibDepth)
00881 pChn->nAutoVibDepth = pins->nVibDepth << 8;
00882 }
00883 pChn->nAutoVibPos += pins->nVibRate;
00884 int val;
00885 switch(pins->nVibType)
00886 {
00887 case 4:
00888 val = ModRandomTable[pChn->nAutoVibPos & 0x3F];
00889 pChn->nAutoVibPos++;
00890 break;
00891 case 3:
00892 val = ((0x40 - (pChn->nAutoVibPos >> 1)) & 0x7F) - 0x40;
00893 break;
00894 case 2:
00895 val = ((0x40 + (pChn->nAutoVibPos >> 1)) & 0x7f) - 0x40;
00896 break;
00897 case 1:
00898 val = (pChn->nAutoVibPos & 128) ? +64 : -64;
00899 break;
00900 default:
00901 val = ft2VibratoTable[pChn->nAutoVibPos & 255];
00902 }
00903 int n = ((val * pChn->nAutoVibDepth) >> 8);
00904 if (m_nType & MOD_TYPE_IT)
00905 {
00906 int df1, df2;
00907 if (n < 0)
00908 {
00909 n = -n;
00910 UINT n1 = n >> 8;
00911 df1 = LinearSlideUpTable[n1];
00912 df2 = LinearSlideUpTable[n1+1];
00913 } else
00914 {
00915 UINT n1 = n >> 8;
00916 df1 = LinearSlideDownTable[n1];
00917 df2 = LinearSlideDownTable[n1+1];
00918 }
00919 n >>= 2;
00920 period = _muldiv(period, df1 + ((df2-df1)*(n&0x3F)>>6), 256);
00921 nPeriodFrac = period & 0xFF;
00922 period >>= 8;
00923 } else
00924 {
00925 period += (n >> 6);
00926 }
00927 }
00928
00929 if (period <= m_nMinPeriod)
00930 {
00931 if (m_nType & MOD_TYPE_S3M) pChn->nLength = 0;
00932 period = m_nMinPeriod;
00933 }
00934 if (period > m_nMaxPeriod)
00935 {
00936 if ((m_nType & MOD_TYPE_IT) || (period >= 0x100000))
00937 {
00938 pChn->nFadeOutVol = 0;
00939 pChn->dwFlags |= CHN_NOTEFADE;
00940 pChn->nRealVolume = 0;
00941 }
00942 period = m_nMaxPeriod;
00943 nPeriodFrac = 0;
00944 }
00945 UINT freq = GetFreqFromPeriod(period, pChn->nC4Speed, nPeriodFrac);
00946 if ((m_nType & MOD_TYPE_IT) && (freq < 256))
00947 {
00948 pChn->nFadeOutVol = 0;
00949 pChn->dwFlags |= CHN_NOTEFADE;
00950 pChn->nRealVolume = 0;
00951 }
00952 UINT ninc = _muldiv(freq, 0x10000, gdwMixingFreq);
00953 if ((ninc >= 0xFFB0) && (ninc <= 0x10090)) ninc = 0x10000;
00954 if (m_nFreqFactor != 128) ninc = (ninc * m_nFreqFactor) >> 7;
00955 if (ninc > 0xFF0000) ninc = 0xFF0000;
00956 pChn->nInc = (ninc+1) & ~3;
00957 }
00958
00959
00960 if (pChn->pHeader)
00961 {
00962 INSTRUMENTHEADER *penv = pChn->pHeader;
00963
00964 if (pChn->dwFlags & CHN_VOLENV)
00965 {
00966
00967 pChn->nVolEnvPosition++;
00968
00969 if (penv->dwFlags & ENV_VOLLOOP)
00970 {
00971 UINT volloopend = penv->VolPoints[penv->nVolLoopEnd];
00972 if (m_nType != MOD_TYPE_XM) volloopend++;
00973 if (pChn->nVolEnvPosition == volloopend)
00974 {
00975 pChn->nVolEnvPosition = penv->VolPoints[penv->nVolLoopStart];
00976 if ((penv->nVolLoopEnd == penv->nVolLoopStart) && (!penv->VolEnv[penv->nVolLoopStart])
00977 && ((!(m_nType & MOD_TYPE_XM)) || (penv->nVolLoopEnd+1 == penv->nVolEnv)))
00978 {
00979 pChn->dwFlags |= CHN_NOTEFADE;
00980 pChn->nFadeOutVol = 0;
00981 }
00982 }
00983 }
00984
00985 if ((penv->dwFlags & ENV_VOLSUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF)))
00986 {
00987 if (pChn->nVolEnvPosition == (UINT)penv->VolPoints[penv->nVolSustainEnd]+1)
00988 pChn->nVolEnvPosition = penv->VolPoints[penv->nVolSustainBegin];
00989 } else
00990
00991 if (pChn->nVolEnvPosition > penv->VolPoints[penv->nVolEnv - 1])
00992 {
00993 if ((m_nType & MOD_TYPE_IT) || (pChn->dwFlags & CHN_KEYOFF)) pChn->dwFlags |= CHN_NOTEFADE;
00994 pChn->nVolEnvPosition = penv->VolPoints[penv->nVolEnv - 1];
00995 if ((!penv->VolEnv[penv->nVolEnv-1]) && ((nChn >= m_nChannels) || (m_nType & MOD_TYPE_IT)))
00996 {
00997 pChn->dwFlags |= CHN_NOTEFADE;
00998 pChn->nFadeOutVol = 0;
00999
01000 pChn->nRealVolume = 0;
01001 }
01002 }
01003 }
01004
01005 if (pChn->dwFlags & CHN_PANENV)
01006 {
01007 pChn->nPanEnvPosition++;
01008 if (penv->dwFlags & ENV_PANLOOP)
01009 {
01010 UINT panloopend = penv->PanPoints[penv->nPanLoopEnd];
01011 if (m_nType != MOD_TYPE_XM) panloopend++;
01012 if (pChn->nPanEnvPosition == panloopend)
01013 pChn->nPanEnvPosition = penv->PanPoints[penv->nPanLoopStart];
01014 }
01015
01016 if ((penv->dwFlags & ENV_PANSUSTAIN) && (pChn->nPanEnvPosition == (UINT)penv->PanPoints[penv->nPanSustainEnd]+1)
01017 && (!(pChn->dwFlags & CHN_KEYOFF)))
01018 {
01019
01020 pChn->nPanEnvPosition = penv->PanPoints[penv->nPanSustainBegin];
01021 } else
01022 {
01023 if (pChn->nPanEnvPosition > penv->PanPoints[penv->nPanEnv - 1])
01024 pChn->nPanEnvPosition = penv->PanPoints[penv->nPanEnv - 1];
01025 }
01026 }
01027
01028 if (pChn->dwFlags & CHN_PITCHENV)
01029 {
01030
01031 pChn->nPitchEnvPosition++;
01032
01033 if (penv->dwFlags & ENV_PITCHLOOP)
01034 {
01035 if (pChn->nPitchEnvPosition >= penv->PitchPoints[penv->nPitchLoopEnd])
01036 pChn->nPitchEnvPosition = penv->PitchPoints[penv->nPitchLoopStart];
01037 }
01038
01039 if ((penv->dwFlags & ENV_PITCHSUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF)))
01040 {
01041 if (pChn->nPitchEnvPosition == (UINT)penv->PitchPoints[penv->nPitchSustainEnd]+1)
01042 pChn->nPitchEnvPosition = penv->PitchPoints[penv->nPitchSustainBegin];
01043 } else
01044 {
01045 if (pChn->nPitchEnvPosition > penv->PitchPoints[penv->nPitchEnv - 1])
01046 pChn->nPitchEnvPosition = penv->PitchPoints[penv->nPitchEnv - 1];
01047 }
01048 }
01049 }
01050 #ifdef MODPLUG_PLAYER
01051
01052 if ((gnCPUUsage >= 80) && (!pChn->nRealVolume))
01053 {
01054 pChn->nLeftVol = pChn->nRightVol = 0;
01055 }
01056 #endif // MODPLUG_PLAYER
01057
01058 pChn->dwFlags &= ~CHN_VOLUMERAMP;
01059 if ((pChn->nRealVolume) || (pChn->nLeftVol) || (pChn->nRightVol))
01060 pChn->dwFlags |= CHN_VOLUMERAMP;
01061 #ifdef MODPLUG_PLAYER
01062
01063 if (pChn->nVUMeter > VUMETER_DECAY) pChn->nVUMeter -= VUMETER_DECAY; else pChn->nVUMeter = 0;
01064 #endif // MODPLUG_PLAYER
01065 #ifdef ENABLE_STEREOVU
01066 if (pChn->nLeftVU > VUMETER_DECAY) pChn->nLeftVU -= VUMETER_DECAY; else pChn->nLeftVU = 0;
01067 if (pChn->nRightVU > VUMETER_DECAY) pChn->nRightVU -= VUMETER_DECAY; else pChn->nRightVU = 0;
01068 #endif
01069
01070 if (((pChn->nInc >> 16) + 1) >= (LONG)(pChn->nLoopEnd - pChn->nLoopStart)) pChn->dwFlags &= ~CHN_LOOP;
01071 pChn->nNewRightVol = pChn->nNewLeftVol = 0;
01072 pChn->pCurrentSample = ((pChn->pSample) && (pChn->nLength) && (pChn->nInc)) ? pChn->pSample : NULL;
01073 if (pChn->pCurrentSample)
01074 {
01075
01076 #ifdef MODPLUG_PLAYER
01077 UINT vutmp = pChn->nRealVolume >> (14 - 8);
01078 if (vutmp > 0xFF) vutmp = 0xFF;
01079 if (pChn->nVUMeter >= 0x100) pChn->nVUMeter = vutmp;
01080 vutmp >>= 1;
01081 if (pChn->nVUMeter < vutmp) pChn->nVUMeter = vutmp;
01082 #endif // MODPLUG_PLAYER
01083 #ifdef ENABLE_STEREOVU
01084 UINT vul = (pChn->nRealVolume * pChn->nRealPan) >> 14;
01085 if (vul > 127) vul = 127;
01086 if (pChn->nLeftVU > 127) pChn->nLeftVU = (BYTE)vul;
01087 vul >>= 1;
01088 if (pChn->nLeftVU < vul) pChn->nLeftVU = (BYTE)vul;
01089 UINT vur = (pChn->nRealVolume * (256-pChn->nRealPan)) >> 14;
01090 if (vur > 127) vur = 127;
01091 if (pChn->nRightVU > 127) pChn->nRightVU = (BYTE)vur;
01092 vur >>= 1;
01093 if (pChn->nRightVU < vur) pChn->nRightVU = (BYTE)vur;
01094 #endif
01095 #ifdef MODPLUG_TRACKER
01096 UINT kChnMasterVol = (pChn->dwFlags & CHN_EXTRALOUD) ? 0x100 : nMasterVol;
01097 #else
01098 #define kChnMasterVol nMasterVol
01099 #endif // MODPLUG_TRACKER
01100
01101 if (gnChannels >= 2)
01102 {
01103 int pan = ((int)pChn->nRealPan) - 128;
01104 pan *= (int)m_nStereoSeparation;
01105 pan /= 128;
01106 pan += 128;
01107
01108 if (pan < 0) pan = 0;
01109 if (pan > 256) pan = 256;
01110 #ifndef FASTSOUNDLIB
01111 if (gdwSoundSetup & SNDMIX_REVERSESTEREO) pan = 256 - pan;
01112 #endif
01113 LONG realvol = (pChn->nRealVolume * kChnMasterVol) >> (8-1);
01114 if (gdwSoundSetup & SNDMIX_SOFTPANNING)
01115 {
01116 if (pan < 128)
01117 {
01118 pChn->nNewLeftVol = (realvol * pan) >> 8;
01119 pChn->nNewRightVol = (realvol * 128) >> 8;
01120 } else
01121 {
01122 pChn->nNewLeftVol = (realvol * 128) >> 8;
01123 pChn->nNewRightVol = (realvol * (256 - pan)) >> 8;
01124 }
01125 } else
01126 {
01127 pChn->nNewLeftVol = (realvol * pan) >> 8;
01128 pChn->nNewRightVol = (realvol * (256 - pan)) >> 8;
01129 }
01130 } else
01131 {
01132 pChn->nNewRightVol = (pChn->nRealVolume * kChnMasterVol) >> 8;
01133 pChn->nNewLeftVol = pChn->nNewRightVol;
01134 }
01135
01136 if (pChn->nNewRightVol > 0xFFFF) pChn->nNewRightVol = 0xFFFF;
01137 if (pChn->nNewLeftVol > 0xFFFF) pChn->nNewLeftVol = 0xFFFF;
01138
01139 if (gdwSoundSetup & SNDMIX_NORESAMPLING)
01140 {
01141 pChn->dwFlags |= CHN_NOIDO;
01142 } else
01143 {
01144 pChn->dwFlags &= ~(CHN_NOIDO|CHN_HQSRC);
01145 if( pChn->nInc == 0x10000 )
01146 { pChn->dwFlags |= CHN_NOIDO;
01147 }
01148 else
01149 { if( ((gdwSoundSetup & SNDMIX_HQRESAMPLER) == 0) && ((gdwSoundSetup & SNDMIX_ULTRAHQSRCMODE) == 0) )
01150 { if (pChn->nInc >= 0xFF00) pChn->dwFlags |= CHN_NOIDO;
01151 }
01152 }
01153 }
01154 pChn->nNewRightVol >>= MIXING_ATTENUATION;
01155 pChn->nNewLeftVol >>= MIXING_ATTENUATION;
01156 pChn->nRightRamp = pChn->nLeftRamp = 0;
01157
01158 if ((pChn->dwFlags & CHN_SURROUND) && (gnChannels <= 2)) pChn->nNewLeftVol = - pChn->nNewLeftVol;
01159
01160 if (pChn->dwFlags & CHN_PINGPONGFLAG) pChn->nInc = -pChn->nInc;
01161
01162 if ((pChn->dwFlags & CHN_VOLUMERAMP)
01163 && ((pChn->nRightVol != pChn->nNewRightVol)
01164 || (pChn->nLeftVol != pChn->nNewLeftVol)))
01165 {
01166 LONG nRampLength = gnVolumeRampSamples;
01167 LONG nRightDelta = ((pChn->nNewRightVol - pChn->nRightVol) << VOLUMERAMPPRECISION);
01168 LONG nLeftDelta = ((pChn->nNewLeftVol - pChn->nLeftVol) << VOLUMERAMPPRECISION);
01169 #ifndef FASTSOUNDLIB
01170 if ((gdwSoundSetup & SNDMIX_DIRECTTODISK)
01171 || ((gdwSysInfo & (SYSMIX_ENABLEMMX|SYSMIX_FASTCPU))
01172 && (gdwSoundSetup & SNDMIX_HQRESAMPLER) && (gnCPUUsage <= 20)))
01173 {
01174 if ((pChn->nRightVol|pChn->nLeftVol) && (pChn->nNewRightVol|pChn->nNewLeftVol) && (!(pChn->dwFlags & CHN_FASTVOLRAMP)))
01175 {
01176 nRampLength = m_nBufferCount;
01177 if (nRampLength > (1 << (VOLUMERAMPPRECISION-1))) nRampLength = (1 << (VOLUMERAMPPRECISION-1));
01178 if (nRampLength < (LONG)gnVolumeRampSamples) nRampLength = gnVolumeRampSamples;
01179 }
01180 }
01181 #endif
01182 pChn->nRightRamp = nRightDelta / nRampLength;
01183 pChn->nLeftRamp = nLeftDelta / nRampLength;
01184 pChn->nRightVol = pChn->nNewRightVol - ((pChn->nRightRamp * nRampLength) >> VOLUMERAMPPRECISION);
01185 pChn->nLeftVol = pChn->nNewLeftVol - ((pChn->nLeftRamp * nRampLength) >> VOLUMERAMPPRECISION);
01186 if (pChn->nRightRamp|pChn->nLeftRamp)
01187 {
01188 pChn->nRampLength = nRampLength;
01189 } else
01190 {
01191 pChn->dwFlags &= ~CHN_VOLUMERAMP;
01192 pChn->nRightVol = pChn->nNewRightVol;
01193 pChn->nLeftVol = pChn->nNewLeftVol;
01194 }
01195 } else
01196 {
01197 pChn->dwFlags &= ~CHN_VOLUMERAMP;
01198 pChn->nRightVol = pChn->nNewRightVol;
01199 pChn->nLeftVol = pChn->nNewLeftVol;
01200 }
01201 pChn->nRampRightVol = pChn->nRightVol << VOLUMERAMPPRECISION;
01202 pChn->nRampLeftVol = pChn->nLeftVol << VOLUMERAMPPRECISION;
01203
01204 ChnMix[m_nMixChannels++] = nChn;
01205 if (m_nMixChannels >= MAX_CHANNELS) break;
01206 } else
01207 {
01208 #ifdef ENABLE_STEREOVU
01209
01210 if (pChn->nLeftVU > 128) pChn->nLeftVU = 0;
01211 if (pChn->nRightVU > 128) pChn->nRightVU = 0;
01212 #endif
01213 if (pChn->nVUMeter > 0xFF) pChn->nVUMeter = 0;
01214 pChn->nLeftVol = pChn->nRightVol = 0;
01215 pChn->nLength = 0;
01216 }
01217 }
01218
01219 if ((m_nMixChannels >= m_nMaxMixChannels) && (!(gdwSoundSetup & SNDMIX_DIRECTTODISK)))
01220 {
01221 for (UINT i=0; i<m_nMixChannels; i++)
01222 {
01223 UINT j=i;
01224 while ((j+1<m_nMixChannels) && (Chn[ChnMix[j]].nRealVolume < Chn[ChnMix[j+1]].nRealVolume))
01225 {
01226 UINT n = ChnMix[j];
01227 ChnMix[j] = ChnMix[j+1];
01228 ChnMix[j+1] = n;
01229 j++;
01230 }
01231 }
01232 }
01233 if (m_dwSongFlags & SONG_GLOBALFADE)
01234 {
01235 if (!m_nGlobalFadeSamples)
01236 {
01237 m_dwSongFlags |= SONG_ENDREACHED;
01238 return FALSE;
01239 }
01240 if (m_nGlobalFadeSamples > m_nBufferCount)
01241 m_nGlobalFadeSamples -= m_nBufferCount;
01242 else
01243 m_nGlobalFadeSamples = 0;
01244 }
01245 return TRUE;
01246 }
01247
01248