[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