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
2009d922
Commit
2009d922
authored
Jan 10, 2016
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/avf_showspectrum: add posibility to display phase
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
405abdba
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
55 additions
and
4 deletions
+55
-4
filters.texi
doc/filters.texi
+3
-0
avf_showspectrum.c
libavfilter/avf_showspectrum.c
+52
-4
No files found.
doc/filters.texi
View file @
2009d922
...
@@ -14712,6 +14712,9 @@ window function currently used.
...
@@ -14712,6 +14712,9 @@ window function currently used.
@item gain
@item gain
Set scale gain for calculating intensity color values.
Set scale gain for calculating intensity color values.
Default value is @code{1}.
Default value is @code{1}.
@item data
Set which data to display. Can be @code{magnitude}, default or @code{phase}.
@end table
@end table
The usage is very similar to the showwaves filter; see the examples in that
The usage is very similar to the showwaves filter; see the examples in that
...
...
libavfilter/avf_showspectrum.c
View file @
2009d922
...
@@ -42,6 +42,7 @@
...
@@ -42,6 +42,7 @@
#include "window_func.h"
#include "window_func.h"
enum
DisplayMode
{
COMBINED
,
SEPARATE
,
NB_MODES
};
enum
DisplayMode
{
COMBINED
,
SEPARATE
,
NB_MODES
};
enum
DataMode
{
D_MAGNITUDE
,
D_PHASE
,
NB_DMODES
};
enum
DisplayScale
{
LINEAR
,
SQRT
,
CBRT
,
LOG
,
FOURTHRT
,
FIFTHRT
,
NB_SCALES
};
enum
DisplayScale
{
LINEAR
,
SQRT
,
CBRT
,
LOG
,
FOURTHRT
,
FIFTHRT
,
NB_SCALES
};
enum
ColorMode
{
CHANNEL
,
INTENSITY
,
RAINBOW
,
MORELAND
,
NEBULAE
,
FIRE
,
FIERY
,
FRUIT
,
COOL
,
NB_CLMODES
};
enum
ColorMode
{
CHANNEL
,
INTENSITY
,
RAINBOW
,
MORELAND
,
NEBULAE
,
FIRE
,
FIERY
,
FRUIT
,
COOL
,
NB_CLMODES
};
enum
SlideMode
{
REPLACE
,
SCROLL
,
FULLFRAME
,
RSCROLL
,
NB_SLIDES
};
enum
SlideMode
{
REPLACE
,
SCROLL
,
FULLFRAME
,
RSCROLL
,
NB_SLIDES
};
...
@@ -60,12 +61,14 @@ typedef struct {
...
@@ -60,12 +61,14 @@ typedef struct {
int
color_mode
;
///< display color scheme
int
color_mode
;
///< display color scheme
int
scale
;
int
scale
;
float
saturation
;
///< color saturation multiplier
float
saturation
;
///< color saturation multiplier
int
data
;
int
xpos
;
///< x position (current column)
int
xpos
;
///< x position (current column)
FFTContext
*
fft
;
///< Fast Fourier Transform context
FFTContext
*
fft
;
///< Fast Fourier Transform context
int
fft_bits
;
///< number of bits (FFT window size = 1<<fft_bits)
int
fft_bits
;
///< number of bits (FFT window size = 1<<fft_bits)
FFTComplex
**
fft_data
;
///< bins holder for each (displayed) channels
FFTComplex
**
fft_data
;
///< bins holder for each (displayed) channels
float
*
window_func_lut
;
///< Window function LUT
float
*
window_func_lut
;
///< Window function LUT
float
**
magnitudes
;
float
**
magnitudes
;
float
**
phases
;
int
win_func
;
int
win_func
;
int
win_size
;
int
win_size
;
double
win_scale
;
double
win_scale
;
...
@@ -134,6 +137,9 @@ static const AVOption showspectrum_options[] = {
...
@@ -134,6 +137,9 @@ static const AVOption showspectrum_options[] = {
{
"horizontal"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
HORIZONTAL
},
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
},
{
"overlap"
,
"set window overlap"
,
OFFSET
(
overlap
),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
0
},
0
,
1
,
FLAGS
},
{
"gain"
,
"set scale gain"
,
OFFSET
(
gain
),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
128
,
FLAGS
},
{
"gain"
,
"set scale gain"
,
OFFSET
(
gain
),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
128
,
FLAGS
},
{
"data"
,
"set data mode"
,
OFFSET
(
data
),
AV_OPT_TYPE_INT
,
{.
i64
=
0
},
0
,
NB_DMODES
-
1
,
FLAGS
,
"data"
},
{
"magnitude"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
D_MAGNITUDE
},
0
,
0
,
FLAGS
,
"data"
},
{
"phase"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
D_PHASE
},
0
,
0
,
FLAGS
,
"data"
},
{
NULL
}
{
NULL
}
};
};
...
@@ -231,6 +237,11 @@ static av_cold void uninit(AVFilterContext *ctx)
...
@@ -231,6 +237,11 @@ static av_cold void uninit(AVFilterContext *ctx)
av_freep
(
&
s
->
magnitudes
);
av_freep
(
&
s
->
magnitudes
);
av_frame_free
(
&
s
->
outpicref
);
av_frame_free
(
&
s
->
outpicref
);
av_audio_fifo_free
(
s
->
fifo
);
av_audio_fifo_free
(
s
->
fifo
);
if
(
s
->
phases
)
{
for
(
i
=
0
;
i
<
s
->
nb_display_channels
;
i
++
)
av_freep
(
&
s
->
phases
[
i
]);
}
av_freep
(
&
s
->
phases
);
}
}
static
int
query_formats
(
AVFilterContext
*
ctx
)
static
int
query_formats
(
AVFilterContext
*
ctx
)
...
@@ -329,6 +340,15 @@ static int config_output(AVFilterLink *outlink)
...
@@ -329,6 +340,15 @@ static int config_output(AVFilterLink *outlink)
return
AVERROR
(
ENOMEM
);
return
AVERROR
(
ENOMEM
);
}
}
s
->
phases
=
av_calloc
(
s
->
nb_display_channels
,
sizeof
(
*
s
->
magnitudes
));
if
(
!
s
->
phases
)
return
AVERROR
(
ENOMEM
);
for
(
i
=
0
;
i
<
s
->
nb_display_channels
;
i
++
)
{
s
->
phases
[
i
]
=
av_calloc
(
s
->
orientation
==
VERTICAL
?
s
->
h
:
s
->
w
,
sizeof
(
**
s
->
phases
));
if
(
!
s
->
phases
[
i
])
return
AVERROR
(
ENOMEM
);
}
s
->
fft_data
=
av_calloc
(
s
->
nb_display_channels
,
sizeof
(
*
s
->
fft_data
));
s
->
fft_data
=
av_calloc
(
s
->
nb_display_channels
,
sizeof
(
*
s
->
fft_data
));
if
(
!
s
->
fft_data
)
if
(
!
s
->
fft_data
)
return
AVERROR
(
ENOMEM
);
return
AVERROR
(
ENOMEM
);
...
@@ -427,6 +447,7 @@ static void run_fft(ShowSpectrumContext *s, AVFrame *fin)
...
@@ -427,6 +447,7 @@ static void run_fft(ShowSpectrumContext *s, AVFrame *fin)
#define RE(y, ch) s->fft_data[ch][y].re
#define RE(y, ch) s->fft_data[ch][y].re
#define IM(y, ch) s->fft_data[ch][y].im
#define IM(y, ch) s->fft_data[ch][y].im
#define MAGNITUDE(y, ch) hypot(RE(y, ch), IM(y, ch))
#define MAGNITUDE(y, ch) hypot(RE(y, ch), IM(y, ch))
#define PHASE(y, ch) atan2(IM(y, ch), RE(y, ch))
static
void
calc_magnitudes
(
ShowSpectrumContext
*
s
)
static
void
calc_magnitudes
(
ShowSpectrumContext
*
s
)
{
{
...
@@ -440,6 +461,18 @@ static void calc_magnitudes(ShowSpectrumContext *s)
...
@@ -440,6 +461,18 @@ static void calc_magnitudes(ShowSpectrumContext *s)
}
}
}
}
static
void
calc_phases
(
ShowSpectrumContext
*
s
)
{
int
ch
,
y
,
h
=
s
->
orientation
==
VERTICAL
?
s
->
h
:
s
->
w
;
for
(
ch
=
0
;
ch
<
s
->
nb_display_channels
;
ch
++
)
{
float
*
phases
=
s
->
phases
[
ch
];
for
(
y
=
0
;
y
<
h
;
y
++
)
phases
[
y
]
=
(
PHASE
(
y
,
ch
)
/
M_PI
+
1
)
/
2
;
}
}
static
void
acalc_magnitudes
(
ShowSpectrumContext
*
s
)
static
void
acalc_magnitudes
(
ShowSpectrumContext
*
s
)
{
{
int
ch
,
y
,
h
=
s
->
orientation
==
VERTICAL
?
s
->
h
:
s
->
w
;
int
ch
,
y
,
h
=
s
->
orientation
==
VERTICAL
?
s
->
h
:
s
->
w
;
...
@@ -578,7 +611,7 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
...
@@ -578,7 +611,7 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
ShowSpectrumContext
*
s
=
ctx
->
priv
;
ShowSpectrumContext
*
s
=
ctx
->
priv
;
AVFrame
*
outpicref
=
s
->
outpicref
;
AVFrame
*
outpicref
=
s
->
outpicref
;
const
double
w
=
s
->
win_scale
;
const
double
w
=
s
->
data
==
D_PHASE
?
1
:
s
->
win_scale
;
const
float
g
=
s
->
gain
;
const
float
g
=
s
->
gain
;
int
h
=
s
->
orientation
==
VERTICAL
?
s
->
channel_height
:
s
->
channel_width
;
int
h
=
s
->
orientation
==
VERTICAL
?
s
->
channel_height
:
s
->
channel_width
;
...
@@ -590,6 +623,7 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
...
@@ -590,6 +623,7 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
for
(
ch
=
0
;
ch
<
s
->
nb_display_channels
;
ch
++
)
{
for
(
ch
=
0
;
ch
<
s
->
nb_display_channels
;
ch
++
)
{
float
*
magnitudes
=
s
->
magnitudes
[
ch
];
float
*
magnitudes
=
s
->
magnitudes
[
ch
];
float
*
phases
=
s
->
phases
[
ch
];
float
yf
,
uf
,
vf
;
float
yf
,
uf
,
vf
;
/* decide color range */
/* decide color range */
...
@@ -599,9 +633,20 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
...
@@ -599,9 +633,20 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
for
(
y
=
0
;
y
<
h
;
y
++
)
{
for
(
y
=
0
;
y
<
h
;
y
++
)
{
int
row
=
(
s
->
mode
==
COMBINED
)
?
y
:
ch
*
h
+
y
;
int
row
=
(
s
->
mode
==
COMBINED
)
?
y
:
ch
*
h
+
y
;
float
*
out
=
&
s
->
combine_buffer
[
3
*
row
];
float
*
out
=
&
s
->
combine_buffer
[
3
*
row
];
float
a
;
/* get magnitude */
switch
(
s
->
data
)
{
float
a
=
g
*
w
*
magnitudes
[
y
];
case
D_MAGNITUDE
:
/* get magnitude */
a
=
g
*
w
*
magnitudes
[
y
];
break
;
case
D_PHASE
:
/* get phase */
a
=
phases
[
y
];
break
;
default:
av_assert0
(
0
);
}
/* apply scale */
/* apply scale */
switch
(
s
->
scale
)
{
switch
(
s
->
scale
)
{
...
@@ -766,7 +811,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
...
@@ -766,7 +811,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
av_assert0
(
fin
->
nb_samples
==
s
->
win_size
);
av_assert0
(
fin
->
nb_samples
==
s
->
win_size
);
run_fft
(
s
,
fin
);
run_fft
(
s
,
fin
);
calc_magnitudes
(
s
);
if
(
s
->
data
==
D_MAGNITUDE
)
calc_magnitudes
(
s
);
if
(
s
->
data
==
D_PHASE
)
calc_phases
(
s
);
ret
=
plot_spectrum_column
(
inlink
,
fin
);
ret
=
plot_spectrum_column
(
inlink
,
fin
);
av_frame_free
(
&
fin
);
av_frame_free
(
&
fin
);
...
...
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