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.

134 lines
3.9KB

  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. #ifndef STREAMS_COMPRESSOR_H_
  29. #define STREAMS_COMPRESSOR_H_
  30. #include "stmlib/stmlib.h"
  31. #include <cstdio>
  32. #include "streams/gain.h"
  33. #include "streams/resources.h"
  34. namespace streams {
  35. class Compressor {
  36. public:
  37. Compressor() { }
  38. ~Compressor() { }
  39. void Init();
  40. void Process(
  41. int16_t audio,
  42. int16_t excite,
  43. uint16_t* gain,
  44. uint16_t* frequency);
  45. void Configure(bool alternate, int32_t* parameters, int32_t* globals) {
  46. uint16_t attack_time;
  47. uint16_t decay_time;
  48. uint16_t amount;
  49. uint16_t threshold;
  50. if (globals) {
  51. attack_time = globals[0] * (128 + 128 + 99) >> 16; // 1ms to 500ms
  52. decay_time = 128 + 99 + (globals[2] >> 8); // 50ms to 5000ms
  53. threshold = globals[1];
  54. amount = globals[3];
  55. } else {
  56. attack_time = !alternate ? 1 : 40; // 0.2ms or 2ms;
  57. decay_time = !alternate ? 279 : 236; // 150ms or 70ms;
  58. threshold = parameters[0];
  59. amount = parameters[1];
  60. }
  61. attack_coefficient_ = lut_lp_coefficients[attack_time];
  62. decay_coefficient_ = lut_lp_coefficients[decay_time];
  63. soft_knee_ = alternate;
  64. threshold_ = (-1280 + 5 * (threshold >> 8)) << 8;
  65. if (amount < 32768) {
  66. // Compression with no makeup gain.
  67. ratio_ = lut_compressor_ratio[(32767 - amount) >> 7];
  68. makeup_gain_ = 0;
  69. } else {
  70. // Adaptive compression with makeup gain.
  71. amount -= 32768;
  72. int32_t max_gain, knee_gain;
  73. max_gain = kMaxExponentialGain;
  74. makeup_gain_ = amount * (max_gain >> 8) >> 7;
  75. knee_gain = threshold_+ makeup_gain_;
  76. if (knee_gain >= 0) {
  77. makeup_gain_ = -threshold_;
  78. knee_gain = 0;
  79. }
  80. if (knee_gain > -4096) {
  81. // So intense! Brickwall limiter mode. In this case, we use an
  82. // instant attack to tame transients as soon as they appear.
  83. ratio_ = 0;
  84. attack_coefficient_ = -1;
  85. } else {
  86. ratio_ = knee_gain / (threshold_ >> 8);
  87. }
  88. }
  89. }
  90. inline int32_t gain_reduction() const { return gain_reduction_; }
  91. private:
  92. static int32_t Log2(int32_t value);
  93. static int32_t Exp2(int32_t value);
  94. static int32_t Compress(
  95. int32_t squared_level,
  96. int32_t threshold,
  97. int32_t ratio,
  98. bool soft_knee);
  99. int32_t ratio_; // Reciprocal of the ratio, 8:8
  100. int32_t threshold_;
  101. int32_t makeup_gain_;
  102. bool soft_knee_;
  103. int64_t attack_coefficient_;
  104. int64_t decay_coefficient_;
  105. int64_t detector_;
  106. int64_t sidechain_signal_detector_;
  107. int32_t gain_reduction_;
  108. DISALLOW_COPY_AND_ASSIGN(Compressor);
  109. };
  110. } // namespace streams
  111. #endif // STREAMS_COMPRESSOR_H_