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
15e1fd98
Commit
15e1fd98
authored
Dec 29, 2015
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/avf_showspectrum: add window overlap support
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
b98c5857
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
54 additions
and
9 deletions
+54
-9
filters.texi
doc/filters.texi
+5
-0
avf_showspectrum.c
libavfilter/avf_showspectrum.c
+49
-9
No files found.
doc/filters.texi
View file @
15e1fd98
...
...
@@ -14677,6 +14677,11 @@ Default value is @code{hann}.
@item orientation
Set orientation of time vs frequency axis. Can be @code{vertical} or
@code{horizontal}. Default is @code{vertical}.
@item overlap
Set ratio of overlap window. Default value is @code{0}.
When value is @code{1} overlap is set to recommended size for specific
window function currently used.
@end table
The usage is very similar to the showwaves filter; see the examples in that
...
...
libavfilter/avf_showspectrum.c
View file @
15e1fd98
/*
* Copyright (c) 2012-2013 Clément Bœsch
* Copyright (c) 2013 Rudolf Polzer <divverent@xonotic.org>
* Copyright (c) 2015 Paul B Mahol
*
* This file is part of FFmpeg.
*
...
...
@@ -28,9 +29,12 @@
#include <math.h>
#include "libavcodec/avfft.h"
#include "libavutil/audio_fifo.h"
#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/opt.h"
#include "audio.h"
#include "video.h"
#include "avfilter.h"
#include "internal.h"
#include "window_func.h"
...
...
@@ -62,7 +66,10 @@ typedef struct {
int
win_func
;
double
win_scale
;
float
overlap
;
int
skip_samples
;
float
*
combine_buffer
;
///< color combining buffer (3 * h items)
AVAudioFifo
*
fifo
;
int64_t
pts
;
}
ShowSpectrumContext
;
#define OFFSET(x) offsetof(ShowSpectrumContext, x)
...
...
@@ -111,6 +118,7 @@ static const AVOption showspectrum_options[] = {
{
"orientation"
,
"set orientation"
,
OFFSET
(
orientation
),
AV_OPT_TYPE_INT
,
{.
i64
=
VERTICAL
},
0
,
NB_ORIENTATIONS
-
1
,
FLAGS
,
"orientation"
},
{
"vertical"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
VERTICAL
},
0
,
0
,
FLAGS
,
"orientation"
},
{
"horizontal"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
HORIZONTAL
},
0
,
0
,
FLAGS
,
"orientation"
},
{
"overlap"
,
"set window overlap"
,
OFFSET
(
overlap
),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
0
},
0
,
1
,
FLAGS
},
{
NULL
}
};
...
...
@@ -178,6 +186,7 @@ static av_cold void uninit(AVFilterContext *ctx)
av_freep
(
&
s
->
rdft_data
);
av_freep
(
&
s
->
window_func_lut
);
av_frame_free
(
&
s
->
outpicref
);
av_audio_fifo_free
(
s
->
fifo
);
}
static
int
query_formats
(
AVFilterContext
*
ctx
)
...
...
@@ -217,6 +226,7 @@ static int config_output(AVFilterLink *outlink)
AVFilterLink
*
inlink
=
ctx
->
inputs
[
0
];
ShowSpectrumContext
*
s
=
ctx
->
priv
;
int
i
,
rdft_bits
,
win_size
,
h
,
w
;
float
overlap
;
outlink
->
w
=
s
->
w
;
outlink
->
h
=
s
->
h
;
...
...
@@ -271,7 +281,14 @@ static int config_output(AVFilterLink *outlink)
sizeof
(
*
s
->
window_func_lut
));
if
(
!
s
->
window_func_lut
)
return
AVERROR
(
ENOMEM
);
ff_generate_window_func
(
s
->
window_func_lut
,
win_size
,
s
->
win_func
,
&
s
->
overlap
);
ff_generate_window_func
(
s
->
window_func_lut
,
win_size
,
s
->
win_func
,
&
overlap
);
if
(
s
->
overlap
==
1
)
s
->
overlap
=
overlap
;
s
->
skip_samples
=
(
1
.
-
s
->
overlap
)
*
win_size
;
if
(
s
->
skip_samples
<
1
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"overlap %f too big
\n
"
,
s
->
overlap
);
return
AVERROR
(
EINVAL
);
}
for
(
s
->
win_scale
=
0
,
i
=
0
;
i
<
win_size
;
i
++
)
{
s
->
win_scale
+=
s
->
window_func_lut
[
i
]
*
s
->
window_func_lut
[
i
];
...
...
@@ -296,15 +313,12 @@ static int config_output(AVFilterLink *outlink)
(
s
->
orientation
==
HORIZONTAL
&&
s
->
xpos
>=
outlink
->
h
))
s
->
xpos
=
0
;
outlink
->
frame_rate
=
av_make_q
(
inlink
->
sample_rate
,
win_size
);
outlink
->
frame_rate
=
av_make_q
(
inlink
->
sample_rate
,
win_size
*
(
1
.
-
s
->
overlap
)
);
if
(
s
->
orientation
==
VERTICAL
&&
s
->
sliding
==
FULLFRAME
)
outlink
->
frame_rate
.
den
*=
outlink
->
w
;
if
(
s
->
orientation
==
HORIZONTAL
&&
s
->
sliding
==
FULLFRAME
)
outlink
->
frame_rate
.
den
*=
outlink
->
h
;
inlink
->
min_samples
=
inlink
->
max_samples
=
inlink
->
partial_buf_size
=
win_size
;
if
(
s
->
orientation
==
VERTICAL
)
{
s
->
combine_buffer
=
av_realloc_f
(
s
->
combine_buffer
,
outlink
->
h
*
3
,
...
...
@@ -317,6 +331,11 @@ static int config_output(AVFilterLink *outlink)
av_log
(
ctx
,
AV_LOG_VERBOSE
,
"s:%dx%d RDFT window size:%d
\n
"
,
s
->
w
,
s
->
h
,
win_size
);
av_audio_fifo_free
(
s
->
fifo
);
s
->
fifo
=
av_audio_fifo_alloc
(
inlink
->
format
,
inlink
->
channels
,
win_size
);
if
(
!
s
->
fifo
)
return
AVERROR
(
ENOMEM
);
return
0
;
}
...
...
@@ -516,6 +535,7 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
}
}
av_frame_make_writable
(
s
->
outpicref
);
/* copy to output */
if
(
s
->
orientation
==
VERTICAL
)
{
if
(
s
->
sliding
==
SCROLL
)
{
...
...
@@ -598,13 +618,33 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
AVFilterContext
*
ctx
=
inlink
->
dst
;
ShowSpectrumContext
*
s
=
ctx
->
priv
;
unsigned
win_size
=
1
<<
s
->
rdft_bits
;
AVFrame
*
fin
=
NULL
;
int
ret
=
0
;
av_assert0
(
insamples
->
nb_samples
<=
win_size
);
if
(
insamples
->
nb_samples
==
win_size
)
ret
=
plot_spectrum_column
(
inlink
,
insamples
);
av_audio_fifo_write
(
s
->
fifo
,
(
void
**
)
insamples
->
extended_data
,
insamples
->
nb_samples
);
av_frame_free
(
&
insamples
);
while
(
av_audio_fifo_size
(
s
->
fifo
)
>=
win_size
)
{
fin
=
ff_get_audio_buffer
(
inlink
,
win_size
);
if
(
!
fin
)
{
ret
=
AVERROR
(
ENOMEM
);
goto
fail
;
}
fin
->
pts
=
s
->
pts
;
s
->
pts
+=
s
->
skip_samples
;
ret
=
av_audio_fifo_peek
(
s
->
fifo
,
(
void
**
)
fin
->
extended_data
,
win_size
);
if
(
ret
<
0
)
goto
fail
;
ret
=
plot_spectrum_column
(
inlink
,
fin
);
av_frame_free
(
&
fin
);
av_audio_fifo_drain
(
s
->
fifo
,
s
->
skip_samples
);
if
(
ret
<
0
)
goto
fail
;
}
fail:
av_frame_free
(
&
fin
);
return
ret
;
}
...
...
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