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
c4f7b8f0
Commit
c4f7b8f0
authored
Nov 28, 2015
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter: add audio pulsator filter
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
ca203e99
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
315 additions
and
1 deletion
+315
-1
Changelog
Changelog
+1
-0
filters.texi
doc/filters.texi
+57
-0
Makefile
libavfilter/Makefile
+1
-0
af_apulsator.c
libavfilter/af_apulsator.c
+254
-0
allfilters.c
libavfilter/allfilters.c
+1
-0
version.h
libavfilter/version.h
+1
-1
No files found.
Changelog
View file @
c4f7b8f0
...
...
@@ -37,6 +37,7 @@ version <next>:
- compensationdelay filter
- acompressor filter
- support encoding 16-bit RLE SGI images
- apulsator filter
version 2.8:
...
...
doc/filters.texi
View file @
c4f7b8f0
...
...
@@ -1030,6 +1030,63 @@ It accepts the following values:
@end table
@end table
@section apulsator
Audio pulsator is something between an autopanner and a tremolo.
But it can produce funny stereo effects as well. Pulsator changes the volume
of the left and right channel based on a LFO (low frequency oscillator) with
different waveforms and shifted phases.
This filter have the ability to define an offset between left and right
channel. An offset of 0 means that both LFO shapes match each other.
The left and right channel are altered equally - a conventional tremolo.
An offset of 50% means that the shape of the right channel is exactly shifted
in phase (or moved backwards about half of the frequency) - pulsator acts as
an autopanner. At 1 both curves match again. Every setting in between moves the
phase shift gapless between all stages and produces some "bypassing" sounds with
sine and triangle waveforms. The more you set the offset near 1 (starting from
the 0.5) the faster the signal passes from the left to the right speaker.
The filter accepts the following options:
@table @option
@item level_in
Set input gain. By default it is 1. Range is [0.015625 - 64].
@item level_out
Set output gain. By default it is 1. Range is [0.015625 - 64].
@item mode
Set waveform shape the LFO will use. Can be one of: sine, triangle, square,
sawup or sawdown. Default is sine.
@item amount
Set modulation. Define how much of original signal is affected by the LFO.
@item offset_l
Set left channel offset. Default is 0. Allowed range is [0 - 1].
@item offset_r
Set right channel offset. Default is 0.5. Allowed range is [0 - 1].
@item width
Set pulse width. Default is 1. Allowed range is [0 - 2].
@item timing
Set possible timing mode. Can be one of: bpm, ms or hz. Default is hz.
@item bpm
Set bpm. Default is 120. Allowed range is [30 - 300]. Only used if timing
is set to bpm.
@item ms
Set ms. Default is 500. Allowed range is [10 - 2000]. Only used if timing
is set to ms.
@item hz
Set frequency in Hz. Default is 2. Allowed range is [0.01 - 100]. Only used
if timing is set to hz.
@end table
@anchor{aresample}
@section aresample
...
...
libavfilter/Makefile
View file @
c4f7b8f0
...
...
@@ -40,6 +40,7 @@ OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o
OBJS-$(CONFIG_APAD_FILTER)
+=
af_apad.o
OBJS-$(CONFIG_APERMS_FILTER)
+=
f_perms.o
OBJS-$(CONFIG_APHASER_FILTER)
+=
af_aphaser.o
generate_wave_table.o
OBJS-$(CONFIG_APULSATOR_FILTER)
+=
af_apulsator.o
OBJS-$(CONFIG_AREALTIME_FILTER)
+=
f_realtime.o
OBJS-$(CONFIG_ARESAMPLE_FILTER)
+=
af_aresample.o
OBJS-$(CONFIG_AREVERSE_FILTER)
+=
f_reverse.o
...
...
libavfilter/af_apulsator.c
0 → 100644
View file @
c4f7b8f0
/*
* Copyright (c) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others
*
* 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 "avfilter.h"
#include "internal.h"
#include "audio.h"
enum
PulsatorModes
{
SINE
,
TRIANGLE
,
SQUARE
,
SAWUP
,
SAWDOWN
,
NB_MODES
};
enum
PulsatorTimings
{
UNIT_BPM
,
UNIT_MS
,
UNIT_HZ
,
NB_TIMINGS
};
typedef
struct
SimpleLFO
{
double
phase
;
double
freq
;
double
offset
;
double
amount
;
double
pwidth
;
int
mode
;
int
srate
;
}
SimpleLFO
;
typedef
struct
AudioPulsatorContext
{
const
AVClass
*
class
;
int
mode
;
double
level_in
;
double
level_out
;
double
amount
;
double
offset_l
;
double
offset_r
;
double
pwidth
;
double
bpm
;
double
hz
;
int
ms
;
int
timing
;
SimpleLFO
lfoL
,
lfoR
;
}
AudioPulsatorContext
;
#define OFFSET(x) offsetof(AudioPulsatorContext, x)
#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
static
const
AVOption
apulsator_options
[]
=
{
{
"level_in"
,
"set input gain"
,
OFFSET
(
level_in
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
0
.
015625
,
64
,
FLAGS
,
},
{
"level_out"
,
"set output gain"
,
OFFSET
(
level_out
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
0
.
015625
,
64
,
FLAGS
,
},
{
"mode"
,
"set mode"
,
OFFSET
(
mode
),
AV_OPT_TYPE_INT
,
{.
i64
=
SINE
},
SINE
,
NB_MODES
-
1
,
FLAGS
,
"mode"
},
{
"sine"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
SINE
},
0
,
0
,
FLAGS
,
"mode"
},
{
"triangle"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
TRIANGLE
},
0
,
0
,
FLAGS
,
"mode"
},
{
"square"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
SQUARE
},
0
,
0
,
FLAGS
,
"mode"
},
{
"sawup"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
SAWUP
},
0
,
0
,
FLAGS
,
"mode"
},
{
"sawdown"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
SAWDOWN
},
0
,
0
,
FLAGS
,
"mode"
},
{
"amount"
,
"set modulation"
,
OFFSET
(
amount
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
0
,
1
,
FLAGS
},
{
"offset_l"
,
"set offset L"
,
OFFSET
(
offset_l
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
0
,
1
,
FLAGS
},
{
"offset_r"
,
"set offset R"
,
OFFSET
(
offset_r
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
.
5
},
0
,
1
,
FLAGS
},
{
"width"
,
"set pulse width"
,
OFFSET
(
pwidth
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
0
,
2
,
FLAGS
},
{
"timing"
,
"set timing"
,
OFFSET
(
timing
),
AV_OPT_TYPE_INT
,
{.
i64
=
2
},
0
,
NB_TIMINGS
-
1
,
FLAGS
,
"timing"
},
{
"bpm"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
UNIT_BPM
},
0
,
0
,
FLAGS
,
"timing"
},
{
"ms"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
UNIT_MS
},
0
,
0
,
FLAGS
,
"timing"
},
{
"hz"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
UNIT_HZ
},
0
,
0
,
FLAGS
,
"timing"
},
{
"bpm"
,
"set BPM"
,
OFFSET
(
bpm
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
120
},
30
,
300
,
FLAGS
},
{
"ms"
,
"set ms"
,
OFFSET
(
ms
),
AV_OPT_TYPE_INT
,
{.
i64
=
500
},
10
,
2000
,
FLAGS
},
{
"hz"
,
"set frequency"
,
OFFSET
(
hz
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
2
},
0
.
01
,
100
,
FLAGS
},
{
NULL
}
};
AVFILTER_DEFINE_CLASS
(
apulsator
);
static
void
lfo_advance
(
SimpleLFO
*
lfo
,
unsigned
count
)
{
lfo
->
phase
=
fabs
(
lfo
->
phase
+
count
*
lfo
->
freq
/
lfo
->
srate
);
if
(
lfo
->
phase
>=
1
)
lfo
->
phase
=
fmod
(
lfo
->
phase
,
1
);
}
static
double
lfo_get_value
(
SimpleLFO
*
lfo
)
{
double
phs
=
FFMIN
(
100
,
lfo
->
phase
/
FFMIN
(
1
.
99
,
FFMAX
(
0
.
01
,
lfo
->
pwidth
))
+
lfo
->
offset
);
double
val
;
if
(
phs
>
1
)
phs
=
fmod
(
phs
,
1
.);
switch
(
lfo
->
mode
)
{
case
SINE
:
val
=
sin
(
phs
*
2
*
M_PI
);
break
;
case
TRIANGLE
:
if
(
phs
>
0
.
75
)
val
=
(
phs
-
0
.
75
)
*
4
-
1
;
else
if
(
phs
>
0
.
25
)
val
=
-
4
*
phs
+
2
;
else
val
=
phs
*
4
;
break
;
case
SQUARE
:
val
=
phs
<
0
.
5
?
-
1
:
+
1
;
break
;
case
SAWUP
:
val
=
phs
*
2
-
1
;
break
;
case
SAWDOWN
:
val
=
1
-
phs
*
2
;
break
;
}
return
val
*
lfo
->
amount
;
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
in
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
AudioPulsatorContext
*
s
=
ctx
->
priv
;
const
double
*
src
=
(
const
double
*
)
in
->
data
[
0
];
const
int
nb_samples
=
in
->
nb_samples
;
const
double
level_out
=
s
->
level_out
;
const
double
level_in
=
s
->
level_in
;
const
double
amount
=
s
->
amount
;
AVFrame
*
out
;
double
*
dst
;
int
n
;
if
(
av_frame_is_writable
(
in
))
{
out
=
in
;
}
else
{
out
=
ff_get_audio_buffer
(
inlink
,
in
->
nb_samples
);
if
(
!
out
)
{
av_frame_free
(
&
in
);
return
AVERROR
(
ENOMEM
);
}
av_frame_copy_props
(
out
,
in
);
}
dst
=
(
double
*
)
out
->
data
[
0
];
for
(
n
=
0
;
n
<
nb_samples
;
n
++
)
{
double
outL
;
double
outR
;
double
inL
=
src
[
0
]
*
level_in
;
double
inR
=
src
[
1
]
*
level_in
;
double
procL
=
inL
;
double
procR
=
inR
;
procL
*=
lfo_get_value
(
&
s
->
lfoL
)
*
0
.
5
+
amount
/
2
;
procR
*=
lfo_get_value
(
&
s
->
lfoR
)
*
0
.
5
+
amount
/
2
;
outL
=
procL
+
inL
*
(
1
-
amount
);
outR
=
procR
+
inR
*
(
1
-
amount
);
outL
*=
level_out
;
outR
*=
level_out
;
dst
[
0
]
=
outL
;
dst
[
1
]
=
outR
;
lfo_advance
(
&
s
->
lfoL
,
1
);
lfo_advance
(
&
s
->
lfoR
,
1
);
dst
+=
2
;
src
+=
2
;
}
if
(
in
!=
out
)
av_frame_free
(
&
in
);
return
ff_filter_frame
(
outlink
,
out
);
}
static
int
query_formats
(
AVFilterContext
*
ctx
)
{
AVFilterChannelLayouts
*
layout
=
NULL
;
AVFilterFormats
*
formats
=
NULL
;
int
ret
;
if
((
ret
=
ff_add_format
(
&
formats
,
AV_SAMPLE_FMT_DBL
))
<
0
||
(
ret
=
ff_set_common_formats
(
ctx
,
formats
))
<
0
||
(
ret
=
ff_add_channel_layout
(
&
layout
,
AV_CH_LAYOUT_STEREO
))
<
0
||
(
ret
=
ff_set_common_channel_layouts
(
ctx
,
layout
))
<
0
)
return
ret
;
formats
=
ff_all_samplerates
();
return
ff_set_common_samplerates
(
ctx
,
formats
);
}
static
int
config_input
(
AVFilterLink
*
inlink
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
AudioPulsatorContext
*
s
=
ctx
->
priv
;
double
freq
;
switch
(
s
->
timing
)
{
case
UNIT_BPM
:
freq
=
s
->
bpm
/
60
;
break
;
case
UNIT_MS
:
freq
=
1
/
(
s
->
ms
/
1000
.);
break
;
case
UNIT_HZ
:
freq
=
s
->
hz
;
break
;
}
s
->
lfoL
.
freq
=
freq
;
s
->
lfoR
.
freq
=
freq
;
s
->
lfoL
.
mode
=
s
->
mode
;
s
->
lfoR
.
mode
=
s
->
mode
;
s
->
lfoL
.
offset
=
s
->
offset_l
;
s
->
lfoR
.
offset
=
s
->
offset_r
;
s
->
lfoL
.
srate
=
inlink
->
sample_rate
;
s
->
lfoR
.
srate
=
inlink
->
sample_rate
;
s
->
lfoL
.
amount
=
s
->
amount
;
s
->
lfoR
.
amount
=
s
->
amount
;
s
->
lfoL
.
pwidth
=
s
->
pwidth
;
s
->
lfoR
.
pwidth
=
s
->
pwidth
;
return
0
;
}
static
const
AVFilterPad
inputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
config_props
=
config_input
,
.
filter_frame
=
filter_frame
,
},
{
NULL
}
};
static
const
AVFilterPad
outputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
},
{
NULL
}
};
AVFilter
ff_af_apulsator
=
{
.
name
=
"apulsator"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Audio pulsator."
),
.
priv_size
=
sizeof
(
AudioPulsatorContext
),
.
priv_class
=
&
apulsator_class
,
.
query_formats
=
query_formats
,
.
inputs
=
inputs
,
.
outputs
=
outputs
,
};
libavfilter/allfilters.c
View file @
c4f7b8f0
...
...
@@ -62,6 +62,7 @@ void avfilter_register_all(void)
REGISTER_FILTER
(
APAD
,
apad
,
af
);
REGISTER_FILTER
(
APERMS
,
aperms
,
af
);
REGISTER_FILTER
(
APHASER
,
aphaser
,
af
);
REGISTER_FILTER
(
APULSATOR
,
apulsator
,
af
);
REGISTER_FILTER
(
AREALTIME
,
arealtime
,
af
);
REGISTER_FILTER
(
ARESAMPLE
,
aresample
,
af
);
REGISTER_FILTER
(
AREVERSE
,
areverse
,
af
);
...
...
libavfilter/version.h
View file @
c4f7b8f0
...
...
@@ -30,7 +30,7 @@
#include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 6
#define LIBAVFILTER_VERSION_MINOR 1
7
#define LIBAVFILTER_VERSION_MINOR 1
8
#define LIBAVFILTER_VERSION_MICRO 100
#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