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
e37edc70
Commit
e37edc70
authored
Oct 03, 2019
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter: add anlms filter
parent
a27c0781
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
384 additions
and
1 deletion
+384
-1
Changelog
Changelog
+1
-0
filters.texi
doc/filters.texi
+52
-0
Makefile
libavfilter/Makefile
+1
-0
af_anlms.c
libavfilter/af_anlms.c
+328
-0
allfilters.c
libavfilter/allfilters.c
+1
-0
version.h
libavfilter/version.h
+1
-1
No files found.
Changelog
View file @
e37edc70
...
...
@@ -14,6 +14,7 @@ version <next>:
- sierpinski video source
- scroll video filter
- photosensitivity filter
- anlms filter
version 4.2:
...
...
doc/filters.texi
View file @
e37edc70
...
...
@@ -1814,6 +1814,58 @@ Change output mode.
Syntax for the command is : "i", "o" or "n" string.
@end table
@section anlms
Apply Normalized Least-Mean-Squares algorithm to the first audio stream using the second audio stream.
This adaptive filter is used to mimic a desired filter by finding the filter coefficients that
relate to producing the least mean square of the error signal (difference between the desired,
2nd input audio stream and the actual signal, the 1st input audio stream).
A description of the accepted options follows.
@table @option
@item order
Set filter order.
@item mu
Set filter mu.
@item eps
Set the filter eps.
@item leakage
Set the filter leakage.
@item out_mode
It accepts the following values:
@table @option
@item i
Pass the 1st input.
@item d
Pass the 2nd input.
@item o
Pass filtered samples.
@item n
Pass difference between desired and filtered samples.
Default value is @var{o}.
@end table
@end table
@subsection Examples
@itemize
@item
One of many usages of this filter is noise reduction, input audio is filtered
with same samples that are delayed by fixed ammount, one such example for stereo audio is:
@example
asplit[a][b],[a]adelay=32S|32S[a],[b][a]anlms=order=128:leakage=0.0005:mu=.5:out_mode=o
@end example
@end itemize
@section anull
Pass the audio source unchanged to the output.
...
...
libavfilter/Makefile
View file @
e37edc70
...
...
@@ -63,6 +63,7 @@ OBJS-$(CONFIG_AMIX_FILTER) += af_amix.o
OBJS-$(CONFIG_AMULTIPLY_FILTER)
+=
af_amultiply.o
OBJS-$(CONFIG_ANEQUALIZER_FILTER)
+=
af_anequalizer.o
OBJS-$(CONFIG_ANLMDN_FILTER)
+=
af_anlmdn.o
OBJS-$(CONFIG_ANLMS_FILTER)
+=
af_anlms.o
OBJS-$(CONFIG_ANULL_FILTER)
+=
af_anull.o
OBJS-$(CONFIG_APAD_FILTER)
+=
af_apad.o
OBJS-$(CONFIG_APERMS_FILTER)
+=
f_perms.o
...
...
libavfilter/af_anlms.c
0 → 100644
View file @
e37edc70
/*
* Copyright (c) 2019 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/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/float_dsp.h"
#include "libavutil/opt.h"
#include "audio.h"
#include "avfilter.h"
#include "formats.h"
#include "filters.h"
#include "internal.h"
enum
OutModes
{
IN_MODE
,
DESIRED_MODE
,
OUT_MODE
,
NOISE_MODE
,
NB_OMODES
};
typedef
struct
AudioNLMSContext
{
const
AVClass
*
class
;
int
order
;
float
mu
;
float
eps
;
float
leakage
;
int
output_mode
;
int
kernel_size
;
AVFrame
*
offset
;
AVFrame
*
delay
;
AVFrame
*
coeffs
;
AVFrame
*
tmp
;
AVFrame
*
frame
[
2
];
AVFloatDSPContext
*
fdsp
;
}
AudioNLMSContext
;
#define OFFSET(x) offsetof(AudioNLMSContext, x)
#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
static
const
AVOption
anlms_options
[]
=
{
{
"order"
,
"set the filter order"
,
OFFSET
(
order
),
AV_OPT_TYPE_INT
,
{.
i64
=
256
},
1
,
INT16_MAX
,
A
},
{
"mu"
,
"set the filter mu"
,
OFFSET
(
mu
),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
0
.
75
},
0
,
1
,
A
},
{
"eps"
,
"set the filter eps"
,
OFFSET
(
eps
),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
1
,
A
},
{
"leakage"
,
"set the filter leakage"
,
OFFSET
(
leakage
),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
0
},
0
,
1
,
A
},
{
"out_mode"
,
"set output mode"
,
OFFSET
(
output_mode
),
AV_OPT_TYPE_INT
,
{.
i64
=
OUT_MODE
},
0
,
NB_OMODES
-
1
,
A
,
"mode"
},
{
"i"
,
"input"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
IN_MODE
},
0
,
0
,
A
,
"mode"
},
{
"d"
,
"desired"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
DESIRED_MODE
},
0
,
0
,
A
,
"mode"
},
{
"o"
,
"output"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
OUT_MODE
},
0
,
0
,
A
,
"mode"
},
{
"n"
,
"noise"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
NOISE_MODE
},
0
,
0
,
A
,
"mode"
},
{
NULL
}
};
AVFILTER_DEFINE_CLASS
(
anlms
);
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
(
!
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
float
fir_sample
(
AudioNLMSContext
*
s
,
float
sample
,
float
*
delay
,
float
*
coeffs
,
float
*
tmp
,
int
*
offset
)
{
const
int
order
=
s
->
order
;
float
output
;
delay
[
*
offset
]
=
sample
;
memcpy
(
tmp
,
coeffs
+
order
-
*
offset
,
order
*
sizeof
(
float
));
output
=
s
->
fdsp
->
scalarproduct_float
(
delay
,
tmp
,
s
->
kernel_size
);
if
(
--
(
*
offset
)
<
0
)
*
offset
=
order
-
1
;
return
output
;
}
static
float
process_sample
(
AudioNLMSContext
*
s
,
float
input
,
float
desired
,
float
*
delay
,
float
*
coeffs
,
float
*
tmp
,
int
*
offsetp
)
{
const
int
order
=
s
->
order
;
const
float
leakage
=
s
->
leakage
;
const
float
mu
=
s
->
mu
;
const
float
a
=
1
.
f
-
leakage
*
mu
;
float
sum
,
output
,
e
,
norm
,
b
;
int
offset
=
*
offsetp
;
delay
[
offset
+
order
]
=
input
;
output
=
fir_sample
(
s
,
input
,
delay
,
coeffs
,
tmp
,
offsetp
);
e
=
desired
-
output
;
sum
=
s
->
fdsp
->
scalarproduct_float
(
delay
,
delay
,
s
->
kernel_size
);
norm
=
s
->
eps
+
sum
;
b
=
mu
*
e
/
norm
;
memcpy
(
tmp
,
delay
+
offset
,
order
*
sizeof
(
float
));
s
->
fdsp
->
vector_fmul_scalar
(
coeffs
,
coeffs
,
a
,
s
->
kernel_size
);
s
->
fdsp
->
vector_fmac_scalar
(
coeffs
,
tmp
,
b
,
s
->
kernel_size
);
memcpy
(
coeffs
+
order
,
coeffs
,
order
*
sizeof
(
float
));
switch
(
s
->
output_mode
)
{
case
IN_MODE
:
output
=
input
;
break
;
case
DESIRED_MODE
:
output
=
desired
;
break
;
case
OUT_MODE
:
/*output = output;*/
break
;
case
NOISE_MODE
:
output
=
desired
-
output
;
break
;
}
return
output
;
}
static
int
process_channels
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
AudioNLMSContext
*
s
=
ctx
->
priv
;
AVFrame
*
out
=
arg
;
const
int
start
=
(
out
->
channels
*
jobnr
)
/
nb_jobs
;
const
int
end
=
(
out
->
channels
*
(
jobnr
+
1
))
/
nb_jobs
;
for
(
int
c
=
start
;
c
<
end
;
c
++
)
{
const
float
*
input
=
(
const
float
*
)
s
->
frame
[
0
]
->
extended_data
[
c
];
const
float
*
desired
=
(
const
float
*
)
s
->
frame
[
1
]
->
extended_data
[
c
];
float
*
delay
=
(
float
*
)
s
->
delay
->
extended_data
[
c
];
float
*
coeffs
=
(
float
*
)
s
->
coeffs
->
extended_data
[
c
];
float
*
tmp
=
(
float
*
)
s
->
tmp
->
extended_data
[
c
];
int
*
offset
=
(
int
*
)
s
->
offset
->
extended_data
[
c
];
float
*
output
=
(
float
*
)
out
->
extended_data
[
c
];
for
(
int
n
=
0
;
n
<
out
->
nb_samples
;
n
++
)
output
[
n
]
=
process_sample
(
s
,
input
[
n
],
desired
[
n
],
delay
,
coeffs
,
tmp
,
offset
);
}
return
0
;
}
static
int
activate
(
AVFilterContext
*
ctx
)
{
AudioNLMSContext
*
s
=
ctx
->
priv
;
int
i
,
ret
,
status
;
int
nb_samples
;
int64_t
pts
;
FF_FILTER_FORWARD_STATUS_BACK_ALL
(
ctx
->
outputs
[
0
],
ctx
);
nb_samples
=
FFMIN
(
ff_inlink_queued_samples
(
ctx
->
inputs
[
0
]),
ff_inlink_queued_samples
(
ctx
->
inputs
[
1
]));
for
(
i
=
0
;
i
<
ctx
->
nb_inputs
&&
nb_samples
>
0
;
i
++
)
{
if
(
s
->
frame
[
i
])
continue
;
if
(
ff_inlink_check_available_samples
(
ctx
->
inputs
[
i
],
nb_samples
)
>
0
)
{
ret
=
ff_inlink_consume_samples
(
ctx
->
inputs
[
i
],
nb_samples
,
nb_samples
,
&
s
->
frame
[
i
]);
if
(
ret
<
0
)
return
ret
;
}
}
if
(
s
->
frame
[
0
]
&&
s
->
frame
[
1
])
{
AVFrame
*
out
;
out
=
ff_get_audio_buffer
(
ctx
->
outputs
[
0
],
s
->
frame
[
0
]
->
nb_samples
);
if
(
!
out
)
{
av_frame_free
(
&
s
->
frame
[
0
]);
av_frame_free
(
&
s
->
frame
[
1
]);
return
AVERROR
(
ENOMEM
);
}
ctx
->
internal
->
execute
(
ctx
,
process_channels
,
out
,
NULL
,
FFMIN
(
ctx
->
outputs
[
0
]
->
channels
,
ff_filter_get_nb_threads
(
ctx
)));
out
->
pts
=
s
->
frame
[
0
]
->
pts
;
av_frame_free
(
&
s
->
frame
[
0
]);
av_frame_free
(
&
s
->
frame
[
1
]);
ret
=
ff_filter_frame
(
ctx
->
outputs
[
0
],
out
);
if
(
ret
<
0
)
return
ret
;
}
if
(
!
nb_samples
)
{
for
(
i
=
0
;
i
<
2
;
i
++
)
{
if
(
ff_inlink_acknowledge_status
(
ctx
->
inputs
[
i
],
&
status
,
&
pts
))
{
ff_outlink_set_status
(
ctx
->
outputs
[
0
],
status
,
pts
);
return
0
;
}
}
}
if
(
ff_outlink_frame_wanted
(
ctx
->
outputs
[
0
]))
{
for
(
i
=
0
;
i
<
2
;
i
++
)
{
if
(
ff_inlink_queued_samples
(
ctx
->
inputs
[
i
])
>
0
)
continue
;
ff_inlink_request_frame
(
ctx
->
inputs
[
i
]);
return
0
;
}
}
return
0
;
}
static
int
config_output
(
AVFilterLink
*
outlink
)
{
AVFilterContext
*
ctx
=
outlink
->
src
;
AudioNLMSContext
*
s
=
ctx
->
priv
;
s
->
kernel_size
=
FFALIGN
(
s
->
order
,
16
);
if
(
!
s
->
offset
)
s
->
offset
=
ff_get_audio_buffer
(
outlink
,
1
);
if
(
!
s
->
delay
)
s
->
delay
=
ff_get_audio_buffer
(
outlink
,
2
*
s
->
kernel_size
);
if
(
!
s
->
coeffs
)
s
->
coeffs
=
ff_get_audio_buffer
(
outlink
,
2
*
s
->
kernel_size
);
if
(
!
s
->
tmp
)
s
->
tmp
=
ff_get_audio_buffer
(
outlink
,
s
->
kernel_size
);
if
(
!
s
->
delay
||
!
s
->
coeffs
||
!
s
->
offset
||
!
s
->
tmp
)
return
AVERROR
(
ENOMEM
);
return
0
;
}
static
av_cold
int
init
(
AVFilterContext
*
ctx
)
{
AudioNLMSContext
*
s
=
ctx
->
priv
;
s
->
fdsp
=
avpriv_float_dsp_alloc
(
0
);
if
(
!
s
->
fdsp
)
return
AVERROR
(
ENOMEM
);
return
0
;
}
static
av_cold
void
uninit
(
AVFilterContext
*
ctx
)
{
AudioNLMSContext
*
s
=
ctx
->
priv
;
av_freep
(
&
s
->
fdsp
);
av_frame_free
(
&
s
->
delay
);
av_frame_free
(
&
s
->
coeffs
);
av_frame_free
(
&
s
->
offset
);
av_frame_free
(
&
s
->
tmp
);
}
static
const
AVFilterPad
inputs
[]
=
{
{
.
name
=
"input"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
},
{
.
name
=
"desired"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
},
{
NULL
}
};
static
const
AVFilterPad
outputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
config_props
=
config_output
,
},
{
NULL
}
};
AVFilter
ff_af_anlms
=
{
.
name
=
"anlms"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Apply Normalized Least-Mean-Squares algorithm to first audio stream."
),
.
priv_size
=
sizeof
(
AudioNLMSContext
),
.
priv_class
=
&
anlms_class
,
.
init
=
init
,
.
uninit
=
uninit
,
.
activate
=
activate
,
.
query_formats
=
query_formats
,
.
inputs
=
inputs
,
.
outputs
=
outputs
,
.
flags
=
AVFILTER_FLAG_SLICE_THREADS
,
};
libavfilter/allfilters.c
View file @
e37edc70
...
...
@@ -56,6 +56,7 @@ extern AVFilter ff_af_amix;
extern
AVFilter
ff_af_amultiply
;
extern
AVFilter
ff_af_anequalizer
;
extern
AVFilter
ff_af_anlmdn
;
extern
AVFilter
ff_af_anlms
;
extern
AVFilter
ff_af_anull
;
extern
AVFilter
ff_af_apad
;
extern
AVFilter
ff_af_aperms
;
...
...
libavfilter/version.h
View file @
e37edc70
...
...
@@ -30,7 +30,7 @@
#include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 7
#define LIBAVFILTER_VERSION_MINOR 6
1
#define LIBAVFILTER_VERSION_MINOR 6
2
#define LIBAVFILTER_VERSION_MICRO 100
...
...
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