123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- #include "Compressor.h"
- #include <cstdlib> // for abs
- using namespace bell;
- float log2f_approx(float X) {
- float Y, F;
- int E;
- F = frexpf(fabsf(X), &E);
- Y = 1.23149591368684f;
- Y *= F;
- Y += -4.11852516267426f;
- Y *= F;
- Y += 6.02197014179219f;
- Y *= F;
- Y += -3.13396450166353f;
- Y += E;
- return (Y);
- }
- Compressor::Compressor() {}
- void Compressor::sumChannels(std::unique_ptr<StreamInfo>& data) {
- tmp.resize(data->numSamples);
- for (int i = 0; i < data->numSamples; i++) {
- float sum = 0.0f;
- for (auto& channel : channels) {
- sum += data->data[channel][i];
- }
- tmp[i] = sum;
- }
- }
- void Compressor::calLoudness() {
- for (auto& value : tmp) {
- value = 20 * log10f_fast(std::abs(value) + 1.0e-9f);
- if (value >= lastLoudness) {
- value = attack * lastLoudness + (1.0 - attack) * value;
- } else {
- value = release * lastLoudness + (1.0 - release) * value;
- }
- lastLoudness = value;
- }
- }
- void Compressor::calGain() {
- for (auto& value : tmp) {
- if (value > threshold) {
- value = -(value - threshold) * (factor - 1.0) / factor;
- } else {
- value = 0.0f;
- }
- value += makeupGain;
- // convert to linear
- value = pow10f(value / 20.0f);
- }
- }
- void Compressor::applyGain(std::unique_ptr<StreamInfo>& data) {
- for (int i = 0; i < data->numSamples; i++) {
- for (auto& channel : channels) {
- data->data[channel][i] *= tmp[i];
- }
- }
- }
- void Compressor::configure(std::vector<int> channels, float attack,
- float release, float threshold, float factor,
- float makeupGain) {
- this->channels = channels;
- this->attack = expf(-1000.0 / this->sampleRate / attack);
- this->release = expf(-1000.0 / this->sampleRate / release);
- this->threshold = threshold;
- this->factor = factor;
- this->makeupGain = makeupGain;
- }
- std::unique_ptr<StreamInfo> Compressor::process(
- std::unique_ptr<StreamInfo> data) {
- std::scoped_lock lock(this->accessMutex);
- sumChannels(data);
- calLoudness();
- calGain();
- applyGain(data);
- return data;
- }
|