]> git.sesse.net Git - nageru/blobdiff - stereocompressor.cpp
Support audio-only FFmpeg inputs. Somewhat wonky, though.
[nageru] / stereocompressor.cpp
index 3c522cc5891301e8a36cb253e9eb9840e503d458..d9f1142fa3595b08ccaadd9431cb70fd7a602288 100644 (file)
@@ -1,8 +1,10 @@
-#include <math.h>
+#include "stereocompressor.h"
+
 #include <assert.h>
 #include <algorithm>
+#include <cmath>
 
-#include "stereocompressor.h"
+using namespace std;
 
 namespace {
 
@@ -51,22 +53,22 @@ inline float fastpow(float x, float y)
 {
        float ln_nom, ln_den;
        if (x < 6.0f) {
-               ln_nom = -0.059237648 + (-0.0165117771 + (0.06818859075 + 0.007560968243 * x) * x) * x;
-               ln_den = 0.0202509098 + (0.08419174188 + (0.03647189417 + 0.001642577975 * x) * x) * x;
+               ln_nom = -0.059237648f + (-0.0165117771f + (0.06818859075f + 0.007560968243f * x) * x) * x;
+               ln_den = 0.0202509098f + (0.08419174188f + (0.03647189417f + 0.001642577975f * x) * x) * x;
        } else {
-               ln_nom = -0.005430534 + (0.00633589178 + (0.0006319155549 + 0.4789541675e-5 * x) * x) * x;
-               ln_den = 0.0064785099 + (0.003219629109 + (0.0001531823694 + 0.6884656640e-6 * x) * x) * x;
+               ln_nom = -0.005430534f + (0.00633589178f + (0.0006319155549f + 0.4789541675e-5f * x) * x) * x;
+               ln_den = 0.0064785099f + (0.003219629109f + (0.0001531823694f + 0.6884656640e-6f * x) * x) * x;
        }
        float v = y * ln_nom / ln_den;
-       float exp_nom = 0.2195097621 + (0.08546059868 + (0.01208501759 + 0.0006173448113 * v) * v) * v;
-       float exp_den = 0.2194980791 + (-0.1343051968 + (0.03556072737 - 0.006174398513 * v) * v) * v;
+       float exp_nom = 0.2195097621f + (0.08546059868f + (0.01208501759f + 0.0006173448113f * v) * v) * v;
+       float exp_den = 0.2194980791f + (-0.1343051968f + (0.03556072737f - 0.006174398513f * v) * v) * v;
        return exp_nom / exp_den;
 }
 
 inline float compressor_knee(float x, float threshold, float inv_threshold, float inv_ratio_minus_one, float postgain)
 {
        assert(inv_ratio_minus_one <= 0.0f);
-       if (x > threshold && inv_ratio_minus_one < 0.0f) {
+       if (x > threshold) {
                return postgain * fastpow(x * inv_threshold, inv_ratio_minus_one);
        } else {
                return postgain;
@@ -91,6 +93,17 @@ void StereoCompressor::process(float *buf, size_t num_samples, float threshold,
        float *left_ptr = buf;
        float *right_ptr = buf + 1;
 
+       if (inv_ratio_minus_one >= 0.0) {
+               for (size_t i = 0; i < num_samples; ++i) {
+                       *left_ptr *= makeup_gain;
+                       left_ptr += 2;
+
+                       *right_ptr *= makeup_gain;
+                       right_ptr += 2;
+               }
+               return;
+       }
+
        float peak_level = this->peak_level;
        float compr_level = this->compr_level;
 
@@ -99,9 +112,9 @@ void StereoCompressor::process(float *buf, size_t num_samples, float threshold,
                if (fabs(*right_ptr) > peak_level) peak_level = float(fabs(*right_ptr));
 
                if (peak_level > compr_level) {
-                       compr_level = std::min(compr_level * attack_increment, peak_level);
+                       compr_level = min(compr_level * attack_increment, peak_level);
                } else {
-                       compr_level = std::max(compr_level * release_increment, 0.0001f);
+                       compr_level = max(compr_level * release_increment, 0.0001f);
                }
 
                float scalefactor_with_gain = compressor_knee(compr_level, threshold, inv_threshold, inv_ratio_minus_one, makeup_gain);
@@ -112,7 +125,7 @@ void StereoCompressor::process(float *buf, size_t num_samples, float threshold,
                *right_ptr *= scalefactor_with_gain;
                right_ptr += 2;
 
-               peak_level = std::max(peak_level * peak_increment, 0.0001f);
+               peak_level = max(peak_level * peak_increment, 0.0001f);
        }
 
        // Store attenuation level for debug/visualization.