Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
ca5cf846
Commit
ca5cf846
authored
Jun 16, 2017
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter: add superequalizer filter
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
d790f18a
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
415 additions
and
1 deletion
+415
-1
Changelog
Changelog
+1
-0
filters.texi
doc/filters.texi
+43
-0
Makefile
libavfilter/Makefile
+1
-0
af_superequalizer.c
libavfilter/af_superequalizer.c
+368
-0
allfilters.c
libavfilter/allfilters.c
+1
-0
version.h
libavfilter/version.h
+1
-1
No files found.
Changelog
View file @
ca5cf846
...
@@ -20,6 +20,7 @@ version <next>:
...
@@ -20,6 +20,7 @@ version <next>:
- sofalizer filter switched to libmysofa
- sofalizer filter switched to libmysofa
- Gremlin Digital Video demuxer and decoder
- Gremlin Digital Video demuxer and decoder
- headphone audio filter
- headphone audio filter
- superequalizer audio filter
version 3.3:
version 3.3:
- CrystalHD decoder moved to new decode API
- CrystalHD decoder moved to new decode API
...
...
doc/filters.texi
View file @
ca5cf846
...
@@ -3835,6 +3835,49 @@ channels. Default is 0.3.
...
@@ -3835,6 +3835,49 @@ channels. Default is 0.3.
Set level of input signal of original channel. Default is 0.8.
Set level of input signal of original channel. Default is 0.8.
@end table
@end table
@section superequalizer
Apply 18th band equalizer.
The filter accpets the following options:
@table @option
@item 1b
Set 65Hz band gain.
@item 2b
Set 92Hz band gain.
@item 3b
Set 131Hz band gain.
@item 4b
Set 185Hz band gain.
@item 5b
Set 262Hz band gain.
@item 6b
Set 370Hz band gain.
@item 7b
Set 523Hz band gain.
@item 8b
Set 740Hz band gain.
@item 9b
Set 1047Hz band gain.
@item 10b
Set 1480Hz band gain.
@item 11b
Set 2093Hz band gain.
@item 12b
Set 2960Hz band gain.
@item 13b
Set 4186Hz band gain.
@item 14b
Set 5920Hz band gain.
@item 15b
Set 8372Hz band gain.
@item 16b
Set 11840Hz band gain.
@item 17b
Set 16744Hz band gain.
@item 18b
Set 20000Hz band gain.
@end table
@section surround
@section surround
Apply audio surround upmix filter.
Apply audio surround upmix filter.
...
...
libavfilter/Makefile
View file @
ca5cf846
...
@@ -109,6 +109,7 @@ OBJS-$(CONFIG_SILENCEREMOVE_FILTER) += af_silenceremove.o
...
@@ -109,6 +109,7 @@ OBJS-$(CONFIG_SILENCEREMOVE_FILTER) += af_silenceremove.o
OBJS-$(CONFIG_SOFALIZER_FILTER)
+=
af_sofalizer.o
OBJS-$(CONFIG_SOFALIZER_FILTER)
+=
af_sofalizer.o
OBJS-$(CONFIG_STEREOTOOLS_FILTER)
+=
af_stereotools.o
OBJS-$(CONFIG_STEREOTOOLS_FILTER)
+=
af_stereotools.o
OBJS-$(CONFIG_STEREOWIDEN_FILTER)
+=
af_stereowiden.o
OBJS-$(CONFIG_STEREOWIDEN_FILTER)
+=
af_stereowiden.o
OBJS-$(CONFIG_SUPEREQUALIZER_FILTER)
+=
af_superequalizer.o
OBJS-$(CONFIG_SURROUND_FILTER)
+=
af_surround.o
OBJS-$(CONFIG_SURROUND_FILTER)
+=
af_surround.o
OBJS-$(CONFIG_TREBLE_FILTER)
+=
af_biquads.o
OBJS-$(CONFIG_TREBLE_FILTER)
+=
af_biquads.o
OBJS-$(CONFIG_TREMOLO_FILTER)
+=
af_tremolo.o
OBJS-$(CONFIG_TREMOLO_FILTER)
+=
af_tremolo.o
...
...
libavfilter/af_superequalizer.c
0 → 100644
View file @
ca5cf846
/*
* Copyright (c) 2002 Naoki Shibata
* 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/opt.h"
#include "libavcodec/avfft.h"
#include "audio.h"
#include "avfilter.h"
#include "internal.h"
#define NBANDS 17
#define M 15
typedef
struct
EqParameter
{
float
lower
,
upper
,
gain
;
}
EqParameter
;
typedef
struct
SuperEqualizerContext
{
const
AVClass
*
class
;
EqParameter
params
[
NBANDS
+
1
];
float
gains
[
NBANDS
+
1
];
float
fact
[
M
+
1
];
float
aa
;
float
iza
;
float
*
ires
,
*
irest
;
float
*
fsamples
;
int
winlen
,
tabsize
;
AVFrame
*
in
,
*
out
;
RDFTContext
*
rdft
,
*
irdft
;
}
SuperEqualizerContext
;
static
const
float
bands
[]
=
{
65
.
406392
,
92
.
498606
,
130
.
81278
,
184
.
99721
,
261
.
62557
,
369
.
99442
,
523
.
25113
,
739
.
9884
,
1046
.
5023
,
1479
.
9768
,
2093
.
0045
,
2959
.
9536
,
4186
.
00
91
,
5919
.
9072
,
8372
.
01
81
,
11839
.
814
,
16744
.
036
};
static
float
izero
(
SuperEqualizerContext
*
s
,
float
x
)
{
float
ret
=
1
;
int
m
;
for
(
m
=
1
;
m
<=
M
;
m
++
)
{
float
t
;
t
=
pow
(
x
/
2
,
m
)
/
s
->
fact
[
m
];
ret
+=
t
*
t
;
}
return
ret
;
}
static
float
hn_lpf
(
int
n
,
float
f
,
float
fs
)
{
float
t
=
1
/
fs
;
float
omega
=
2
*
M_PI
*
f
;
if
(
n
*
omega
*
t
==
0
)
return
2
*
f
*
t
;
return
2
*
f
*
t
*
sinf
(
n
*
omega
*
t
)
/
(
n
*
omega
*
t
);
}
static
float
hn_imp
(
int
n
)
{
return
n
==
0
?
1
.
f
:
0
.
f
;
}
static
float
hn
(
int
n
,
EqParameter
*
param
,
float
fs
)
{
float
ret
,
lhn
;
int
i
;
lhn
=
hn_lpf
(
n
,
param
[
0
].
upper
,
fs
);
ret
=
param
[
0
].
gain
*
lhn
;
for
(
i
=
1
;
i
<
NBANDS
+
1
&&
param
[
i
].
upper
<
fs
/
2
;
i
++
)
{
float
lhn2
=
hn_lpf
(
n
,
param
[
i
].
upper
,
fs
);
ret
+=
param
[
i
].
gain
*
(
lhn2
-
lhn
);
lhn
=
lhn2
;
}
ret
+=
param
[
i
].
gain
*
(
hn_imp
(
n
)
-
lhn
);
return
ret
;
}
static
float
alpha
(
float
a
)
{
if
(
a
<=
21
)
return
0
;
if
(
a
<=
50
)
return
.
5842
f
*
pow
(
a
-
21
,
0
.
4
f
)
+
0
.
07
886
f
*
(
a
-
21
);
return
.
1102
f
*
(
a
-
8
.
7
f
);
}
static
float
win
(
SuperEqualizerContext
*
s
,
float
n
,
int
N
)
{
return
izero
(
s
,
alpha
(
s
->
aa
)
*
sqrtf
(
1
-
4
*
n
*
n
/
((
N
-
1
)
*
(
N
-
1
))))
/
s
->
iza
;
}
static
void
process_param
(
float
*
bc
,
EqParameter
*
param
,
float
fs
)
{
int
i
;
for
(
i
=
0
;
i
<=
NBANDS
;
i
++
)
{
param
[
i
].
lower
=
i
==
0
?
0
:
bands
[
i
-
1
];
param
[
i
].
upper
=
i
==
NBANDS
-
1
?
fs
:
bands
[
i
];
param
[
i
].
gain
=
bc
[
i
];
}
}
static
int
equ_init
(
SuperEqualizerContext
*
s
,
int
wb
)
{
int
i
,
j
;
s
->
rdft
=
av_rdft_init
(
wb
,
DFT_R2C
);
s
->
irdft
=
av_rdft_init
(
wb
,
IDFT_C2R
);
if
(
!
s
->
rdft
||
!
s
->
irdft
)
return
AVERROR
(
ENOMEM
);
s
->
aa
=
96
;
s
->
winlen
=
(
1
<<
(
wb
-
1
))
-
1
;
s
->
tabsize
=
1
<<
wb
;
s
->
ires
=
av_calloc
(
s
->
tabsize
,
sizeof
(
float
));
s
->
irest
=
av_calloc
(
s
->
tabsize
,
sizeof
(
float
));
s
->
fsamples
=
av_calloc
(
s
->
tabsize
,
sizeof
(
float
));
for
(
i
=
0
;
i
<=
M
;
i
++
)
{
s
->
fact
[
i
]
=
1
;
for
(
j
=
1
;
j
<=
i
;
j
++
)
s
->
fact
[
i
]
*=
j
;
}
s
->
iza
=
izero
(
s
,
alpha
(
s
->
aa
));
return
0
;
}
static
void
make_fir
(
SuperEqualizerContext
*
s
,
float
*
lbc
,
float
*
rbc
,
EqParameter
*
param
,
float
fs
)
{
const
int
winlen
=
s
->
winlen
;
const
int
tabsize
=
s
->
tabsize
;
float
*
nires
;
int
i
;
if
(
fs
<=
0
)
return
;
process_param
(
lbc
,
param
,
fs
);
for
(
i
=
0
;
i
<
winlen
;
i
++
)
s
->
irest
[
i
]
=
hn
(
i
-
winlen
/
2
,
param
,
fs
)
*
win
(
s
,
i
-
winlen
/
2
,
winlen
);
for
(;
i
<
tabsize
;
i
++
)
s
->
irest
[
i
]
=
0
;
av_rdft_calc
(
s
->
rdft
,
s
->
irest
);
nires
=
s
->
ires
;
for
(
i
=
0
;
i
<
tabsize
;
i
++
)
nires
[
i
]
=
s
->
irest
[
i
];
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
in
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
SuperEqualizerContext
*
s
=
ctx
->
priv
;
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
const
float
*
ires
=
s
->
ires
;
float
*
fsamples
=
s
->
fsamples
;
int
ch
,
i
;
AVFrame
*
out
=
ff_get_audio_buffer
(
outlink
,
s
->
winlen
);
float
*
src
,
*
dst
,
*
ptr
;
if
(
!
out
)
{
av_frame_free
(
&
in
);
return
AVERROR
(
ENOMEM
);
}
for
(
ch
=
0
;
ch
<
in
->
channels
;
ch
++
)
{
ptr
=
(
float
*
)
out
->
extended_data
[
ch
];
dst
=
(
float
*
)
s
->
out
->
extended_data
[
ch
];
src
=
(
float
*
)
in
->
extended_data
[
ch
];
for
(
i
=
0
;
i
<
s
->
winlen
;
i
++
)
fsamples
[
i
]
=
src
[
i
];
for
(;
i
<
s
->
tabsize
;
i
++
)
fsamples
[
i
]
=
0
;
av_rdft_calc
(
s
->
rdft
,
fsamples
);
fsamples
[
0
]
=
ires
[
0
]
*
fsamples
[
0
];
fsamples
[
1
]
=
ires
[
1
]
*
fsamples
[
1
];
for
(
i
=
1
;
i
<
s
->
tabsize
/
2
;
i
++
)
{
float
re
,
im
;
re
=
ires
[
i
*
2
]
*
fsamples
[
i
*
2
]
-
ires
[
i
*
2
+
1
]
*
fsamples
[
i
*
2
+
1
];
im
=
ires
[
i
*
2
+
1
]
*
fsamples
[
i
*
2
]
+
ires
[
i
*
2
]
*
fsamples
[
i
*
2
+
1
];
fsamples
[
i
*
2
]
=
re
;
fsamples
[
i
*
2
+
1
]
=
im
;
}
av_rdft_calc
(
s
->
irdft
,
fsamples
);
for
(
i
=
0
;
i
<
s
->
winlen
;
i
++
)
dst
[
i
]
+=
fsamples
[
i
]
/
s
->
tabsize
*
2
;
for
(
i
=
s
->
winlen
;
i
<
s
->
tabsize
;
i
++
)
dst
[
i
]
=
fsamples
[
i
]
/
s
->
tabsize
*
2
;
for
(
i
=
0
;
i
<
s
->
winlen
;
i
++
)
ptr
[
i
]
=
dst
[
i
];
for
(
i
=
0
;
i
<
s
->
winlen
;
i
++
)
dst
[
i
]
=
dst
[
i
+
s
->
winlen
];
}
out
->
pts
=
in
->
pts
;
av_frame_free
(
&
in
);
return
ff_filter_frame
(
outlink
,
out
);
}
static
av_cold
int
init
(
AVFilterContext
*
ctx
)
{
SuperEqualizerContext
*
s
=
ctx
->
priv
;
return
equ_init
(
s
,
14
);
}
static
int
query_formats
(
AVFilterContext
*
ctx
)
{
AVFilterFormats
*
formats
;
AVFilterChannelLayouts
*
layouts
;
static
const
enum
AVSampleFormat
sample_fmts
[]
=
{
AV_SAMPLE_FMT_FLTP
,
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
((
ret
=
ff_set_common_formats
(
ctx
,
formats
))
<
0
)
return
ret
;
formats
=
ff_all_samplerates
();
return
ff_set_common_samplerates
(
ctx
,
formats
);
}
static
int
config_input
(
AVFilterLink
*
inlink
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
SuperEqualizerContext
*
s
=
ctx
->
priv
;
inlink
->
partial_buf_size
=
inlink
->
min_samples
=
inlink
->
max_samples
=
s
->
winlen
;
s
->
out
=
ff_get_audio_buffer
(
inlink
,
s
->
tabsize
);
if
(
!
s
->
out
)
return
AVERROR
(
ENOMEM
);
return
0
;
}
static
int
config_output
(
AVFilterLink
*
outlink
)
{
AVFilterContext
*
ctx
=
outlink
->
src
;
SuperEqualizerContext
*
s
=
ctx
->
priv
;
make_fir
(
s
,
s
->
gains
,
s
->
gains
,
s
->
params
,
outlink
->
sample_rate
);
return
0
;
}
static
av_cold
void
uninit
(
AVFilterContext
*
ctx
)
{
SuperEqualizerContext
*
s
=
ctx
->
priv
;
av_freep
(
&
s
->
irest
);
av_freep
(
&
s
->
ires
);
av_freep
(
&
s
->
fsamples
);
av_rdft_end
(
s
->
rdft
);
av_rdft_end
(
s
->
irdft
);
}
static
const
AVFilterPad
superequalizer_inputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
filter_frame
=
filter_frame
,
.
config_props
=
config_input
,
},
{
NULL
}
};
static
const
AVFilterPad
superequalizer_outputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
config_props
=
config_output
,
},
{
NULL
}
};
#define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
#define OFFSET(x) offsetof(SuperEqualizerContext, x)
static
const
AVOption
superequalizer_options
[]
=
{
{
"1b"
,
"set 65Hz band gain"
,
OFFSET
(
gains
[
0
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"2b"
,
"set 92Hz band gain"
,
OFFSET
(
gains
[
1
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"3b"
,
"set 131Hz band gain"
,
OFFSET
(
gains
[
2
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"4b"
,
"set 185Hz band gain"
,
OFFSET
(
gains
[
3
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"5b"
,
"set 262Hz band gain"
,
OFFSET
(
gains
[
4
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"6b"
,
"set 370Hz band gain"
,
OFFSET
(
gains
[
5
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"7b"
,
"set 523Hz band gain"
,
OFFSET
(
gains
[
6
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"8b"
,
"set 740Hz band gain"
,
OFFSET
(
gains
[
7
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"9b"
,
"set 1047Hz band gain"
,
OFFSET
(
gains
[
8
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"10b"
,
"set 1480Hz band gain"
,
OFFSET
(
gains
[
9
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"11b"
,
"set 2093Hz band gain"
,
OFFSET
(
gains
[
10
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"12b"
,
"set 2960Hz band gain"
,
OFFSET
(
gains
[
11
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"13b"
,
"set 4186Hz band gain"
,
OFFSET
(
gains
[
12
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"14b"
,
"set 5920Hz band gain"
,
OFFSET
(
gains
[
13
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"15b"
,
"set 8372Hz band gain"
,
OFFSET
(
gains
[
14
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"16b"
,
"set 11840Hz band gain"
,
OFFSET
(
gains
[
15
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"17b"
,
"set 16744Hz band gain"
,
OFFSET
(
gains
[
16
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
"18b"
,
"set 20000Hz band gain"
,
OFFSET
(
gains
[
17
]),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
20
,
AF
},
{
NULL
}
};
AVFILTER_DEFINE_CLASS
(
superequalizer
);
AVFilter
ff_af_superequalizer
=
{
.
name
=
"superequalizer"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Apply 18-th band equalization filter."
),
.
priv_size
=
sizeof
(
SuperEqualizerContext
),
.
priv_class
=
&
superequalizer_class
,
.
query_formats
=
query_formats
,
.
init
=
init
,
.
uninit
=
uninit
,
.
inputs
=
superequalizer_inputs
,
.
outputs
=
superequalizer_outputs
,
};
libavfilter/allfilters.c
View file @
ca5cf846
...
@@ -122,6 +122,7 @@ static void register_all(void)
...
@@ -122,6 +122,7 @@ static void register_all(void)
REGISTER_FILTER
(
SOFALIZER
,
sofalizer
,
af
);
REGISTER_FILTER
(
SOFALIZER
,
sofalizer
,
af
);
REGISTER_FILTER
(
STEREOTOOLS
,
stereotools
,
af
);
REGISTER_FILTER
(
STEREOTOOLS
,
stereotools
,
af
);
REGISTER_FILTER
(
STEREOWIDEN
,
stereowiden
,
af
);
REGISTER_FILTER
(
STEREOWIDEN
,
stereowiden
,
af
);
REGISTER_FILTER
(
SUPEREQUALIZER
,
superequalizer
,
af
);
REGISTER_FILTER
(
SURROUND
,
surround
,
af
);
REGISTER_FILTER
(
SURROUND
,
surround
,
af
);
REGISTER_FILTER
(
TREBLE
,
treble
,
af
);
REGISTER_FILTER
(
TREBLE
,
treble
,
af
);
REGISTER_FILTER
(
TREMOLO
,
tremolo
,
af
);
REGISTER_FILTER
(
TREMOLO
,
tremolo
,
af
);
...
...
libavfilter/version.h
View file @
ca5cf846
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
#include "libavutil/version.h"
#include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 6
#define LIBAVFILTER_VERSION_MAJOR 6
#define LIBAVFILTER_VERSION_MINOR 9
2
#define LIBAVFILTER_VERSION_MINOR 9
3
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment