Unstubbed the portable C sound mixer

This commit is contained in:
ptitSeb 2016-04-06 13:35:58 +02:00
parent 4e9dee7763
commit f105e7225a

View File

@ -44,7 +44,11 @@ static CSoundData *psd;
// nasm on MacOS X is getting wrong addresses of external globals, so I have // nasm on MacOS X is getting wrong addresses of external globals, so I have
// to define them in the .asm file...lame. // to define them in the .asm file...lame.
#ifdef __GNU_INLINE__ #ifdef __GNU_INLINE__
#ifdef USE_PORTABLE_C
#define INASM
#else
#define INASM extern #define INASM extern
#endif
#else #else
#define INASM static #define INASM static
static __int64 mmInvFactor = 0x00007FFF00007FFF; static __int64 mmInvFactor = 0x00007FFF00007FFF;
@ -79,7 +83,7 @@ void ResetMixer( const SLONG *pslBuffer, const SLONG slBufferSize)
// wipe destination mixer buffer // 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.) // (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)) #if ((defined USE_PORTABLE_C) || (PLATFORM_MACOSX))
memset(pvMixerBuffer, '\0', slMixerBufferSize * 8); memset(pvMixerBuffer, 0, slMixerBufferSize * 8);
#elif (defined __MSVC_INLINE__) #elif (defined __MSVC_INLINE__)
__asm { __asm {
@ -154,12 +158,12 @@ void CopyMixerBuffer_mono( const SLONG slSrcOffset, void *pDstBuffer, const SLON
#if (defined USE_PORTABLE_C) #if (defined USE_PORTABLE_C)
// (This is untested, currently. --ryan.) // (This is untested, currently. --ryan.)
WORD *dest = (WORD *) pDstBuffer; WORD *dest = (WORD *) pDstBuffer;
DWORD *src = (DWORD *) ( ((char *) pvMixerBuffer) + slSrcOffset ); WORD *src = (WORD *) ( ((char *) pvMixerBuffer) + slSrcOffset );
SLONG max = slBytes / 4; SLONG max = slBytes / 4;
for (SLONG i = 0; i < max; i++) { for (SLONG i = 0; i < max; i++) {
*dest = *((WORD *) src); *dest = *src;
dest++; // move 16 bits. dest++; // move 16 bits.
src++; // move 32 bits. src+=2; // move 32 bits.
} }
#elif (defined __MSVC_INLINE__) #elif (defined __MSVC_INLINE__)
@ -207,7 +211,21 @@ static void ConvertMixerBuffer( const SLONG slBytes)
if( slBytes<4) return; if( slBytes<4) return;
#if (defined USE_PORTABLE_C) #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__) #elif (defined __MSVC_INLINE__)
__asm { __asm {
@ -322,6 +340,9 @@ inline void MixMono( CSoundObject *pso)
__int64 fixSoundBufferSize = ((__int64)slSoundBufferSize)<<16; __int64 fixSoundBufferSize = ((__int64)slSoundBufferSize)<<16;
mmSurroundFactor = (__int64)(SWORD)mmSurroundFactor; mmSurroundFactor = (__int64)(SWORD)mmSurroundFactor;
SLONG slLeftVolume_ = slLeftVolume >> 16;
SLONG slRightVolume_ = slRightVolume >> 16;
// loop thru source buffer // loop thru source buffer
INDEX iCt = slMixerBufferSize; INDEX iCt = slMixerBufferSize;
FOREVER FOREVER
@ -355,10 +376,11 @@ inline void MixMono( CSoundObject *pso)
slLastRightSample += ((slRightSample-slLastRightSample)*slRightFilter)>>15; slLastRightSample += ((slRightSample-slLastRightSample)*slRightFilter)>>15;
// apply stereo volume to current sample // apply stereo volume to current sample
slLeftSample = (slLastLeftSample * slLeftVolume) >>15; slLeftSample = (slLastLeftSample * slLeftVolume_) >>15;
slRightSample = (slLastRightSample * slRightVolume)>>15; slRightSample = (slLastRightSample * slRightVolume_)>>15;
slRightSample = slRightSample ^ mmSurroundFactor; slLeftSample ^= (SLONG)((mmSurroundFactor>> 0)&0xFFFFFFFF);
slRightSample ^= (SLONG)((mmSurroundFactor>>32)&0xFFFFFFFF);
// mix in current sample // mix in current sample
slLeftSample += pslDstBuffer[0]; slLeftSample += pslDstBuffer[0];
@ -381,7 +403,7 @@ inline void MixMono( CSoundObject *pso)
// advance to next sample // advance to next sample
fixLeftOfs += fixLeftStep; fixLeftOfs += fixLeftStep;
fixRightOfs += fixRightStep; fixRightOfs += fixRightStep;
pslDstBuffer += 4; pslDstBuffer += 2;
iCt--; iCt--;
} }
@ -536,7 +558,82 @@ inline void MixStereo( CSoundObject *pso)
_pfSoundProfile.StartTimer(CSoundProfile::PTI_RAWMIXER); _pfSoundProfile.StartTimer(CSoundProfile::PTI_RAWMIXER);
#if (defined USE_PORTABLE_C) #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__) #elif (defined __MSVC_INLINE__)
__asm { __asm {