Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
3f895dcb
Commit
3f895dcb
authored
Nov 24, 2015
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter: add compensation delay line filter
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
dad354f3
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
250 additions
and
1 deletion
+250
-1
Changelog
Changelog
+1
-0
filters.texi
doc/filters.texi
+48
-0
Makefile
libavfilter/Makefile
+1
-0
af_compensationdelay.c
libavfilter/af_compensationdelay.c
+198
-0
allfilters.c
libavfilter/allfilters.c
+1
-0
version.h
libavfilter/version.h
+1
-1
No files found.
Changelog
View file @
3f895dcb
...
@@ -34,6 +34,7 @@ version <next>:
...
@@ -34,6 +34,7 @@ version <next>:
- realtime filter
- realtime filter
- anoisesrc audio filter source
- anoisesrc audio filter source
- IVR demuxer
- IVR demuxer
- compensationdelay filter
version 2.8:
version 2.8:
...
...
doc/filters.texi
View file @
3f895dcb
...
@@ -1628,6 +1628,54 @@ compand=.1|.1:.1|.1:-45.1/-45.1|-45/-900|0/-900:.01:45:-90:.1
...
@@ -1628,6 +1628,54 @@ compand=.1|.1:.1|.1:-45.1/-45.1|-45/-900|0/-900:.01:45:-90:.1
@end example
@end example
@end itemize
@end itemize
@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 can be achieved 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:
@table @option
@item mm
Set millimeters distance. This is compensation distance for fine tuning.
Default is 0.
@item cm
Set cm distance. This is compensation distance for tightening distance setup.
Default is 0.
@item m
Set meters distance. This is compensation distance for hard distance setup.
Default is 0.
@item dry
Set dry amount. Amount of unprocessed (dry) signal.
Default is 0.
@item wet
Set wet amount. Amount of processed (wet) signal.
Default is 1.
@item temp
Set temperature degree in Celsius. This is the temperature of the environment.
Default is 20.
@end table
@section dcshift
@section dcshift
Apply a DC shift to the audio.
Apply a DC shift to the audio.
...
...
libavfilter/Makefile
View file @
3f895dcb
...
@@ -64,6 +64,7 @@ OBJS-$(CONFIG_CHANNELMAP_FILTER) += af_channelmap.o
...
@@ -64,6 +64,7 @@ OBJS-$(CONFIG_CHANNELMAP_FILTER) += af_channelmap.o
OBJS-$(CONFIG_CHANNELSPLIT_FILTER)
+=
af_channelsplit.o
OBJS-$(CONFIG_CHANNELSPLIT_FILTER)
+=
af_channelsplit.o
OBJS-$(CONFIG_CHORUS_FILTER)
+=
af_chorus.o
generate_wave_table.o
OBJS-$(CONFIG_CHORUS_FILTER)
+=
af_chorus.o
generate_wave_table.o
OBJS-$(CONFIG_COMPAND_FILTER)
+=
af_compand.o
OBJS-$(CONFIG_COMPAND_FILTER)
+=
af_compand.o
OBJS-$(CONFIG_COMPENSATIONDELAY_FILTER)
+=
af_compensationdelay.o
OBJS-$(CONFIG_DCSHIFT_FILTER)
+=
af_dcshift.o
OBJS-$(CONFIG_DCSHIFT_FILTER)
+=
af_dcshift.o
OBJS-$(CONFIG_DYNAUDNORM_FILTER)
+=
af_dynaudnorm.o
OBJS-$(CONFIG_DYNAUDNORM_FILTER)
+=
af_dynaudnorm.o
OBJS-$(CONFIG_EARWAX_FILTER)
+=
af_earwax.o
OBJS-$(CONFIG_EARWAX_FILTER)
+=
af_earwax.o
...
...
libavfilter/af_compensationdelay.c
0 → 100644
View file @
3f895dcb
/*
* 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
},
0
,
1
,
A
},
{
"wet"
,
"set wet amount"
,
OFFSET
(
wet
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
0
,
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
);
}
static
int
config_input
(
AVFilterLink
*
inlink
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
CompensationDelayContext
*
s
=
ctx
->
priv
;
unsigned
min_size
,
new_size
=
1
;
s
->
delay
=
(
s
->
distance_m
*
100
.
+
s
->
distance_cm
*
1
.
+
s
->
distance_mm
*
.
1
)
*
COMP_DELAY_SOUND_FRONT_DELAY
(
s
->
temp
)
*
inlink
->
sample_rate
;
min_size
=
inlink
->
sample_rate
*
COMP_DELAY_MAX_DELAY
;
while
(
new_size
<
min_size
)
new_size
<<=
1
;
s
->
delay_frame
=
av_frame_alloc
();
if
(
!
s
->
delay_frame
)
return
AVERROR
(
ENOMEM
);
s
->
buf_size
=
new_size
;
s
->
delay_frame
->
format
=
inlink
->
format
;
s
->
delay_frame
->
nb_samples
=
new_size
;
s
->
delay_frame
->
channel_layout
=
inlink
->
channel_layout
;
return
av_frame_get_buffer
(
s
->
delay_frame
,
32
);
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
in
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
CompensationDelayContext
*
s
=
ctx
->
priv
;
const
unsigned
b_mask
=
s
->
buf_size
-
1
;
const
unsigned
buf_size
=
s
->
buf_size
;
const
unsigned
delay
=
s
->
delay
;
const
double
dry
=
s
->
dry
;
const
double
wet
=
s
->
wet
;
unsigned
r_ptr
,
w_ptr
;
AVFrame
*
out
;
int
n
,
ch
;
out
=
ff_get_audio_buffer
(
inlink
,
in
->
nb_samples
);
if
(
!
out
)
{
av_frame_free
(
&
in
);
return
AVERROR
(
ENOMEM
);
}
av_frame_copy_props
(
out
,
in
);
for
(
ch
=
0
;
ch
<
inlink
->
channels
;
ch
++
)
{
const
double
*
src
=
(
const
double
*
)
in
->
extended_data
[
ch
];
double
*
dst
=
(
double
*
)
out
->
extended_data
[
ch
];
double
*
buffer
=
(
double
*
)
s
->
delay_frame
->
extended_data
[
ch
];
w_ptr
=
s
->
w_ptr
;
r_ptr
=
(
w_ptr
+
buf_size
-
delay
)
&
b_mask
;
for
(
n
=
0
;
n
<
in
->
nb_samples
;
n
++
)
{
const
double
sample
=
src
[
n
];
buffer
[
w_ptr
]
=
sample
;
dst
[
n
]
=
dry
*
sample
+
wet
*
buffer
[
r_ptr
];
w_ptr
=
(
w_ptr
+
1
)
&
b_mask
;
r_ptr
=
(
r_ptr
+
1
)
&
b_mask
;
}
}
s
->
w_ptr
=
w_ptr
;
av_frame_free
(
&
in
);
return
ff_filter_frame
(
ctx
->
outputs
[
0
],
out
);
}
static
av_cold
void
uninit
(
AVFilterContext
*
ctx
)
{
CompensationDelayContext
*
s
=
ctx
->
priv
;
av_frame_free
(
&
s
->
delay_frame
);
}
static
const
AVFilterPad
compensationdelay_inputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
config_props
=
config_input
,
.
filter_frame
=
filter_frame
,
},
{
NULL
}
};
static
const
AVFilterPad
compensationdelay_outputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
},
{
NULL
}
};
AVFilter
ff_af_compensationdelay
=
{
.
name
=
"compensationdelay"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Audio Compensation Delay Line."
),
.
query_formats
=
query_formats
,
.
priv_size
=
sizeof
(
CompensationDelayContext
),
.
priv_class
=
&
compensationdelay_class
,
.
uninit
=
uninit
,
.
inputs
=
compensationdelay_inputs
,
.
outputs
=
compensationdelay_outputs
,
};
libavfilter/allfilters.c
View file @
3f895dcb
...
@@ -86,6 +86,7 @@ void avfilter_register_all(void)
...
@@ -86,6 +86,7 @@ void avfilter_register_all(void)
REGISTER_FILTER
(
CHANNELSPLIT
,
channelsplit
,
af
);
REGISTER_FILTER
(
CHANNELSPLIT
,
channelsplit
,
af
);
REGISTER_FILTER
(
CHORUS
,
chorus
,
af
);
REGISTER_FILTER
(
CHORUS
,
chorus
,
af
);
REGISTER_FILTER
(
COMPAND
,
compand
,
af
);
REGISTER_FILTER
(
COMPAND
,
compand
,
af
);
REGISTER_FILTER
(
COMPENSATIONDELAY
,
compensationdelay
,
af
);
REGISTER_FILTER
(
DCSHIFT
,
dcshift
,
af
);
REGISTER_FILTER
(
DCSHIFT
,
dcshift
,
af
);
REGISTER_FILTER
(
DYNAUDNORM
,
dynaudnorm
,
af
);
REGISTER_FILTER
(
DYNAUDNORM
,
dynaudnorm
,
af
);
REGISTER_FILTER
(
EARWAX
,
earwax
,
af
);
REGISTER_FILTER
(
EARWAX
,
earwax
,
af
);
...
...
libavfilter/version.h
View file @
3f895dcb
...
@@ -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 1
5
#define LIBAVFILTER_VERSION_MINOR 1
6
#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