LCOV - code coverage report
Current view: top level - src/libavfilter - asrc_anoisesrc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 68 0.0 %
Date: 2017-01-24 04:42:20 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2015 Kyle Swanson <k@ylo.ph>.
       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 "libavutil/lfg.h"
      26             : #include "libavutil/random_seed.h"
      27             : 
      28             : typedef struct {
      29             :     const AVClass *class;
      30             :     int sample_rate;
      31             :     double amplitude;
      32             :     int64_t duration;
      33             :     int64_t color;
      34             :     int64_t seed;
      35             :     int nb_samples;
      36             : 
      37             :     int64_t pts;
      38             :     int infinite;
      39             :     double (*filter)(double white, double *buf);
      40             :     double buf[7];
      41             :     AVLFG c;
      42             : } ANoiseSrcContext;
      43             : 
      44             : #define OFFSET(x) offsetof(ANoiseSrcContext, x)
      45             : #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
      46             : 
      47             : static const AVOption anoisesrc_options[] = {
      48             :     { "sample_rate",  "set sample rate",  OFFSET(sample_rate),  AV_OPT_TYPE_INT,       {.i64 = 48000},  15,  INT_MAX,    FLAGS },
      49             :     { "r",            "set sample rate",  OFFSET(sample_rate),  AV_OPT_TYPE_INT,       {.i64 = 48000},  15,  INT_MAX,    FLAGS },
      50             :     { "amplitude",    "set amplitude",    OFFSET(amplitude),    AV_OPT_TYPE_DOUBLE,    {.dbl = 1.},     0.,  1.,         FLAGS },
      51             :     { "a",            "set amplitude",    OFFSET(amplitude),    AV_OPT_TYPE_DOUBLE,    {.dbl = 1.},     0.,  1.,         FLAGS },
      52             :     { "duration",     "set duration",     OFFSET(duration),     AV_OPT_TYPE_DURATION,  {.i64 =  0},      0,  INT64_MAX,  FLAGS },
      53             :     { "d",            "set duration",     OFFSET(duration),     AV_OPT_TYPE_DURATION,  {.i64 =  0},      0,  INT64_MAX,  FLAGS },
      54             :     { "color",        "set noise color",  OFFSET(color),        AV_OPT_TYPE_INT,       {.i64 =  1},      0,  2,          FLAGS, "color" },
      55             :     { "colour",       "set noise color",  OFFSET(color),        AV_OPT_TYPE_INT,       {.i64 =  1},      0,  2,          FLAGS, "color" },
      56             :     { "c",            "set noise color",  OFFSET(color),        AV_OPT_TYPE_INT,       {.i64 =  0},      0,  2,          FLAGS, "color" },
      57             :     {     "white",    0,                  0,                    AV_OPT_TYPE_CONST,     {.i64 =  0},      0,  0,          FLAGS, "color" },
      58             :     {     "pink",     0,                  0,                    AV_OPT_TYPE_CONST,     {.i64 =  1},      0,  0,          FLAGS, "color" },
      59             :     {     "brown",    0,                  0,                    AV_OPT_TYPE_CONST,     {.i64 =  2},      0,  0,          FLAGS, "color" },
      60             :     { "seed",         "set random seed",  OFFSET(seed),         AV_OPT_TYPE_INT64,     {.i64 = -1},     -1,  UINT_MAX,   FLAGS },
      61             :     { "s",            "set random seed",  OFFSET(seed),         AV_OPT_TYPE_INT64,     {.i64 = -1},     -1,  UINT_MAX,   FLAGS },
      62             :     { "nb_samples",   "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS },
      63             :     { "n",            "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS },
      64             :     {NULL}
      65             : };
      66             : 
      67             : AVFILTER_DEFINE_CLASS(anoisesrc);
      68             : 
      69           0 : static av_cold int query_formats(AVFilterContext *ctx)
      70             : {
      71           0 :     ANoiseSrcContext *s = ctx->priv;
      72             :     static const int64_t chlayouts[] = { AV_CH_LAYOUT_MONO, -1 };
      73           0 :     int sample_rates[] = { s->sample_rate, -1 };
      74             :     static const enum AVSampleFormat sample_fmts[] = {
      75             :         AV_SAMPLE_FMT_DBL,
      76             :         AV_SAMPLE_FMT_NONE
      77             :     };
      78             : 
      79             :     AVFilterFormats *formats;
      80             :     AVFilterChannelLayouts *layouts;
      81             :     int ret;
      82             : 
      83           0 :     formats = ff_make_format_list(sample_fmts);
      84           0 :     if (!formats)
      85           0 :         return AVERROR(ENOMEM);
      86           0 :     ret = ff_set_common_formats (ctx, formats);
      87           0 :     if (ret < 0)
      88           0 :         return ret;
      89             : 
      90           0 :     layouts = avfilter_make_format64_list(chlayouts);
      91           0 :     if (!layouts)
      92           0 :         return AVERROR(ENOMEM);
      93           0 :     ret = ff_set_common_channel_layouts(ctx, layouts);
      94           0 :     if (ret < 0)
      95           0 :         return ret;
      96             : 
      97           0 :     formats = ff_make_format_list(sample_rates);
      98           0 :     if (!formats)
      99           0 :         return AVERROR(ENOMEM);
     100           0 :     return ff_set_common_samplerates(ctx, formats);
     101             : }
     102             : 
     103           0 : static double white_filter(double white, double *buf)
     104             : {
     105           0 :     return white;
     106             : }
     107             : 
     108           0 : static double pink_filter(double white, double *buf)
     109             : {
     110             :     double pink;
     111             : 
     112             :     /* http://www.musicdsp.org/files/pink.txt */
     113           0 :     buf[0] = 0.99886 * buf[0] + white * 0.0555179;
     114           0 :     buf[1] = 0.99332 * buf[1] + white * 0.0750759;
     115           0 :     buf[2] = 0.96900 * buf[2] + white * 0.1538520;
     116           0 :     buf[3] = 0.86650 * buf[3] + white * 0.3104856;
     117           0 :     buf[4] = 0.55000 * buf[4] + white * 0.5329522;
     118           0 :     buf[5] = -0.7616 * buf[5] - white * 0.0168980;
     119           0 :     pink = buf[0] + buf[1] + buf[2] + buf[3] + buf[4] + buf[5] + buf[6] + white * 0.5362;
     120           0 :     buf[6] = white * 0.115926;
     121           0 :     return pink * 0.11;
     122             : }
     123             : 
     124           0 : static double brown_filter(double white, double *buf)
     125             : {
     126             :     double brown;
     127             : 
     128           0 :     brown = ((0.02 * white) + buf[0]) / 1.02;
     129           0 :     buf[0] = brown;
     130           0 :     return brown * 3.5;
     131             : }
     132             : 
     133           0 : static av_cold int config_props(AVFilterLink *outlink)
     134             : {
     135           0 :     AVFilterContext *ctx = outlink->src;
     136           0 :     ANoiseSrcContext *s = ctx->priv;
     137             : 
     138           0 :     if (s->seed == -1)
     139           0 :         s->seed = av_get_random_seed();
     140           0 :     av_lfg_init(&s->c, s->seed);
     141             : 
     142           0 :     if (s->duration == 0)
     143           0 :         s->infinite = 1;
     144           0 :     s->duration = av_rescale(s->duration, s->sample_rate, AV_TIME_BASE);
     145             : 
     146           0 :     switch (s->color) {
     147           0 :     case 0: s->filter = white_filter; break;
     148           0 :     case 1: s->filter = pink_filter;  break;
     149           0 :     case 2: s->filter = brown_filter; break;
     150             :     }
     151             : 
     152           0 :     return 0;
     153             : }
     154             : 
     155           0 : static int request_frame(AVFilterLink *outlink)
     156             : {
     157           0 :     AVFilterContext *ctx = outlink->src;
     158           0 :     ANoiseSrcContext *s = ctx->priv;
     159             :     AVFrame *frame;
     160             :     int nb_samples, i;
     161             :     double *dst;
     162             : 
     163           0 :     if (!s->infinite && s->duration <= 0) {
     164           0 :         return AVERROR_EOF;
     165           0 :     } else if (!s->infinite && s->duration < s->nb_samples) {
     166           0 :         nb_samples = s->duration;
     167             :     } else {
     168           0 :         nb_samples = s->nb_samples;
     169             :     }
     170             : 
     171           0 :     if (!(frame = ff_get_audio_buffer(outlink, nb_samples)))
     172           0 :         return AVERROR(ENOMEM);
     173             : 
     174           0 :     dst = (double *)frame->data[0];
     175           0 :     for (i = 0; i < nb_samples; i++) {
     176             :         double white;
     177           0 :         white = s->amplitude * ((2 * ((double) av_lfg_get(&s->c) / 0xffffffff)) - 1);
     178           0 :         dst[i] = s->filter(white, s->buf);
     179             :     }
     180             : 
     181           0 :     if (!s->infinite)
     182           0 :         s->duration -= nb_samples;
     183             : 
     184           0 :     frame->pts = s->pts;
     185           0 :     s->pts    += nb_samples;
     186           0 :     return ff_filter_frame(outlink, frame);
     187             : }
     188             : 
     189             : static const AVFilterPad anoisesrc_outputs[] = {
     190             :     {
     191             :         .name          = "default",
     192             :         .type          = AVMEDIA_TYPE_AUDIO,
     193             :         .request_frame = request_frame,
     194             :         .config_props  = config_props,
     195             :     },
     196             :     { NULL }
     197             : };
     198             : 
     199             : AVFilter ff_asrc_anoisesrc = {
     200             :     .name          = "anoisesrc",
     201             :     .description   = NULL_IF_CONFIG_SMALL("Generate a noise audio signal."),
     202             :     .query_formats = query_formats,
     203             :     .priv_size     = sizeof(ANoiseSrcContext),
     204             :     .inputs        = NULL,
     205             :     .outputs       = anoisesrc_outputs,
     206             :     .priv_class    = &anoisesrc_class,
     207             : };

Generated by: LCOV version 1.12