avfilter/avf_showwaves: add sqrt and cbrt amplitude scalers
authorPaul B Mahol <onemda@gmail.com>
Wed, 10 Aug 2016 09:34:04 +0000 (11:34 +0200)
committerPaul B Mahol <onemda@gmail.com>
Wed, 10 Aug 2016 09:34:04 +0000 (11:34 +0200)
doc/filters.texi
libavfilter/avf_showwaves.c

index 8b52a02..9dab959 100644 (file)
@@ -16834,9 +16834,24 @@ Set if channels should be drawn separately or overlap. Default value is 0.
 Set colors separated by '|' which are going to be used for drawing of each channel.
 
 @item scale
-Set amplitude scale. Can be linear @code{lin} or logarithmic @code{log}.
-Default is linear.
+Set amplitude scale.
+
+Available values are:
+@table @samp
+@item lin
+Linear.
 
+@item log
+Logarithmic.
+
+@item sqrt
+Square root.
+
+@item cbrt
+Cubic root.
+@end table
+
+Default is linear.
 @end table
 
 @subsection Examples
index 9008964..05aa995 100644 (file)
@@ -45,6 +45,8 @@ enum ShowWavesMode {
 enum ShowWavesScale {
     SCALE_LIN,
     SCALE_LOG,
+    SCALE_SQRT,
+    SCALE_CBRT,
     SCALE_NB,
 };
 
@@ -100,6 +102,8 @@ static const AVOption showwaves_options[] = {
     { "scale", "set amplitude scale", OFFSET(scale), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, SCALE_NB-1, FLAGS, .unit="scale" },
         { "lin", "linear",         0, AV_OPT_TYPE_CONST, {.i64=SCALE_LIN}, .flags=FLAGS, .unit="scale"},
         { "log", "logarithmic",    0, AV_OPT_TYPE_CONST, {.i64=SCALE_LOG}, .flags=FLAGS, .unit="scale"},
+        { "sqrt", "square root",   0, AV_OPT_TYPE_CONST, {.i64=SCALE_SQRT}, .flags=FLAGS, .unit="scale"},
+        { "cbrt", "cubic root",    0, AV_OPT_TYPE_CONST, {.i64=SCALE_CBRT}, .flags=FLAGS, .unit="scale"},
     { NULL }
 };
 
@@ -178,6 +182,26 @@ static int get_log_h2(int16_t sample, int height)
     return log10(1 + FFABS(sample)) * height / log10(1 + INT16_MAX);
 }
 
+static int get_sqrt_h(int16_t sample, int height)
+{
+    return height/2 - FFSIGN(sample) * (sqrt(FFABS(sample)) * (height/2) / sqrt(INT16_MAX));
+}
+
+static int get_sqrt_h2(int16_t sample, int height)
+{
+    return sqrt(FFABS(sample)) * height / sqrt(INT16_MAX);
+}
+
+static int get_cbrt_h(int16_t sample, int height)
+{
+    return height/2 - FFSIGN(sample) * (cbrt(FFABS(sample)) * (height/2) / cbrt(INT16_MAX));
+}
+
+static int get_cbrt_h2(int16_t sample, int height)
+{
+    return cbrt(FFABS(sample)) * height / cbrt(INT16_MAX);
+}
+
 static void draw_sample_point_rgba(uint8_t *buf, int height, int linesize,
                                    int16_t *prev_y,
                                    const uint8_t color[4], int h)
@@ -376,6 +400,26 @@ static int config_output(AVFilterLink *outlink)
             return AVERROR_BUG;
         }
         break;
+    case SCALE_SQRT:
+        switch (showwaves->mode) {
+        case MODE_POINT:
+        case MODE_LINE:
+        case MODE_P2P:           showwaves->get_h = get_sqrt_h;  break;
+        case MODE_CENTERED_LINE: showwaves->get_h = get_sqrt_h2; break;
+        default:
+            return AVERROR_BUG;
+        }
+        break;
+    case SCALE_CBRT:
+        switch (showwaves->mode) {
+        case MODE_POINT:
+        case MODE_LINE:
+        case MODE_P2P:           showwaves->get_h = get_cbrt_h;  break;
+        case MODE_CENTERED_LINE: showwaves->get_h = get_cbrt_h2; break;
+        default:
+            return AVERROR_BUG;
+        }
+        break;
     }
 
     showwaves->fg = av_malloc_array(nb_channels, 4 * sizeof(*showwaves->fg));