Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2013 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
  8.  * License 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 GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with FFmpeg; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19.  */
  20.  
  21. #include "libavutil/avassert.h"
  22. #include "libavutil/avstring.h"
  23. #include "libavutil/opt.h"
  24. #include "libavutil/samplefmt.h"
  25. #include "avfilter.h"
  26. #include "audio.h"
  27. #include "internal.h"
  28.  
  29. typedef struct AudioEchoContext {
  30.     const AVClass *class;
  31.     float in_gain, out_gain;
  32.     char *delays, *decays;
  33.     float *delay, *decay;
  34.     int nb_echoes;
  35.     int delay_index;
  36.     uint8_t **delayptrs;
  37.     int max_samples, fade_out;
  38.     int *samples;
  39.     int64_t next_pts;
  40.  
  41.     void (*echo_samples)(struct AudioEchoContext *ctx, uint8_t **delayptrs,
  42.                          uint8_t * const *src, uint8_t **dst,
  43.                          int nb_samples, int channels);
  44. } AudioEchoContext;
  45.  
  46. #define OFFSET(x) offsetof(AudioEchoContext, x)
  47. #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
  48.  
  49. static const AVOption aecho_options[] = {
  50.     { "in_gain",  "set signal input gain",  OFFSET(in_gain),  AV_OPT_TYPE_FLOAT,  {.dbl=0.6}, 0, 1, A },
  51.     { "out_gain", "set signal output gain", OFFSET(out_gain), AV_OPT_TYPE_FLOAT,  {.dbl=0.3}, 0, 1, A },
  52.     { "delays",   "set list of signal delays", OFFSET(delays), AV_OPT_TYPE_STRING, {.str="1000"}, 0, 0, A },
  53.     { "decays",   "set list of signal decays", OFFSET(decays), AV_OPT_TYPE_STRING, {.str="0.5"}, 0, 0, A },
  54.     { NULL }
  55. };
  56.  
  57. AVFILTER_DEFINE_CLASS(aecho);
  58.  
  59. static void count_items(char *item_str, int *nb_items)
  60. {
  61.     char *p;
  62.  
  63.     *nb_items = 1;
  64.     for (p = item_str; *p; p++) {
  65.         if (*p == '|')
  66.             (*nb_items)++;
  67.     }
  68.  
  69. }
  70.  
  71. static void fill_items(char *item_str, int *nb_items, float *items)
  72. {
  73.     char *p, *saveptr = NULL;
  74.     int i, new_nb_items = 0;
  75.  
  76.     p = item_str;
  77.     for (i = 0; i < *nb_items; i++) {
  78.         char *tstr = av_strtok(p, "|", &saveptr);
  79.         p = NULL;
  80.         new_nb_items += sscanf(tstr, "%f", &items[i]) == 1;
  81.     }
  82.  
  83.     *nb_items = new_nb_items;
  84. }
  85.  
  86. static av_cold void uninit(AVFilterContext *ctx)
  87. {
  88.     AudioEchoContext *s = ctx->priv;
  89.  
  90.     av_freep(&s->delay);
  91.     av_freep(&s->decay);
  92.     av_freep(&s->samples);
  93.  
  94.     if (s->delayptrs)
  95.         av_freep(&s->delayptrs[0]);
  96.     av_freep(&s->delayptrs);
  97. }
  98.  
  99. static av_cold int init(AVFilterContext *ctx)
  100. {
  101.     AudioEchoContext *s = ctx->priv;
  102.     int nb_delays, nb_decays, i;
  103.  
  104.     if (!s->delays || !s->decays) {
  105.         av_log(ctx, AV_LOG_ERROR, "Missing delays and/or decays.\n");
  106.         return AVERROR(EINVAL);
  107.     }
  108.  
  109.     count_items(s->delays, &nb_delays);
  110.     count_items(s->decays, &nb_decays);
  111.  
  112.     s->delay = av_realloc_f(s->delay, nb_delays, sizeof(*s->delay));
  113.     s->decay = av_realloc_f(s->decay, nb_decays, sizeof(*s->decay));
  114.     if (!s->delay || !s->decay)
  115.         return AVERROR(ENOMEM);
  116.  
  117.     fill_items(s->delays, &nb_delays, s->delay);
  118.     fill_items(s->decays, &nb_decays, s->decay);
  119.  
  120.     if (nb_delays != nb_decays) {
  121.         av_log(ctx, AV_LOG_ERROR, "Number of delays %d differs from number of decays %d.\n", nb_delays, nb_decays);
  122.         return AVERROR(EINVAL);
  123.     }
  124.  
  125.     s->nb_echoes = nb_delays;
  126.     if (!s->nb_echoes) {
  127.         av_log(ctx, AV_LOG_ERROR, "At least one decay & delay must be set.\n");
  128.         return AVERROR(EINVAL);
  129.     }
  130.  
  131.     s->samples = av_realloc_f(s->samples, nb_delays, sizeof(*s->samples));
  132.     if (!s->samples)
  133.         return AVERROR(ENOMEM);
  134.  
  135.     for (i = 0; i < nb_delays; i++) {
  136.         if (s->delay[i] <= 0 || s->delay[i] > 90000) {
  137.             av_log(ctx, AV_LOG_ERROR, "delay[%d]: %f is out of allowed range: (0, 90000]\n", i, s->delay[i]);
  138.             return AVERROR(EINVAL);
  139.         }
  140.         if (s->decay[i] <= 0 || s->decay[i] > 1) {
  141.             av_log(ctx, AV_LOG_ERROR, "decay[%d]: %f is out of allowed range: (0, 1]\n", i, s->decay[i]);
  142.             return AVERROR(EINVAL);
  143.         }
  144.     }
  145.  
  146.     s->next_pts = AV_NOPTS_VALUE;
  147.  
  148.     av_log(ctx, AV_LOG_DEBUG, "nb_echoes:%d\n", s->nb_echoes);
  149.     return 0;
  150. }
  151.  
  152. static int query_formats(AVFilterContext *ctx)
  153. {
  154.     AVFilterChannelLayouts *layouts;
  155.     AVFilterFormats *formats;
  156.     static const enum AVSampleFormat sample_fmts[] = {
  157.         AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P,
  158.         AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP,
  159.         AV_SAMPLE_FMT_NONE
  160.     };
  161.     int ret;
  162.  
  163.     layouts = ff_all_channel_layouts();
  164.     if (!layouts)
  165.         return AVERROR(ENOMEM);
  166.     ret = ff_set_common_channel_layouts(ctx, layouts);
  167.     if (ret < 0)
  168.         return ret;
  169.  
  170.     formats = ff_make_format_list(sample_fmts);
  171.     if (!formats)
  172.         return AVERROR(ENOMEM);
  173.     ret = ff_set_common_formats(ctx, formats);
  174.     if (ret < 0)
  175.         return ret;
  176.  
  177.     formats = ff_all_samplerates();
  178.     if (!formats)
  179.         return AVERROR(ENOMEM);
  180.     return ff_set_common_samplerates(ctx, formats);
  181. }
  182.  
  183. #define MOD(a, b) (((a) >= (b)) ? (a) - (b) : (a))
  184.  
  185. #define ECHO(name, type, min, max)                                          \
  186. static void echo_samples_## name ##p(AudioEchoContext *ctx,                 \
  187.                                      uint8_t **delayptrs,                   \
  188.                                      uint8_t * const *src, uint8_t **dst,   \
  189.                                      int nb_samples, int channels)          \
  190. {                                                                           \
  191.     const double out_gain = ctx->out_gain;                                  \
  192.     const double in_gain = ctx->in_gain;                                    \
  193.     const int nb_echoes = ctx->nb_echoes;                                   \
  194.     const int max_samples = ctx->max_samples;                               \
  195.     int i, j, chan, av_uninit(index);                                       \
  196.                                                                             \
  197.     av_assert1(channels > 0); /* would corrupt delay_index */               \
  198.                                                                             \
  199.     for (chan = 0; chan < channels; chan++) {                               \
  200.         const type *s = (type *)src[chan];                                  \
  201.         type *d = (type *)dst[chan];                                        \
  202.         type *dbuf = (type *)delayptrs[chan];                               \
  203.                                                                             \
  204.         index = ctx->delay_index;                                           \
  205.         for (i = 0; i < nb_samples; i++, s++, d++) {                        \
  206.             double out, in;                                                 \
  207.                                                                             \
  208.             in = *s;                                                        \
  209.             out = in * in_gain;                                             \
  210.             for (j = 0; j < nb_echoes; j++) {                               \
  211.                 int ix = index + max_samples - ctx->samples[j];             \
  212.                 ix = MOD(ix, max_samples);                                  \
  213.                 out += dbuf[ix] * ctx->decay[j];                            \
  214.             }                                                               \
  215.             out *= out_gain;                                                \
  216.                                                                             \
  217.             *d = av_clipd(out, min, max);                                   \
  218.             dbuf[index] = in;                                               \
  219.                                                                             \
  220.             index = MOD(index + 1, max_samples);                            \
  221.         }                                                                   \
  222.     }                                                                       \
  223.     ctx->delay_index = index;                                               \
  224. }
  225.  
  226. ECHO(dbl, double,  -1.0,      1.0      )
  227. ECHO(flt, float,   -1.0,      1.0      )
  228. ECHO(s16, int16_t, INT16_MIN, INT16_MAX)
  229. ECHO(s32, int32_t, INT32_MIN, INT32_MAX)
  230.  
  231. static int config_output(AVFilterLink *outlink)
  232. {
  233.     AVFilterContext *ctx = outlink->src;
  234.     AudioEchoContext *s = ctx->priv;
  235.     float volume = 1.0;
  236.     int i;
  237.  
  238.     for (i = 0; i < s->nb_echoes; i++) {
  239.         s->samples[i] = s->delay[i] * outlink->sample_rate / 1000.0;
  240.         s->max_samples = FFMAX(s->max_samples, s->samples[i]);
  241.         volume += s->decay[i];
  242.     }
  243.  
  244.     if (s->max_samples <= 0) {
  245.         av_log(ctx, AV_LOG_ERROR, "Nothing to echo - missing delay samples.\n");
  246.         return AVERROR(EINVAL);
  247.     }
  248.     s->fade_out = s->max_samples;
  249.  
  250.     if (volume * s->in_gain * s->out_gain > 1.0)
  251.         av_log(ctx, AV_LOG_WARNING,
  252.                "out_gain %f can cause saturation of output\n", s->out_gain);
  253.  
  254.     switch (outlink->format) {
  255.     case AV_SAMPLE_FMT_DBLP: s->echo_samples = echo_samples_dblp; break;
  256.     case AV_SAMPLE_FMT_FLTP: s->echo_samples = echo_samples_fltp; break;
  257.     case AV_SAMPLE_FMT_S16P: s->echo_samples = echo_samples_s16p; break;
  258.     case AV_SAMPLE_FMT_S32P: s->echo_samples = echo_samples_s32p; break;
  259.     }
  260.  
  261.  
  262.     if (s->delayptrs)
  263.         av_freep(&s->delayptrs[0]);
  264.     av_freep(&s->delayptrs);
  265.  
  266.     return av_samples_alloc_array_and_samples(&s->delayptrs, NULL,
  267.                                               outlink->channels,
  268.                                               s->max_samples,
  269.                                               outlink->format, 0);
  270. }
  271.  
  272. static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
  273. {
  274.     AVFilterContext *ctx = inlink->dst;
  275.     AudioEchoContext *s = ctx->priv;
  276.     AVFrame *out_frame;
  277.  
  278.     if (av_frame_is_writable(frame)) {
  279.         out_frame = frame;
  280.     } else {
  281.         out_frame = ff_get_audio_buffer(inlink, frame->nb_samples);
  282.         if (!out_frame)
  283.             return AVERROR(ENOMEM);
  284.         av_frame_copy_props(out_frame, frame);
  285.     }
  286.  
  287.     s->echo_samples(s, s->delayptrs, frame->extended_data, out_frame->extended_data,
  288.                     frame->nb_samples, inlink->channels);
  289.  
  290.     s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base);
  291.  
  292.     if (frame != out_frame)
  293.         av_frame_free(&frame);
  294.  
  295.     return ff_filter_frame(ctx->outputs[0], out_frame);
  296. }
  297.  
  298. static int request_frame(AVFilterLink *outlink)
  299. {
  300.     AVFilterContext *ctx = outlink->src;
  301.     AudioEchoContext *s = ctx->priv;
  302.     int ret;
  303.  
  304.     ret = ff_request_frame(ctx->inputs[0]);
  305.  
  306.     if (ret == AVERROR_EOF && !ctx->is_disabled && s->fade_out) {
  307.         int nb_samples = FFMIN(s->fade_out, 2048);
  308.         AVFrame *frame;
  309.  
  310.         frame = ff_get_audio_buffer(outlink, nb_samples);
  311.         if (!frame)
  312.             return AVERROR(ENOMEM);
  313.         s->fade_out -= nb_samples;
  314.  
  315.         av_samples_set_silence(frame->extended_data, 0,
  316.                                frame->nb_samples,
  317.                                outlink->channels,
  318.                                frame->format);
  319.  
  320.         s->echo_samples(s, s->delayptrs, frame->extended_data, frame->extended_data,
  321.                         frame->nb_samples, outlink->channels);
  322.  
  323.         frame->pts = s->next_pts;
  324.         if (s->next_pts != AV_NOPTS_VALUE)
  325.             s->next_pts += av_rescale_q(nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base);
  326.  
  327.         return ff_filter_frame(outlink, frame);
  328.     }
  329.  
  330.     return ret;
  331. }
  332.  
  333. static const AVFilterPad aecho_inputs[] = {
  334.     {
  335.         .name         = "default",
  336.         .type         = AVMEDIA_TYPE_AUDIO,
  337.         .filter_frame = filter_frame,
  338.     },
  339.     { NULL }
  340. };
  341.  
  342. static const AVFilterPad aecho_outputs[] = {
  343.     {
  344.         .name          = "default",
  345.         .request_frame = request_frame,
  346.         .config_props  = config_output,
  347.         .type          = AVMEDIA_TYPE_AUDIO,
  348.     },
  349.     { NULL }
  350. };
  351.  
  352. AVFilter ff_af_aecho = {
  353.     .name          = "aecho",
  354.     .description   = NULL_IF_CONFIG_SMALL("Add echoing to the audio."),
  355.     .query_formats = query_formats,
  356.     .priv_size     = sizeof(AudioEchoContext),
  357.     .priv_class    = &aecho_class,
  358.     .init          = init,
  359.     .uninit        = uninit,
  360.     .inputs        = aecho_inputs,
  361.     .outputs       = aecho_outputs,
  362. };
  363.