[FFmpeg-devel] [PATCH] avfilter: add compensationdelay filter

Ganesh Ajjanagadde gajjanag at mit.edu
Wed Nov 25 02:22:19 CET 2015


On Tue, Nov 24, 2015 at 7:18 AM, Paul B Mahol <onemda at gmail.com> wrote:
> Subject: [PATCH] avfilter: add compensation delay line filter
>
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
>  doc/filters.texi                   |  42 ++++++++
>  libavfilter/Makefile               |   1 +
>  libavfilter/af_compensationdelay.c | 196 +++++++++++++++++++++++++++++++++++++
>  libavfilter/allfilters.c           |   1 +
>  4 files changed, 240 insertions(+)
>  create mode 100644 libavfilter/af_compensationdelay.c
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index f351390..d8b2fb5 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -1628,6 +1628,48 @@
> compand=.1|.1:.1|.1:-45.1/-45.1|-45/-900|0/-900:.01:45:-90:.1
>  @end example
>  @end itemize
>
> + at section compensationdelay
> +
> +Compensation Delay Line is a metric based delay to compensate differing
> +positions of microphones or speakers.
> +
> +For example, you have recorded guitar with two microphones placed in
> +different location. Because the front of sound wave has fixed speed in
> +normal conditions, the phasing of microphones can vary and depends on
> +their location and interposition. The best sound mix you will get when
> +these microphones are in phase (synchronized). Note that distance of
> +~30 cm between microphones makes one microphone to capture signal in
> +antiphase to another microphone. That makes the final mix sounding moody.
> +This filter helps to solve phasing problems by adding different delays
> +to each microphone track and make them synchronized.
> +
> +The best result can be reached when you take one track as base and
> +synchronize other tracks one by one with it.
> +Remember that synchronization/delay tolerance depends on sample rate, too.
> +Higher sample rates will give more tolerance.
> +
> +It accepts the following parameters:
> +
> + at table @option
> + at item mm
> +Set millimeters distance. This is compensation distance for fine tuning.
> +
> + at item cm
> +Set cm distance. This is compensation distance for tighten distance setup.
> +
> + at item m
> +Set meters distance. This is compensation distance for hard distance setup.
> +
> + at item dry
> +Set dry amount. Amount of unprocessed (dry) signal.
> +
> + at item wet
> +Set wet amount. Amount of processed (wet) signal.
> +
> + at item temp
> +Set temperature degree in Celzius. This is the temperature of the environment.
> + at end table
> +
>  @section dcshift
>  Apply a DC shift to the audio.
>
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index 1f4abeb..c896374 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -64,6 +64,7 @@ OBJS-$(CONFIG_CHANNELMAP_FILTER)             +=
> af_channelmap.o
>  OBJS-$(CONFIG_CHANNELSPLIT_FILTER)           += af_channelsplit.o
>  OBJS-$(CONFIG_CHORUS_FILTER)                 += af_chorus.o
> generate_wave_table.o
>  OBJS-$(CONFIG_COMPAND_FILTER)                += af_compand.o
> +OBJS-$(CONFIG_COMPENSATIONDELAY_FILTER)      += af_compensationdelay.o
>  OBJS-$(CONFIG_DCSHIFT_FILTER)                += af_dcshift.o
>  OBJS-$(CONFIG_DYNAUDNORM_FILTER)             += af_dynaudnorm.o
>  OBJS-$(CONFIG_EARWAX_FILTER)                 += af_earwax.o
> diff --git a/libavfilter/af_compensationdelay.c
> b/libavfilter/af_compensationdelay.c
> new file mode 100644
> index 0000000..1a32879
> --- /dev/null
> +++ b/libavfilter/af_compensationdelay.c
> @@ -0,0 +1,196 @@
> +/*
> + * Copyright (c) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor
> Harald Johansen, Vladimir Sadovnikov and others
> + * Copyright (c) 2015 Paul B Mahol
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include "libavutil/opt.h"
> +#include "libavutil/samplefmt.h"
> +#include "avfilter.h"
> +#include "audio.h"
> +#include "internal.h"
> +
> +typedef struct CompensationDelayContext {
> +    const AVClass *class;
> +    int distance_mm;
> +    int distance_cm;
> +    int distance_m;
> +    double dry, wet;
> +    int temp;
> +
> +    unsigned delay;
> +    unsigned w_ptr;
> +    unsigned buf_size;
> +    AVFrame *delay_frame;
> +} CompensationDelayContext;
> +
> +#define OFFSET(x) offsetof(CompensationDelayContext, x)
> +#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
> +
> +static const AVOption compensationdelay_options[] = {
> +    { "mm",   "set mm distance",    OFFSET(distance_mm),
> AV_OPT_TYPE_INT,    {.i64=0},                           0,  10, A },
> +    { "cm",   "set cm distance",    OFFSET(distance_cm),
> AV_OPT_TYPE_INT,    {.i64=0},                           0, 100, A },
> +    { "m",    "set meter distance", OFFSET(distance_m),
> AV_OPT_TYPE_INT,    {.i64=0},                           0, 100, A },
> +    { "dry",  "set dry amount",     OFFSET(dry),
> AV_OPT_TYPE_DOUBLE, {.dbl=0.000244140625}, 0.000244140625,   1, A },
> +    { "wet",  "set wet amount",     OFFSET(wet),
> AV_OPT_TYPE_DOUBLE, {.dbl=1},              0.000244140625,   1, A },
> +    { "temp", "set temperature **C", OFFSET(temp),
> AV_OPT_TYPE_INT,    {.i64=20},                        -50,  50, A },
> +    { NULL }
> +};
> +
> +AVFILTER_DEFINE_CLASS(compensationdelay);
> +
> +// The maximum distance for options
> +#define COMP_DELAY_MAX_DISTANCE            (100.0 * 100.0 + 100.0 * 1.0 + 1.0)
> +// The actual speed of sound in normal conditions
> +#define COMP_DELAY_SOUND_SPEED_KM_H(temp)  1.85325 * (643.95 *
> pow(((temp + 273.15) / 273.15), 0.5))
> +#define COMP_DELAY_SOUND_SPEED_CM_S(temp)
> (COMP_DELAY_SOUND_SPEED_KM_H(temp) * (1000.0 * 100.0) /* cm/km */ /
> (60.0 * 60.0) /* s/h */)
> +#define COMP_DELAY_SOUND_FRONT_DELAY(temp) (1.0 /
> COMP_DELAY_SOUND_SPEED_CM_S(temp))
> +// The maximum delay may be reached by this filter
> +#define COMP_DELAY_MAX_DELAY               (COMP_DELAY_MAX_DISTANCE *
> COMP_DELAY_SOUND_FRONT_DELAY(50))
> +
> +static int query_formats(AVFilterContext *ctx)
> +{
> +    AVFilterChannelLayouts *layouts;
> +    AVFilterFormats *formats;
> +    static const enum AVSampleFormat sample_fmts[] = {
> +        AV_SAMPLE_FMT_DBLP,
> +        AV_SAMPLE_FMT_NONE
> +    };
> +    int ret;
> +
> +    layouts = ff_all_channel_counts();
> +    if (!layouts)
> +        return AVERROR(ENOMEM);
> +    ret = ff_set_common_channel_layouts(ctx, layouts);
> +    if (ret < 0)
> +        return ret;
> +
> +    formats = ff_make_format_list(sample_fmts);
> +    if (!formats)
> +        return AVERROR(ENOMEM);
> +    ret = ff_set_common_formats(ctx, formats);
> +    if (ret < 0)
> +        return ret;
> +
> +    formats = ff_all_samplerates();
> +    if (!formats)
> +        return AVERROR(ENOMEM);
> +    return ff_set_common_samplerates(ctx, formats);

Are you sure this does not memleak e.g when ff_all_channel_counts,
ff_set_common_channel_layouts succeed and ff_make_format_list fails?
Maybe a goto fail?

[...]


More information about the ffmpeg-devel mailing list