1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
/*
* DMOUtils.cpp
* ------------
* Purpose: Utility functions shared by DMO plugins
* Notes : none
* Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#include "stdafx.h"
#include "DMOUtils.h"
#ifndef NO_PLUGINS
#include "../../Sndfile.h"
#endif // !NO_PLUGINS
OPENMPT_NAMESPACE_BEGIN
#ifndef NO_PLUGINS
namespace DMO
{
// Computes (log2(x) + 1) * 2 ^ (shiftL - shiftR) (x = -2^31...2^31)
float logGain(float x, int32 shiftL, int32 shiftR)
{
uint32 intSample;
if(x <= static_cast<float>(int32_min) || x > static_cast<float>(int32_max))
intSample = static_cast<uint32>(int32_min);
else
intSample = static_cast<uint32>(static_cast<int32>(x));
const uint32 sign = intSample & 0x80000000;
if(sign)
intSample = (~intSample) + 1;
// Multiply until overflow (or edge shift factor is reached)
while(shiftL > 0 && intSample < 0x80000000)
{
intSample += intSample;
shiftL--;
}
// Unsign clipped sample
if(intSample >= 0x80000000)
{
intSample &= 0x7FFFFFFF;
shiftL++;
}
intSample = (shiftL << (31 - shiftR)) | (intSample >> shiftR);
if(sign)
intSample = ~intSample | sign;
return static_cast<float>(static_cast<int32>(intSample));
}
} // namespace DMO
#else
MPT_MSVC_WORKAROUND_LNK4221(DMOUtils)
#endif // !NO_PLUGINS
OPENMPT_NAMESPACE_END
|