FFmpeg/libavfilter/af_earwax.c
Michael Niedermayer a05a44e205 Merge commit '7e350379f87e7f74420b4813170fe808e2313911'
* commit '7e350379f87e7f74420b4813170fe808e2313911':
  lavfi: switch to AVFrame.

Conflicts:
	doc/filters.texi
	libavfilter/af_ashowinfo.c
	libavfilter/audio.c
	libavfilter/avfilter.c
	libavfilter/avfilter.h
	libavfilter/buffersink.c
	libavfilter/buffersrc.c
	libavfilter/buffersrc.h
	libavfilter/f_select.c
	libavfilter/f_setpts.c
	libavfilter/fifo.c
	libavfilter/split.c
	libavfilter/src_movie.c
	libavfilter/version.h
	libavfilter/vf_aspect.c
	libavfilter/vf_bbox.c
	libavfilter/vf_blackframe.c
	libavfilter/vf_delogo.c
	libavfilter/vf_drawbox.c
	libavfilter/vf_drawtext.c
	libavfilter/vf_fade.c
	libavfilter/vf_fieldorder.c
	libavfilter/vf_fps.c
	libavfilter/vf_frei0r.c
	libavfilter/vf_gradfun.c
	libavfilter/vf_hqdn3d.c
	libavfilter/vf_lut.c
	libavfilter/vf_overlay.c
	libavfilter/vf_pad.c
	libavfilter/vf_scale.c
	libavfilter/vf_showinfo.c
	libavfilter/vf_transpose.c
	libavfilter/vf_vflip.c
	libavfilter/vf_yadif.c
	libavfilter/video.c
	libavfilter/vsrc_testsrc.c
	libavfilter/yadif.h

Following are notes about the merge authorship and various technical details.

Michael Niedermayer:
  * Main merge operation, notably avfilter.c and video.c
  * Switch to AVFrame:
    - afade
    - anullsrc
    - apad
    - aresample
    - blackframe
    - deshake
    - idet
    - il
    - mandelbrot
    - mptestsrc
    - noise
    - setfield
    - smartblur
    - tinterlace
  * various merge changes and fixes in:
    - ashowinfo
    - blackdetect
    - field
    - fps
    - select
    - testsrc
    - yadif

Nicolas George:
  * Switch to AVFrame:
    - make rawdec work with refcounted frames. Adapted from commit
      759001c534 by Anton Khirnov.
      Also, fix the use of || instead of | in a flags check.
    - make buffer sink and src, audio and video work all together

Clément Bœsch:
  * Switch to AVFrame:
    - aevalsrc
    - alphaextract
    - blend
    - cellauto
    - colormatrix
    - concat
    - earwax
    - ebur128
    - edgedetect
    - geq
    - histeq
    - histogram
    - hue
    - kerndeint
    - life
    - movie
    - mp (with the help of Michael)
    - overlay
    - pad
    - pan
    - pp
    - pp
    - removelogo
    - sendcmd
    - showspectrum
    - showwaves
    - silencedetect
    - stereo3d
    - subtitles
    - super2xsai
    - swapuv
    - thumbnail
    - tile

Hendrik Leppkes:
  * Switch to AVFrame:
    - aconvert
    - amerge
    - asetnsamples
    - atempo
    - biquads

Matthieu Bouron:
  * Switch to AVFrame
    - alphamerge
    - decimate
    - volumedetect

Stefano Sabatini:
  * Switch to AVFrame:
    - astreamsync
    - flite
    - framestep

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Signed-off-by: Nicolas George <nicolas.george@normalesup.org>
Signed-off-by: Clément Bœsch <ubitux@gmail.com>
Signed-off-by: Hendrik Leppkes <h.leppkes@gmail.com>
Signed-off-by: Matthieu Bouron <matthieu.bouron@gmail.com>
Signed-off-by: Stefano Sabatini <stefasab@gmail.com>

Merged-by: Michael Niedermayer <michaelni@gmx.at>
2013-03-10 01:40:35 +01:00

170 lines
5.9 KiB
C

/*
* Copyright (c) 2011 Mina Nagy Zaki
* Copyright (c) 2000 Edward Beingessner And Sundry Contributors.
* This source code is freely redistributable and may be used for any purpose.
* This copyright notice must be maintained. Edward Beingessner And Sundry
* Contributors are not responsible for the consequences of using this
* software.
*
* 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
*/
/**
* @file
* Stereo Widening Effect. Adds audio cues to move stereo image in
* front of the listener. Adapted from the libsox earwax effect.
*/
#include "libavutil/channel_layout.h"
#include "avfilter.h"
#include "audio.h"
#include "formats.h"
#define NUMTAPS 64
static const int8_t filt[NUMTAPS] = {
/* 30° 330° */
4, -6, /* 32 tap stereo FIR filter. */
4, -11, /* One side filters as if the */
-1, -5, /* signal was from 30 degrees */
3, 3, /* from the ear, the other as */
-2, 5, /* if 330 degrees. */
-5, 0,
9, 1,
6, 3, /* Input */
-4, -1, /* Left Right */
-5, -3, /* __________ __________ */
-2, -5, /* | | | | */
-7, 1, /* .---| Hh,0(f) | | Hh,0(f) |---. */
6, -7, /* / |__________| |__________| \ */
30, -29, /* / \ / \ */
12, -3, /* / X \ */
-11, 4, /* / / \ \ */
-3, 7, /* ____V_____ __________V V__________ _____V____ */
-20, 23, /* | | | | | | | | */
2, 0, /* | Hh,30(f) | | Hh,330(f)| | Hh,330(f)| | Hh,30(f) | */
1, -6, /* |__________| |__________| |__________| |__________| */
-14, -5, /* \ ___ / \ ___ / */
15, -18, /* \ / \ / _____ \ / \ / */
6, 7, /* `->| + |<--' / \ `-->| + |<-' */
15, -10, /* \___/ _/ \_ \___/ */
-14, 22, /* \ / \ / \ / */
-7, -2, /* `--->| | | |<---' */
-4, 9, /* \_/ \_/ */
6, -12, /* */
6, -6, /* Headphones */
0, -11,
0, -5,
4, 0};
typedef struct {
int16_t taps[NUMTAPS * 2];
} EarwaxContext;
static int query_formats(AVFilterContext *ctx)
{
static const int sample_rates[] = { 44100, -1 };
AVFilterFormats *formats = NULL;
AVFilterChannelLayouts *layout = NULL;
ff_add_format(&formats, AV_SAMPLE_FMT_S16);
ff_set_common_formats(ctx, formats);
ff_add_channel_layout(&layout, AV_CH_LAYOUT_STEREO);
ff_set_common_channel_layouts(ctx, layout);
ff_set_common_samplerates(ctx, ff_make_format_list(sample_rates));
return 0;
}
//FIXME: replace with DSPContext.scalarproduct_int16
static inline int16_t *scalarproduct(const int16_t *in, const int16_t *endin, int16_t *out)
{
int32_t sample;
int16_t j;
while (in < endin) {
sample = 32;
for (j = 0; j < NUMTAPS; j++)
sample += in[j] * filt[j];
*out = sample >> 6;
out++;
in++;
}
return out;
}
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
{
AVFilterLink *outlink = inlink->dst->outputs[0];
int16_t *taps, *endin, *in, *out;
AVFrame *outsamples = ff_get_audio_buffer(inlink, insamples->nb_samples);
int ret;
if (!outsamples) {
av_frame_free(&insamples);
return AVERROR(ENOMEM);
}
av_frame_copy_props(outsamples, insamples);
taps = ((EarwaxContext *)inlink->dst->priv)->taps;
out = (int16_t *)outsamples->data[0];
in = (int16_t *)insamples ->data[0];
// copy part of new input and process with saved input
memcpy(taps+NUMTAPS, in, NUMTAPS * sizeof(*taps));
out = scalarproduct(taps, taps + NUMTAPS, out);
// process current input
endin = in + insamples->nb_samples * 2 - NUMTAPS;
scalarproduct(in, endin, out);
// save part of input for next round
memcpy(taps, endin, NUMTAPS * sizeof(*taps));
ret = ff_filter_frame(outlink, outsamples);
av_frame_free(&insamples);
return ret;
}
static const AVFilterPad earwax_inputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
},
{ NULL }
};
static const AVFilterPad earwax_outputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
},
{ NULL }
};
AVFilter avfilter_af_earwax = {
.name = "earwax",
.description = NULL_IF_CONFIG_SMALL("Widen the stereo image."),
.query_formats = query_formats,
.priv_size = sizeof(EarwaxContext),
.inputs = earwax_inputs,
.outputs = earwax_outputs,
};