diff mbox

[FFmpeg-devel] avfilter/firequalizer: add scale option

Message ID 1476573041-10119-1-git-send-email-mfcc64@gmail.com
State Accepted
Headers show

Commit Message

Muhammad Faiz Oct. 15, 2016, 11:10 p.m. UTC
Signed-off-by: Muhammad Faiz <mfcc64@gmail.com>
---
 doc/filters.texi              | 13 +++++++++++++
 libavfilter/af_firequalizer.c | 33 ++++++++++++++++++++++++++++++---
 2 files changed, 43 insertions(+), 3 deletions(-)

Comments

Muhammad Faiz Oct. 16, 2016, 8:23 p.m. UTC | #1
On Sun, Oct 16, 2016 at 6:10 AM, Muhammad Faiz <mfcc64@gmail.com> wrote:
> Signed-off-by: Muhammad Faiz <mfcc64@gmail.com>
> ---
>  doc/filters.texi              | 13 +++++++++++++
>  libavfilter/af_firequalizer.c | 33 ++++++++++++++++++++++++++++++---
>  2 files changed, 43 insertions(+), 3 deletions(-)
>

pushed with fixed documentation

thanks
diff mbox

Patch

diff --git a/doc/filters.texi b/doc/filters.texi
index f5cc9b7..d4eec70 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -2565,6 +2565,19 @@  Enable zero phase mode by subtracting timestamp to compensate delay.
 Default is disabled.
 @end table
 
+@item scale
+Set scale used by gain. Acceptable values are:
+@table @option
+@item linlin
+linear frequency, linear gain
+@item linlog
+linear frequency, logarithmic (in dB) gain (default)
+@item loglin
+logarithmic (in octave scale where 20 Hz is 0) frequency, linear gain
+@item loglog
+logarithmic frequency, logarithmic gain
+@end table
+
 @subsection Examples
 @itemize
 @item
diff --git a/libavfilter/af_firequalizer.c b/libavfilter/af_firequalizer.c
index c7569bb..78d7767 100644
--- a/libavfilter/af_firequalizer.c
+++ b/libavfilter/af_firequalizer.c
@@ -43,6 +43,14 @@  enum WindowFunc {
     NB_WFUNC
 };
 
+enum Scale {
+    SCALE_LINLIN,
+    SCALE_LINLOG,
+    SCALE_LOGLIN,
+    SCALE_LOGLOG,
+    NB_SCALE
+};
+
 #define NB_GAIN_ENTRY_MAX 4096
 typedef struct {
     double  freq;
@@ -84,6 +92,7 @@  typedef struct {
     int           fixed;
     int           multi;
     int           zero_phase;
+    int           scale;
 
     int           nb_gain_entry;
     int           gain_entry_err;
@@ -112,6 +121,11 @@  static const AVOption firequalizer_options[] = {
     { "fixed", "set fixed frame samples", OFFSET(fixed), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
     { "multi", "set multi channels mode", OFFSET(multi), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
     { "zero_phase", "set zero phase mode", OFFSET(zero_phase), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
+    { "scale", "set gain scale", OFFSET(scale), AV_OPT_TYPE_INT, { .i64 = SCALE_LINLOG }, 0, NB_SCALE-1, FLAGS, "scale" },
+        { "linlin", "linear-freq linear-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LINLIN }, 0, 0, FLAGS, "scale" },
+        { "linlog", "linear-freq logarithmic-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LINLOG }, 0, 0, FLAGS, "scale" },
+        { "loglin", "logarithmic-freq linear-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LOGLIN }, 0, 0, FLAGS, "scale" },
+        { "loglog", "logarithmic-freq logarithmic-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LOGLOG }, 0, 0, FLAGS, "scale" },
     { NULL }
 };
 
@@ -316,6 +330,8 @@  static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g
     double vars[VAR_NB];
     AVExpr *gain_expr;
     int ret, k, center, ch;
+    int xlog = s->scale == SCALE_LOGLIN || s->scale == SCALE_LOGLOG;
+    int ylog = s->scale == SCALE_LINLOG || s->scale == SCALE_LOGLOG;
 
     s->nb_gain_entry = 0;
     s->gain_entry_err = 0;
@@ -340,16 +356,27 @@  static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g
     vars[VAR_CHLAYOUT] = inlink->channel_layout;
     vars[VAR_SR] = inlink->sample_rate;
     for (ch = 0; ch < inlink->channels; ch++) {
+        double result;
         vars[VAR_CH] = ch;
         vars[VAR_CHID] = av_channel_layout_extract_channel(inlink->channel_layout, ch);
         vars[VAR_F] = 0.0;
-        s->analysis_buf[0] = pow(10.0, 0.05 * av_expr_eval(gain_expr, vars, ctx));
+        if (xlog)
+            vars[VAR_F] = log2(0.05 * vars[VAR_F]);
+        result = av_expr_eval(gain_expr, vars, ctx);
+        s->analysis_buf[0] = ylog ? pow(10.0, 0.05 * result) : result;
+
         vars[VAR_F] = 0.5 * inlink->sample_rate;
-        s->analysis_buf[1] = pow(10.0, 0.05 * av_expr_eval(gain_expr, vars, ctx));
+        if (xlog)
+            vars[VAR_F] = log2(0.05 * vars[VAR_F]);
+        result = av_expr_eval(gain_expr, vars, ctx);
+        s->analysis_buf[1] = ylog ? pow(10.0, 0.05 * result) : result;
 
         for (k = 1; k < s->analysis_rdft_len/2; k++) {
             vars[VAR_F] = k * ((double)inlink->sample_rate /(double)s->analysis_rdft_len);
-            s->analysis_buf[2*k] = pow(10.0, 0.05 * av_expr_eval(gain_expr, vars, ctx));
+            if (xlog)
+                vars[VAR_F] = log2(0.05 * vars[VAR_F]);
+            result = av_expr_eval(gain_expr, vars, ctx);
+            s->analysis_buf[2*k] = ylog ? pow(10.0, 0.05 * result) : result;
             s->analysis_buf[2*k+1] = 0.0;
         }