From f105e7225ab11bc68de3807373091905b4dc7543 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Wed, 6 Apr 2016 13:35:58 +0200 Subject: [PATCH] Unstubbed the portable C sound mixer --- Sources/Engine/Sound/SoundMixer.cpp | 117 +++++++++++++++++++++++++--- 1 file changed, 107 insertions(+), 10 deletions(-) diff --git a/Sources/Engine/Sound/SoundMixer.cpp b/Sources/Engine/Sound/SoundMixer.cpp index 8aa8a82..1a81457 100644 --- a/Sources/Engine/Sound/SoundMixer.cpp +++ b/Sources/Engine/Sound/SoundMixer.cpp @@ -44,7 +44,11 @@ static CSoundData *psd; // nasm on MacOS X is getting wrong addresses of external globals, so I have // to define them in the .asm file...lame. #ifdef __GNU_INLINE__ +#ifdef USE_PORTABLE_C +#define INASM +#else #define INASM extern +#endif #else #define INASM static static __int64 mmInvFactor = 0x00007FFF00007FFF; @@ -79,7 +83,7 @@ void ResetMixer( const SLONG *pslBuffer, const SLONG slBufferSize) // wipe destination mixer buffer // (Mac OS X uses this path because Apple's memset() is customized for each CPU they support and way faster than this inline asm. --ryan.) #if ((defined USE_PORTABLE_C) || (PLATFORM_MACOSX)) - memset(pvMixerBuffer, '\0', slMixerBufferSize * 8); + memset(pvMixerBuffer, 0, slMixerBufferSize * 8); #elif (defined __MSVC_INLINE__) __asm { @@ -154,12 +158,12 @@ void CopyMixerBuffer_mono( const SLONG slSrcOffset, void *pDstBuffer, const SLON #if (defined USE_PORTABLE_C) // (This is untested, currently. --ryan.) WORD *dest = (WORD *) pDstBuffer; - DWORD *src = (DWORD *) ( ((char *) pvMixerBuffer) + slSrcOffset ); + WORD *src = (WORD *) ( ((char *) pvMixerBuffer) + slSrcOffset ); SLONG max = slBytes / 4; for (SLONG i = 0; i < max; i++) { - *dest = *((WORD *) src); + *dest = *src; dest++; // move 16 bits. - src++; // move 32 bits. + src+=2; // move 32 bits. } #elif (defined __MSVC_INLINE__) @@ -207,7 +211,21 @@ static void ConvertMixerBuffer( const SLONG slBytes) if( slBytes<4) return; #if (defined USE_PORTABLE_C) - STUBBED("ConvertMixerBuffer"); + //STUBBED("ConvertMixerBuffer"); + SWORD *dest = (SWORD *) pvMixerBuffer; + SLONG *src = (SLONG *) pvMixerBuffer; + SLONG max = slBytes / 2; + int tmp; + for (SLONG i = 0; i < max; i++) { + tmp = *src; + if (tmp>32767) tmp=32767; + if (tmp<-32767) tmp=-32767; + *dest=tmp; + dest++; // move 16 bits. + src++; // move 32 bits. + } + + #elif (defined __MSVC_INLINE__) __asm { @@ -322,6 +340,9 @@ inline void MixMono( CSoundObject *pso) __int64 fixSoundBufferSize = ((__int64)slSoundBufferSize)<<16; mmSurroundFactor = (__int64)(SWORD)mmSurroundFactor; + SLONG slLeftVolume_ = slLeftVolume >> 16; + SLONG slRightVolume_ = slRightVolume >> 16; + // loop thru source buffer INDEX iCt = slMixerBufferSize; FOREVER @@ -355,10 +376,11 @@ inline void MixMono( CSoundObject *pso) slLastRightSample += ((slRightSample-slLastRightSample)*slRightFilter)>>15; // apply stereo volume to current sample - slLeftSample = (slLastLeftSample * slLeftVolume) >>15; - slRightSample = (slLastRightSample * slRightVolume)>>15; + slLeftSample = (slLastLeftSample * slLeftVolume_) >>15; + slRightSample = (slLastRightSample * slRightVolume_)>>15; - slRightSample = slRightSample ^ mmSurroundFactor; + slLeftSample ^= (SLONG)((mmSurroundFactor>> 0)&0xFFFFFFFF); + slRightSample ^= (SLONG)((mmSurroundFactor>>32)&0xFFFFFFFF); // mix in current sample slLeftSample += pslDstBuffer[0]; @@ -381,7 +403,7 @@ inline void MixMono( CSoundObject *pso) // advance to next sample fixLeftOfs += fixLeftStep; fixRightOfs += fixRightStep; - pslDstBuffer += 4; + pslDstBuffer += 2; iCt--; } @@ -536,7 +558,82 @@ inline void MixStereo( CSoundObject *pso) _pfSoundProfile.StartTimer(CSoundProfile::PTI_RAWMIXER); #if (defined USE_PORTABLE_C) - STUBBED("MixStereo"); + // initialize some local vars + SLONG slLeftSample, slRightSample, slNextSample; + SLONG *pslDstBuffer = (SLONG*)pvMixerBuffer; + fixLeftOfs = (__int64)(fLeftOfs * 65536.0); + fixRightOfs = (__int64)(fRightOfs * 65536.0); + __int64 fixLeftStep = (__int64)(fLeftStep * 65536.0); + __int64 fixRightStep = (__int64)(fRightStep * 65536.0); + __int64 fixSoundBufferSize = ((__int64)slSoundBufferSize)<<16; + mmSurroundFactor = (__int64)(SWORD)mmSurroundFactor; + + SLONG slLeftVolume_ = slLeftVolume >> 16; + SLONG slRightVolume_ = slRightVolume >> 16; + + // loop thru source buffer + INDEX iCt = slMixerBufferSize; + FOREVER + { + // if left channel source sample came to end of sample buffer + if( fixLeftOfs >= fixSoundBufferSize) { + fixLeftOfs -= fixSoundBufferSize; + // if has no loop, end it + bEndOfSound = bNotLoop; + } + // if right channel source sample came to end of sample buffer + if( fixRightOfs >= fixSoundBufferSize) { + fixRightOfs -= fixSoundBufferSize; + // if has no loop, end it + bEndOfSound = bNotLoop; + } + // end of buffer? + if( iCt<=0 || bEndOfSound) break; + + // fetch one lineary interpolated sample on left channel + slLeftSample = pswSrcBuffer[(fixLeftOfs>>15)+0]; + slNextSample = pswSrcBuffer[(fixLeftOfs>>15)+2]; + slLeftSample = (slLeftSample*(65535-(fixLeftOfs&65535)) + slNextSample*(fixLeftOfs&65535)) >>16; + // fetch one lineary interpolated sample on right channel + slRightSample = pswSrcBuffer[(fixRightOfs>>15)+0]; + slNextSample = pswSrcBuffer[(fixRightOfs>>15)+2]; + slRightSample = (slRightSample*(65535-(fixRightOfs&65535)) + slNextSample*(fixRightOfs&65535)) >>16; + + // filter samples + slLastLeftSample += ((slLeftSample -slLastLeftSample) *slLeftFilter) >>15; + slLastRightSample += ((slRightSample-slLastRightSample)*slRightFilter)>>15; + + // apply stereo volume to current sample + slLeftSample = (slLastLeftSample * slLeftVolume_) >>15; + slRightSample = (slLastRightSample * slRightVolume_)>>15; + + slLeftSample ^= (SLONG)((mmSurroundFactor>> 0)&0xFFFFFFFF); + slRightSample ^= (SLONG)((mmSurroundFactor>>32)&0xFFFFFFFF); + + // mix in current sample + slLeftSample += pslDstBuffer[0]; + slRightSample += pslDstBuffer[1]; + // upper clamp + if( slLeftSample > MAX_SWORD) slLeftSample = MAX_SWORD; + if( slRightSample > MAX_SWORD) slRightSample = MAX_SWORD; + // lower clamp + if( slLeftSample < MIN_SWORD) slLeftSample = MIN_SWORD; + if( slRightSample < MIN_SWORD) slRightSample = MIN_SWORD; + + // store samples (both channels) + pslDstBuffer[0] = slLeftSample; + pslDstBuffer[1] = slRightSample; + + // modify volume ` + slLeftVolume += (SWORD)((mmVolumeGain>> 0)&0xFFFF); + slRightVolume += (SWORD)((mmVolumeGain>>16)&0xFFFF); + + // advance to next sample + fixLeftOfs += fixLeftStep; + fixRightOfs += fixRightStep; + pslDstBuffer += 2; + iCt--; + } #elif (defined __MSVC_INLINE__) __asm {