LCOV - code coverage report
Current view: top level - libavfilter - asrc_anoisesrc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 84 0.0 %
Date: 2017-12-12 11:08:38 Functions: 0 8 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 ANoiseSrcContext {
      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             : enum NoiseMode {
      45             :     NM_WHITE,
      46             :     NM_PINK,
      47             :     NM_BROWN,
      48             :     NM_BLUE,
      49             :     NM_VIOLET,
      50             :     NM_NB
      51             : };
      52             : 
      53             : #define OFFSET(x) offsetof(ANoiseSrcContext, x)
      54             : #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
      55             : 
      56             : static const AVOption anoisesrc_options[] = {
      57             :     { "sample_rate",  "set sample rate",  OFFSET(sample_rate),  AV_OPT_TYPE_INT,       {.i64 = 48000},     15,  INT_MAX,    FLAGS },
      58             :     { "r",            "set sample rate",  OFFSET(sample_rate),  AV_OPT_TYPE_INT,       {.i64 = 48000},     15,  INT_MAX,    FLAGS },
      59             :     { "amplitude",    "set amplitude",    OFFSET(amplitude),    AV_OPT_TYPE_DOUBLE,    {.dbl = 1.},        0.,  1.,         FLAGS },
      60             :     { "a",            "set amplitude",    OFFSET(amplitude),    AV_OPT_TYPE_DOUBLE,    {.dbl = 1.},        0.,  1.,         FLAGS },
      61             :     { "duration",     "set duration",     OFFSET(duration),     AV_OPT_TYPE_DURATION,  {.i64 =  0},         0,  INT64_MAX,  FLAGS },
      62             :     { "d",            "set duration",     OFFSET(duration),     AV_OPT_TYPE_DURATION,  {.i64 =  0},         0,  INT64_MAX,  FLAGS },
      63             :     { "color",        "set noise color",  OFFSET(color),        AV_OPT_TYPE_INT,       {.i64 =  0},         0,  NM_NB - 1,  FLAGS, "color" },
      64             :     { "colour",       "set noise color",  OFFSET(color),        AV_OPT_TYPE_INT,       {.i64 =  0},         0,  NM_NB - 1,  FLAGS, "color" },
      65             :     { "c",            "set noise color",  OFFSET(color),        AV_OPT_TYPE_INT,       {.i64 =  0},         0,  NM_NB - 1,  FLAGS, "color" },
      66             :     {     "white",    0,                  0,                    AV_OPT_TYPE_CONST,     {.i64 = NM_WHITE},   0,  0,          FLAGS, "color" },
      67             :     {     "pink",     0,                  0,                    AV_OPT_TYPE_CONST,     {.i64 = NM_PINK},    0,  0,          FLAGS, "color" },
      68             :     {     "brown",    0,                  0,                    AV_OPT_TYPE_CONST,     {.i64 = NM_BROWN},   0,  0,          FLAGS, "color" },
      69             :     {     "blue",     0,                  0,                    AV_OPT_TYPE_CONST,     {.i64 = NM_BLUE},    0,  0,          FLAGS, "color" },
      70             :     {     "violet",   0,                  0,                    AV_OPT_TYPE_CONST,     {.i64 = NM_VIOLET},  0,  0,          FLAGS, "color" },
      71             :     { "seed",         "set random seed",  OFFSET(seed),         AV_OPT_TYPE_INT64,     {.i64 = -1},        -1,  UINT_MAX,   FLAGS },
      72             :     { "s",            "set random seed",  OFFSET(seed),         AV_OPT_TYPE_INT64,     {.i64 = -1},        -1,  UINT_MAX,   FLAGS },
      73             :     { "nb_samples",   "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS },
      74             :     { "n",            "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS },
      75             :     {NULL}
      76             : };
      77             : 
      78             : AVFILTER_DEFINE_CLASS(anoisesrc);
      79             : 
      80           0 : static av_cold int query_formats(AVFilterContext *ctx)
      81             : {
      82           0 :     ANoiseSrcContext *s = ctx->priv;
      83             :     static const int64_t chlayouts[] = { AV_CH_LAYOUT_MONO, -1 };
      84           0 :     int sample_rates[] = { s->sample_rate, -1 };
      85             :     static const enum AVSampleFormat sample_fmts[] = {
      86             :         AV_SAMPLE_FMT_DBL,
      87             :         AV_SAMPLE_FMT_NONE
      88             :     };
      89             : 
      90             :     AVFilterFormats *formats;
      91             :     AVFilterChannelLayouts *layouts;
      92             :     int ret;
      93             : 
      94           0 :     formats = ff_make_format_list(sample_fmts);
      95           0 :     if (!formats)
      96           0 :         return AVERROR(ENOMEM);
      97           0 :     ret = ff_set_common_formats (ctx, formats);
      98           0 :     if (ret < 0)
      99           0 :         return ret;
     100             : 
     101           0 :     layouts = avfilter_make_format64_list(chlayouts);
     102           0 :     if (!layouts)
     103           0 :         return AVERROR(ENOMEM);
     104           0 :     ret = ff_set_common_channel_layouts(ctx, layouts);
     105           0 :     if (ret < 0)
     106           0 :         return ret;
     107             : 
     108           0 :     formats = ff_make_format_list(sample_rates);
     109           0 :     if (!formats)
     110           0 :         return AVERROR(ENOMEM);
     111           0 :     return ff_set_common_samplerates(ctx, formats);
     112             : }
     113             : 
     114           0 : static double white_filter(double white, double *buf)
     115             : {
     116           0 :     return white;
     117             : }
     118             : 
     119           0 : static double pink_filter(double white, double *buf)
     120             : {
     121             :     double pink;
     122             : 
     123             :     /* http://www.musicdsp.org/files/pink.txt */
     124           0 :     buf[0] = 0.99886 * buf[0] + white * 0.0555179;
     125           0 :     buf[1] = 0.99332 * buf[1] + white * 0.0750759;
     126           0 :     buf[2] = 0.96900 * buf[2] + white * 0.1538520;
     127           0 :     buf[3] = 0.86650 * buf[3] + white * 0.3104856;
     128           0 :     buf[4] = 0.55000 * buf[4] + white * 0.5329522;
     129           0 :     buf[5] = -0.7616 * buf[5] - white * 0.0168980;
     130           0 :     pink = buf[0] + buf[1] + buf[2] + buf[3] + buf[4] + buf[5] + buf[6] + white * 0.5362;
     131           0 :     buf[6] = white * 0.115926;
     132           0 :     return pink * 0.11;
     133             : }
     134             : 
     135           0 : static double blue_filter(double white, double *buf)
     136             : {
     137             :     double blue;
     138             : 
     139             :     /* Same as pink_filter but subtract the offsets rather than add */
     140           0 :     buf[0] = 0.0555179 * white - 0.99886 * buf[0];
     141           0 :     buf[1] = 0.0750759 * white - 0.99332 * buf[1];
     142           0 :     buf[2] = 0.1538520 * white - 0.96900 * buf[2];
     143           0 :     buf[3] = 0.3104856 * white - 0.86650 * buf[3];
     144           0 :     buf[4] = 0.5329522 * white - 0.55000 * buf[4];
     145           0 :     buf[5] = -0.016898 * white + 0.76160 * buf[5];
     146           0 :     blue = buf[0] + buf[1] + buf[2] + buf[3] + buf[4] + buf[5] + buf[6] + white * 0.5362;
     147           0 :     buf[6] = white * 0.115926;
     148           0 :     return blue * 0.11;
     149             : }
     150             : 
     151           0 : static double brown_filter(double white, double *buf)
     152             : {
     153             :     double brown;
     154             : 
     155           0 :     brown = ((0.02 * white) + buf[0]) / 1.02;
     156           0 :     buf[0] = brown;
     157           0 :     return brown * 3.5;
     158             : }
     159             : 
     160           0 : static double violet_filter(double white, double *buf)
     161             : {
     162             :     double violet;
     163             : 
     164           0 :     violet = ((0.02 * white) - buf[0]) / 1.02;
     165           0 :     buf[0] = violet;
     166           0 :     return violet * 3.5;
     167             : }
     168             : 
     169           0 : static av_cold int config_props(AVFilterLink *outlink)
     170             : {
     171           0 :     AVFilterContext *ctx = outlink->src;
     172           0 :     ANoiseSrcContext *s = ctx->priv;
     173             : 
     174           0 :     if (s->seed == -1)
     175           0 :         s->seed = av_get_random_seed();
     176           0 :     av_lfg_init(&s->c, s->seed);
     177             : 
     178           0 :     if (s->duration == 0)
     179           0 :         s->infinite = 1;
     180           0 :     s->duration = av_rescale(s->duration, s->sample_rate, AV_TIME_BASE);
     181             : 
     182           0 :     switch (s->color) {
     183           0 :     case NM_WHITE:  s->filter = white_filter;  break;
     184           0 :     case NM_PINK:   s->filter = pink_filter;   break;
     185           0 :     case NM_BROWN:  s->filter = brown_filter;  break;
     186           0 :     case NM_BLUE:   s->filter = blue_filter;   break;
     187           0 :     case NM_VIOLET: s->filter = violet_filter; break;
     188             :     }
     189             : 
     190           0 :     return 0;
     191             : }
     192             : 
     193           0 : static int request_frame(AVFilterLink *outlink)
     194             : {
     195           0 :     AVFilterContext *ctx = outlink->src;
     196           0 :     ANoiseSrcContext *s = ctx->priv;
     197             :     AVFrame *frame;
     198             :     int nb_samples, i;
     199             :     double *dst;
     200             : 
     201           0 :     if (!s->infinite && s->duration <= 0) {
     202           0 :         return AVERROR_EOF;
     203           0 :     } else if (!s->infinite && s->duration < s->nb_samples) {
     204           0 :         nb_samples = s->duration;
     205             :     } else {
     206           0 :         nb_samples = s->nb_samples;
     207             :     }
     208             : 
     209           0 :     if (!(frame = ff_get_audio_buffer(outlink, nb_samples)))
     210           0 :         return AVERROR(ENOMEM);
     211             : 
     212           0 :     dst = (double *)frame->data[0];
     213           0 :     for (i = 0; i < nb_samples; i++) {
     214             :         double white;
     215           0 :         white = s->amplitude * ((2 * ((double) av_lfg_get(&s->c) / 0xffffffff)) - 1);
     216           0 :         dst[i] = s->filter(white, s->buf);
     217             :     }
     218             : 
     219           0 :     if (!s->infinite)
     220           0 :         s->duration -= nb_samples;
     221             : 
     222           0 :     frame->pts = s->pts;
     223           0 :     s->pts    += nb_samples;
     224           0 :     return ff_filter_frame(outlink, frame);
     225             : }
     226             : 
     227             : static const AVFilterPad anoisesrc_outputs[] = {
     228             :     {
     229             :         .name          = "default",
     230             :         .type          = AVMEDIA_TYPE_AUDIO,
     231             :         .request_frame = request_frame,
     232             :         .config_props  = config_props,
     233             :     },
     234             :     { NULL }
     235             : };
     236             : 
     237             : AVFilter ff_asrc_anoisesrc = {
     238             :     .name          = "anoisesrc",
     239             :     .description   = NULL_IF_CONFIG_SMALL("Generate a noise audio signal."),
     240             :     .query_formats = query_formats,
     241             :     .priv_size     = sizeof(ANoiseSrcContext),
     242             :     .inputs        = NULL,
     243             :     .outputs       = anoisesrc_outputs,
     244             :     .priv_class    = &anoisesrc_class,
     245             : };

Generated by: LCOV version 1.13