Compressor.cpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include "Compressor.h"
  2. #include <cstdlib> // for abs
  3. using namespace bell;
  4. float log2f_approx(float X) {
  5. float Y, F;
  6. int E;
  7. F = frexpf(fabsf(X), &E);
  8. Y = 1.23149591368684f;
  9. Y *= F;
  10. Y += -4.11852516267426f;
  11. Y *= F;
  12. Y += 6.02197014179219f;
  13. Y *= F;
  14. Y += -3.13396450166353f;
  15. Y += E;
  16. return (Y);
  17. }
  18. Compressor::Compressor() {}
  19. void Compressor::sumChannels(std::unique_ptr<StreamInfo>& data) {
  20. tmp.resize(data->numSamples);
  21. for (int i = 0; i < data->numSamples; i++) {
  22. float sum = 0.0f;
  23. for (auto& channel : channels) {
  24. sum += data->data[channel][i];
  25. }
  26. tmp[i] = sum;
  27. }
  28. }
  29. void Compressor::calLoudness() {
  30. for (auto& value : tmp) {
  31. value = 20 * log10f_fast(std::abs(value) + 1.0e-9f);
  32. if (value >= lastLoudness) {
  33. value = attack * lastLoudness + (1.0 - attack) * value;
  34. } else {
  35. value = release * lastLoudness + (1.0 - release) * value;
  36. }
  37. lastLoudness = value;
  38. }
  39. }
  40. void Compressor::calGain() {
  41. for (auto& value : tmp) {
  42. if (value > threshold) {
  43. value = -(value - threshold) * (factor - 1.0) / factor;
  44. } else {
  45. value = 0.0f;
  46. }
  47. value += makeupGain;
  48. // convert to linear
  49. value = pow10f(value / 20.0f);
  50. }
  51. }
  52. void Compressor::applyGain(std::unique_ptr<StreamInfo>& data) {
  53. for (int i = 0; i < data->numSamples; i++) {
  54. for (auto& channel : channels) {
  55. data->data[channel][i] *= tmp[i];
  56. }
  57. }
  58. }
  59. void Compressor::configure(std::vector<int> channels, float attack,
  60. float release, float threshold, float factor,
  61. float makeupGain) {
  62. this->channels = channels;
  63. this->attack = expf(-1000.0 / this->sampleRate / attack);
  64. this->release = expf(-1000.0 / this->sampleRate / release);
  65. this->threshold = threshold;
  66. this->factor = factor;
  67. this->makeupGain = makeupGain;
  68. }
  69. std::unique_ptr<StreamInfo> Compressor::process(
  70. std::unique_ptr<StreamInfo> data) {
  71. std::scoped_lock lock(this->accessMutex);
  72. sumChannels(data);
  73. calLoudness();
  74. calGain();
  75. applyGain(data);
  76. return data;
  77. }