Compressor.cpp 2.0 KB

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