SampleNormalize.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * SampleNormalize.h
  3. * -----------------
  4. * Purpose: Functions for normalizing samples.
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #pragma once
  10. #include "openmpt/all/BuildSettings.hpp"
  11. OPENMPT_NAMESPACE_BEGIN
  12. namespace SC
  13. { // SC = _S_ample_C_onversion
  14. template <typename Tsample>
  15. struct Normalize;
  16. template <>
  17. struct Normalize<int32>
  18. {
  19. typedef int32 input_t;
  20. typedef int32 output_t;
  21. typedef uint32 peak_t;
  22. uint32 maxVal;
  23. MPT_FORCEINLINE Normalize()
  24. : maxVal(0) {}
  25. MPT_FORCEINLINE void FindMax(input_t val)
  26. {
  27. if(val < 0)
  28. {
  29. if(val == std::numeric_limits<int32>::min())
  30. {
  31. maxVal = static_cast<uint32>(-static_cast<int64>(std::numeric_limits<int32>::min()));
  32. return;
  33. }
  34. val = -val;
  35. }
  36. if(static_cast<uint32>(val) > maxVal)
  37. {
  38. maxVal = static_cast<uint32>(val);
  39. }
  40. }
  41. MPT_FORCEINLINE bool IsSilent() const
  42. {
  43. return maxVal == 0;
  44. }
  45. MPT_FORCEINLINE output_t operator()(input_t val)
  46. {
  47. return Util::muldivrfloor(val, static_cast<uint32>(1) << 31, maxVal);
  48. }
  49. MPT_FORCEINLINE peak_t GetSrcPeak() const
  50. {
  51. return maxVal;
  52. }
  53. };
  54. template <>
  55. struct Normalize<float32>
  56. {
  57. typedef float32 input_t;
  58. typedef float32 output_t;
  59. typedef float32 peak_t;
  60. float maxVal;
  61. float maxValInv;
  62. MPT_FORCEINLINE Normalize()
  63. : maxVal(0.0f), maxValInv(1.0f) {}
  64. MPT_FORCEINLINE void FindMax(input_t val)
  65. {
  66. float absval = std::fabs(val);
  67. if(absval > maxVal)
  68. {
  69. maxVal = absval;
  70. }
  71. }
  72. MPT_FORCEINLINE bool IsSilent()
  73. {
  74. if(maxVal == 0.0f)
  75. {
  76. maxValInv = 1.0f;
  77. return true;
  78. } else
  79. {
  80. maxValInv = 1.0f / maxVal;
  81. return false;
  82. }
  83. }
  84. MPT_FORCEINLINE output_t operator()(input_t val)
  85. {
  86. return val * maxValInv;
  87. }
  88. MPT_FORCEINLINE peak_t GetSrcPeak() const
  89. {
  90. return maxVal;
  91. }
  92. };
  93. template <>
  94. struct Normalize<float64>
  95. {
  96. typedef float64 input_t;
  97. typedef float64 output_t;
  98. typedef float64 peak_t;
  99. double maxVal;
  100. double maxValInv;
  101. MPT_FORCEINLINE Normalize()
  102. : maxVal(0.0), maxValInv(1.0) {}
  103. MPT_FORCEINLINE void FindMax(input_t val)
  104. {
  105. double absval = std::fabs(val);
  106. if(absval > maxVal)
  107. {
  108. maxVal = absval;
  109. }
  110. }
  111. MPT_FORCEINLINE bool IsSilent()
  112. {
  113. if(maxVal == 0.0)
  114. {
  115. maxValInv = 1.0;
  116. return true;
  117. } else
  118. {
  119. maxValInv = 1.0 / maxVal;
  120. return false;
  121. }
  122. }
  123. MPT_FORCEINLINE output_t operator()(input_t val)
  124. {
  125. return val * maxValInv;
  126. }
  127. MPT_FORCEINLINE peak_t GetSrcPeak() const
  128. {
  129. return maxVal;
  130. }
  131. };
  132. // Reads sample data with Func1, then normalizes the sample data, and then converts it with Func2.
  133. // Func1::output_t and Func2::input_t must be identical.
  134. // Func1 can also be the identity decode (DecodeIdentity<T>).
  135. // Func2 can also be the identity conversion (Convert<T,T>).
  136. template <typename Func2, typename Func1>
  137. struct NormalizationChain
  138. {
  139. typedef typename Func1::input_t input_t;
  140. typedef typename Func1::output_t normalize_t;
  141. typedef typename Normalize<normalize_t>::peak_t peak_t;
  142. typedef typename Func2::output_t output_t;
  143. static constexpr std::size_t input_inc = Func1::input_inc;
  144. Func1 func1;
  145. Normalize<normalize_t> normalize;
  146. Func2 func2;
  147. MPT_FORCEINLINE void FindMax(const input_t *inBuf)
  148. {
  149. normalize.FindMax(func1(inBuf));
  150. }
  151. MPT_FORCEINLINE bool IsSilent()
  152. {
  153. return normalize.IsSilent();
  154. }
  155. MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
  156. {
  157. return func2(normalize(func1(inBuf)));
  158. }
  159. MPT_FORCEINLINE peak_t GetSrcPeak() const
  160. {
  161. return normalize.GetSrcPeak();
  162. }
  163. MPT_FORCEINLINE NormalizationChain(Func2 f2 = Func2(), Func1 f1 = Func1())
  164. : func1(f1)
  165. , func2(f2)
  166. {
  167. return;
  168. }
  169. };
  170. } // namespace SC
  171. OPENMPT_NAMESPACE_END