LCOV - code coverage report
Current view: top level - libavfilter - asrc_hilbert.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 56 0.0 %
Date: 2018-05-20 11:54:08 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018 Paul B Mahol
       3             :  *
       4             :  * This file is part of FFmpeg.
       5             :  *
       6             :  * FFmpeg is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU Lesser General Public License
       8             :  * as published by the Free Software Foundation; either
       9             :  * version 2.1 of the License, or (at your option) any later version.
      10             :  *
      11             :  * FFmpeg is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public License
      17             :  * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
      18             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include "libavutil/opt.h"
      22             : #include "audio.h"
      23             : #include "avfilter.h"
      24             : #include "internal.h"
      25             : #include "window_func.h"
      26             : 
      27             : typedef struct HilbertContext {
      28             :     const AVClass *class;
      29             : 
      30             :     int sample_rate;
      31             :     int nb_taps;
      32             :     int nb_samples;
      33             :     int win_func;
      34             : 
      35             :     float *taps;
      36             :     int64_t pts;
      37             : } HilbertContext;
      38             : 
      39             : #define OFFSET(x) offsetof(HilbertContext, x)
      40             : #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
      41             : 
      42             : static const AVOption hilbert_options[] = {
      43             :     { "sample_rate", "set sample rate",    OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100},  1, INT_MAX,    FLAGS },
      44             :     { "r",           "set sample rate",    OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100},  1, INT_MAX,    FLAGS },
      45             :     { "taps",        "set number of taps", OFFSET(nb_taps),     AV_OPT_TYPE_INT, {.i64=22051}, 11, UINT16_MAX, FLAGS },
      46             :     { "t",           "set number of taps", OFFSET(nb_taps),     AV_OPT_TYPE_INT, {.i64=22051}, 11, UINT16_MAX, FLAGS },
      47             :     { "nb_samples",  "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS },
      48             :     { "n",           "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS },
      49             :     { "win_func", "set window function", OFFSET(win_func), AV_OPT_TYPE_INT, {.i64=WFUNC_BLACKMAN}, 0, NB_WFUNC-1, FLAGS, "win_func" },
      50             :     { "w",        "set window function", OFFSET(win_func), AV_OPT_TYPE_INT, {.i64=WFUNC_BLACKMAN}, 0, NB_WFUNC-1, FLAGS, "win_func" },
      51             :         { "rect",     "Rectangular",      0, AV_OPT_TYPE_CONST, {.i64=WFUNC_RECT},     0, 0, FLAGS, "win_func" },
      52             :         { "bartlett", "Bartlett",         0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BARTLETT}, 0, 0, FLAGS, "win_func" },
      53             :         { "hanning",  "Hanning",          0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING},  0, 0, FLAGS, "win_func" },
      54             :         { "hamming",  "Hamming",          0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HAMMING},  0, 0, FLAGS, "win_func" },
      55             :         { "blackman", "Blackman",         0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BLACKMAN}, 0, 0, FLAGS, "win_func" },
      56             :         { "welch",    "Welch",            0, AV_OPT_TYPE_CONST, {.i64=WFUNC_WELCH},    0, 0, FLAGS, "win_func" },
      57             :         { "flattop",  "Flat-top",         0, AV_OPT_TYPE_CONST, {.i64=WFUNC_FLATTOP},  0, 0, FLAGS, "win_func" },
      58             :         { "bharris",  "Blackman-Harris",  0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHARRIS},  0, 0, FLAGS, "win_func" },
      59             :         { "bnuttall", "Blackman-Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BNUTTALL}, 0, 0, FLAGS, "win_func" },
      60             :         { "bhann",    "Bartlett-Hann",    0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHANN},    0, 0, FLAGS, "win_func" },
      61             :         { "sine",     "Sine",             0, AV_OPT_TYPE_CONST, {.i64=WFUNC_SINE},     0, 0, FLAGS, "win_func" },
      62             :         { "nuttall",  "Nuttall",          0, AV_OPT_TYPE_CONST, {.i64=WFUNC_NUTTALL},  0, 0, FLAGS, "win_func" },
      63             :         { "lanczos",  "Lanczos",          0, AV_OPT_TYPE_CONST, {.i64=WFUNC_LANCZOS},  0, 0, FLAGS, "win_func" },
      64             :         { "gauss",    "Gauss",            0, AV_OPT_TYPE_CONST, {.i64=WFUNC_GAUSS},    0, 0, FLAGS, "win_func" },
      65             :         { "tukey",    "Tukey",            0, AV_OPT_TYPE_CONST, {.i64=WFUNC_TUKEY},    0, 0, FLAGS, "win_func" },
      66             :         { "dolph",    "Dolph-Chebyshev",  0, AV_OPT_TYPE_CONST, {.i64=WFUNC_DOLPH},    0, 0, FLAGS, "win_func" },
      67             :         { "cauchy",   "Cauchy",           0, AV_OPT_TYPE_CONST, {.i64=WFUNC_CAUCHY},   0, 0, FLAGS, "win_func" },
      68             :         { "parzen",   "Parzen",           0, AV_OPT_TYPE_CONST, {.i64=WFUNC_PARZEN},   0, 0, FLAGS, "win_func" },
      69             :         { "poisson",  "Poisson",          0, AV_OPT_TYPE_CONST, {.i64=WFUNC_POISSON},  0, 0, FLAGS, "win_func" },
      70             :     {NULL}
      71             : };
      72             : 
      73             : AVFILTER_DEFINE_CLASS(hilbert);
      74             : 
      75           0 : static av_cold int init(AVFilterContext *ctx)
      76             : {
      77           0 :     HilbertContext *s = ctx->priv;
      78             : 
      79           0 :     if (!(s->nb_taps & 1)) {
      80           0 :         av_log(s, AV_LOG_ERROR, "Number of taps %d must be odd length.\n", s->nb_taps);
      81           0 :         return AVERROR(EINVAL);
      82             :     }
      83             : 
      84           0 :     return 0;
      85             : }
      86             : 
      87           0 : static av_cold void uninit(AVFilterContext *ctx)
      88             : {
      89           0 :     HilbertContext *s = ctx->priv;
      90             : 
      91           0 :     av_freep(&s->taps);
      92           0 : }
      93             : 
      94           0 : static av_cold int query_formats(AVFilterContext *ctx)
      95             : {
      96           0 :     HilbertContext *s = ctx->priv;
      97             :     static const int64_t chlayouts[] = { AV_CH_LAYOUT_MONO, -1 };
      98           0 :     int sample_rates[] = { s->sample_rate, -1 };
      99             :     static const enum AVSampleFormat sample_fmts[] = {
     100             :         AV_SAMPLE_FMT_FLT,
     101             :         AV_SAMPLE_FMT_NONE
     102             :     };
     103             : 
     104             :     AVFilterFormats *formats;
     105             :     AVFilterChannelLayouts *layouts;
     106             :     int ret;
     107             : 
     108           0 :     formats = ff_make_format_list(sample_fmts);
     109           0 :     if (!formats)
     110           0 :         return AVERROR(ENOMEM);
     111           0 :     ret = ff_set_common_formats (ctx, formats);
     112           0 :     if (ret < 0)
     113           0 :         return ret;
     114             : 
     115           0 :     layouts = avfilter_make_format64_list(chlayouts);
     116           0 :     if (!layouts)
     117           0 :         return AVERROR(ENOMEM);
     118           0 :     ret = ff_set_common_channel_layouts(ctx, layouts);
     119           0 :     if (ret < 0)
     120           0 :         return ret;
     121             : 
     122           0 :     formats = ff_make_format_list(sample_rates);
     123           0 :     if (!formats)
     124           0 :         return AVERROR(ENOMEM);
     125           0 :     return ff_set_common_samplerates(ctx, formats);
     126             : }
     127             : 
     128           0 : static av_cold int config_props(AVFilterLink *outlink)
     129             : {
     130           0 :     AVFilterContext *ctx = outlink->src;
     131           0 :     HilbertContext *s = ctx->priv;
     132             :     float overlap;
     133             :     int i;
     134             : 
     135           0 :     s->taps = av_malloc_array(s->nb_taps, sizeof(*s->taps));
     136           0 :     if (!s->taps)
     137           0 :         return AVERROR(ENOMEM);
     138             : 
     139           0 :     generate_window_func(s->taps, s->nb_taps, s->win_func, &overlap);
     140             : 
     141           0 :     for (i = 0; i < s->nb_taps; i++) {
     142           0 :         int k = -(s->nb_taps / 2) + i;
     143             : 
     144           0 :         if (k & 1) {
     145           0 :             float pk = M_PI * k;
     146             : 
     147           0 :             s->taps[i] *= (1.f - cosf(pk)) / pk;
     148             :         } else {
     149           0 :             s->taps[i] = 0.f;
     150             :         }
     151             :     }
     152             : 
     153           0 :     s->pts = 0;
     154             : 
     155           0 :     return 0;
     156             : }
     157             : 
     158           0 : static int request_frame(AVFilterLink *outlink)
     159             : {
     160           0 :     AVFilterContext *ctx = outlink->src;
     161           0 :     HilbertContext *s = ctx->priv;
     162             :     AVFrame *frame;
     163             :     int nb_samples;
     164             : 
     165           0 :     nb_samples = FFMIN(s->nb_samples, s->nb_taps - s->pts);
     166           0 :     if (!nb_samples)
     167           0 :         return AVERROR_EOF;
     168             : 
     169           0 :     if (!(frame = ff_get_audio_buffer(outlink, nb_samples)))
     170           0 :         return AVERROR(ENOMEM);
     171             : 
     172           0 :     memcpy(frame->data[0], s->taps + s->pts, nb_samples * sizeof(float));
     173             : 
     174           0 :     frame->pts = s->pts;
     175           0 :     s->pts    += nb_samples;
     176           0 :     return ff_filter_frame(outlink, frame);
     177             : }
     178             : 
     179             : static const AVFilterPad hilbert_outputs[] = {
     180             :     {
     181             :         .name          = "default",
     182             :         .type          = AVMEDIA_TYPE_AUDIO,
     183             :         .request_frame = request_frame,
     184             :         .config_props  = config_props,
     185             :     },
     186             :     { NULL }
     187             : };
     188             : 
     189             : AVFilter ff_asrc_hilbert = {
     190             :     .name          = "hilbert",
     191             :     .description   = NULL_IF_CONFIG_SMALL("Generate a Hilbert transform FIR coefficients."),
     192             :     .query_formats = query_formats,
     193             :     .init          = init,
     194             :     .uninit        = uninit,
     195             :     .priv_size     = sizeof(HilbertContext),
     196             :     .inputs        = NULL,
     197             :     .outputs       = hilbert_outputs,
     198             :     .priv_class    = &hilbert_class,
     199             : };

Generated by: LCOV version 1.13