You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
4.4KB

  1. // Copyright 2014 Olivier Gillet.
  2. //
  3. // Author: Olivier Gillet (ol.gillet@gmail.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. // See http://creativecommons.org/licenses/MIT/ for more information.
  24. //
  25. // -----------------------------------------------------------------------------
  26. //
  27. // Compressor.
  28. #include "streams/compressor.h"
  29. // #include <cmath>
  30. #include "stmlib/utils/dsp.h"
  31. namespace streams {
  32. using namespace stmlib;
  33. // 256 LSB <=> 1.55dB
  34. const int32_t kGainConstant = 1 / (1.55 / 6.0 * 65536.0 / 256.0) * 65536;
  35. void Compressor::Init() {
  36. detector_ = 0;
  37. }
  38. /* static */
  39. int32_t Compressor::Log2(int32_t value) {
  40. if (value <= 0) {
  41. value = 1;
  42. }
  43. int32_t log_value = 0;
  44. while (value >= 512) {
  45. value >>= 1;
  46. log_value += 65536;
  47. }
  48. while (value < 256) {
  49. value <<= 1;
  50. log_value -= 65536;
  51. }
  52. // Value is between 256 and 512, we can use the LUT.
  53. return log_value + lut_log2[value - 256];
  54. }
  55. /* static */
  56. int32_t Compressor::Exp2(int32_t value) {
  57. int32_t num_shifts = 0;
  58. while (value >= 65536) {
  59. ++num_shifts;
  60. value -= 65536;
  61. }
  62. while (value < 0) {
  63. --num_shifts;
  64. value += 65536;
  65. }
  66. // Value is between 0 and 65535, we can use the LUT.
  67. int32_t a = lut_exp2[value >> 8];
  68. int32_t b = lut_exp2[(value >> 8) + 1];
  69. int32_t mantissa = a + ((b - a) * (value & 0xff) >> 8);
  70. return num_shifts >= 0 ? mantissa << num_shifts : mantissa >> -num_shifts;
  71. }
  72. /* static */
  73. int32_t Compressor::Compress(
  74. int32_t squared_level,
  75. int32_t threshold,
  76. int32_t ratio,
  77. bool soft_knee) {
  78. int32_t level = (Log2(squared_level) >> 1) - 15 * 65536; // 15-bit peak
  79. int32_t position = level - threshold;
  80. if (position < 0) {
  81. return 0;
  82. }
  83. int32_t attenuation = position - (position * ratio >> 8);
  84. if (attenuation < 65535 && soft_knee) {
  85. int32_t a = lut_soft_knee[attenuation >> 8];
  86. int32_t b = lut_soft_knee[(attenuation >> 8) + 1];
  87. int32_t soft_knee = a + ((b - a) * (attenuation & 0xff) >> 8);
  88. attenuation += \
  89. (soft_knee - attenuation) * ((65535 - attenuation) >> 1) >> 15;
  90. }
  91. return -attenuation;
  92. }
  93. void Compressor::Process(
  94. int16_t audio,
  95. int16_t excite,
  96. uint16_t* gain,
  97. uint16_t* frequency) {
  98. int32_t energy;
  99. int64_t error;
  100. // Detect the RMS level on the EXCITE input.
  101. energy = excite;
  102. energy *= energy;
  103. error = energy - sidechain_signal_detector_;
  104. if (error > 0) {
  105. sidechain_signal_detector_ += error;
  106. } else {
  107. // Decay time: 5s.
  108. sidechain_signal_detector_ += error * 14174 >> 31;
  109. }
  110. // If there is no signal on the "excite" input, disable sidechain and
  111. // compress by metering input.
  112. if (sidechain_signal_detector_ < (1024 * 1024)) {
  113. energy = audio;
  114. energy *= energy;
  115. }
  116. // Detect the RMS level on the EXCITE or AUDIO input - whichever active.
  117. error = energy - detector_;
  118. if (error > 0) {
  119. if (attack_coefficient_ == -1) {
  120. detector_ += error;
  121. } else {
  122. detector_ += error * attack_coefficient_ >> 31;
  123. }
  124. } else {
  125. detector_ += error * decay_coefficient_ >> 31;
  126. }
  127. int32_t g = Compress(detector_, threshold_, ratio_, soft_knee_);
  128. gain_reduction_ = g >> 3;
  129. g = kUnityGain + ((g + makeup_gain_) * kGainConstant >> 16);
  130. if (g > 65535) {
  131. g = 65535;
  132. }
  133. *gain = g;
  134. // float ogain = powf(10.0f, 1.55f / 20.0f * (g - kUnityGain) / 256.0f);
  135. // printf("%f %f\n", gain_reduction_ / 32768.0 * 24, 20 * logf(ogain) / logf(10.0f));
  136. *frequency = 65535;
  137. }
  138. } // namespace streams