lavr: resampling: add filter type and Kaiser window beta to AVOptions
authorJustin Ruggles <justin.ruggles@gmail.com>
Sat, 26 May 2012 18:50:02 +0000 (14:50 -0400)
committerJustin Ruggles <justin.ruggles@gmail.com>
Sun, 8 Jul 2012 19:22:11 +0000 (15:22 -0400)
libavresample/avresample.h
libavresample/internal.h
libavresample/options.c
libavresample/resample.c

index 002bec2..b93aba5 100644 (file)
@@ -45,6 +45,13 @@ enum AVMixCoeffType {
     AV_MIX_COEFF_TYPE_NB,   /** Number of coeff types. Not part of ABI      */
 };
 
+/** Resampling Filter Types */
+enum AVResampleFilterType {
+    AV_RESAMPLE_FILTER_TYPE_CUBIC,              /**< Cubic */
+    AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL,   /**< Blackman Nuttall Windowed Sinc */
+    AV_RESAMPLE_FILTER_TYPE_KAISER,             /**< Kaiser Windowed Sinc */
+};
+
 /**
  * Return the LIBAVRESAMPLE_VERSION_INT constant.
  */
index fa9499a..7b7648f 100644 (file)
@@ -50,6 +50,8 @@ struct AVAudioResampleContext {
     int phase_shift;                            /**< log2 of the number of entries in the resampling polyphase filterbank */
     int linear_interp;                          /**< if 1 then the resampling FIR filter will be linearly interpolated */
     double cutoff;                              /**< resampling cutoff frequency. 1.0 corresponds to half the output sample rate */
+    enum AVResampleFilterType filter_type;      /**< resampling filter type */
+    int kaiser_beta;                            /**< beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER) */
 
     int in_channels;        /**< number of input channels                   */
     int out_channels;       /**< number of output channels                  */
index 45678dc..02e1f86 100644 (file)
@@ -56,6 +56,11 @@ static const AVOption options[] = {
         { "none",  "None",               0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_NONE  }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
         { "dolby", "Dolby",              0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_DOLBY }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
         { "dplii", "Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_DPLII }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
+    { "filter_type",            "Filter Type",              OFFSET(filter_type),            AV_OPT_TYPE_INT,    { AV_RESAMPLE_FILTER_TYPE_KAISER }, AV_RESAMPLE_FILTER_TYPE_CUBIC, AV_RESAMPLE_FILTER_TYPE_KAISER,  PARAM, "filter_type" },
+        { "cubic",            "Cubic",                          0, AV_OPT_TYPE_CONST, { AV_RESAMPLE_FILTER_TYPE_CUBIC            }, INT_MIN, INT_MAX, PARAM, "filter_type" },
+        { "blackman_nuttall", "Blackman Nuttall Windowed Sinc", 0, AV_OPT_TYPE_CONST, { AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL }, INT_MIN, INT_MAX, PARAM, "filter_type" },
+        { "kaiser",           "Kaiser Windowed Sinc",           0, AV_OPT_TYPE_CONST, { AV_RESAMPLE_FILTER_TYPE_KAISER           }, INT_MIN, INT_MAX, PARAM, "filter_type" },
+    { "kaiser_beta",            "Kaiser Window Beta",       OFFSET(kaiser_beta),            AV_OPT_TYPE_INT,    { 9                     }, 2,                    16,                     PARAM },
     { NULL },
 };
 
index 5529faf..7316e4e 100644 (file)
@@ -30,7 +30,6 @@
 #define FELEM         float
 #define FELEM2        float
 #define FELEML        float
-#define WINDOW_TYPE   24
 #elifdef CONFIG_RESAMPLE_S32
 /* s32 template */
 #define FILTER_SHIFT  30
@@ -39,7 +38,6 @@
 #define FELEML        int64_t
 #define FELEM_MAX     INT32_MAX
 #define FELEM_MIN     INT32_MIN
-#define WINDOW_TYPE   12
 #else
 /* s16 template */
 #define FILTER_SHIFT  15
@@ -48,7 +46,6 @@
 #define FELEML        int64_t
 #define FELEM_MAX     INT16_MAX
 #define FELEM_MIN     INT16_MIN
-#define WINDOW_TYPE   9
 #endif
 
 struct ResampleContext {
@@ -65,6 +62,8 @@ struct ResampleContext {
     int phase_shift;
     int phase_mask;
     int linear;
+    enum AVResampleFilterType filter_type;
+    int kaiser_beta;
     double factor;
 };
 
@@ -95,13 +94,13 @@ static double bessel(double x)
  * @param      tap_count    tap count
  * @param      phase_count  phase count
  * @param      scale        wanted sum of coefficients for each filter
- * @param      type         0->cubic
- *                          1->blackman nuttall windowed sinc
- *                          2..16->kaiser windowed sinc beta=2..16
+ * @param      filter_type  filter type
+ * @param      kaiser_beta  kaiser window beta
  * @return                  0 on success, negative AVERROR code on failure
  */
 static int build_filter(FELEM *filter, double factor, int tap_count,
-                        int phase_count, int scale, int type)
+                        int phase_count, int scale, int filter_type,
+                        int kaiser_beta)
 {
     int ph, i;
     double x, y, w;
@@ -122,23 +121,23 @@ static int build_filter(FELEM *filter, double factor, int tap_count,
             x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
             if (x == 0) y = 1.0;
             else        y = sin(x) / x;
-            switch (type) {
-            case 0: {
+            switch (filter_type) {
+            case AV_RESAMPLE_FILTER_TYPE_CUBIC: {
                 const float d = -0.5; //first order derivative = -0.5
                 x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
                 if (x < 1.0) y = 1 - 3 * x*x + 2 * x*x*x + d * (                -x*x + x*x*x);
                 else         y =                           d * (-4 + 8 * x - 5 * x*x + x*x*x);
                 break;
             }
-            case 1:
+            case AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL:
                 w  = 2.0 * x / (factor * tap_count) + M_PI;
                 y *= 0.3635819 - 0.4891775 * cos(    w) +
                                  0.1365995 * cos(2 * w) -
                                  0.0106411 * cos(3 * w);
                 break;
-            default:
+            case AV_RESAMPLE_FILTER_TYPE_KAISER:
                 w  = 2.0 * x / (factor * tap_count * M_PI);
-                y *= bessel(type * sqrt(FFMAX(1 - w * w, 0)));
+                y *= bessel(kaiser_beta * sqrt(FFMAX(1 - w * w, 0)));
                 break;
             }
 
@@ -186,13 +185,15 @@ ResampleContext *ff_audio_resample_init(AVAudioResampleContext *avr)
     c->linear        = avr->linear_interp;
     c->factor        = factor;
     c->filter_length = FFMAX((int)ceil(avr->filter_size / factor), 1);
+    c->filter_type   = avr->filter_type;
+    c->kaiser_beta   = avr->kaiser_beta;
 
     c->filter_bank = av_mallocz(c->filter_length * (phase_count + 1) * sizeof(FELEM));
     if (!c->filter_bank)
         goto error;
 
     if (build_filter(c->filter_bank, factor, c->filter_length, phase_count,
-                     1 << FILTER_SHIFT, WINDOW_TYPE) < 0)
+                     1 << FILTER_SHIFT, c->filter_type, c->kaiser_beta) < 0)
         goto error;
 
     memcpy(&c->filter_bank[c->filter_length * phase_count + 1],