DMOUtils.cpp 1.2 KB

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