Commit 49bbfb9d authored by Paul B Mahol's avatar Paul B Mahol

avfilter: add arbitrary audio FIR filter

Signed-off-by: 's avatarPaul B Mahol <onemda@gmail.com>
parent f1a4dd5e
......@@ -3083,6 +3083,8 @@ unix_protocol_select="network"
# filters
afftfilt_filter_deps="avcodec"
afftfilt_filter_select="fft"
afir_filter_deps="avcodec"
afir_filter_select="fft"
amovie_filter_deps="avcodec avformat"
aresample_filter_deps="swresample"
ass_filter_deps="libass"
......@@ -6476,6 +6478,7 @@ enabled zlib && add_cppflags -DZLIB_CONST
# conditional library dependencies, in linking order
enabled afftfilt_filter && prepend avfilter_deps "avcodec"
enabled afir_filter && prepend avfilter_deps "avcodec"
enabled amovie_filter && prepend avfilter_deps "avformat avcodec"
enabled aresample_filter && prepend avfilter_deps "swresample"
enabled atempo_filter && prepend avfilter_deps "avcodec"
......
......@@ -878,6 +878,49 @@ afftfilt="1-clip((b/nb)*b,0,1)"
@end example
@end itemize
@section afir
Apply an arbitrary Frequency Impulse Response filter.
This filter is designed for applying long FIR filters,
up to 30 seconds long.
It can be used as component for digital crossover filters,
room equalization, cross talk cancellation, wavefield synthesis,
auralization, ambiophonics and ambisonics.
This filter uses second stream as FIR coefficients.
If second stream holds single channel, it will be used
for all input channels in first stream, otherwise
number of channels in second stream must be same as
number of channels in first stream.
It accepts the following parameters:
@table @option
@item dry
Set dry gain. This sets input gain.
@item wet
Set wet gain. This sets final output gain.
@item length
Set Impulse Response filter length. Default is 1, which means whole IR is processed.
@item again
Enable applying gain measured from power of IR.
@end table
@subsection Examples
@itemize
@item
Apply reverb to stream using mono IR file as second input, complete command using ffmpeg:
@example
ffmpeg -i input.wav -i middle_tunnel_1way_mono.wav -lavfi afir output.wav
@end example
@end itemize
@anchor{aformat}
@section aformat
......
......@@ -37,6 +37,7 @@ OBJS-$(CONFIG_AEMPHASIS_FILTER) += af_aemphasis.o
OBJS-$(CONFIG_AEVAL_FILTER) += aeval.o
OBJS-$(CONFIG_AFADE_FILTER) += af_afade.o
OBJS-$(CONFIG_AFFTFILT_FILTER) += af_afftfilt.o window_func.o
OBJS-$(CONFIG_AFIR_FILTER) += af_afir.o
OBJS-$(CONFIG_AFORMAT_FILTER) += af_aformat.o
OBJS-$(CONFIG_AGATE_FILTER) += af_agate.o
OBJS-$(CONFIG_AINTERLEAVE_FILTER) += f_interleave.o
......
This diff is collapsed.
/*
* Copyright (c) 2017 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
*/
#ifndef AVFILTER_AFIR_H
#define AVFILTER_AFIR_H
#include "libavutil/audio_fifo.h"
#include "libavutil/common.h"
#include "libavutil/float_dsp.h"
#include "libavutil/opt.h"
#include "libavcodec/avfft.h"
#include "audio.h"
#include "avfilter.h"
#include "formats.h"
#include "internal.h"
#define MAX_IR_DURATION 30
typedef struct AudioFIRContext {
const AVClass *class;
float wet_gain;
float dry_gain;
float length;
int again;
float gain;
int eof_coeffs;
int have_coeffs;
int nb_coeffs;
int nb_taps;
int part_size;
int part_index;
int coeff_size;
int block_size;
int nb_partitions;
int nb_channels;
int ir_length;
int fft_length;
int nb_coef_channels;
int one2many;
int nb_samples;
int want_skip;
int need_padding;
RDFTContext **rdft, **irdft;
float **sum;
float **block;
FFTComplex **coeff;
AVAudioFifo *fifo[2];
AVFrame *in[2];
AVFrame *buffer;
int64_t pts;
int index;
AVFloatDSPContext *fdsp;
void (*fcmul_add)(float *sum, const float *t, const float *c,
ptrdiff_t len);
} AudioFIRContext;
void ff_afir_init_x86(AudioFIRContext *s);
#endif /* AVFILTER_AFIR_H */
......@@ -50,6 +50,7 @@ static void register_all(void)
REGISTER_FILTER(AEVAL, aeval, af);
REGISTER_FILTER(AFADE, afade, af);
REGISTER_FILTER(AFFTFILT, afftfilt, af);
REGISTER_FILTER(AFIR, afir, af);
REGISTER_FILTER(AFORMAT, aformat, af);
REGISTER_FILTER(AGATE, agate, af);
REGISTER_FILTER(AINTERLEAVE, ainterleave, af);
......
......@@ -30,7 +30,7 @@
#include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 6
#define LIBAVFILTER_VERSION_MINOR 88
#define LIBAVFILTER_VERSION_MINOR 89
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
......
OBJS-$(CONFIG_AFIR_FILTER) += x86/af_afir_init.o
OBJS-$(CONFIG_BLEND_FILTER) += x86/vf_blend_init.o
OBJS-$(CONFIG_BWDIF_FILTER) += x86/vf_bwdif_init.o
OBJS-$(CONFIG_COLORSPACE_FILTER) += x86/colorspacedsp_init.o
......@@ -23,6 +24,7 @@ OBJS-$(CONFIG_VOLUME_FILTER) += x86/af_volume_init.o
OBJS-$(CONFIG_W3FDIF_FILTER) += x86/vf_w3fdif_init.o
OBJS-$(CONFIG_YADIF_FILTER) += x86/vf_yadif_init.o
YASM-OBJS-$(CONFIG_AFIR_FILTER) += x86/af_afir.o
YASM-OBJS-$(CONFIG_BLEND_FILTER) += x86/vf_blend.o
YASM-OBJS-$(CONFIG_BWDIF_FILTER) += x86/vf_bwdif.o
YASM-OBJS-$(CONFIG_COLORSPACE_FILTER) += x86/colorspacedsp.o
......
;*****************************************************************************
;* x86-optimized functions for afir filter
;* Copyright (c) 2017 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/x86/x86util.asm"
SECTION .text
;------------------------------------------------------------------------------
; void ff_fcmul_add(float *sum, const float *t, const float *c, int len)
;------------------------------------------------------------------------------
INIT_XMM sse3
cglobal fcmul_add, 4,4,6, sum, t, c, len
shl lend, 3
add lend, mmsize*2
add tq, lenq
add cq, lenq
add sumq, lenq
neg lenq
ALIGN 16
.loop:
movsldup m0, [tq + lenq]
movsldup m3, [tq + lenq+mmsize]
movaps m1, [cq + lenq]
movaps m4, [cq + lenq+mmsize]
mulps m0, m1
mulps m3, m4
shufps m1, m1, 0xb1
shufps m4, m4, 0xb1
movshdup m2, [tq + lenq]
movshdup m5, [tq + lenq+mmsize]
mulps m2, m1
mulps m5, m4
addsubps m0, m2
addsubps m3, m5
addps m0, [sumq + lenq]
addps m3, [sumq + lenq+mmsize]
movaps [sumq + lenq], m0
movaps [sumq + lenq+mmsize], m3
add lenq, mmsize*2
jl .loop
REP_RET
/*
* 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 "config.h"
#include "libavutil/attributes.h"
#include "libavutil/cpu.h"
#include "libavutil/x86/cpu.h"
#include "libavfilter/af_afir.h"
void ff_fcmul_add_sse3(float *sum, const float *t, const float *c,
ptrdiff_t len);
av_cold void ff_afir_init_x86(AudioFIRContext *s)
{
int cpu_flags = av_get_cpu_flags();
if (EXTERNAL_SSE3(cpu_flags)) {
s->fcmul_add = ff_fcmul_add_sse3;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment