From: <man...@us...> - 2013-06-12 21:29:10
|
Revision: 2347 http://sourceforge.net/p/modplug/code/2347 Author: manxorist Date: 2013-06-12 21:29:03 +0000 (Wed, 12 Jun 2013) Log Message: ----------- [Fix] Avoid tiny int->float->int roundtrip rounding errors by converting with power-of-2 factors instead of power-of-2 minus 1. Modified Paths: -------------- trunk/OpenMPT/sounddsp/EQ.cpp trunk/OpenMPT/soundlib/Fastmix.cpp trunk/OpenMPT/soundlib/Snd_defs.h trunk/OpenMPT/soundlib/SoundFilePlayConfig.cpp Modified: trunk/OpenMPT/sounddsp/EQ.cpp =================================================================== --- trunk/OpenMPT/sounddsp/EQ.cpp 2013-06-12 20:43:11 UTC (rev 2346) +++ trunk/OpenMPT/sounddsp/EQ.cpp 2013-06-12 21:29:03 UTC (rev 2347) @@ -316,12 +316,12 @@ void CEQ::ProcessMono(int *pbuffer, float *MixFloatBuffer, UINT nCount) //--------------------------------------------------------------------- { - MonoMixToFloat(pbuffer, MixFloatBuffer, nCount, 1.0f/static_cast<float>(MIXING_CLIPMAX)); + MonoMixToFloat(pbuffer, MixFloatBuffer, nCount, 1.0f/MIXING_SCALEF); for (UINT b=0; b<MAX_EQ_BANDS; b++) { if ((gEQ[b].bEnable) && (gEQ[b].Gain != 1.0f)) EQFilter(&gEQ[b], MixFloatBuffer, nCount); } - FloatToMonoMix(MixFloatBuffer, pbuffer, nCount, static_cast<float>(MIXING_CLIPMAX)); + FloatToMonoMix(MixFloatBuffer, pbuffer, nCount, MIXING_SCALEF); } @@ -334,7 +334,7 @@ if(GetProcSupport() & PROCSUPPORT_SSE) { int sse_state, sse_eqstate; - MonoMixToFloat(pbuffer, MixFloatBuffer, nCount*2, 1.0f/static_cast<float>(MIXING_CLIPMAX)); + MonoMixToFloat(pbuffer, MixFloatBuffer, nCount*2, 1.0f/MIXING_SCALEF); _asm stmxcsr sse_state; sse_eqstate = sse_state | 0xFF80; // set flush-to-zero, denormals-are-zero, round-to-zero, mask all exception, leave flags alone @@ -346,7 +346,7 @@ } _asm ldmxcsr sse_state; - FloatToMonoMix(MixFloatBuffer, pbuffer, nCount*2, static_cast<float>(MIXING_CLIPMAX)); + FloatToMonoMix(MixFloatBuffer, pbuffer, nCount*2, MIXING_SCALEF); } else @@ -356,7 +356,7 @@ if(GetProcSupport() & PROCSUPPORT_AMD_3DNOW) { - MonoMixToFloat(pbuffer, MixFloatBuffer, nCount*2, 1.0f/static_cast<float>(MIXING_CLIPMAX)); + MonoMixToFloat(pbuffer, MixFloatBuffer, nCount*2, 1.0f/MIXING_SCALEF); for (UINT b=0; b<MAX_EQ_BANDS; b++) { @@ -365,14 +365,14 @@ AMD_StereoEQ(&gEQ[b], &gEQ[b+MAX_EQ_BANDS], MixFloatBuffer, nCount); } - FloatToMonoMix(MixFloatBuffer, pbuffer, nCount*2, static_cast<float>(MIXING_CLIPMAX)); + FloatToMonoMix(MixFloatBuffer, pbuffer, nCount*2, MIXING_SCALEF); } else #endif // ENABLE_X86_AMD { - StereoMixToFloat(pbuffer, MixFloatBuffer, MixFloatBuffer+MIXBUFFERSIZE, nCount, 1.0f/static_cast<float>(MIXING_CLIPMAX)); + StereoMixToFloat(pbuffer, MixFloatBuffer, MixFloatBuffer+MIXBUFFERSIZE, nCount, 1.0f/MIXING_SCALEF); for (UINT bl=0; bl<MAX_EQ_BANDS; bl++) { @@ -383,7 +383,7 @@ if ((gEQ[br].bEnable) && (gEQ[br].Gain != 1.0f)) EQFilter(&gEQ[br], MixFloatBuffer+MIXBUFFERSIZE, nCount); } - FloatToStereoMix(MixFloatBuffer, MixFloatBuffer+MIXBUFFERSIZE, pbuffer, nCount, static_cast<float>(MIXING_CLIPMAX)); + FloatToStereoMix(MixFloatBuffer, MixFloatBuffer+MIXBUFFERSIZE, pbuffer, nCount, MIXING_SCALEF); } } Modified: trunk/OpenMPT/soundlib/Fastmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Fastmix.cpp 2013-06-12 20:43:11 UTC (rev 2346) +++ trunk/OpenMPT/soundlib/Fastmix.cpp 2013-06-12 21:29:03 UTC (rev 2347) @@ -1997,7 +1997,7 @@ void Convert32ToInterleaved(float *dest, const int *mixbuffer, std::size_t count) //------------------------------------------------------------------------------- { - const float factor = (1.0f/(float)MIXING_CLIPMAX); + const float factor = (1.0f/MIXING_SCALEF); for(std::size_t i=0; i<count; i++) { dest[i] = mixbuffer[i] * factor; @@ -2007,7 +2007,7 @@ void Convert32ToNonInterleaved(float * const * const buffers, const int *mixbuffer, std::size_t channels, std::size_t count) //-------------------------------------------------------------------------------------------------------------------------- { - const float factor = (1.0f/(float)MIXING_CLIPMAX); + const float factor = (1.0f/MIXING_SCALEF); for(std::size_t i = 0; i < count; ++i) { for(std::size_t channel = 0; channel < channels; ++channel) Modified: trunk/OpenMPT/soundlib/Snd_defs.h =================================================================== --- trunk/OpenMPT/soundlib/Snd_defs.h 2013-06-12 20:43:11 UTC (rev 2346) +++ trunk/OpenMPT/soundlib/Snd_defs.h 2013-06-12 21:29:03 UTC (rev 2347) @@ -310,7 +310,9 @@ MIXING_CLIPMIN = -(MIXING_CLIPMAX), }; +const float MIXING_SCALEF = static_cast<float>(1 << (32 - MIXING_ATTENUATION - 1)); + #define MAX_GLOBAL_VOLUME 256u // Resampling modes Modified: trunk/OpenMPT/soundlib/SoundFilePlayConfig.cpp =================================================================== --- trunk/OpenMPT/soundlib/SoundFilePlayConfig.cpp 2013-06-12 20:43:11 UTC (rev 2346) +++ trunk/OpenMPT/soundlib/SoundFilePlayConfig.cpp 2013-06-12 21:29:03 UTC (rev 2347) @@ -66,8 +66,8 @@ case mixLevels_117RC2: setVSTiAttenuation(2.0f); - setIntToFloat(1.0f/static_cast<float>(MIXING_CLIPMAX)); - setFloatToInt(static_cast<float>(MIXING_CLIPMAX)); + setIntToFloat(1.0f/MIXING_SCALEF); + setFloatToInt(MIXING_SCALEF); setGlobalVolumeAppliesToMaster(true); setUseGlobalPreAmp(true); setForcePanningMode(dontForcePanningMode); @@ -84,8 +84,8 @@ default: case mixLevels_117RC3: setVSTiAttenuation(1.0f); - setIntToFloat(1.0f/static_cast<float>(MIXING_CLIPMAX)); - setFloatToInt(static_cast<float>(MIXING_CLIPMAX)); + setIntToFloat(1.0f/MIXING_SCALEF); + setFloatToInt(MIXING_SCALEF); setGlobalVolumeAppliesToMaster(true); setUseGlobalPreAmp(false); setForcePanningMode(forceSoftPanning); @@ -101,8 +101,8 @@ // Sample attenuation is the same as in Schism Tracker (more attenuation than with RC3, thus VSTi attenuation is also higher). case mixLevels_compatible: setVSTiAttenuation(0.75f); - setIntToFloat(1.0f/static_cast<float>(MIXING_CLIPMAX)); - setFloatToInt(static_cast<float>(MIXING_CLIPMAX)); + setIntToFloat(1.0f/MIXING_SCALEF); + setFloatToInt(MIXING_SCALEF); setGlobalVolumeAppliesToMaster(true); setUseGlobalPreAmp(false); setForcePanningMode(forceNoSoftPanning); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |