Mercurial > audlegacy-plugins
diff src/modplug/fastmix.cxx @ 2337:107c1fed3d92
Port Schism modplug core.
author | "Tony Vroon <chainsaw@gentoo.org>" |
---|---|
date | Thu, 24 Jan 2008 12:05:59 +0000 |
parents | 6907fc39b53f |
children |
line wrap: on
line diff
--- a/src/modplug/fastmix.cxx Wed Jan 23 19:37:05 2008 +0100 +++ b/src/modplug/fastmix.cxx Thu Jan 24 12:05:59 2008 +0000 @@ -12,10 +12,6 @@ #include "sndfile.h" #include <math.h> -#ifdef MSC_VER -#pragma bss_seg(".modplug") -#endif - // Front Mix Buffer (Also room for interleaved rear mix) int MixSoundBuffer[MIXBUFFERSIZE*4]; @@ -25,14 +21,8 @@ extern UINT gnReverbSend; #endif -#ifndef MODPLUG_FASTSOUNDLIB int MixRearBuffer[MIXBUFFERSIZE*2]; float MixFloatBuffer[MIXBUFFERSIZE*2]; -#endif - -#ifdef MSC_VER -#pragma bss_seg() -#endif extern LONG gnDryROfsVol; @@ -530,37 +520,39 @@ // Resonant Filters // Mono -#define MIX_BEGIN_FILTER\ - int fy1 = pChannel->nFilter_Y1;\ - int fy2 = pChannel->nFilter_Y2;\ +#define MIX_BEGIN_FILTER \ + double fy1 = pChannel->nFilter_Y1;\ + double fy2 = pChannel->nFilter_Y2;\ + double ta; -#define MIX_END_FILTER\ +#define MIX_END_FILTER \ pChannel->nFilter_Y1 = fy1;\ pChannel->nFilter_Y2 = fy2; -#define SNDMIX_PROCESSFILTER\ - vol = (vol * pChn->nFilter_A0 + fy1 * pChn->nFilter_B0 + fy2 * pChn->nFilter_B1 + 4096) >> 13;\ - fy2 = fy1;\ - fy1 = vol;\ +#define SNDMIX_PROCESSFILTER \ +ta = ((double)vol * pChn->nFilter_A0 + fy1 * pChn->nFilter_B0 + fy2 * pChn->nFilter_B1);\ +fy2 = fy1;\ +fy1 = ta;vol=(int)ta; // Stereo -#define MIX_BEGIN_STEREO_FILTER\ - int fy1 = pChannel->nFilter_Y1;\ - int fy2 = pChannel->nFilter_Y2;\ - int fy3 = pChannel->nFilter_Y3;\ - int fy4 = pChannel->nFilter_Y4;\ +#define MIX_BEGIN_STEREO_FILTER \ +double fy1 = pChannel->nFilter_Y1;\ +double fy2 = pChannel->nFilter_Y2;\ +double fy3 = pChannel->nFilter_Y3;\ +double fy4 = pChannel->nFilter_Y4;\ +double ta, tb; -#define MIX_END_STEREO_FILTER\ - pChannel->nFilter_Y1 = fy1;\ - pChannel->nFilter_Y2 = fy2;\ - pChannel->nFilter_Y3 = fy3;\ - pChannel->nFilter_Y4 = fy4;\ +#define MIX_END_STEREO_FILTER \ +pChannel->nFilter_Y1 = fy1;\ +pChannel->nFilter_Y2 = fy2;\ +pChannel->nFilter_Y3 = fy3;\ +pChannel->nFilter_Y4 = fy4;\ -#define SNDMIX_PROCESSSTEREOFILTER\ - vol_l = (vol_l * pChn->nFilter_A0 + fy1 * pChn->nFilter_B0 + fy2 * pChn->nFilter_B1 + 4096) >> 13;\ - vol_r = (vol_r * pChn->nFilter_A0 + fy3 * pChn->nFilter_B0 + fy4 * pChn->nFilter_B1 + 4096) >> 13;\ - fy2 = fy1; fy1 = vol_l;\ - fy4 = fy3; fy3 = vol_r;\ +#define SNDMIX_PROCESSSTEREOFILTER \ +ta = ((double)vol_l * pChn->nFilter_A0 + fy1 * pChn->nFilter_B0 + fy2 * pChn->nFilter_B1);\ +tb = ((double)vol_r * pChn->nFilter_A0 + fy3 * pChn->nFilter_B0 + fy4 * pChn->nFilter_B1);\ +fy2 = fy1; fy1 = ta;vol_l=(int)ta;\ +fy4 = fy3; fy3 = tb;vol_r=(int)tb; ////////////////////////////////////////////////////////// // Interfaces @@ -659,11 +651,17 @@ ///////////////////////////////////////////////////// // -void MPPASMCALL X86_InitMixBuffer(int *pBuffer, UINT nSamples); -void MPPASMCALL X86_EndChannelOfs(MODCHANNEL *pChannel, int *pBuffer, UINT nSamples); -void MPPASMCALL X86_StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs); -void X86_StereoMixToFloat(const int *, float *, float *, UINT nCount); -void X86_FloatToStereoMix(const float *pIn1, const float *pIn2, int *pOut, UINT nCount); +extern void StereoMixToFloat(const int *pSrc, float *pOut1, float *pOut2, UINT nCount, const float _i2fc); +extern void FloatToStereoMix(const float *pIn1, const float *pIn2, int *pOut, UINT nCount, const float _f2ic); +extern void MonoMixToFloat(const int *pSrc, float *pOut, UINT nCount, const float _i2fc); +extern void FloatToMonoMix(const float *pIn, int *pOut, UINT nCount, const float _f2ic); + +void InitMixBuffer(int *pBuffer, UINT nSamples); +void EndChannelOfs(MODCHANNEL *pChannel, int *pBuffer, UINT nSamples); +void StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs); + +void StereoMixToFloat(const int *, float *, float *, UINT nCount); +void FloatToStereoMix(const float *pIn1, const float *pIn2, int *pOut, UINT nCount); ///////////////////////////////////////////////////// // Mono samples functions @@ -1466,9 +1464,7 @@ DWORD nchused, nchmixed; if (!count) return 0; -#ifndef MODPLUG_FASTSOUNDLIB - if (gnChannels > 2) X86_InitMixBuffer(MixRearBuffer, count*2); -#endif + if (gnChannels > 2) InitMixBuffer(MixRearBuffer, count*2); nchused = nchmixed = 0; for (UINT nChn=0; nChn<m_nMixChannels; nChn++) { @@ -1489,15 +1485,16 @@ #ifndef NO_FILTER if (pChannel->dwFlags & CHN_FILTER) nFlags |= MIXNDX_FILTER; #endif - if (!(pChannel->dwFlags & CHN_NOIDO)) + if (!(pChannel->dwFlags & CHN_NOIDO) + && !(gdwSoundSetup & SNDMIX_NORESAMPLING)) { // use hq-fir mixer? if( (gdwSoundSetup & (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE)) == (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE) ) - nFlags += MIXNDX_FIRSRC; - else if( (gdwSoundSetup & (SNDMIX_HQRESAMPLER)) == SNDMIX_HQRESAMPLER ) - nFlags += MIXNDX_SPLINESRC; + nFlags |= MIXNDX_FIRSRC; + else if( (gdwSoundSetup & SNDMIX_HQRESAMPLER)) + nFlags |= MIXNDX_SPLINESRC; else - nFlags += MIXNDX_LINEARSRC; // use + nFlags |= MIXNDX_LINEARSRC; // use } if ((nFlags < 0x40) && (pChannel->nLeftVol == pChannel->nRightVol) && ((!pChannel->nRampLength) || (pChannel->nLeftRamp == pChannel->nRightRamp))) @@ -1536,7 +1533,7 @@ pChannel->nPos = 0; pChannel->nPosLo = 0; pChannel->nRampLength = 0; - X86_EndChannelOfs(pChannel, pbuffer, nsamples); + EndChannelOfs(pChannel, pbuffer, nsamples); *pOfsR += pChannel->nROfs; *pOfsL += pChannel->nLOfs; pChannel->nROfs = pChannel->nLOfs = 0; @@ -1557,6 +1554,10 @@ } else // Do mixing { + if (pChannel->nLength) { + pChannel->topnote_offset = ((pChannel->nPos << 16) | pChannel->nPosLo) % pChannel->nLength; + } + // Choose function for mixing LPMIXINTERFACE pMixFunc; pMixFunc = (pChannel->nRampLength) ? pMixFuncTable[nFlags|MIXNDX_RAMP] : pMixFuncTable[nFlags]; @@ -1593,81 +1594,59 @@ return nchused; } +static float f2ic = (float)(1 << 28); +static float i2fc = (float)(1.0 / (1 << 28)); -#ifdef MSC_VER -#pragma warning (disable:4100) -#endif +VOID CSoundFile::StereoMixToFloat(const int *pSrc, float *pOut1, float *pOut2, UINT nCount) +//----------------------------------------------------------------------------------------- +{ + for (UINT i = 0; i < nCount; i++) { + *pOut1++ = *pSrc * i2fc; /*!*/ + pSrc++; + + *pOut2++ = *pSrc * i2fc; /*!*/ + pSrc++; + } +} + + +VOID CSoundFile::FloatToStereoMix(const float *pIn1, const float *pIn2, int *pOut, UINT nCount) +//--------------------------------------------------------------------------------------------- +{ + for (UINT i = 0; i < nCount; i++) { + *pOut++ = (int)(*pIn1 * f2ic); + *pOut++ = (int)(*pIn2 * f2ic); + pIn1++; + pIn2++; + } +} + + +VOID CSoundFile::MonoMixToFloat(const int *pSrc, float *pOut, UINT nCount) +//------------------------------------------------------------------------ +{ + for (UINT i = 0; i < nCount; i++) { + *pOut++ = *pSrc * i2fc; /*!*/ + pSrc++; + } +} + + +VOID CSoundFile::FloatToMonoMix(const float *pIn, int *pOut, UINT nCount) +//----------------------------------------------------------------------- +{ + for (UINT i = 0; i < nCount; i++) { + *pOut++ = (int)(*pIn * f2ic); /*!*/ + pIn++; + } +} + // Clip and convert to 8 bit -#ifdef MSC_VER -__declspec(naked) DWORD MPPASMCALL X86_Convert32To8(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax) -//---------------------------------------------------------------------------------------------------------------------------- -{ - _asm { - push ebx - push esi - push edi - mov ebx, 16[esp] // ebx = 8-bit buffer - mov esi, 20[esp] // esi = pBuffer - mov edi, 24[esp] // edi = lSampleCount - mov eax, 28[esp] - mov ecx, dword ptr [eax] // ecx = clipmin - mov eax, 32[esp] - mov edx, dword ptr [eax] // edx = clipmax -cliploop: - mov eax, dword ptr [esi] - inc ebx - cdq - and edx, (1 << (24-MIXING_ATTENUATION)) - 1 - add eax, edx - cmp eax, MIXING_CLIPMIN - jl cliplow - cmp eax, MIXING_CLIPMAX - jg cliphigh - cmp eax, ecx - jl updatemin - cmp eax, edx - jg updatemax -cliprecover: - add esi, 4 - sar eax, 24-MIXING_ATTENUATION - xor eax, 0x80 - dec edi - mov byte ptr [ebx-1], al - jnz cliploop - mov eax, 28[esp] - mov dword ptr [eax], ecx - mov eax, 32[esp] - mov dword ptr [eax], edx - mov eax, 24[esp] - pop edi - pop esi - pop ebx - ret -updatemin: - mov ecx, eax - jmp cliprecover -updatemax: - mov edx, eax - jmp cliprecover -cliplow: - mov ecx, MIXING_CLIPMIN - mov edx, MIXING_CLIPMAX - mov eax, MIXING_CLIPMIN - jmp cliprecover -cliphigh: - mov ecx, MIXING_CLIPMIN - mov edx, MIXING_CLIPMAX - mov eax, MIXING_CLIPMAX - jmp cliprecover - } -} -#else //MSC_VER //---GCCFIX: Asm replaced with C function // The C version was written by Rani Assaf <rani@magic.metawire.com>, I believe -DWORD MPPASMCALL X86_Convert32To8(LPVOID lp8, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax) +DWORD Convert32To8(LPVOID lp8, int *pBuffer, DWORD lSampleCount, LONG mins[2], LONG maxs[2]) { - int vumin = *lpMin, vumax = *lpMax; unsigned char *p = (unsigned char *)lp8; for (UINT i=0; i<lSampleCount; i++) { @@ -1676,92 +1655,18 @@ n = MIXING_CLIPMIN; else if (n > MIXING_CLIPMAX) n = MIXING_CLIPMAX; - if (n < vumin) - vumin = n; - else if (n > vumax) - vumax = n; + if (n < mins[i&1]) + mins[i&1]= n; + else if (n > maxs[i&1]) + maxs[i&1] = n; p[i] = (n >> (24-MIXING_ATTENUATION)) ^ 0x80; // 8-bit unsigned } - *lpMin = vumin; - *lpMax = vumax; return lSampleCount; } -#endif //MSC_VER, else - - -#ifdef MSC_VER -// Clip and convert to 16 bit -__declspec(naked) DWORD MPPASMCALL X86_Convert32To16(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax) -//----------------------------------------------------------------------------------------------------------------------------- -{ - _asm { - push ebx - push esi - push edi - mov ebx, 16[esp] // ebx = 16-bit buffer - mov eax, 28[esp] - mov esi, 20[esp] // esi = pBuffer - mov ecx, dword ptr [eax] // ecx = clipmin - mov edi, 24[esp] // edi = lSampleCount - mov eax, 32[esp] - push ebp - mov ebp, dword ptr [eax] // edx = clipmax -cliploop: - mov eax, dword ptr [esi] - add ebx, 2 - cdq - and edx, (1 << (16-MIXING_ATTENUATION)) - 1 - add esi, 4 - add eax, edx - cmp eax, MIXING_CLIPMIN - jl cliplow - cmp eax, MIXING_CLIPMAX - jg cliphigh - cmp eax, ecx - jl updatemin - cmp eax, ebp - jg updatemax -cliprecover: - sar eax, 16-MIXING_ATTENUATION - dec edi - mov word ptr [ebx-2], ax - jnz cliploop - mov edx, ebp - pop ebp - mov eax, 28[esp] - mov dword ptr [eax], ecx - mov eax, 32[esp] - mov dword ptr [eax], edx - mov eax, 24[esp] - pop edi - shl eax, 1 - pop esi - pop ebx - ret -updatemin: - mov ecx, eax - jmp cliprecover -updatemax: - mov ebp, eax - jmp cliprecover -cliplow: - mov ecx, MIXING_CLIPMIN - mov ebp, MIXING_CLIPMAX - mov eax, MIXING_CLIPMIN - jmp cliprecover -cliphigh: - mov ecx, MIXING_CLIPMIN - mov ebp, MIXING_CLIPMAX - mov eax, MIXING_CLIPMAX - jmp cliprecover - } -} -#else //MSC_VER //---GCCFIX: Asm replaced with C function // The C version was written by Rani Assaf <rani@magic.metawire.com>, I believe -DWORD MPPASMCALL X86_Convert32To16(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax) +DWORD Convert32To16(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LONG mins[2], LONG maxs[2]) { - int vumin = *lpMin, vumax = *lpMax; signed short *p = (signed short *)lp16; for (UINT i=0; i<lSampleCount; i++) { @@ -1770,323 +1675,78 @@ n = MIXING_CLIPMIN; else if (n > MIXING_CLIPMAX) n = MIXING_CLIPMAX; - if (n < vumin) - vumin = n; - else if (n > vumax) - vumax = n; + if (n < mins[i&1]) + mins[i&1]= n; + else if (n > maxs[i&1]) + maxs[i&1] = n; p[i] = n >> (16-MIXING_ATTENUATION); // 16-bit signed } - *lpMin = vumin; - *lpMax = vumax; return lSampleCount * 2; } -#endif //MSC_VER, else - -#ifdef MSC_VER -// Clip and convert to 24 bit -__declspec(naked) DWORD MPPASMCALL X86_Convert32To24(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax) -//----------------------------------------------------------------------------------------------------------------------------- -{ - _asm { - push ebx - push esi - push edi - mov ebx, 16[esp] // ebx = 8-bit buffer - mov esi, 20[esp] // esi = pBuffer - mov edi, 24[esp] // edi = lSampleCount - mov eax, 28[esp] - mov ecx, dword ptr [eax] // ecx = clipmin - mov eax, 32[esp] - push ebp - mov edx, dword ptr [eax] // edx = clipmax -cliploop: - mov eax, dword ptr [esi] - mov ebp, eax - sar ebp, 31 - and ebp, (1 << (8-MIXING_ATTENUATION)) - 1 - add eax, ebp - cmp eax, MIXING_CLIPMIN - jl cliplow - cmp eax, MIXING_CLIPMAX - jg cliphigh - cmp eax, ecx - jl updatemin - cmp eax, edx - jg updatemax -cliprecover: - add ebx, 3 - sar eax, 8-MIXING_ATTENUATION - add esi, 4 - mov word ptr [ebx-3], ax - shr eax, 16 - dec edi - mov byte ptr [ebx-1], al - jnz cliploop - pop ebp - mov eax, 28[esp] - mov dword ptr [eax], ecx - mov eax, 32[esp] - mov dword ptr [eax], edx - mov edx, 24[esp] - mov eax, edx - pop edi - shl eax, 1 - pop esi - add eax, edx - pop ebx - ret -updatemin: - mov ecx, eax - jmp cliprecover -updatemax: - mov edx, eax - jmp cliprecover -cliplow: - mov ecx, MIXING_CLIPMIN - mov edx, MIXING_CLIPMAX - mov eax, MIXING_CLIPMIN - jmp cliprecover -cliphigh: - mov ecx, MIXING_CLIPMIN - mov edx, MIXING_CLIPMAX - mov eax, MIXING_CLIPMAX - jmp cliprecover - } -} -#else //MSC_VER //---GCCFIX: Asm replaced with C function -DWORD MPPASMCALL X86_Convert32To24(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax) +// 24-bit might not work... +DWORD Convert32To24(LPVOID lp24, int *pBuffer, DWORD lSampleCount, LONG mins[2], LONG maxs[2]) { - UINT i ; - int vumin = *lpMin, vumax = *lpMax; - int n,p ; - unsigned char* buf = (unsigned char*)lp16 ; - - for ( i=0; i<lSampleCount; i++) - { - n = pBuffer[i]; - if (n < MIXING_CLIPMIN) - n = MIXING_CLIPMIN; - else if (n > MIXING_CLIPMAX) - n = MIXING_CLIPMAX; - if (n < vumin) - vumin = n; - else if (n > vumax) - vumax = n; - p = n >> (8-MIXING_ATTENUATION) ; // 24-bit signed -// buf[i*3] = p & 0xFF0000 ; //XXX -// buf[i*3+1] = p & 0x00FF00 ; -// buf[i*3+2] = p & 0x0000FF ; - buf[i*3] = (p & 0xFF0000) >> 16 ; - buf[i*3+1] = (p & 0x00FF00) >> 8 ; - buf[i*3+2] = p & 0x0000FF ; - } - *lpMin = vumin; - *lpMax = vumax; - return lSampleCount * 3; -} -#endif - -#ifdef MSC_VER -// Clip and convert to 32 bit -__declspec(naked) DWORD MPPASMCALL X86_Convert32To32(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax) -//----------------------------------------------------------------------------------------------------------------------------- -{ - _asm { - push ebx - push esi - push edi - mov ebx, 16[esp] // ebx = 32-bit buffer - mov esi, 20[esp] // esi = pBuffer - mov edi, 24[esp] // edi = lSampleCount - mov eax, 28[esp] - mov ecx, dword ptr [eax] // ecx = clipmin - mov eax, 32[esp] - mov edx, dword ptr [eax] // edx = clipmax -cliploop: - mov eax, dword ptr [esi] - add ebx, 4 - add esi, 4 - cmp eax, MIXING_CLIPMIN - jl cliplow - cmp eax, MIXING_CLIPMAX - jg cliphigh - cmp eax, ecx - jl updatemin - cmp eax, edx - jg updatemax -cliprecover: - shl eax, MIXING_ATTENUATION - dec edi - mov dword ptr [ebx-4], eax - jnz cliploop - mov eax, 28[esp] - mov dword ptr [eax], ecx - mov eax, 32[esp] - mov dword ptr [eax], edx - mov edx, 24[esp] - pop edi - mov eax, edx - pop esi - shl eax, 2 - pop ebx - ret -updatemin: - mov ecx, eax - jmp cliprecover -updatemax: - mov edx, eax - jmp cliprecover -cliplow: - mov ecx, MIXING_CLIPMIN - mov edx, MIXING_CLIPMAX - mov eax, MIXING_CLIPMIN - jmp cliprecover -cliphigh: - mov ecx, MIXING_CLIPMIN - mov edx, MIXING_CLIPMAX - mov eax, MIXING_CLIPMAX - jmp cliprecover - } -} -#else -//---GCCFIX: Asm replaced with C function -DWORD MPPASMCALL X86_Convert32To32(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax) -{ - UINT i ; - int vumin = *lpMin, vumax = *lpMax; - signed long *p = (signed long *)lp16; - - for ( i=0; i<lSampleCount; i++) + /* the inventor of 24bit anything should be shot */ + unsigned char *p = (unsigned char *)lp24; + for (UINT i=0; i<lSampleCount; i++) { int n = pBuffer[i]; if (n < MIXING_CLIPMIN) n = MIXING_CLIPMIN; else if (n > MIXING_CLIPMAX) n = MIXING_CLIPMAX; - if (n < vumin) - vumin = n; - else if (n > vumax) - vumax = n; - p[i] = n << MIXING_ATTENUATION; // 32-bit signed + if (n < mins[i&1]) + mins[i&1]= n; + else if (n > maxs[i&1]) + maxs[i&1] = n; + n = n >> (8-MIXING_ATTENUATION); // 24-bit signed + /* err, assume same endian */ + memcpy(p, &n, 3); + p += 3; } - *lpMin = vumin; - *lpMax = vumax; - return lSampleCount * 4; + return lSampleCount * 2; } -#endif - - -#ifdef MSC_VER -void MPPASMCALL X86_InitMixBuffer(int *pBuffer, UINT nSamples) -//------------------------------------------------------------ +//---GCCFIX: Asm replaced with C function +// 32-bit might not work... +DWORD Convert32To32(LPVOID lp32, int *pBuffer, DWORD lSampleCount, LONG mins[2], LONG maxs[2]) { - _asm { - mov ecx, nSamples - mov esi, pBuffer - xor eax, eax - mov edx, ecx - shr ecx, 2 - and edx, 3 - jz unroll4x -loop1x: - add esi, 4 - dec edx - mov dword ptr [esi-4], eax - jnz loop1x -unroll4x: - or ecx, ecx - jnz loop4x - jmp done -loop4x: - add esi, 16 - dec ecx - mov dword ptr [esi-16], eax - mov dword ptr [esi-12], eax - mov dword ptr [esi-8], eax - mov dword ptr [esi-4], eax - jnz loop4x -done:; + signed int *p = (signed int *)lp32; + for (UINT i=0; i<lSampleCount; i++) + { + int n = pBuffer[i]; + if (n < MIXING_CLIPMIN) + n = MIXING_CLIPMIN; + else if (n > MIXING_CLIPMAX) + n = MIXING_CLIPMAX; + if (n < mins[i&1]) + mins[i&1]= n; + else if (n > maxs[i&1]) + maxs[i&1] = n; + p[i] = (n >> MIXING_ATTENUATION); // 32-bit signed } + return lSampleCount * 2; } -#else //---GCCFIX: Asm replaced with C function // Will fill in later. -void MPPASMCALL X86_InitMixBuffer(int *pBuffer, UINT nSamples) +void InitMixBuffer(int *pBuffer, UINT nSamples) { memset(pBuffer, 0, nSamples * sizeof(int)); } -#endif - -#ifdef MSC_VER -__declspec(naked) void MPPASMCALL X86_InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples) -//------------------------------------------------------------------------------------------------------ +//---GCCFIX: Asm replaced with C function +void InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples) { - _asm { - push ebx - push ebp - push esi - push edi - mov ecx, 28[esp] // ecx = samplecount - mov esi, 20[esp] // esi = front buffer - mov edi, 24[esp] // edi = rear buffer - lea esi, [esi+ecx*4] // esi = &front[N] - lea edi, [edi+ecx*4] // edi = &rear[N] - lea ebx, [esi+ecx*4] // ebx = &front[N*2] -interleaveloop: - mov eax, dword ptr [esi-8] - mov edx, dword ptr [esi-4] - sub ebx, 16 - mov ebp, dword ptr [edi-8] - mov dword ptr [ebx], eax - mov dword ptr [ebx+4], edx - mov eax, dword ptr [edi-4] - sub esi, 8 - sub edi, 8 - dec ecx - mov dword ptr [ebx+8], ebp - mov dword ptr [ebx+12], eax - jnz interleaveloop - pop edi - pop esi - pop ebp - pop ebx - ret + DWORD i=0; + + pRearBuf[i] = pFrontBuf[1]; + for (i = 1; i < nSamples; i++) { + pRearBuf[i] = pFrontBuf[(i*2)+1]; + pFrontBuf[i] = pFrontBuf[i*2]; } } -#else //---GCCFIX: Asm replaced with C function -// Multichannel not supported. -void MPPASMCALL X86_InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples) -{ -} -#endif - - -#ifdef MSC_VER -VOID MPPASMCALL X86_MonoFromStereo(int *pMixBuf, UINT nSamples) -//------------------------------------------------------------- -{ - _asm { - mov ecx, nSamples - mov esi, pMixBuf - mov edi, esi -stloop: - mov eax, dword ptr [esi] - mov edx, dword ptr [esi+4] - add edi, 4 - add esi, 8 - add eax, edx - sar eax, 1 - dec ecx - mov dword ptr [edi-4], eax - jnz stloop - } -} -#else -//---GCCFIX: Asm replaced with C function -VOID MPPASMCALL X86_MonoFromStereo(int *pMixBuf, UINT nSamples) +VOID MonoFromStereo(int *pMixBuf, UINT nSamples) { UINT j; for(UINT i = 0; i < nSamples; i++) @@ -2095,89 +1755,11 @@ pMixBuf[i] = (pMixBuf[j] + pMixBuf[j + 1]) >> 1; } } -#endif -#define OFSDECAYSHIFT 8 -#define OFSDECAYMASK 0xFF - - -#ifdef MSC_VER -void MPPASMCALL X86_StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs) -//--------------------------------------------------------------------------------------- -{ - _asm { - mov edi, pBuffer - mov ecx, nSamples - mov eax, lpROfs - mov edx, lpLOfs - mov eax, [eax] - mov edx, [edx] - or ecx, ecx - jz fill_loop - mov ebx, eax - or ebx, edx - jz fill_loop -ofsloop: - mov ebx, eax - mov esi, edx - neg ebx - neg esi - sar ebx, 31 - sar esi, 31 - and ebx, OFSDECAYMASK - and esi, OFSDECAYMASK - add ebx, eax - add esi, edx - sar ebx, OFSDECAYSHIFT - sar esi, OFSDECAYSHIFT - sub eax, ebx - sub edx, esi - mov ebx, eax - or ebx, edx - jz fill_loop - add edi, 8 - dec ecx - mov [edi-8], eax - mov [edi-4], edx - jnz ofsloop -fill_loop: - mov ebx, ecx - and ebx, 3 - jz fill4x -fill1x: - mov [edi], eax - mov [edi+4], edx - add edi, 8 - dec ebx - jnz fill1x -fill4x: - shr ecx, 2 - or ecx, ecx - jz done -fill4xloop: - mov [edi], eax - mov [edi+4], edx - mov [edi+8], eax - mov [edi+12], edx - add edi, 8*4 - dec ecx - mov [edi-16], eax - mov [edi-12], edx - mov [edi-8], eax - mov [edi-4], edx - jnz fill4xloop -done: - mov esi, lpROfs - mov edi, lpLOfs - mov [esi], eax - mov [edi], edx - } -} -#else //---GCCFIX: Asm replaced with C function #define OFSDECAYSHIFT 8 #define OFSDECAYMASK 0xFF -void MPPASMCALL X86_StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs) +void StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs) //--------------------------------------------------------------------------------------------------------- { int rofs = *lpROfs; @@ -2185,7 +1767,7 @@ if ((!rofs) && (!lofs)) { - X86_InitMixBuffer(pBuffer, nSamples*2); + InitMixBuffer(pBuffer, nSamples*2); return; } for (UINT i=0; i<nSamples; i++) @@ -2200,53 +1782,9 @@ *lpROfs = rofs; *lpLOfs = lofs; } -#endif - -#ifdef MSC_VER -void MPPASMCALL X86_EndChannelOfs(MODCHANNEL *pChannel, int *pBuffer, UINT nSamples) -//---------------------------------------------------------------------------------- -{ - _asm { - mov esi, pChannel - mov edi, pBuffer - mov ecx, nSamples - mov eax, dword ptr [esi+MODCHANNEL.nROfs] - mov edx, dword ptr [esi+MODCHANNEL.nLOfs] - or ecx, ecx - jz brkloop -ofsloop: - mov ebx, eax - mov esi, edx - neg ebx - neg esi - sar ebx, 31 - sar esi, 31 - and ebx, OFSDECAYMASK - and esi, OFSDECAYMASK - add ebx, eax - add esi, edx - sar ebx, OFSDECAYSHIFT - sar esi, OFSDECAYSHIFT - sub eax, ebx - sub edx, esi - mov ebx, eax - add dword ptr [edi], eax - add dword ptr [edi+4], edx - or ebx, edx - jz brkloop - add edi, 8 - dec ecx - jnz ofsloop -brkloop: - mov esi, pChannel - mov dword ptr [esi+MODCHANNEL.nROfs], eax - mov dword ptr [esi+MODCHANNEL.nLOfs], edx - } -} -#else //---GCCFIX: Asm replaced with C function // Will fill in later. -void MPPASMCALL X86_EndChannelOfs(MODCHANNEL *pChannel, int *pBuffer, UINT nSamples) +void EndChannelOfs(MODCHANNEL *pChannel, int *pBuffer, UINT nSamples) { int rofs = pChannel->nROfs; int lofs = pChannel->nLOfs; @@ -2264,7 +1802,9 @@ pChannel->nROfs = rofs; pChannel->nLOfs = lofs; } -#endif + + + ////////////////////////////////////////////////////////////////////////////////// @@ -2276,72 +1816,11 @@ #define MIXING_LIMITMAX (0x08100000) #define MIXING_LIMITMIN (-MIXING_LIMITMAX) -#ifdef MSC_VER -__declspec(naked) UINT MPPASMCALL X86_AGC(int *pBuffer, UINT nSamples, UINT nAGC) -//------------------------------------------------------------------------------- -{ - __asm { - push ebx - push ebp - push esi - push edi - mov esi, 20[esp] // esi = pBuffer+i - mov ecx, 24[esp] // ecx = i - mov edi, 28[esp] // edi = AGC (0..256) -agcloop: - mov eax, dword ptr [esi] - imul edi - shrd eax, edx, AGC_PRECISION - add esi, 4 - cmp eax, MIXING_LIMITMIN - jl agcupdate - cmp eax, MIXING_LIMITMAX - jg agcupdate -agcrecover: - dec ecx - mov dword ptr [esi-4], eax - jnz agcloop - mov eax, edi - pop edi - pop esi - pop ebp - pop ebx - ret -agcupdate: - dec edi - jmp agcrecover - } -} - -#pragma warning (default:4100) -#else -// Version for GCC -UINT MPPASMCALL X86_AGC(int *pBuffer, UINT nSamples, UINT nAGC) -{ - int x; - - while(nSamples) - { - x = ((long long int)(*pBuffer) * nAGC) >> AGC_PRECISION; - - if((x < MIXING_LIMITMIN) || (x > MIXING_LIMITMAX)) - nAGC--; - - *pBuffer = x; - - pBuffer++; - nSamples--; - } - - return nAGC; -} -#endif - void CSoundFile::ProcessAGC(int count) //------------------------------------ { static DWORD gAGCRecoverCount = 0; - UINT agc = X86_AGC(MixSoundBuffer, count, gnAGC); + UINT agc = AGC(MixSoundBuffer, count, gnAGC); // Some kind custom law, so that the AGC stays quite stable, but slowly // goes back up if the sound level stays below a level inversely proportional // to the AGC level. (J'me comprends) @@ -2371,3 +1850,4 @@ } #endif // NO_AGC +