00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "stdafx.h"
00012 #include "sndfile.h"
00013 #include <math.h>
00014
00015 #ifdef WIN32
00016 #pragma bss_seg(".modplug")
00017 #endif
00018
00019
00020 int MixSoundBuffer[MIXBUFFERSIZE*4];
00021
00022
00023 #ifndef NO_REVERB
00024 int MixReverbBuffer[MIXBUFFERSIZE*2];
00025 extern UINT gnReverbSend;
00026 #endif
00027
00028 #ifndef FASTSOUNDLIB
00029 int MixRearBuffer[MIXBUFFERSIZE*2];
00030 float MixFloatBuffer[MIXBUFFERSIZE*2];
00031 #endif
00032
00033 #ifdef WIN32
00034 #pragma bss_seg()
00035 #endif
00036
00037
00038 extern LONG gnDryROfsVol;
00039 extern LONG gnDryLOfsVol;
00040 extern LONG gnRvbROfsVol;
00041 extern LONG gnRvbLOfsVol;
00042
00043
00044 extern short int gFastSinc[];
00045 extern short int gKaiserSinc[];
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 #define SPLINE_QUANTBITS 14
00092 #define SPLINE_QUANTSCALE (1L<<SPLINE_QUANTBITS)
00093 #define SPLINE_8SHIFT (SPLINE_QUANTBITS-8)
00094 #define SPLINE_16SHIFT (SPLINE_QUANTBITS)
00095
00096 #define SPLINE_CLAMPFORUNITY
00097
00098 #define SPLINE_FRACBITS 10
00099 #define SPLINE_LUTLEN (1L<<SPLINE_FRACBITS)
00100
00101 class CzCUBICSPLINE
00102 { public:
00103 CzCUBICSPLINE( );
00104 ~CzCUBICSPLINE( );
00105 static signed short lut[4*(1L<<SPLINE_FRACBITS)];
00106 };
00107
00108 signed short CzCUBICSPLINE::lut[4*(1L<<SPLINE_FRACBITS)];
00109
00110 CzCUBICSPLINE::CzCUBICSPLINE( )
00111 { int _LIi;
00112 int _LLen = (1L<<SPLINE_FRACBITS);
00113 float _LFlen = 1.0f / (float)_LLen;
00114 float _LScale = (float)SPLINE_QUANTSCALE;
00115 for(_LIi=0;_LIi<_LLen;_LIi++)
00116 { float _LCm1, _LC0, _LC1, _LC2;
00117 float _LX = ((float)_LIi)*_LFlen;
00118 int _LSum,_LIdx = _LIi<<2;
00119 _LCm1 = (float)floor( 0.5 + _LScale * (-0.5*_LX*_LX*_LX + 1.0 * _LX*_LX - 0.5 * _LX ) );
00120 _LC0 = (float)floor( 0.5 + _LScale * ( 1.5*_LX*_LX*_LX - 2.5 * _LX*_LX + 1.0 ) );
00121 _LC1 = (float)floor( 0.5 + _LScale * (-1.5*_LX*_LX*_LX + 2.0 * _LX*_LX + 0.5 * _LX ) );
00122 _LC2 = (float)floor( 0.5 + _LScale * ( 0.5*_LX*_LX*_LX - 0.5 * _LX*_LX ) );
00123 lut[_LIdx+0] = (signed short)( (_LCm1 < -_LScale) ? -_LScale : ((_LCm1 > _LScale) ? _LScale : _LCm1) );
00124 lut[_LIdx+1] = (signed short)( (_LC0 < -_LScale) ? -_LScale : ((_LC0 > _LScale) ? _LScale : _LC0 ) );
00125 lut[_LIdx+2] = (signed short)( (_LC1 < -_LScale) ? -_LScale : ((_LC1 > _LScale) ? _LScale : _LC1 ) );
00126 lut[_LIdx+3] = (signed short)( (_LC2 < -_LScale) ? -_LScale : ((_LC2 > _LScale) ? _LScale : _LC2 ) );
00127 #ifdef SPLINE_CLAMPFORUNITY
00128 _LSum = lut[_LIdx+0]+lut[_LIdx+1]+lut[_LIdx+2]+lut[_LIdx+3];
00129 if( _LSum != SPLINE_QUANTSCALE )
00130 { int _LMax = _LIdx;
00131 if( lut[_LIdx+1]>lut[_LMax] ) _LMax = _LIdx+1;
00132 if( lut[_LIdx+2]>lut[_LMax] ) _LMax = _LIdx+2;
00133 if( lut[_LIdx+3]>lut[_LMax] ) _LMax = _LIdx+3;
00134 lut[_LMax] += (SPLINE_QUANTSCALE-_LSum);
00135 }
00136 #endif
00137 }
00138 }
00139
00140 CzCUBICSPLINE::~CzCUBICSPLINE( )
00141 {
00142 }
00143
00144 CzCUBICSPLINE sspline;
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 #define WFIR_QUANTBITS 15
00163 #define WFIR_QUANTSCALE (1L<<WFIR_QUANTBITS)
00164 #define WFIR_8SHIFT (WFIR_QUANTBITS-8)
00165 #define WFIR_16BITSHIFT (WFIR_QUANTBITS)
00166
00167 #define WFIR_FRACBITS 10
00168 #define WFIR_LUTLEN ((1L<<(WFIR_FRACBITS+1))+1)
00169
00170 #define WFIR_LOG2WIDTH 3
00171 #define WFIR_WIDTH (1L<<WFIR_LOG2WIDTH)
00172 #define WFIR_SMPSPERWING ((WFIR_WIDTH-1)>>1)
00173
00174 #define WFIR_CUTOFF 0.90f
00175
00176 #define WFIR_HANN 0
00177 #define WFIR_HAMMING 1
00178 #define WFIR_BLACKMANEXACT 2
00179 #define WFIR_BLACKMAN3T61 3
00180 #define WFIR_BLACKMAN3T67 4
00181 #define WFIR_BLACKMAN4T92 5
00182 #define WFIR_BLACKMAN4T74 6
00183 #define WFIR_KAISER4T 7
00184 #define WFIR_TYPE WFIR_BLACKMANEXACT
00185
00186 #ifndef M_zPI
00187 #define M_zPI 3.1415926535897932384626433832795
00188 #endif
00189 #define M_zEPS 1e-8
00190 #define M_zBESSELEPS 1e-21
00191
00192 class CzWINDOWEDFIR
00193 { public:
00194 CzWINDOWEDFIR( );
00195 ~CzWINDOWEDFIR( );
00196 float coef( int _PCnr, float _POfs, float _PCut, int _PWidth, int _PType )
00197 { double _LWidthM1 = _PWidth-1;
00198 double _LWidthM1Half = 0.5*_LWidthM1;
00199 double _LPosU = ((double)_PCnr - _POfs);
00200 double _LPos = _LPosU-_LWidthM1Half;
00201 double _LPIdl = 2.0*M_zPI/_LWidthM1;
00202 double _LWc,_LSi;
00203 if( fabs(_LPos)<M_zEPS )
00204 { _LWc = 1.0;
00205 _LSi = _PCut;
00206 }
00207 else
00208 { switch( _PType )
00209 { case WFIR_HANN:
00210 _LWc = 0.50 - 0.50 * cos(_LPIdl*_LPosU);
00211 break;
00212 case WFIR_HAMMING:
00213 _LWc = 0.54 - 0.46 * cos(_LPIdl*_LPosU);
00214 break;
00215 case WFIR_BLACKMANEXACT:
00216 _LWc = 0.42 - 0.50 * cos(_LPIdl*_LPosU) + 0.08 * cos(2.0*_LPIdl*_LPosU);
00217 break;
00218 case WFIR_BLACKMAN3T61:
00219 _LWc = 0.44959 - 0.49364 * cos(_LPIdl*_LPosU) + 0.05677 * cos(2.0*_LPIdl*_LPosU);
00220 break;
00221 case WFIR_BLACKMAN3T67:
00222 _LWc = 0.42323 - 0.49755 * cos(_LPIdl*_LPosU) + 0.07922 * cos(2.0*_LPIdl*_LPosU);
00223 break;
00224 case WFIR_BLACKMAN4T92:
00225 _LWc = 0.35875 - 0.48829 * cos(_LPIdl*_LPosU) + 0.14128 * cos(2.0*_LPIdl*_LPosU) - 0.01168 * cos(3.0*_LPIdl*_LPosU);
00226 break;
00227 case WFIR_BLACKMAN4T74:
00228 _LWc = 0.40217 - 0.49703 * cos(_LPIdl*_LPosU) + 0.09392 * cos(2.0*_LPIdl*_LPosU) - 0.00183 * cos(3.0*_LPIdl*_LPosU);
00229 break;
00230 case WFIR_KAISER4T:
00231 _LWc = 0.40243 - 0.49804 * cos(_LPIdl*_LPosU) + 0.09831 * cos(2.0*_LPIdl*_LPosU) - 0.00122 * cos(3.0*_LPIdl*_LPosU);
00232 break;
00233 default:
00234 _LWc = 1.0;
00235 break;
00236 }
00237 _LPos *= M_zPI;
00238 _LSi = sin(_PCut*_LPos)/_LPos;
00239 }
00240 return (float)(_LWc*_LSi);
00241 }
00242 static signed short lut[WFIR_LUTLEN*WFIR_WIDTH];
00243 };
00244
00245 signed short CzWINDOWEDFIR::lut[WFIR_LUTLEN*WFIR_WIDTH];
00246
00247 CzWINDOWEDFIR::CzWINDOWEDFIR()
00248 { int _LPcl;
00249 float _LPcllen = (float)(1L<<WFIR_FRACBITS);
00250 float _LNorm = 1.0f / (float)(2.0f * _LPcllen);
00251 float _LCut = WFIR_CUTOFF;
00252 float _LScale = (float)WFIR_QUANTSCALE;
00253 for( _LPcl=0;_LPcl<WFIR_LUTLEN;_LPcl++ )
00254 { float _LGain,_LCoefs[WFIR_WIDTH];
00255 float _LOfs = ((float)_LPcl-_LPcllen)*_LNorm;
00256 int _LCc,_LIdx = _LPcl<<WFIR_LOG2WIDTH;
00257 for( _LCc=0,_LGain=0.0f;_LCc<WFIR_WIDTH;_LCc++ )
00258 { _LGain += (_LCoefs[_LCc] = coef( _LCc, _LOfs, _LCut, WFIR_WIDTH, WFIR_TYPE ));
00259 }
00260 _LGain = 1.0f/_LGain;
00261 for( _LCc=0;_LCc<WFIR_WIDTH;_LCc++ )
00262 { float _LCoef = (float)floor( 0.5 + _LScale*_LCoefs[_LCc]*_LGain );
00263 lut[_LIdx+_LCc] = (signed short)( (_LCoef<-_LScale)?-_LScale:((_LCoef>_LScale)?_LScale:_LCoef) );
00264 }
00265 }
00266 }
00267
00268 CzWINDOWEDFIR::~CzWINDOWEDFIR()
00269 {
00270 }
00271
00272 CzWINDOWEDFIR sfir;
00273
00274
00275
00276
00278
00279
00280 #define SNDMIX_BEGINSAMPLELOOP8\
00281 register MODCHANNEL * const pChn = pChannel;\
00282 nPos = pChn->nPosLo;\
00283 const signed char *p = (signed char *)(pChn->pCurrentSample+pChn->nPos);\
00284 if (pChn->dwFlags & CHN_STEREO) p += pChn->nPos;\
00285 int *pvol = pbuffer;\
00286 do {
00287
00288 #define SNDMIX_BEGINSAMPLELOOP16\
00289 register MODCHANNEL * const pChn = pChannel;\
00290 nPos = pChn->nPosLo;\
00291 const signed short *p = (signed short *)(pChn->pCurrentSample+(pChn->nPos*2));\
00292 if (pChn->dwFlags & CHN_STEREO) p += pChn->nPos;\
00293 int *pvol = pbuffer;\
00294 do {
00295
00296 #define SNDMIX_ENDSAMPLELOOP\
00297 nPos += pChn->nInc;\
00298 } while (pvol < pbufmax);\
00299 pChn->nPos += nPos >> 16;\
00300 pChn->nPosLo = nPos & 0xFFFF;
00301
00302 #define SNDMIX_ENDSAMPLELOOP8 SNDMIX_ENDSAMPLELOOP
00303 #define SNDMIX_ENDSAMPLELOOP16 SNDMIX_ENDSAMPLELOOP
00304
00306
00307
00308
00309 #define SNDMIX_GETMONOVOL8NOIDO\
00310 int vol = p[nPos >> 16] << 8;
00311
00312 #define SNDMIX_GETMONOVOL16NOIDO\
00313 int vol = p[nPos >> 16];
00314
00315
00316 #define SNDMIX_GETMONOVOL8LINEAR\
00317 int poshi = nPos >> 16;\
00318 int poslo = (nPos >> 8) & 0xFF;\
00319 int srcvol = p[poshi];\
00320 int destvol = p[poshi+1];\
00321 int vol = (srcvol<<8) + ((int)(poslo * (destvol - srcvol)));
00322
00323 #define SNDMIX_GETMONOVOL16LINEAR\
00324 int poshi = nPos >> 16;\
00325 int poslo = (nPos >> 8) & 0xFF;\
00326 int srcvol = p[poshi];\
00327 int destvol = p[poshi+1];\
00328 int vol = srcvol + ((int)(poslo * (destvol - srcvol)) >> 8);
00329
00330
00331 #define SPLINE_FRACSHIFT ((16-SPLINE_FRACBITS)-2)
00332 #define SPLINE_FRACMASK (((1L<<(16-SPLINE_FRACSHIFT))-1)&~3)
00333
00334 #define SNDMIX_GETMONOVOL8SPLINE \
00335 int poshi = nPos >> 16; \
00336 int poslo = (nPos >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \
00337 int vol = (CzCUBICSPLINE::lut[poslo ]*(int)p[poshi-1] + \
00338 CzCUBICSPLINE::lut[poslo+1]*(int)p[poshi ] + \
00339 CzCUBICSPLINE::lut[poslo+3]*(int)p[poshi+2] + \
00340 CzCUBICSPLINE::lut[poslo+2]*(int)p[poshi+1]) >> SPLINE_8SHIFT;
00341
00342 #define SNDMIX_GETMONOVOL16SPLINE \
00343 int poshi = nPos >> 16; \
00344 int poslo = (nPos >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \
00345 int vol = (CzCUBICSPLINE::lut[poslo ]*(int)p[poshi-1] + \
00346 CzCUBICSPLINE::lut[poslo+1]*(int)p[poshi ] + \
00347 CzCUBICSPLINE::lut[poslo+3]*(int)p[poshi+2] + \
00348 CzCUBICSPLINE::lut[poslo+2]*(int)p[poshi+1]) >> SPLINE_16SHIFT;
00349
00350
00351
00352 #define WFIR_FRACSHIFT (16-(WFIR_FRACBITS+1+WFIR_LOG2WIDTH))
00353 #define WFIR_FRACMASK ((((1L<<(17-WFIR_FRACSHIFT))-1)&~((1L<<WFIR_LOG2WIDTH)-1)))
00354 #define WFIR_FRACHALVE (1L<<(16-(WFIR_FRACBITS+2)))
00355
00356 #define SNDMIX_GETMONOVOL8FIRFILTER \
00357 int poshi = nPos >> 16;\
00358 int poslo = (nPos & 0xFFFF);\
00359 int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \
00360 int vol = (CzWINDOWEDFIR::lut[firidx+0]*(int)p[poshi+1-4]); \
00361 vol += (CzWINDOWEDFIR::lut[firidx+1]*(int)p[poshi+2-4]); \
00362 vol += (CzWINDOWEDFIR::lut[firidx+2]*(int)p[poshi+3-4]); \
00363 vol += (CzWINDOWEDFIR::lut[firidx+3]*(int)p[poshi+4-4]); \
00364 vol += (CzWINDOWEDFIR::lut[firidx+4]*(int)p[poshi+5-4]); \
00365 vol += (CzWINDOWEDFIR::lut[firidx+5]*(int)p[poshi+6-4]); \
00366 vol += (CzWINDOWEDFIR::lut[firidx+6]*(int)p[poshi+7-4]); \
00367 vol += (CzWINDOWEDFIR::lut[firidx+7]*(int)p[poshi+8-4]); \
00368 vol >>= WFIR_8SHIFT;
00369
00370 #define SNDMIX_GETMONOVOL16FIRFILTER \
00371 int poshi = nPos >> 16;\
00372 int poslo = (nPos & 0xFFFF);\
00373 int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \
00374 int vol1 = (CzWINDOWEDFIR::lut[firidx+0]*(int)p[poshi+1-4]); \
00375 vol1 += (CzWINDOWEDFIR::lut[firidx+1]*(int)p[poshi+2-4]); \
00376 vol1 += (CzWINDOWEDFIR::lut[firidx+2]*(int)p[poshi+3-4]); \
00377 vol1 += (CzWINDOWEDFIR::lut[firidx+3]*(int)p[poshi+4-4]); \
00378 int vol2 = (CzWINDOWEDFIR::lut[firidx+4]*(int)p[poshi+5-4]); \
00379 vol2 += (CzWINDOWEDFIR::lut[firidx+5]*(int)p[poshi+6-4]); \
00380 vol2 += (CzWINDOWEDFIR::lut[firidx+6]*(int)p[poshi+7-4]); \
00381 vol2 += (CzWINDOWEDFIR::lut[firidx+7]*(int)p[poshi+8-4]); \
00382 int vol = ((vol1>>1)+(vol2>>1)) >> (WFIR_16BITSHIFT-1);
00383
00385
00386
00387
00388 #define SNDMIX_GETSTEREOVOL8NOIDO\
00389 int vol_l = p[(nPos>>16)*2] << 8;\
00390 int vol_r = p[(nPos>>16)*2+1] << 8;
00391
00392 #define SNDMIX_GETSTEREOVOL16NOIDO\
00393 int vol_l = p[(nPos>>16)*2];\
00394 int vol_r = p[(nPos>>16)*2+1];
00395
00396
00397 #define SNDMIX_GETSTEREOVOL8LINEAR\
00398 int poshi = nPos >> 16;\
00399 int poslo = (nPos >> 8) & 0xFF;\
00400 int srcvol_l = p[poshi*2];\
00401 int vol_l = (srcvol_l<<8) + ((int)(poslo * (p[poshi*2+2] - srcvol_l)));\
00402 int srcvol_r = p[poshi*2+1];\
00403 int vol_r = (srcvol_r<<8) + ((int)(poslo * (p[poshi*2+3] - srcvol_r)));
00404
00405 #define SNDMIX_GETSTEREOVOL16LINEAR\
00406 int poshi = nPos >> 16;\
00407 int poslo = (nPos >> 8) & 0xFF;\
00408 int srcvol_l = p[poshi*2];\
00409 int vol_l = srcvol_l + ((int)(poslo * (p[poshi*2+2] - srcvol_l)) >> 8);\
00410 int srcvol_r = p[poshi*2+1];\
00411 int vol_r = srcvol_r + ((int)(poslo * (p[poshi*2+3] - srcvol_r)) >> 8);\
00412
00413
00414 #define SNDMIX_GETSTEREOVOL8SPLINE \
00415 int poshi = nPos >> 16; \
00416 int poslo = (nPos >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \
00417 int vol_l = (CzCUBICSPLINE::lut[poslo ]*(int)p[(poshi-1)*2 ] + \
00418 CzCUBICSPLINE::lut[poslo+1]*(int)p[(poshi )*2 ] + \
00419 CzCUBICSPLINE::lut[poslo+2]*(int)p[(poshi+1)*2 ] + \
00420 CzCUBICSPLINE::lut[poslo+3]*(int)p[(poshi+2)*2 ]) >> SPLINE_8SHIFT; \
00421 int vol_r = (CzCUBICSPLINE::lut[poslo ]*(int)p[(poshi-1)*2+1] + \
00422 CzCUBICSPLINE::lut[poslo+1]*(int)p[(poshi )*2+1] + \
00423 CzCUBICSPLINE::lut[poslo+2]*(int)p[(poshi+1)*2+1] + \
00424 CzCUBICSPLINE::lut[poslo+3]*(int)p[(poshi+2)*2+1]) >> SPLINE_8SHIFT;
00425
00426 #define SNDMIX_GETSTEREOVOL16SPLINE \
00427 int poshi = nPos >> 16; \
00428 int poslo = (nPos >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \
00429 int vol_l = (CzCUBICSPLINE::lut[poslo ]*(int)p[(poshi-1)*2 ] + \
00430 CzCUBICSPLINE::lut[poslo+1]*(int)p[(poshi )*2 ] + \
00431 CzCUBICSPLINE::lut[poslo+2]*(int)p[(poshi+1)*2 ] + \
00432 CzCUBICSPLINE::lut[poslo+3]*(int)p[(poshi+2)*2 ]) >> SPLINE_16SHIFT; \
00433 int vol_r = (CzCUBICSPLINE::lut[poslo ]*(int)p[(poshi-1)*2+1] + \
00434 CzCUBICSPLINE::lut[poslo+1]*(int)p[(poshi )*2+1] + \
00435 CzCUBICSPLINE::lut[poslo+2]*(int)p[(poshi+1)*2+1] + \
00436 CzCUBICSPLINE::lut[poslo+3]*(int)p[(poshi+2)*2+1]) >> SPLINE_16SHIFT;
00437
00438
00439 #define SNDMIX_GETSTEREOVOL8FIRFILTER \
00440 int poshi = nPos >> 16;\
00441 int poslo = (nPos & 0xFFFF);\
00442 int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \
00443 int vol_l = (CzWINDOWEDFIR::lut[firidx+0]*(int)p[(poshi+1-4)*2 ]); \
00444 vol_l += (CzWINDOWEDFIR::lut[firidx+1]*(int)p[(poshi+2-4)*2 ]); \
00445 vol_l += (CzWINDOWEDFIR::lut[firidx+2]*(int)p[(poshi+3-4)*2 ]); \
00446 vol_l += (CzWINDOWEDFIR::lut[firidx+3]*(int)p[(poshi+4-4)*2 ]); \
00447 vol_l += (CzWINDOWEDFIR::lut[firidx+4]*(int)p[(poshi+5-4)*2 ]); \
00448 vol_l += (CzWINDOWEDFIR::lut[firidx+5]*(int)p[(poshi+6-4)*2 ]); \
00449 vol_l += (CzWINDOWEDFIR::lut[firidx+6]*(int)p[(poshi+7-4)*2 ]); \
00450 vol_l += (CzWINDOWEDFIR::lut[firidx+7]*(int)p[(poshi+8-4)*2 ]); \
00451 vol_l >>= WFIR_8SHIFT; \
00452 int vol_r = (CzWINDOWEDFIR::lut[firidx+0]*(int)p[(poshi+1-4)*2+1]); \
00453 vol_r += (CzWINDOWEDFIR::lut[firidx+1]*(int)p[(poshi+2-4)*2+1]); \
00454 vol_r += (CzWINDOWEDFIR::lut[firidx+2]*(int)p[(poshi+3-4)*2+1]); \
00455 vol_r += (CzWINDOWEDFIR::lut[firidx+3]*(int)p[(poshi+4-4)*2+1]); \
00456 vol_r += (CzWINDOWEDFIR::lut[firidx+4]*(int)p[(poshi+5-4)*2+1]); \
00457 vol_r += (CzWINDOWEDFIR::lut[firidx+5]*(int)p[(poshi+6-4)*2+1]); \
00458 vol_r += (CzWINDOWEDFIR::lut[firidx+6]*(int)p[(poshi+7-4)*2+1]); \
00459 vol_r += (CzWINDOWEDFIR::lut[firidx+7]*(int)p[(poshi+8-4)*2+1]); \
00460 vol_r >>= WFIR_8SHIFT;
00461
00462 #define SNDMIX_GETSTEREOVOL16FIRFILTER \
00463 int poshi = nPos >> 16;\
00464 int poslo = (nPos & 0xFFFF);\
00465 int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \
00466 int vol1_l = (CzWINDOWEDFIR::lut[firidx+0]*(int)p[(poshi+1-4)*2 ]); \
00467 vol1_l += (CzWINDOWEDFIR::lut[firidx+1]*(int)p[(poshi+2-4)*2 ]); \
00468 vol1_l += (CzWINDOWEDFIR::lut[firidx+2]*(int)p[(poshi+3-4)*2 ]); \
00469 vol1_l += (CzWINDOWEDFIR::lut[firidx+3]*(int)p[(poshi+4-4)*2 ]); \
00470 int vol2_l = (CzWINDOWEDFIR::lut[firidx+4]*(int)p[(poshi+5-4)*2 ]); \
00471 vol2_l += (CzWINDOWEDFIR::lut[firidx+5]*(int)p[(poshi+6-4)*2 ]); \
00472 vol2_l += (CzWINDOWEDFIR::lut[firidx+6]*(int)p[(poshi+7-4)*2 ]); \
00473 vol2_l += (CzWINDOWEDFIR::lut[firidx+7]*(int)p[(poshi+8-4)*2 ]); \
00474 int vol_l = ((vol1_l>>1)+(vol2_l>>1)) >> (WFIR_16BITSHIFT-1); \
00475 int vol1_r = (CzWINDOWEDFIR::lut[firidx+0]*(int)p[(poshi+1-4)*2+1]); \
00476 vol1_r += (CzWINDOWEDFIR::lut[firidx+1]*(int)p[(poshi+2-4)*2+1]); \
00477 vol1_r += (CzWINDOWEDFIR::lut[firidx+2]*(int)p[(poshi+3-4)*2+1]); \
00478 vol1_r += (CzWINDOWEDFIR::lut[firidx+3]*(int)p[(poshi+4-4)*2+1]); \
00479 int vol2_r = (CzWINDOWEDFIR::lut[firidx+4]*(int)p[(poshi+5-4)*2+1]); \
00480 vol2_r += (CzWINDOWEDFIR::lut[firidx+5]*(int)p[(poshi+6-4)*2+1]); \
00481 vol2_r += (CzWINDOWEDFIR::lut[firidx+6]*(int)p[(poshi+7-4)*2+1]); \
00482 vol2_r += (CzWINDOWEDFIR::lut[firidx+7]*(int)p[(poshi+8-4)*2+1]); \
00483 int vol_r = ((vol1_r>>1)+(vol2_r>>1)) >> (WFIR_16BITSHIFT-1);
00484
00485
00487
00488 #define SNDMIX_STOREMONOVOL\
00489 pvol[0] += vol * pChn->nRightVol;\
00490 pvol[1] += vol * pChn->nLeftVol;\
00491 pvol += 2;
00492
00493 #define SNDMIX_STORESTEREOVOL\
00494 pvol[0] += vol_l * pChn->nRightVol;\
00495 pvol[1] += vol_r * pChn->nLeftVol;\
00496 pvol += 2;
00497
00498 #define SNDMIX_STOREFASTMONOVOL\
00499 int v = vol * pChn->nRightVol;\
00500 pvol[0] += v;\
00501 pvol[1] += v;\
00502 pvol += 2;
00503
00504 #define SNDMIX_RAMPMONOVOL\
00505 nRampLeftVol += pChn->nLeftRamp;\
00506 nRampRightVol += pChn->nRightRamp;\
00507 pvol[0] += vol * (nRampRightVol >> VOLUMERAMPPRECISION);\
00508 pvol[1] += vol * (nRampLeftVol >> VOLUMERAMPPRECISION);\
00509 pvol += 2;
00510
00511 #define SNDMIX_RAMPFASTMONOVOL\
00512 nRampRightVol += pChn->nRightRamp;\
00513 int fastvol = vol * (nRampRightVol >> VOLUMERAMPPRECISION);\
00514 pvol[0] += fastvol;\
00515 pvol[1] += fastvol;\
00516 pvol += 2;
00517
00518 #define SNDMIX_RAMPSTEREOVOL\
00519 nRampLeftVol += pChn->nLeftRamp;\
00520 nRampRightVol += pChn->nRightRamp;\
00521 pvol[0] += vol_l * (nRampRightVol >> VOLUMERAMPPRECISION);\
00522 pvol[1] += vol_r * (nRampLeftVol >> VOLUMERAMPPRECISION);\
00523 pvol += 2;
00524
00525
00527
00528
00529
00530 #define MIX_BEGIN_FILTER\
00531 int fy1 = pChannel->nFilter_Y1;\
00532 int fy2 = pChannel->nFilter_Y2;\
00533
00534 #define MIX_END_FILTER\
00535 pChannel->nFilter_Y1 = fy1;\
00536 pChannel->nFilter_Y2 = fy2;
00537
00538 #define SNDMIX_PROCESSFILTER\
00539 vol = (vol * pChn->nFilter_A0 + fy1 * pChn->nFilter_B0 + fy2 * pChn->nFilter_B1 + 4096) >> 13;\
00540 fy2 = fy1;\
00541 fy1 = vol;\
00542
00543
00544 #define MIX_BEGIN_STEREO_FILTER\
00545 int fy1 = pChannel->nFilter_Y1;\
00546 int fy2 = pChannel->nFilter_Y2;\
00547 int fy3 = pChannel->nFilter_Y3;\
00548 int fy4 = pChannel->nFilter_Y4;\
00549
00550 #define MIX_END_STEREO_FILTER\
00551 pChannel->nFilter_Y1 = fy1;\
00552 pChannel->nFilter_Y2 = fy2;\
00553 pChannel->nFilter_Y3 = fy3;\
00554 pChannel->nFilter_Y4 = fy4;\
00555
00556 #define SNDMIX_PROCESSSTEREOFILTER\
00557 vol_l = (vol_l * pChn->nFilter_A0 + fy1 * pChn->nFilter_B0 + fy2 * pChn->nFilter_B1 + 4096) >> 13;\
00558 vol_r = (vol_r * pChn->nFilter_A0 + fy3 * pChn->nFilter_B0 + fy4 * pChn->nFilter_B1 + 4096) >> 13;\
00559 fy2 = fy1; fy1 = vol_l;\
00560 fy4 = fy3; fy3 = vol_r;\
00561
00562
00563
00564
00565 typedef VOID (MPPASMCALL * LPMIXINTERFACE)(MODCHANNEL *, int *, int *);
00566
00567 #define BEGIN_MIX_INTERFACE(func)\
00568 VOID MPPASMCALL func(MODCHANNEL *pChannel, int *pbuffer, int *pbufmax)\
00569 {\
00570 LONG nPos;
00571
00572 #define END_MIX_INTERFACE()\
00573 SNDMIX_ENDSAMPLELOOP\
00574 }
00575
00576
00577 #define BEGIN_RAMPMIX_INTERFACE(func)\
00578 BEGIN_MIX_INTERFACE(func)\
00579 LONG nRampRightVol = pChannel->nRampRightVol;\
00580 LONG nRampLeftVol = pChannel->nRampLeftVol;
00581
00582 #define END_RAMPMIX_INTERFACE()\
00583 SNDMIX_ENDSAMPLELOOP\
00584 pChannel->nRampRightVol = nRampRightVol;\
00585 pChannel->nRightVol = nRampRightVol >> VOLUMERAMPPRECISION;\
00586 pChannel->nRampLeftVol = nRampLeftVol;\
00587 pChannel->nLeftVol = nRampLeftVol >> VOLUMERAMPPRECISION;\
00588 }
00589
00590 #define BEGIN_FASTRAMPMIX_INTERFACE(func)\
00591 BEGIN_MIX_INTERFACE(func)\
00592 LONG nRampRightVol = pChannel->nRampRightVol;
00593
00594 #define END_FASTRAMPMIX_INTERFACE()\
00595 SNDMIX_ENDSAMPLELOOP\
00596 pChannel->nRampRightVol = nRampRightVol;\
00597 pChannel->nRampLeftVol = nRampRightVol;\
00598 pChannel->nRightVol = nRampRightVol >> VOLUMERAMPPRECISION;\
00599 pChannel->nLeftVol = pChannel->nRightVol;\
00600 }
00601
00602
00603
00604 #define BEGIN_MIX_FLT_INTERFACE(func)\
00605 BEGIN_MIX_INTERFACE(func)\
00606 MIX_BEGIN_FILTER
00607
00608
00609 #define END_MIX_FLT_INTERFACE()\
00610 SNDMIX_ENDSAMPLELOOP\
00611 MIX_END_FILTER\
00612 }
00613
00614 #define BEGIN_RAMPMIX_FLT_INTERFACE(func)\
00615 BEGIN_MIX_INTERFACE(func)\
00616 LONG nRampRightVol = pChannel->nRampRightVol;\
00617 LONG nRampLeftVol = pChannel->nRampLeftVol;\
00618 MIX_BEGIN_FILTER
00619
00620 #define END_RAMPMIX_FLT_INTERFACE()\
00621 SNDMIX_ENDSAMPLELOOP\
00622 MIX_END_FILTER\
00623 pChannel->nRampRightVol = nRampRightVol;\
00624 pChannel->nRightVol = nRampRightVol >> VOLUMERAMPPRECISION;\
00625 pChannel->nRampLeftVol = nRampLeftVol;\
00626 pChannel->nLeftVol = nRampLeftVol >> VOLUMERAMPPRECISION;\
00627 }
00628
00629
00630 #define BEGIN_MIX_STFLT_INTERFACE(func)\
00631 BEGIN_MIX_INTERFACE(func)\
00632 MIX_BEGIN_STEREO_FILTER
00633
00634
00635 #define END_MIX_STFLT_INTERFACE()\
00636 SNDMIX_ENDSAMPLELOOP\
00637 MIX_END_STEREO_FILTER\
00638 }
00639
00640 #define BEGIN_RAMPMIX_STFLT_INTERFACE(func)\
00641 BEGIN_MIX_INTERFACE(func)\
00642 LONG nRampRightVol = pChannel->nRampRightVol;\
00643 LONG nRampLeftVol = pChannel->nRampLeftVol;\
00644 MIX_BEGIN_STEREO_FILTER
00645
00646 #define END_RAMPMIX_STFLT_INTERFACE()\
00647 SNDMIX_ENDSAMPLELOOP\
00648 MIX_END_STEREO_FILTER\
00649 pChannel->nRampRightVol = nRampRightVol;\
00650 pChannel->nRightVol = nRampRightVol >> VOLUMERAMPPRECISION;\
00651 pChannel->nRampLeftVol = nRampLeftVol;\
00652 pChannel->nLeftVol = nRampLeftVol >> VOLUMERAMPPRECISION;\
00653 }
00654
00655
00657
00658
00659 void MPPASMCALL X86_InitMixBuffer(int *pBuffer, UINT nSamples);
00660 void MPPASMCALL X86_EndChannelOfs(MODCHANNEL *pChannel, int *pBuffer, UINT nSamples);
00661 void MPPASMCALL X86_StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs);
00662 void X86_StereoMixToFloat(const int *, float *, float *, UINT nCount);
00663 void X86_FloatToStereoMix(const float *pIn1, const float *pIn2, int *pOut, UINT nCount);
00664
00666
00667
00668 BEGIN_MIX_INTERFACE(Mono8BitMix)
00669 SNDMIX_BEGINSAMPLELOOP8
00670 SNDMIX_GETMONOVOL8NOIDO
00671 SNDMIX_STOREMONOVOL
00672 END_MIX_INTERFACE()
00673
00674 BEGIN_MIX_INTERFACE(Mono16BitMix)
00675 SNDMIX_BEGINSAMPLELOOP16
00676 SNDMIX_GETMONOVOL16NOIDO
00677 SNDMIX_STOREMONOVOL
00678 END_MIX_INTERFACE()
00679
00680 BEGIN_MIX_INTERFACE(Mono8BitLinearMix)
00681 SNDMIX_BEGINSAMPLELOOP8
00682 SNDMIX_GETMONOVOL8LINEAR
00683 SNDMIX_STOREMONOVOL
00684 END_MIX_INTERFACE()
00685
00686 BEGIN_MIX_INTERFACE(Mono16BitLinearMix)
00687 SNDMIX_BEGINSAMPLELOOP16
00688 SNDMIX_GETMONOVOL16LINEAR
00689 SNDMIX_STOREMONOVOL
00690 END_MIX_INTERFACE()
00691
00692 BEGIN_MIX_INTERFACE(Mono8BitSplineMix)
00693 SNDMIX_BEGINSAMPLELOOP8
00694 SNDMIX_GETMONOVOL8SPLINE
00695 SNDMIX_STOREMONOVOL
00696 END_MIX_INTERFACE()
00697
00698 BEGIN_MIX_INTERFACE(Mono16BitSplineMix)
00699 SNDMIX_BEGINSAMPLELOOP16
00700 SNDMIX_GETMONOVOL16SPLINE
00701 SNDMIX_STOREMONOVOL
00702 END_MIX_INTERFACE()
00703
00704 BEGIN_MIX_INTERFACE(Mono8BitFirFilterMix)
00705 SNDMIX_BEGINSAMPLELOOP8
00706 SNDMIX_GETMONOVOL8FIRFILTER
00707 SNDMIX_STOREMONOVOL
00708 END_MIX_INTERFACE()
00709
00710 BEGIN_MIX_INTERFACE(Mono16BitFirFilterMix)
00711 SNDMIX_BEGINSAMPLELOOP16
00712 SNDMIX_GETMONOVOL16FIRFILTER
00713 SNDMIX_STOREMONOVOL
00714 END_MIX_INTERFACE()
00715
00716
00717
00718 BEGIN_RAMPMIX_INTERFACE(Mono8BitRampMix)
00719 SNDMIX_BEGINSAMPLELOOP8
00720 SNDMIX_GETMONOVOL8NOIDO
00721 SNDMIX_RAMPMONOVOL
00722 END_RAMPMIX_INTERFACE()
00723
00724 BEGIN_RAMPMIX_INTERFACE(Mono16BitRampMix)
00725 SNDMIX_BEGINSAMPLELOOP16
00726 SNDMIX_GETMONOVOL16NOIDO
00727 SNDMIX_RAMPMONOVOL
00728 END_RAMPMIX_INTERFACE()
00729
00730 BEGIN_RAMPMIX_INTERFACE(Mono8BitLinearRampMix)
00731 SNDMIX_BEGINSAMPLELOOP8
00732 SNDMIX_GETMONOVOL8LINEAR
00733 SNDMIX_RAMPMONOVOL
00734 END_RAMPMIX_INTERFACE()
00735
00736 BEGIN_RAMPMIX_INTERFACE(Mono16BitLinearRampMix)
00737 SNDMIX_BEGINSAMPLELOOP16
00738 SNDMIX_GETMONOVOL16LINEAR
00739 SNDMIX_RAMPMONOVOL
00740 END_RAMPMIX_INTERFACE()
00741
00742 BEGIN_RAMPMIX_INTERFACE(Mono8BitSplineRampMix)
00743 SNDMIX_BEGINSAMPLELOOP8
00744 SNDMIX_GETMONOVOL8SPLINE
00745 SNDMIX_RAMPMONOVOL
00746 END_RAMPMIX_INTERFACE()
00747
00748 BEGIN_RAMPMIX_INTERFACE(Mono16BitSplineRampMix)
00749 SNDMIX_BEGINSAMPLELOOP16
00750 SNDMIX_GETMONOVOL16SPLINE
00751 SNDMIX_RAMPMONOVOL
00752 END_RAMPMIX_INTERFACE()
00753
00754 BEGIN_RAMPMIX_INTERFACE(Mono8BitFirFilterRampMix)
00755 SNDMIX_BEGINSAMPLELOOP8
00756 SNDMIX_GETMONOVOL8FIRFILTER
00757 SNDMIX_RAMPMONOVOL
00758 END_RAMPMIX_INTERFACE()
00759
00760 BEGIN_RAMPMIX_INTERFACE(Mono16BitFirFilterRampMix)
00761 SNDMIX_BEGINSAMPLELOOP16
00762 SNDMIX_GETMONOVOL16FIRFILTER
00763 SNDMIX_RAMPMONOVOL
00764 END_RAMPMIX_INTERFACE()
00765
00766
00768
00769
00770 BEGIN_MIX_INTERFACE(FastMono8BitMix)
00771 SNDMIX_BEGINSAMPLELOOP8
00772 SNDMIX_GETMONOVOL8NOIDO
00773 SNDMIX_STOREFASTMONOVOL
00774 END_MIX_INTERFACE()
00775
00776 BEGIN_MIX_INTERFACE(FastMono16BitMix)
00777 SNDMIX_BEGINSAMPLELOOP16
00778 SNDMIX_GETMONOVOL16NOIDO
00779 SNDMIX_STOREFASTMONOVOL
00780 END_MIX_INTERFACE()
00781
00782 BEGIN_MIX_INTERFACE(FastMono8BitLinearMix)
00783 SNDMIX_BEGINSAMPLELOOP8
00784 SNDMIX_GETMONOVOL8LINEAR
00785 SNDMIX_STOREFASTMONOVOL
00786 END_MIX_INTERFACE()
00787
00788 BEGIN_MIX_INTERFACE(FastMono16BitLinearMix)
00789 SNDMIX_BEGINSAMPLELOOP16
00790 SNDMIX_GETMONOVOL16LINEAR
00791 SNDMIX_STOREFASTMONOVOL
00792 END_MIX_INTERFACE()
00793
00794 BEGIN_MIX_INTERFACE(FastMono8BitSplineMix)
00795 SNDMIX_BEGINSAMPLELOOP8
00796 SNDMIX_GETMONOVOL8SPLINE
00797 SNDMIX_STOREFASTMONOVOL
00798 END_MIX_INTERFACE()
00799
00800 BEGIN_MIX_INTERFACE(FastMono16BitSplineMix)
00801 SNDMIX_BEGINSAMPLELOOP16
00802 SNDMIX_GETMONOVOL16SPLINE
00803 SNDMIX_STOREFASTMONOVOL
00804 END_MIX_INTERFACE()
00805
00806 BEGIN_MIX_INTERFACE(FastMono8BitFirFilterMix)
00807 SNDMIX_BEGINSAMPLELOOP8
00808 SNDMIX_GETMONOVOL8FIRFILTER
00809 SNDMIX_STOREFASTMONOVOL
00810 END_MIX_INTERFACE()
00811
00812 BEGIN_MIX_INTERFACE(FastMono16BitFirFilterMix)
00813 SNDMIX_BEGINSAMPLELOOP16
00814 SNDMIX_GETMONOVOL16FIRFILTER
00815 SNDMIX_STOREFASTMONOVOL
00816 END_MIX_INTERFACE()
00817
00818
00819
00820 BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitRampMix)
00821 SNDMIX_BEGINSAMPLELOOP8
00822 SNDMIX_GETMONOVOL8NOIDO
00823 SNDMIX_RAMPFASTMONOVOL
00824 END_FASTRAMPMIX_INTERFACE()
00825
00826 BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitRampMix)
00827 SNDMIX_BEGINSAMPLELOOP16
00828 SNDMIX_GETMONOVOL16NOIDO
00829 SNDMIX_RAMPFASTMONOVOL
00830 END_FASTRAMPMIX_INTERFACE()
00831
00832 BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitLinearRampMix)
00833 SNDMIX_BEGINSAMPLELOOP8
00834 SNDMIX_GETMONOVOL8LINEAR
00835 SNDMIX_RAMPFASTMONOVOL
00836 END_FASTRAMPMIX_INTERFACE()
00837
00838 BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitLinearRampMix)
00839 SNDMIX_BEGINSAMPLELOOP16
00840 SNDMIX_GETMONOVOL16LINEAR
00841 SNDMIX_RAMPFASTMONOVOL
00842 END_FASTRAMPMIX_INTERFACE()
00843
00844 BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitSplineRampMix)
00845 SNDMIX_BEGINSAMPLELOOP8
00846 SNDMIX_GETMONOVOL8SPLINE
00847 SNDMIX_RAMPFASTMONOVOL
00848 END_FASTRAMPMIX_INTERFACE()
00849
00850 BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitSplineRampMix)
00851 SNDMIX_BEGINSAMPLELOOP16
00852 SNDMIX_GETMONOVOL16SPLINE
00853 SNDMIX_RAMPFASTMONOVOL
00854 END_FASTRAMPMIX_INTERFACE()
00855
00856 BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitFirFilterRampMix)
00857 SNDMIX_BEGINSAMPLELOOP8
00858 SNDMIX_GETMONOVOL8FIRFILTER
00859 SNDMIX_RAMPFASTMONOVOL
00860 END_FASTRAMPMIX_INTERFACE()
00861
00862 BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitFirFilterRampMix)
00863 SNDMIX_BEGINSAMPLELOOP16
00864 SNDMIX_GETMONOVOL16FIRFILTER
00865 SNDMIX_RAMPFASTMONOVOL
00866 END_FASTRAMPMIX_INTERFACE()
00867
00868
00870
00871
00872 BEGIN_MIX_INTERFACE(Stereo8BitMix)
00873 SNDMIX_BEGINSAMPLELOOP8
00874 SNDMIX_GETSTEREOVOL8NOIDO
00875 SNDMIX_STORESTEREOVOL
00876 END_MIX_INTERFACE()
00877
00878 BEGIN_MIX_INTERFACE(Stereo16BitMix)
00879 SNDMIX_BEGINSAMPLELOOP16
00880 SNDMIX_GETSTEREOVOL16NOIDO
00881 SNDMIX_STORESTEREOVOL
00882 END_MIX_INTERFACE()
00883
00884 BEGIN_MIX_INTERFACE(Stereo8BitLinearMix)
00885 SNDMIX_BEGINSAMPLELOOP8
00886 SNDMIX_GETSTEREOVOL8LINEAR
00887 SNDMIX_STORESTEREOVOL
00888 END_MIX_INTERFACE()
00889
00890 BEGIN_MIX_INTERFACE(Stereo16BitLinearMix)
00891 SNDMIX_BEGINSAMPLELOOP16
00892 SNDMIX_GETSTEREOVOL16LINEAR
00893 SNDMIX_STORESTEREOVOL
00894 END_MIX_INTERFACE()
00895
00896 BEGIN_MIX_INTERFACE(Stereo8BitSplineMix)
00897 SNDMIX_BEGINSAMPLELOOP8
00898 SNDMIX_GETSTEREOVOL8SPLINE
00899 SNDMIX_STORESTEREOVOL
00900 END_MIX_INTERFACE()
00901
00902 BEGIN_MIX_INTERFACE(Stereo16BitSplineMix)
00903 SNDMIX_BEGINSAMPLELOOP16
00904 SNDMIX_GETSTEREOVOL16SPLINE
00905 SNDMIX_STORESTEREOVOL
00906 END_MIX_INTERFACE()
00907
00908 BEGIN_MIX_INTERFACE(Stereo8BitFirFilterMix)
00909 SNDMIX_BEGINSAMPLELOOP8
00910 SNDMIX_GETSTEREOVOL8FIRFILTER
00911 SNDMIX_STORESTEREOVOL
00912 END_MIX_INTERFACE()
00913
00914 BEGIN_MIX_INTERFACE(Stereo16BitFirFilterMix)
00915 SNDMIX_BEGINSAMPLELOOP16
00916 SNDMIX_GETSTEREOVOL16FIRFILTER
00917 SNDMIX_STORESTEREOVOL
00918 END_MIX_INTERFACE()
00919
00920
00921
00922 BEGIN_RAMPMIX_INTERFACE(Stereo8BitRampMix)
00923 SNDMIX_BEGINSAMPLELOOP8
00924 SNDMIX_GETSTEREOVOL8NOIDO
00925 SNDMIX_RAMPSTEREOVOL
00926 END_RAMPMIX_INTERFACE()
00927
00928 BEGIN_RAMPMIX_INTERFACE(Stereo16BitRampMix)
00929 SNDMIX_BEGINSAMPLELOOP16
00930 SNDMIX_GETSTEREOVOL16NOIDO
00931 SNDMIX_RAMPSTEREOVOL
00932 END_RAMPMIX_INTERFACE()
00933
00934 BEGIN_RAMPMIX_INTERFACE(Stereo8BitLinearRampMix)
00935 SNDMIX_BEGINSAMPLELOOP8
00936 SNDMIX_GETSTEREOVOL8LINEAR
00937 SNDMIX_RAMPSTEREOVOL
00938 END_RAMPMIX_INTERFACE()
00939
00940 BEGIN_RAMPMIX_INTERFACE(Stereo16BitLinearRampMix)
00941 SNDMIX_BEGINSAMPLELOOP16
00942 SNDMIX_GETSTEREOVOL16LINEAR
00943 SNDMIX_RAMPSTEREOVOL
00944 END_RAMPMIX_INTERFACE()
00945
00946 BEGIN_RAMPMIX_INTERFACE(Stereo8BitSplineRampMix)
00947 SNDMIX_BEGINSAMPLELOOP8
00948 SNDMIX_GETSTEREOVOL8SPLINE
00949 SNDMIX_RAMPSTEREOVOL
00950 END_RAMPMIX_INTERFACE()
00951
00952 BEGIN_RAMPMIX_INTERFACE(Stereo16BitSplineRampMix)
00953 SNDMIX_BEGINSAMPLELOOP16
00954 SNDMIX_GETSTEREOVOL16SPLINE
00955 SNDMIX_RAMPSTEREOVOL
00956 END_RAMPMIX_INTERFACE()
00957
00958 BEGIN_RAMPMIX_INTERFACE(Stereo8BitFirFilterRampMix)
00959 SNDMIX_BEGINSAMPLELOOP8
00960 SNDMIX_GETSTEREOVOL8FIRFILTER
00961 SNDMIX_RAMPSTEREOVOL
00962 END_RAMPMIX_INTERFACE()
00963
00964 BEGIN_RAMPMIX_INTERFACE(Stereo16BitFirFilterRampMix)
00965 SNDMIX_BEGINSAMPLELOOP16
00966 SNDMIX_GETSTEREOVOL16FIRFILTER
00967 SNDMIX_RAMPSTEREOVOL
00968 END_RAMPMIX_INTERFACE()
00969
00970
00971
00973
00974
00975 #ifndef NO_FILTER
00976
00977
00978 BEGIN_MIX_FLT_INTERFACE(FilterMono8BitMix)
00979 SNDMIX_BEGINSAMPLELOOP8
00980 SNDMIX_GETMONOVOL8NOIDO
00981 SNDMIX_PROCESSFILTER
00982 SNDMIX_STOREMONOVOL
00983 END_MIX_FLT_INTERFACE()
00984
00985 BEGIN_MIX_FLT_INTERFACE(FilterMono16BitMix)
00986 SNDMIX_BEGINSAMPLELOOP16
00987 SNDMIX_GETMONOVOL16NOIDO
00988 SNDMIX_PROCESSFILTER
00989 SNDMIX_STOREMONOVOL
00990 END_MIX_FLT_INTERFACE()
00991
00992 BEGIN_MIX_FLT_INTERFACE(FilterMono8BitLinearMix)
00993 SNDMIX_BEGINSAMPLELOOP8
00994 SNDMIX_GETMONOVOL8LINEAR
00995 SNDMIX_PROCESSFILTER
00996 SNDMIX_STOREMONOVOL
00997 END_MIX_FLT_INTERFACE()
00998
00999 BEGIN_MIX_FLT_INTERFACE(FilterMono16BitLinearMix)
01000 SNDMIX_BEGINSAMPLELOOP16
01001 SNDMIX_GETMONOVOL16LINEAR
01002 SNDMIX_PROCESSFILTER
01003 SNDMIX_STOREMONOVOL
01004 END_MIX_FLT_INTERFACE()
01005
01006 BEGIN_MIX_FLT_INTERFACE(FilterMono8BitSplineMix)
01007 SNDMIX_BEGINSAMPLELOOP8
01008 SNDMIX_GETMONOVOL8SPLINE
01009 SNDMIX_PROCESSFILTER
01010 SNDMIX_STOREMONOVOL
01011 END_MIX_FLT_INTERFACE()
01012
01013 BEGIN_MIX_FLT_INTERFACE(FilterMono16BitSplineMix)
01014 SNDMIX_BEGINSAMPLELOOP16
01015 SNDMIX_GETMONOVOL16SPLINE
01016 SNDMIX_PROCESSFILTER
01017 SNDMIX_STOREMONOVOL
01018 END_MIX_FLT_INTERFACE()
01019
01020 BEGIN_MIX_FLT_INTERFACE(FilterMono8BitFirFilterMix)
01021 SNDMIX_BEGINSAMPLELOOP8
01022 SNDMIX_GETMONOVOL8FIRFILTER
01023 SNDMIX_PROCESSFILTER
01024 SNDMIX_STOREMONOVOL
01025 END_MIX_FLT_INTERFACE()
01026
01027 BEGIN_MIX_FLT_INTERFACE(FilterMono16BitFirFilterMix)
01028 SNDMIX_BEGINSAMPLELOOP16
01029 SNDMIX_GETMONOVOL16FIRFILTER
01030 SNDMIX_PROCESSFILTER
01031 SNDMIX_STOREMONOVOL
01032 END_MIX_FLT_INTERFACE()
01033
01034
01035 BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitRampMix)
01036 SNDMIX_BEGINSAMPLELOOP8
01037 SNDMIX_GETMONOVOL8NOIDO
01038 SNDMIX_PROCESSFILTER
01039 SNDMIX_RAMPMONOVOL
01040 END_RAMPMIX_FLT_INTERFACE()
01041
01042 BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitRampMix)
01043 SNDMIX_BEGINSAMPLELOOP16
01044 SNDMIX_GETMONOVOL16NOIDO
01045 SNDMIX_PROCESSFILTER
01046 SNDMIX_RAMPMONOVOL
01047 END_RAMPMIX_FLT_INTERFACE()
01048
01049 BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitLinearRampMix)
01050 SNDMIX_BEGINSAMPLELOOP8
01051 SNDMIX_GETMONOVOL8LINEAR
01052 SNDMIX_PROCESSFILTER
01053 SNDMIX_RAMPMONOVOL
01054 END_RAMPMIX_FLT_INTERFACE()
01055
01056 BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitLinearRampMix)
01057 SNDMIX_BEGINSAMPLELOOP16
01058 SNDMIX_GETMONOVOL16LINEAR
01059 SNDMIX_PROCESSFILTER
01060 SNDMIX_RAMPMONOVOL
01061 END_RAMPMIX_FLT_INTERFACE()
01062
01063 BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitSplineRampMix)
01064 SNDMIX_BEGINSAMPLELOOP8
01065 SNDMIX_GETMONOVOL8SPLINE
01066 SNDMIX_PROCESSFILTER
01067 SNDMIX_RAMPMONOVOL
01068 END_RAMPMIX_FLT_INTERFACE()
01069
01070 BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitSplineRampMix)
01071 SNDMIX_BEGINSAMPLELOOP16
01072 SNDMIX_GETMONOVOL16SPLINE
01073 SNDMIX_PROCESSFILTER
01074 SNDMIX_RAMPMONOVOL
01075 END_RAMPMIX_FLT_INTERFACE()
01076
01077 BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitFirFilterRampMix)
01078 SNDMIX_BEGINSAMPLELOOP8
01079 SNDMIX_GETMONOVOL8FIRFILTER
01080 SNDMIX_PROCESSFILTER
01081 SNDMIX_RAMPMONOVOL
01082 END_RAMPMIX_FLT_INTERFACE()
01083
01084 BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitFirFilterRampMix)
01085 SNDMIX_BEGINSAMPLELOOP16
01086 SNDMIX_GETMONOVOL16FIRFILTER
01087 SNDMIX_PROCESSFILTER
01088 SNDMIX_RAMPMONOVOL
01089 END_RAMPMIX_FLT_INTERFACE()
01090
01091
01092
01093 BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitMix)
01094 SNDMIX_BEGINSAMPLELOOP8
01095 SNDMIX_GETSTEREOVOL8NOIDO
01096 SNDMIX_PROCESSSTEREOFILTER
01097 SNDMIX_STORESTEREOVOL
01098 END_MIX_STFLT_INTERFACE()
01099
01100 BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitMix)
01101 SNDMIX_BEGINSAMPLELOOP16
01102 SNDMIX_GETSTEREOVOL16NOIDO
01103 SNDMIX_PROCESSSTEREOFILTER
01104 SNDMIX_STORESTEREOVOL
01105 END_MIX_STFLT_INTERFACE()
01106
01107 BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitLinearMix)
01108 SNDMIX_BEGINSAMPLELOOP8
01109 SNDMIX_GETSTEREOVOL8LINEAR
01110 SNDMIX_PROCESSSTEREOFILTER
01111 SNDMIX_STORESTEREOVOL
01112 END_MIX_STFLT_INTERFACE()
01113
01114 BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitLinearMix)
01115 SNDMIX_BEGINSAMPLELOOP16
01116 SNDMIX_GETSTEREOVOL16LINEAR
01117 SNDMIX_PROCESSSTEREOFILTER
01118 SNDMIX_STORESTEREOVOL
01119 END_MIX_STFLT_INTERFACE()
01120
01121 BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitSplineMix)
01122 SNDMIX_BEGINSAMPLELOOP8
01123 SNDMIX_GETSTEREOVOL8SPLINE
01124 SNDMIX_PROCESSSTEREOFILTER
01125 SNDMIX_STORESTEREOVOL
01126 END_MIX_STFLT_INTERFACE()
01127
01128 BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitSplineMix)
01129 SNDMIX_BEGINSAMPLELOOP16
01130 SNDMIX_GETSTEREOVOL16SPLINE
01131 SNDMIX_PROCESSSTEREOFILTER
01132 SNDMIX_STORESTEREOVOL
01133 END_MIX_STFLT_INTERFACE()
01134
01135 BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitFirFilterMix)
01136 SNDMIX_BEGINSAMPLELOOP8
01137 SNDMIX_GETSTEREOVOL8FIRFILTER
01138 SNDMIX_PROCESSSTEREOFILTER
01139 SNDMIX_STORESTEREOVOL
01140 END_MIX_STFLT_INTERFACE()
01141
01142 BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitFirFilterMix)
01143 SNDMIX_BEGINSAMPLELOOP16
01144 SNDMIX_GETSTEREOVOL16FIRFILTER
01145 SNDMIX_PROCESSSTEREOFILTER
01146 SNDMIX_STORESTEREOVOL
01147 END_MIX_STFLT_INTERFACE()
01148
01149
01150 BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitRampMix)
01151 SNDMIX_BEGINSAMPLELOOP8
01152 SNDMIX_GETSTEREOVOL8NOIDO
01153 SNDMIX_PROCESSSTEREOFILTER
01154 SNDMIX_RAMPSTEREOVOL
01155 END_RAMPMIX_STFLT_INTERFACE()
01156
01157 BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitRampMix)
01158 SNDMIX_BEGINSAMPLELOOP16
01159 SNDMIX_GETSTEREOVOL16NOIDO
01160 SNDMIX_PROCESSSTEREOFILTER
01161 SNDMIX_RAMPSTEREOVOL
01162 END_RAMPMIX_STFLT_INTERFACE()
01163
01164 BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitLinearRampMix)
01165 SNDMIX_BEGINSAMPLELOOP8
01166 SNDMIX_GETSTEREOVOL8LINEAR
01167 SNDMIX_PROCESSSTEREOFILTER
01168 SNDMIX_RAMPSTEREOVOL
01169 END_RAMPMIX_STFLT_INTERFACE()
01170
01171 BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitLinearRampMix)
01172 SNDMIX_BEGINSAMPLELOOP16
01173 SNDMIX_GETSTEREOVOL16LINEAR
01174 SNDMIX_PROCESSSTEREOFILTER
01175 SNDMIX_RAMPSTEREOVOL
01176 END_RAMPMIX_STFLT_INTERFACE()
01177
01178 BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitSplineRampMix)
01179 SNDMIX_BEGINSAMPLELOOP8
01180 SNDMIX_GETSTEREOVOL8SPLINE
01181 SNDMIX_PROCESSSTEREOFILTER
01182 SNDMIX_RAMPSTEREOVOL
01183 END_RAMPMIX_STFLT_INTERFACE()
01184
01185 BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitSplineRampMix)
01186 SNDMIX_BEGINSAMPLELOOP16
01187 SNDMIX_GETSTEREOVOL16SPLINE
01188 SNDMIX_PROCESSSTEREOFILTER
01189 SNDMIX_RAMPSTEREOVOL
01190 END_RAMPMIX_STFLT_INTERFACE()
01191
01192 BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitFirFilterRampMix)
01193 SNDMIX_BEGINSAMPLELOOP8
01194 SNDMIX_GETSTEREOVOL8FIRFILTER
01195 SNDMIX_PROCESSSTEREOFILTER
01196 SNDMIX_RAMPSTEREOVOL
01197 END_RAMPMIX_STFLT_INTERFACE()
01198
01199 BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitFirFilterRampMix)
01200 SNDMIX_BEGINSAMPLELOOP16
01201 SNDMIX_GETSTEREOVOL16FIRFILTER
01202 SNDMIX_PROCESSSTEREOFILTER
01203 SNDMIX_RAMPSTEREOVOL
01204 END_RAMPMIX_STFLT_INTERFACE()
01205
01206
01207 #else
01208
01209 #define FilterMono8BitMix Mono8BitMix
01210 #define FilterMono16BitMix Mono16BitMix
01211 #define FilterMono8BitLinearMix Mono8BitLinearMix
01212 #define FilterMono16BitLinearMix Mono16BitLinearMix
01213 #define FilterMono8BitSplineMix Mono8BitSplineMix
01214 #define FilterMono16BitSplineMix Mono16BitSplineMix
01215 #define FilterMono8BitFirFilterMix Mono8BitFirFilterMix
01216 #define FilterMono16BitFirFilterMix Mono16BitFirFilterMix
01217 #define FilterMono8BitRampMix Mono8BitRampMix
01218 #define FilterMono16BitRampMix Mono16BitRampMix
01219 #define FilterMono8BitLinearRampMix Mono8BitLinearRampMix
01220 #define FilterMono16BitLinearRampMix Mono16BitLinearRampMix
01221 #define FilterMono8BitSplineRampMix Mono8BitSplineRampMix
01222 #define FilterMono16BitSplineRampMix Mono16BitSplineRampMix
01223 #define FilterMono8BitFirFilterRampMix Mono8BitFirFilterRampMix
01224 #define FilterMono16BitFirFilterRampMix Mono16BitFirFilterRampMix
01225
01226 #define FilterStereo8BitMix Stereo8BitMix
01227 #define FilterStereo16BitMix Stereo16BitMix
01228 #define FilterStereo8BitLinearMix Stereo8BitLinearMix
01229 #define FilterStereo16BitLinearMix Stereo16BitLinearMix
01230 #define FilterStereo8BitSplineMix Stereo8BitSplineMix
01231 #define FilterStereo16BitSplineMix Stereo16BitSplineMix
01232 #define FilterStereo8BitFirFilterMix Stereo8BitFirFilterMix
01233 #define FilterStereo16BitFirFilterMix Stereo16BitFirFilterMix
01234 #define FilterStereo8BitRampMix Stereo8BitRampMix
01235 #define FilterStereo16BitRampMix Stereo16BitRampMix
01236 #define FilterStereo8BitLinearRampMix Stereo8BitLinearRampMix
01237 #define FilterStereo16BitLinearRampMix Stereo16BitLinearRampMix
01238 #define FilterStereo8BitSplineRampMix Stereo8BitSplineRampMix
01239 #define FilterStereo16BitSplineRampMix Stereo16BitSplineRampMix
01240 #define FilterStereo8BitFirFilterRampMix Stereo8BitFirFilterRampMix
01241 #define FilterStereo16BitFirFilterRampMix Stereo16BitFirFilterRampMix
01242
01243 #endif
01244
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257 #define MIXNDX_16BIT 0x01
01258 #define MIXNDX_STEREO 0x02
01259 #define MIXNDX_RAMP 0x04
01260 #define MIXNDX_FILTER 0x08
01261 #define MIXNDX_LINEARSRC 0x10
01262 #define MIXNDX_SPLINESRC 0x20
01263 #define MIXNDX_FIRSRC 0x30
01264
01265 const LPMIXINTERFACE gpMixFunctionTable[2*2*16] =
01266 {
01267
01268 Mono8BitMix, Mono16BitMix, Stereo8BitMix, Stereo16BitMix,
01269 Mono8BitRampMix, Mono16BitRampMix, Stereo8BitRampMix, Stereo16BitRampMix,
01270
01271 FilterMono8BitMix, FilterMono16BitMix, FilterStereo8BitMix, FilterStereo16BitMix,
01272 FilterMono8BitRampMix, FilterMono16BitRampMix, FilterStereo8BitRampMix,FilterStereo16BitRampMix,
01273
01274 Mono8BitLinearMix, Mono16BitLinearMix, Stereo8BitLinearMix, Stereo16BitLinearMix,
01275 Mono8BitLinearRampMix, Mono16BitLinearRampMix, Stereo8BitLinearRampMix,Stereo16BitLinearRampMix,
01276
01277 FilterMono8BitLinearMix, FilterMono16BitLinearMix, FilterStereo8BitLinearMix, FilterStereo16BitLinearMix,
01278 FilterMono8BitLinearRampMix,FilterMono16BitLinearRampMix,FilterStereo8BitLinearRampMix,FilterStereo16BitLinearRampMix,
01279
01280
01281 Mono8BitSplineMix, Mono16BitSplineMix, Stereo8BitSplineMix, Stereo16BitSplineMix,
01282 Mono8BitSplineRampMix, Mono16BitSplineRampMix, Stereo8BitSplineRampMix,Stereo16BitSplineRampMix,
01283
01284 FilterMono8BitSplineMix, FilterMono16BitSplineMix, FilterStereo8BitSplineMix, FilterStereo16BitSplineMix,
01285 FilterMono8BitSplineRampMix,FilterMono16BitSplineRampMix,FilterStereo8BitSplineRampMix,FilterStereo16BitSplineRampMix,
01286
01287
01288 Mono8BitFirFilterMix, Mono16BitFirFilterMix, Stereo8BitFirFilterMix, Stereo16BitFirFilterMix,
01289 Mono8BitFirFilterRampMix, Mono16BitFirFilterRampMix, Stereo8BitFirFilterRampMix,Stereo16BitFirFilterRampMix,
01290
01291 FilterMono8BitFirFilterMix, FilterMono16BitFirFilterMix, FilterStereo8BitFirFilterMix, FilterStereo16BitFirFilterMix,
01292 FilterMono8BitFirFilterRampMix,FilterMono16BitFirFilterRampMix,FilterStereo8BitFirFilterRampMix,FilterStereo16BitFirFilterRampMix
01293 };
01294
01295 const LPMIXINTERFACE gpFastMixFunctionTable[2*2*16] =
01296 {
01297
01298 FastMono8BitMix, FastMono16BitMix, Stereo8BitMix, Stereo16BitMix,
01299 FastMono8BitRampMix, FastMono16BitRampMix, Stereo8BitRampMix, Stereo16BitRampMix,
01300
01301 FilterMono8BitMix, FilterMono16BitMix, FilterStereo8BitMix, FilterStereo16BitMix,
01302 FilterMono8BitRampMix, FilterMono16BitRampMix, FilterStereo8BitRampMix,FilterStereo16BitRampMix,
01303
01304 FastMono8BitLinearMix, FastMono16BitLinearMix, Stereo8BitLinearMix, Stereo16BitLinearMix,
01305 FastMono8BitLinearRampMix, FastMono16BitLinearRampMix, Stereo8BitLinearRampMix,Stereo16BitLinearRampMix,
01306
01307 FilterMono8BitLinearMix, FilterMono16BitLinearMix, FilterStereo8BitLinearMix, FilterStereo16BitLinearMix,
01308 FilterMono8BitLinearRampMix,FilterMono16BitLinearRampMix,FilterStereo8BitLinearRampMix,FilterStereo16BitLinearRampMix,
01309
01310
01311 Mono8BitSplineMix, Mono16BitSplineMix, Stereo8BitSplineMix, Stereo16BitSplineMix,
01312 Mono8BitSplineRampMix, Mono16BitSplineRampMix, Stereo8BitSplineRampMix,Stereo16BitSplineRampMix,
01313
01314 FilterMono8BitSplineMix, FilterMono16BitSplineMix, FilterStereo8BitSplineMix, FilterStereo16BitSplineMix,
01315 FilterMono8BitSplineRampMix,FilterMono16BitSplineRampMix,FilterStereo8BitSplineRampMix,FilterStereo16BitSplineRampMix,
01316
01317
01318 Mono8BitFirFilterMix, Mono16BitFirFilterMix, Stereo8BitFirFilterMix, Stereo16BitFirFilterMix,
01319 Mono8BitFirFilterRampMix, Mono16BitFirFilterRampMix, Stereo8BitFirFilterRampMix,Stereo16BitFirFilterRampMix,
01320
01321 FilterMono8BitFirFilterMix, FilterMono16BitFirFilterMix, FilterStereo8BitFirFilterMix, FilterStereo16BitFirFilterMix,
01322 FilterMono8BitFirFilterRampMix,FilterMono16BitFirFilterRampMix,FilterStereo8BitFirFilterRampMix,FilterStereo16BitFirFilterRampMix,
01323 };
01324
01325
01327
01328 static LONG MPPFASTCALL GetSampleCount(MODCHANNEL *pChn, LONG nSamples)
01329
01330 {
01331 LONG nLoopStart = (pChn->dwFlags & CHN_LOOP) ? pChn->nLoopStart : 0;
01332 LONG nInc = pChn->nInc;
01333
01334 if ((nSamples <= 0) || (!nInc) || (!pChn->nLength)) return 0;
01335
01336 if ((LONG)pChn->nPos < nLoopStart)
01337 {
01338 if (nInc < 0)
01339 {
01340
01341 LONG nDelta = ((nLoopStart - pChn->nPos) << 16) - (pChn->nPosLo & 0xffff);
01342 pChn->nPos = nLoopStart | (nDelta>>16);
01343 pChn->nPosLo = nDelta & 0xffff;
01344 if (((LONG)pChn->nPos < nLoopStart) || (pChn->nPos >= (nLoopStart+pChn->nLength)/2))
01345 {
01346 pChn->nPos = nLoopStart; pChn->nPosLo = 0;
01347 }
01348 nInc = -nInc;
01349 pChn->nInc = nInc;
01350 pChn->dwFlags &= ~(CHN_PINGPONGFLAG);
01351 if ((!(pChn->dwFlags & CHN_LOOP)) || (pChn->nPos >= pChn->nLength))
01352 {
01353 pChn->nPos = pChn->nLength;
01354 pChn->nPosLo = 0;
01355 return 0;
01356 }
01357 } else
01358 {
01359
01360 if ((LONG)pChn->nPos < 0) pChn->nPos = 0;
01361 }
01362 } else
01363
01364 if (pChn->nPos >= pChn->nLength)
01365 {
01366 if (!(pChn->dwFlags & CHN_LOOP)) return 0;
01367 if (pChn->dwFlags & CHN_PINGPONGLOOP)
01368 {
01369
01370 if (nInc > 0)
01371 {
01372 nInc = -nInc;
01373 pChn->nInc = nInc;
01374 }
01375 pChn->dwFlags |= CHN_PINGPONGFLAG;
01376
01377 LONG nDeltaHi = (pChn->nPos - pChn->nLength);
01378 LONG nDeltaLo = 0x10000 - (pChn->nPosLo & 0xffff);
01379 pChn->nPos = pChn->nLength - nDeltaHi - (nDeltaLo>>16);
01380 pChn->nPosLo = nDeltaLo & 0xffff;
01381 if ((pChn->nPos <= pChn->nLoopStart) || (pChn->nPos >= pChn->nLength)) pChn->nPos = pChn->nLength-1;
01382 } else
01383 {
01384 if (nInc < 0)
01385 {
01386 nInc = -nInc;
01387 pChn->nInc = nInc;
01388 }
01389
01390 pChn->nPos += nLoopStart - pChn->nLength;
01391 if ((LONG)pChn->nPos < nLoopStart) pChn->nPos = pChn->nLoopStart;
01392 }
01393 }
01394 LONG nPos = pChn->nPos;
01395
01396 if (nPos < nLoopStart)
01397 {
01398 if ((nPos < 0) || (nInc < 0)) return 0;
01399 }
01400 if ((nPos < 0) || (nPos >= (LONG)pChn->nLength)) return 0;
01401 LONG nPosLo = (USHORT)pChn->nPosLo, nSmpCount = nSamples;
01402 if (nInc < 0)
01403 {
01404 LONG nInv = -nInc;
01405 LONG maxsamples = 16384 / ((nInv>>16)+1);
01406 if (maxsamples < 2) maxsamples = 2;
01407 if (nSamples > maxsamples) nSamples = maxsamples;
01408 LONG nDeltaHi = (nInv>>16) * (nSamples - 1);
01409 LONG nDeltaLo = (nInv&0xffff) * (nSamples - 1);
01410 LONG nPosDest = nPos - nDeltaHi + ((nPosLo - nDeltaLo) >> 16);
01411 if (nPosDest < nLoopStart)
01412 {
01413 nSmpCount = (ULONG)(((((LONGLONG)nPos - nLoopStart) << 16) + nPosLo - 1) / nInv) + 1;
01414 }
01415 } else
01416 {
01417 LONG maxsamples = 16384 / ((nInc>>16)+1);
01418 if (maxsamples < 2) maxsamples = 2;
01419 if (nSamples > maxsamples) nSamples = maxsamples;
01420 LONG nDeltaHi = (nInc>>16) * (nSamples - 1);
01421 LONG nDeltaLo = (nInc&0xffff) * (nSamples - 1);
01422 LONG nPosDest = nPos + nDeltaHi + ((nPosLo + nDeltaLo)>>16);
01423 if (nPosDest >= (LONG)pChn->nLength)
01424 {
01425 nSmpCount = (ULONG)(((((LONGLONG)pChn->nLength - nPos) << 16) - nPosLo - 1) / nInc) + 1;
01426 }
01427 }
01428 if (nSmpCount <= 1) return 1;
01429 if (nSmpCount > nSamples) return nSamples;
01430 return nSmpCount;
01431 }
01432
01433
01434 UINT CSoundFile::CreateStereoMix(int count)
01435
01436 {
01437 LPLONG pOfsL, pOfsR;
01438 DWORD nchused, nchmixed;
01439
01440 if (!count) return 0;
01441 #ifndef FASTSOUNDLIB
01442 if (gnChannels > 2) X86_InitMixBuffer(MixRearBuffer, count*2);
01443 #endif
01444 nchused = nchmixed = 0;
01445 for (UINT nChn=0; nChn<m_nMixChannels; nChn++)
01446 {
01447 const LPMIXINTERFACE *pMixFuncTable;
01448 MODCHANNEL * const pChannel = &Chn[ChnMix[nChn]];
01449 UINT nFlags, nMasterCh;
01450 LONG nSmpCount;
01451 int nsamples;
01452 int *pbuffer;
01453
01454 if (!pChannel->pCurrentSample) continue;
01455 nMasterCh = (ChnMix[nChn] < m_nChannels) ? ChnMix[nChn]+1 : pChannel->nMasterChn;
01456 pOfsR = &gnDryROfsVol;
01457 pOfsL = &gnDryLOfsVol;
01458 nFlags = 0;
01459 if (pChannel->dwFlags & CHN_16BIT) nFlags |= MIXNDX_16BIT;
01460 if (pChannel->dwFlags & CHN_STEREO) nFlags |= MIXNDX_STEREO;
01461 #ifndef NO_FILTER
01462 if (pChannel->dwFlags & CHN_FILTER) nFlags |= MIXNDX_FILTER;
01463 #endif
01464 if (!(pChannel->dwFlags & CHN_NOIDO))
01465 {
01466
01467 if( (gdwSoundSetup & (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE)) == (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE) )
01468 nFlags += MIXNDX_FIRSRC;
01469 else if( (gdwSoundSetup & (SNDMIX_HQRESAMPLER)) == SNDMIX_HQRESAMPLER )
01470 nFlags += MIXNDX_SPLINESRC;
01471 else
01472 nFlags += MIXNDX_LINEARSRC;
01473 }
01474 if ((nFlags < 0x40) && (pChannel->nLeftVol == pChannel->nRightVol)
01475 && ((!pChannel->nRampLength) || (pChannel->nLeftRamp == pChannel->nRightRamp)))
01476 {
01477 pMixFuncTable = gpFastMixFunctionTable;
01478 } else
01479 {
01480 pMixFuncTable = gpMixFunctionTable;
01481 }
01482 nsamples = count;
01483 #ifndef NO_REVERB
01484 pbuffer = (gdwSoundSetup & SNDMIX_REVERB) ? MixReverbBuffer : MixSoundBuffer;
01485 if (pChannel->dwFlags & CHN_NOREVERB) pbuffer = MixSoundBuffer;
01486 if (pChannel->dwFlags & CHN_REVERB) pbuffer = MixReverbBuffer;
01487 if (pbuffer == MixReverbBuffer)
01488 {
01489 if (!gnReverbSend) memset(MixReverbBuffer, 0, count * 8);
01490 gnReverbSend += count;
01491 }
01492 #else
01493 pbuffer = MixSoundBuffer;
01494 #endif
01495 nchused++;
01497 SampleLooping:
01498 UINT nrampsamples = nsamples;
01499 if (pChannel->nRampLength > 0)
01500 {
01501 if ((LONG)nrampsamples > pChannel->nRampLength) nrampsamples = pChannel->nRampLength;
01502 }
01503 if ((nSmpCount = GetSampleCount(pChannel, nrampsamples)) <= 0)
01504 {
01505
01506 pChannel->pCurrentSample = NULL;
01507 pChannel->nLength = 0;
01508 pChannel->nPos = 0;
01509 pChannel->nPosLo = 0;
01510 pChannel->nRampLength = 0;
01511 X86_EndChannelOfs(pChannel, pbuffer, nsamples);
01512 *pOfsR += pChannel->nROfs;
01513 *pOfsL += pChannel->nLOfs;
01514 pChannel->nROfs = pChannel->nLOfs = 0;
01515 pChannel->dwFlags &= ~CHN_PINGPONGFLAG;
01516 continue;
01517 }
01518
01519 UINT naddmix;
01520 if (((nchmixed >= m_nMaxMixChannels) && (!(gdwSoundSetup & SNDMIX_DIRECTTODISK)))
01521 || ((!pChannel->nRampLength) && (!(pChannel->nLeftVol|pChannel->nRightVol))))
01522 {
01523 LONG delta = (pChannel->nInc * (LONG)nSmpCount) + (LONG)pChannel->nPosLo;
01524 pChannel->nPosLo = delta & 0xFFFF;
01525 pChannel->nPos += (delta >> 16);
01526 pChannel->nROfs = pChannel->nLOfs = 0;
01527 pbuffer += nSmpCount*2;
01528 naddmix = 0;
01529 } else
01530
01531 {
01532
01533 LPMIXINTERFACE pMixFunc;
01534 pMixFunc = (pChannel->nRampLength) ? pMixFuncTable[nFlags|MIXNDX_RAMP] : pMixFuncTable[nFlags];
01535 int *pbufmax = pbuffer + (nSmpCount*2);
01536 pChannel->nROfs = - *(pbufmax-2);
01537 pChannel->nLOfs = - *(pbufmax-1);
01538 pMixFunc(pChannel, pbuffer, pbufmax);
01539 pChannel->nROfs += *(pbufmax-2);
01540 pChannel->nLOfs += *(pbufmax-1);
01541 pbuffer = pbufmax;
01542 naddmix = 1;
01543
01544 }
01545 nsamples -= nSmpCount;
01546 if (pChannel->nRampLength)
01547 {
01548 pChannel->nRampLength -= nSmpCount;
01549 if (pChannel->nRampLength <= 0)
01550 {
01551 pChannel->nRampLength = 0;
01552 pChannel->nRightVol = pChannel->nNewRightVol;
01553 pChannel->nLeftVol = pChannel->nNewLeftVol;
01554 pChannel->nRightRamp = pChannel->nLeftRamp = 0;
01555 if ((pChannel->dwFlags & CHN_NOTEFADE) && (!(pChannel->nFadeOutVol)))
01556 {
01557 pChannel->nLength = 0;
01558 pChannel->pCurrentSample = NULL;
01559 }
01560 }
01561 }
01562 if (nsamples > 0) goto SampleLooping;
01563 nchmixed += naddmix;
01564 }
01565 return nchused;
01566 }
01567
01568
01569 #ifdef WIN32
01570 #pragma warning (disable:4100)
01571 #endif
01572
01573
01574 #ifdef WIN32
01575 __declspec(naked) DWORD MPPASMCALL X86_Convert32To8(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax)
01576
01577 {
01578 _asm {
01579 push ebx
01580 push esi
01581 push edi
01582 mov ebx, 16[esp]
01583 mov esi, 20[esp]
01584 mov edi, 24[esp]
01585 mov eax, 28[esp]
01586 mov ecx, dword ptr [eax]
01587 mov eax, 32[esp]
01588 mov edx, dword ptr [eax]
01589 cliploop:
01590 mov eax, dword ptr [esi]
01591 inc ebx
01592 cdq
01593 and edx, (1 << (24-MIXING_ATTENUATION)) - 1
01594 add eax, edx
01595 cmp eax, MIXING_CLIPMIN
01596 jl cliplow
01597 cmp eax, MIXING_CLIPMAX
01598 jg cliphigh
01599 cmp eax, ecx
01600 jl updatemin
01601 cmp eax, edx
01602 jg updatemax
01603 cliprecover:
01604 add esi, 4
01605 sar eax, 24-MIXING_ATTENUATION
01606 xor eax, 0x80
01607 dec edi
01608 mov byte ptr [ebx-1], al
01609 jnz cliploop
01610 mov eax, 28[esp]
01611 mov dword ptr [eax], ecx
01612 mov eax, 32[esp]
01613 mov dword ptr [eax], edx
01614 mov eax, 24[esp]
01615 pop edi
01616 pop esi
01617 pop ebx
01618 ret
01619 updatemin:
01620 mov ecx, eax
01621 jmp cliprecover
01622 updatemax:
01623 mov edx, eax
01624 jmp cliprecover
01625 cliplow:
01626 mov ecx, MIXING_CLIPMIN
01627 mov edx, MIXING_CLIPMAX
01628 mov eax, MIXING_CLIPMIN
01629 jmp cliprecover
01630 cliphigh:
01631 mov ecx, MIXING_CLIPMIN
01632 mov edx, MIXING_CLIPMAX
01633 mov eax, MIXING_CLIPMAX
01634 jmp cliprecover
01635 }
01636 }
01637 #else //WIN32
01638
01639
01640 __declspec(naked) DWORD MPPASMCALL X86_Convert32To8(LPVOID lp8, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax)
01641 {
01642 int vumin = *lpMin, vumax = *lpMax;
01643 unsigned char *p = (unsigned char *)lp8;
01644 for (UINT i=0; i<lSampleCount; i++)
01645 {
01646 int n = pBuffer[i];
01647 if (n < MIXING_CLIPMIN)
01648 n = MIXING_CLIPMIN;
01649 else if (n > MIXING_CLIPMAX)
01650 n = MIXING_CLIPMAX;
01651 if (n < vumin)
01652 vumin = n;
01653 else if (n > vumax)
01654 vumax = n;
01655 p[i] = (n >> (24-MIXING_ATTENUATION)) ^ 0x80;
01656 }
01657 *lpMin = vumin;
01658 *lpMax = vumax;
01659 return lSampleCount;
01660 }
01661 #endif //WIN32, else
01662
01663
01664 #ifdef WIN32
01665
01666 __declspec(naked) DWORD MPPASMCALL X86_Convert32To16(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax)
01667
01668 {
01669 _asm {
01670 push ebx
01671 push esi
01672 push edi
01673 mov ebx, 16[esp]
01674 mov eax, 28[esp]
01675 mov esi, 20[esp]
01676 mov ecx, dword ptr [eax]
01677 mov edi, 24[esp]
01678 mov eax, 32[esp]
01679 push ebp
01680 mov ebp, dword ptr [eax]
01681 cliploop:
01682 mov eax, dword ptr [esi]
01683 add ebx, 2
01684 cdq
01685 and edx, (1 << (16-MIXING_ATTENUATION)) - 1
01686 add esi, 4
01687 add eax, edx
01688 cmp eax, MIXING_CLIPMIN
01689 jl cliplow
01690 cmp eax, MIXING_CLIPMAX
01691 jg cliphigh
01692 cmp eax, ecx
01693 jl updatemin
01694 cmp eax, ebp
01695 jg updatemax
01696 cliprecover:
01697 sar eax, 16-MIXING_ATTENUATION
01698 dec edi
01699 mov word ptr [ebx-2], ax
01700 jnz cliploop
01701 mov edx, ebp
01702 pop ebp
01703 mov eax, 28[esp]
01704 mov dword ptr [eax], ecx
01705 mov eax, 32[esp]
01706 mov dword ptr [eax], edx
01707 mov eax, 24[esp]
01708 pop edi
01709 shl eax, 1
01710 pop esi
01711 pop ebx
01712 ret
01713 updatemin:
01714 mov ecx, eax
01715 jmp cliprecover
01716 updatemax:
01717 mov ebp, eax
01718 jmp cliprecover
01719 cliplow:
01720 mov ecx, MIXING_CLIPMIN
01721 mov ebp, MIXING_CLIPMAX
01722 mov eax, MIXING_CLIPMIN
01723 jmp cliprecover
01724 cliphigh:
01725 mov ecx, MIXING_CLIPMIN
01726 mov ebp, MIXING_CLIPMAX
01727 mov eax, MIXING_CLIPMAX
01728 jmp cliprecover
01729 }
01730 }
01731 #else //WIN32
01732
01733
01734 __declspec(naked) DWORD MPPASMCALL X86_Convert32To16(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax)
01735 {
01736 int vumin = *lpMin, vumax = *lpMax;
01737 signed short *p = (signed short *)lp16;
01738 for (UINT i=0; i<lSampleCount; i++)
01739 {
01740 int n = pBuffer[i];
01741 if (n < MIXING_CLIPMIN)
01742 n = MIXING_CLIPMIN;
01743 else if (n > MIXING_CLIPMAX)
01744 n = MIXING_CLIPMAX;
01745 if (n < vumin)
01746 vumin = n;
01747 else if (n > vumax)
01748 vumax = n;
01749 p[i] = n >> (16-MIXING_ATTENUATION);
01750 }
01751 *lpMin = vumin;
01752 *lpMax = vumax;
01753 return lSampleCount * 2;
01754 }
01755 #endif //WIN32, else
01756
01757 #ifdef WIN32
01758
01759 __declspec(naked) DWORD MPPASMCALL X86_Convert32To24(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax)
01760
01761 {
01762 _asm {
01763 push ebx
01764 push esi
01765 push edi
01766 mov ebx, 16[esp]
01767 mov esi, 20[esp]
01768 mov edi, 24[esp]
01769 mov eax, 28[esp]
01770 mov ecx, dword ptr [eax]
01771 mov eax, 32[esp]
01772 push ebp
01773 mov edx, dword ptr [eax]
01774 cliploop:
01775 mov eax, dword ptr [esi]
01776 mov ebp, eax
01777 sar ebp, 31
01778 and ebp, (1 << (8-MIXING_ATTENUATION)) - 1
01779 add eax, ebp
01780 cmp eax, MIXING_CLIPMIN
01781 jl cliplow
01782 cmp eax, MIXING_CLIPMAX
01783 jg cliphigh
01784 cmp eax, ecx
01785 jl updatemin
01786 cmp eax, edx
01787 jg updatemax
01788 cliprecover:
01789 add ebx, 3
01790 sar eax, 8-MIXING_ATTENUATION
01791 add esi, 4
01792 mov word ptr [ebx-3], ax
01793 shr eax, 16
01794 dec edi
01795 mov byte ptr [ebx-1], al
01796 jnz cliploop
01797 pop ebp
01798 mov eax, 28[esp]
01799 mov dword ptr [eax], ecx
01800 mov eax, 32[esp]
01801 mov dword ptr [eax], edx
01802 mov edx, 24[esp]
01803 mov eax, edx
01804 pop edi
01805 shl eax, 1
01806 pop esi
01807 add eax, edx
01808 pop ebx
01809 ret
01810 updatemin:
01811 mov ecx, eax
01812 jmp cliprecover
01813 updatemax:
01814 mov edx, eax
01815 jmp cliprecover
01816 cliplow:
01817 mov ecx, MIXING_CLIPMIN
01818 mov edx, MIXING_CLIPMAX
01819 mov eax, MIXING_CLIPMIN
01820 jmp cliprecover
01821 cliphigh:
01822 mov ecx, MIXING_CLIPMIN
01823 mov edx, MIXING_CLIPMAX
01824 mov eax, MIXING_CLIPMAX
01825 jmp cliprecover
01826 }
01827 }
01828 #else //WIN32
01829
01830
01831 __declspec(naked) DWORD MPPASMCALL X86_Convert32To24(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax)
01832 {
01833 return 0;
01834 }
01835 #endif
01836
01837 #ifdef WIN32
01838
01839 __declspec(naked) DWORD MPPASMCALL X86_Convert32To32(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax)
01840
01841 {
01842 _asm {
01843 push ebx
01844 push esi
01845 push edi
01846 mov ebx, 16[esp]
01847 mov esi, 20[esp]
01848 mov edi, 24[esp]
01849 mov eax, 28[esp]
01850 mov ecx, dword ptr [eax]
01851 mov eax, 32[esp]
01852 mov edx, dword ptr [eax]
01853 cliploop:
01854 mov eax, dword ptr [esi]
01855 add ebx, 4
01856 add esi, 4
01857 cmp eax, MIXING_CLIPMIN
01858 jl cliplow
01859 cmp eax, MIXING_CLIPMAX
01860 jg cliphigh
01861 cmp eax, ecx
01862 jl updatemin
01863 cmp eax, edx
01864 jg updatemax
01865 cliprecover:
01866 shl eax, MIXING_ATTENUATION
01867 dec edi
01868 mov dword ptr [ebx-4], eax
01869 jnz cliploop
01870 mov eax, 28[esp]
01871 mov dword ptr [eax], ecx
01872 mov eax, 32[esp]
01873 mov dword ptr [eax], edx
01874 mov edx, 24[esp]
01875 pop edi
01876 mov eax, edx
01877 pop esi
01878 shl eax, 2
01879 pop ebx
01880 ret
01881 updatemin:
01882 mov ecx, eax
01883 jmp cliprecover
01884 updatemax:
01885 mov edx, eax
01886 jmp cliprecover
01887 cliplow:
01888 mov ecx, MIXING_CLIPMIN
01889 mov edx, MIXING_CLIPMAX
01890 mov eax, MIXING_CLIPMIN
01891 jmp cliprecover
01892 cliphigh:
01893 mov ecx, MIXING_CLIPMIN
01894 mov edx, MIXING_CLIPMAX
01895 mov eax, MIXING_CLIPMAX
01896 jmp cliprecover
01897 }
01898 }
01899 #else
01900
01901
01902 __declspec(naked) DWORD MPPASMCALL X86_Convert32To32(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax)
01903 {
01904 return 0;
01905 }
01906 #endif
01907
01908
01909 #ifdef WIN32
01910 void MPPASMCALL X86_InitMixBuffer(int *pBuffer, UINT nSamples)
01911
01912 {
01913 _asm {
01914 mov ecx, nSamples
01915 mov esi, pBuffer
01916 xor eax, eax
01917 mov edx, ecx
01918 shr ecx, 2
01919 and edx, 3
01920 jz unroll4x
01921 loop1x:
01922 add esi, 4
01923 dec edx
01924 mov dword ptr [esi-4], eax
01925 jnz loop1x
01926 unroll4x:
01927 or ecx, ecx
01928 jnz loop4x
01929 jmp done
01930 loop4x:
01931 add esi, 16
01932 dec ecx
01933 mov dword ptr [esi-16], eax
01934 mov dword ptr [esi-12], eax
01935 mov dword ptr [esi-8], eax
01936 mov dword ptr [esi-4], eax
01937 jnz loop4x
01938 done:;
01939 }
01940 }
01941 #else
01942
01943
01944 void MPPASMCALL X86_InitMixBuffer(int *pBuffer, UINT nSamples)
01945 {
01946 memset(pBuffer, 0, nSamples * sizeof(int));
01947 }
01948 #endif
01949
01950
01951 #ifdef WIN32
01952 __declspec(naked) void MPPASMCALL X86_InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples)
01953
01954 {
01955 _asm {
01956 push ebx
01957 push ebp
01958 push esi
01959 push edi
01960 mov ecx, 28[esp]
01961 mov esi, 20[esp]
01962 mov edi, 24[esp]
01963 lea esi, [esi+ecx*4]
01964 lea edi, [edi+ecx*4]
01965 lea ebx, [esi+ecx*4]
01966 interleaveloop:
01967 mov eax, dword ptr [esi-8]
01968 mov edx, dword ptr [esi-4]
01969 sub ebx, 16
01970 mov ebp, dword ptr [edi-8]
01971 mov dword ptr [ebx], eax
01972 mov dword ptr [ebx+4], edx
01973 mov eax, dword ptr [edi-4]
01974 sub esi, 8
01975 sub edi, 8
01976 dec ecx
01977 mov dword ptr [ebx+8], ebp
01978 mov dword ptr [ebx+12], eax
01979 jnz interleaveloop
01980 pop edi
01981 pop esi
01982 pop ebp
01983 pop ebx
01984 ret
01985 }
01986 }
01987 #else
01988
01989
01990 __declspec(naked) void MPPASMCALL X86_InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples)
01991 {
01992 }
01993 #endif
01994
01995
01996 #ifdef WIN32
01997 VOID MPPASMCALL X86_MonoFromStereo(int *pMixBuf, UINT nSamples)
01998
01999 {
02000 _asm {
02001 mov ecx, nSamples
02002 mov esi, pMixBuf
02003 mov edi, esi
02004 stloop:
02005 mov eax, dword ptr [esi]
02006 mov edx, dword ptr [esi+4]
02007 add edi, 4
02008 add esi, 8
02009 add eax, edx
02010 sar eax, 1
02011 dec ecx
02012 mov dword ptr [edi-4], eax
02013 jnz stloop
02014 }
02015 }
02016 #else
02017
02018 VOID MPPASMCALL X86_MonoFromStereo(int *pMixBuf, UINT nSamples)
02019 {
02020 UINT j;
02021 for(UINT i = 0; i < nSamples; i++)
02022 {
02023 j = i << 1;
02024 pMixBuf[i] = (pMixBuf[j] + pMixBuf[j + 1]) >> 1;
02025 }
02026 }
02027 #endif
02028
02029 #define OFSDECAYSHIFT 8
02030 #define OFSDECAYMASK 0xFF
02031
02032
02033 #ifdef WIN32
02034 void MPPASMCALL X86_StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs)
02035
02036 {
02037 _asm {
02038 mov edi, pBuffer
02039 mov ecx, nSamples
02040 mov eax, lpROfs
02041 mov edx, lpLOfs
02042 mov eax, [eax]
02043 mov edx, [edx]
02044 or ecx, ecx
02045 jz fill_loop
02046 mov ebx, eax
02047 or ebx, edx
02048 jz fill_loop
02049 ofsloop:
02050 mov ebx, eax
02051 mov esi, edx
02052 neg ebx
02053 neg esi
02054 sar ebx, 31
02055 sar esi, 31
02056 and ebx, OFSDECAYMASK
02057 and esi, OFSDECAYMASK
02058 add ebx, eax
02059 add esi, edx
02060 sar ebx, OFSDECAYSHIFT
02061 sar esi, OFSDECAYSHIFT
02062 sub eax, ebx
02063 sub edx, esi
02064 mov ebx, eax
02065 or ebx, edx
02066 jz fill_loop
02067 add edi, 8
02068 dec ecx
02069 mov [edi-8], eax
02070 mov [edi-4], edx
02071 jnz ofsloop
02072 fill_loop:
02073 mov ebx, ecx
02074 and ebx, 3
02075 jz fill4x
02076 fill1x:
02077 mov [edi], eax
02078 mov [edi+4], edx
02079 add edi, 8
02080 dec ebx
02081 jnz fill1x
02082 fill4x:
02083 shr ecx, 2
02084 or ecx, ecx
02085 jz done
02086 fill4xloop:
02087 mov [edi], eax
02088 mov [edi+4], edx
02089 mov [edi+8], eax
02090 mov [edi+12], edx
02091 add edi, 8*4
02092 dec ecx
02093 mov [edi-16], eax
02094 mov [edi-12], edx
02095 mov [edi-8], eax
02096 mov [edi-4], edx
02097 jnz fill4xloop
02098 done:
02099 mov esi, lpROfs
02100 mov edi, lpLOfs
02101 mov [esi], eax
02102 mov [edi], edx
02103 }
02104 }
02105 #else
02106
02107 #define OFSDECAYSHIFT 8
02108 #define OFSDECAYMASK 0xFF
02109 __declspec(naked) void MPPASMCALL X86_StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs)
02110
02111 {
02112 int rofs = *lpROfs;
02113 int lofs = *lpLOfs;
02114
02115 if ((!rofs) && (!lofs))
02116 {
02117 X86_InitMixBuffer(pBuffer, nSamples*2);
02118 return;
02119 }
02120 for (UINT i=0; i<nSamples; i++)
02121 {
02122 int x_r = (rofs + (((-rofs)>>31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
02123 int x_l = (lofs + (((-lofs)>>31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
02124 rofs -= x_r;
02125 lofs -= x_l;
02126 pBuffer[i*2] = x_r;
02127 pBuffer[i*2+1] = x_l;
02128 }
02129 *lpROfs = rofs;
02130 *lpLOfs = lofs;
02131 }
02132 #endif
02133
02134 #ifdef WIN32
02135 void MPPASMCALL X86_EndChannelOfs(MODCHANNEL *pChannel, int *pBuffer, UINT nSamples)
02136
02137 {
02138 _asm {
02139 mov esi, pChannel
02140 mov edi, pBuffer
02141 mov ecx, nSamples
02142 mov eax, dword ptr [esi+MODCHANNEL.nROfs]
02143 mov edx, dword ptr [esi+MODCHANNEL.nLOfs]
02144 or ecx, ecx
02145 jz brkloop
02146 ofsloop:
02147 mov ebx, eax
02148 mov esi, edx
02149 neg ebx
02150 neg esi
02151 sar ebx, 31
02152 sar esi, 31
02153 and ebx, OFSDECAYMASK
02154 and esi, OFSDECAYMASK
02155 add ebx, eax
02156 add esi, edx
02157 sar ebx, OFSDECAYSHIFT
02158 sar esi, OFSDECAYSHIFT
02159 sub eax, ebx
02160 sub edx, esi
02161 mov ebx, eax
02162 add dword ptr [edi], eax
02163 add dword ptr [edi+4], edx
02164 or ebx, edx
02165 jz brkloop
02166 add edi, 8
02167 dec ecx
02168 jnz ofsloop
02169 brkloop:
02170 mov esi, pChannel
02171 mov dword ptr [esi+MODCHANNEL.nROfs], eax
02172 mov dword ptr [esi+MODCHANNEL.nLOfs], edx
02173 }
02174 }
02175 #else
02176
02177
02178 void MPPASMCALL X86_EndChannelOfs(MODCHANNEL *pChannel, int *pBuffer, UINT nSamples)
02179 {
02180 int rofs = pChannel->nROfs;
02181 int lofs = pChannel->nLOfs;
02182
02183 if ((!rofs) && (!lofs)) return;
02184 for (UINT i=0; i<nSamples; i++)
02185 {
02186 int x_r = (rofs + (((-rofs)>>31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
02187 int x_l = (lofs + (((-lofs)>>31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
02188 rofs -= x_r;
02189 lofs -= x_l;
02190 pBuffer[i*2] += x_r;
02191 pBuffer[i*2+1] += x_l;
02192 }
02193 pChannel->nROfs = rofs;
02194 pChannel->nLOfs = lofs;
02195 }
02196 #endif
02197
02198
02200
02201
02202 #ifndef NO_AGC
02203
02204
02205 #define MIXING_LIMITMAX (0x08100000)
02206 #define MIXING_LIMITMIN (-MIXING_LIMITMAX)
02207
02208 __declspec(naked) UINT MPPASMCALL X86_AGC(int *pBuffer, UINT nSamples, UINT nAGC)
02209
02210 {
02211 __asm {
02212 push ebx
02213 push ebp
02214 push esi
02215 push edi
02216 mov esi, 20[esp]
02217 mov ecx, 24[esp]
02218 mov edi, 28[esp]
02219 agcloop:
02220 mov eax, dword ptr [esi]
02221 imul edi
02222 shrd eax, edx, AGC_PRECISION
02223 add esi, 4
02224 cmp eax, MIXING_LIMITMIN
02225 jl agcupdate
02226 cmp eax, MIXING_LIMITMAX
02227 jg agcupdate
02228 agcrecover:
02229 dec ecx
02230 mov dword ptr [esi-4], eax
02231 jnz agcloop
02232 mov eax, edi
02233 pop edi
02234 pop esi
02235 pop ebp
02236 pop ebx
02237 ret
02238 agcupdate:
02239 dec edi
02240 jmp agcrecover
02241 }
02242 }
02243
02244 #pragma warning (default:4100)
02245
02246 void CSoundFile::ProcessAGC(int count)
02247
02248 {
02249 static DWORD gAGCRecoverCount = 0;
02250 UINT agc = X86_AGC(MixSoundBuffer, count, gnAGC);
02251
02252
02253
02254 if ((agc >= gnAGC) && (gnAGC < AGC_UNITY) && (gnVUMeter < (0xFF - (gnAGC >> (AGC_PRECISION-7))) ))
02255 {
02256 gAGCRecoverCount += count;
02257 UINT agctimeout = gdwMixingFreq + gnAGC;
02258 if (gnChannels >= 2) agctimeout <<= 1;
02259 if (gAGCRecoverCount >= agctimeout)
02260 {
02261 gAGCRecoverCount = 0;
02262 gnAGC++;
02263 }
02264 } else
02265 {
02266 gnAGC = agc;
02267 gAGCRecoverCount = 0;
02268 }
02269 }
02270
02271
02272
02273 void CSoundFile::ResetAGC()
02274
02275 {
02276 gnAGC = AGC_UNITY;
02277 }
02278
02279 #endif // NO_AGC
02280