Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
FFmpeg
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
libremedia
Tethys
FFmpeg
Commits
36c06b09
Commit
36c06b09
authored
13 years ago
by
Stefano Sabatini
Committed by
Stefano Sabatini
13 years ago
Browse files
Options
Downloads
Patches
Plain Diff
lavfi: add audio eval signal source
parent
b874e2d0
No related branches found
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
doc/filters.texi
+80
-0
80 additions, 0 deletions
doc/filters.texi
libavfilter/Makefile
+1
-0
1 addition, 0 deletions
libavfilter/Makefile
libavfilter/allfilters.c
+1
-0
1 addition, 0 deletions
libavfilter/allfilters.c
libavfilter/asrc_aevalsrc.c
+226
-0
226 additions, 0 deletions
libavfilter/asrc_aevalsrc.c
with
308 additions
and
0 deletions
doc/filters.texi
+
80
−
0
View file @
36c06b09
...
...
@@ -275,6 +275,86 @@ equivalent to:
abuffer=44100:1:3:1
@end example
@section aevalsrc
Generate an audio signal specified by an expression.
This source accepts in input one or more expressions (one for each
channel), which are evaluated and used to generate a corresponding
audio signal.
It accepts the syntax: @var{exprs}[::@var{options}].
@var{exprs} is a list of expressions separated by ":", one for each
separate channel. The output channel layout depends on the number of
provided expressions, up to 8 channels are supported.
@var{options} is an optional sequence of @var{key}=@var{value} pairs,
separated by ":".
The description of the accepted options follows.
@table @option
@item nb_samples, n
Set the number of samples per channel per each output frame,
default to 1024.
@item sample_rate, s
Specify the sample rate, default to 44100.
@end table
Each expression in @var{exprs} can contain the following constants:
@table @option
@item n
number of the evaluated sample, starting from 0
@item t
time of the evaluated sample expressed in seconds, starting from 0
@item s
sample rate
@end table
@subsection Examples
@itemize
@item
Generate silence:
@example
aevalsrc=0
@end example
@item
Generate a sin signal with frequence of 440 Hz, set sample rate to
8000 Hz:
@example
aevalsrc="sin(440*2*PI*t)::s=8000"
@end example
@item
Generate white noise:
@example
aevalsrc="-2+random(0)"
@end example
@item
Generate an amplitude modulated signal:
@example
aevalsrc="sin(10*2*PI*t)*sin(880*2*PI*t)"
@end example
@item
Generate 2.5 Hz binaural beats on a 360 Hz carrier:
@example
aevalsrc=0.1*sin(2*PI*(360-2.5/2)*t) : 0.1*sin(2*PI*(360+2.5/2)*t)
@end example
@end itemize
@section amovie
Read an audio stream from a movie container.
...
...
This diff is collapsed.
Click to expand it.
libavfilter/Makefile
+
1
−
0
View file @
36c06b09
...
...
@@ -30,6 +30,7 @@ OBJS-$(CONFIG_ARESAMPLE_FILTER) += af_aresample.o
OBJS-$(CONFIG_ASHOWINFO_FILTER)
+=
af_ashowinfo.o
OBJS-$(CONFIG_ABUFFER_FILTER)
+=
asrc_abuffer.o
OBJS-$(CONFIG_AEVALSRC_FILTER)
+=
asrc_aevalsrc.o
OBJS-$(CONFIG_AMOVIE_FILTER)
+=
src_movie.o
OBJS-$(CONFIG_ANULLSRC_FILTER)
+=
asrc_anullsrc.o
...
...
This diff is collapsed.
Click to expand it.
libavfilter/allfilters.c
+
1
−
0
View file @
36c06b09
...
...
@@ -41,6 +41,7 @@ void avfilter_register_all(void)
REGISTER_FILTER
(
ASHOWINFO
,
ashowinfo
,
af
);
REGISTER_FILTER
(
ABUFFER
,
abuffer
,
asrc
);
REGISTER_FILTER
(
AEVALSRC
,
aevalsrc
,
asrc
);
REGISTER_FILTER
(
AMOVIE
,
amovie
,
asrc
);
REGISTER_FILTER
(
ANULLSRC
,
anullsrc
,
asrc
);
...
...
This diff is collapsed.
Click to expand it.
libavfilter/asrc_aevalsrc.c
0 → 100644
+
226
−
0
View file @
36c06b09
/*
* Copyright (c) 2011 Stefano Sabatini
*
* 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
*/
/**
* @file
* eval audio source
*/
#include
"libavutil/audioconvert.h"
#include
"libavutil/avassert.h"
#include
"libavutil/avstring.h"
#include
"libavutil/eval.h"
#include
"libavutil/opt.h"
#include
"avfilter.h"
#include
"internal.h"
static
const
char
*
var_names
[]
=
{
"n"
,
///< number of frame
"t"
,
///< timestamp expressed in seconds
"s"
,
///< sample rate
NULL
};
enum
var_name
{
VAR_N
,
VAR_T
,
VAR_S
,
VAR_VARS_NB
};
typedef
struct
{
const
AVClass
*
class
;
char
*
sample_rate_str
;
int
sample_rate
;
int64_t
chlayout
;
int
nb_channels
;
int64_t
pts
;
AVExpr
*
expr
[
8
];
char
*
expr_str
[
8
];
int
nb_samples
;
///< number of samples per requested frame
uint64_t
n
;
double
var_values
[
VAR_VARS_NB
];
}
EvalContext
;
#define OFFSET(x) offsetof(EvalContext, x)
static
const
AVOption
eval_options
[]
=
{
{
"nb_samples"
,
"set the number of samples per requested frame"
,
OFFSET
(
nb_samples
),
FF_OPT_TYPE_INT
,
{.
dbl
=
1024
},
0
,
INT_MAX
},
{
"n"
,
"set the number of samples per requested frame"
,
OFFSET
(
nb_samples
),
FF_OPT_TYPE_INT
,
{.
dbl
=
1024
},
0
,
INT_MAX
},
{
"sample_rate"
,
"set the sample rate"
,
OFFSET
(
sample_rate_str
),
FF_OPT_TYPE_STRING
,
{.
str
=
"44100"
},
0
,
INT_MAX
},
{
"s"
,
"set the sample rate"
,
OFFSET
(
sample_rate_str
),
FF_OPT_TYPE_STRING
,
{.
str
=
"44100"
},
0
,
INT_MAX
},
{
NULL
},
};
static
const
char
*
eval_get_name
(
void
*
ctx
)
{
return
"aevalsrc"
;
}
static
const
AVClass
eval_class
=
{
"AEvalSrcContext"
,
eval_get_name
,
eval_options
};
static
int
init
(
AVFilterContext
*
ctx
,
const
char
*
args
,
void
*
opaque
)
{
EvalContext
*
eval
=
ctx
->
priv
;
char
*
args1
=
av_strdup
(
args
);
char
*
expr
,
*
buf
,
*
bufptr
;
int
ret
,
i
;
eval
->
class
=
&
eval_class
;
av_opt_set_defaults
(
eval
);
/* parse expressions */
buf
=
args1
;
i
=
0
;
while
(
expr
=
strtok_r
(
buf
,
":"
,
&
bufptr
))
{
if
(
i
>=
8
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"More than 8 expressions provided, unsupported.
\n
"
);
ret
=
AVERROR
(
EINVAL
);
return
ret
;
}
ret
=
av_expr_parse
(
&
eval
->
expr
[
i
],
expr
,
var_names
,
NULL
,
NULL
,
NULL
,
NULL
,
0
,
ctx
);
if
(
ret
<
0
)
goto
end
;
i
++
;
if
(
bufptr
&&
*
bufptr
==
':'
)
{
/* found last expression */
bufptr
++
;
break
;
}
buf
=
NULL
;
}
/* guess channel layout from nb expressions/channels */
eval
->
nb_channels
=
i
;
eval
->
chlayout
=
av_get_default_channel_layout
(
eval
->
nb_channels
);
if
(
!
eval
->
chlayout
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Invalid number of channels '%d' provided
\n
"
,
eval
->
nb_channels
);
ret
=
AVERROR
(
EINVAL
);
goto
end
;
}
if
(
bufptr
&&
(
ret
=
av_set_options_string
(
eval
,
bufptr
,
"="
,
":"
))
<
0
)
goto
end
;
if
((
ret
=
ff_parse_sample_rate
(
&
eval
->
sample_rate
,
eval
->
sample_rate_str
,
ctx
)))
goto
end
;
eval
->
n
=
0
;
end:
av_free
(
args1
);
return
ret
;
}
static
void
uninit
(
AVFilterContext
*
ctx
)
{
EvalContext
*
eval
=
ctx
->
priv
;
int
i
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
av_expr_free
(
eval
->
expr
[
i
]);
eval
->
expr
[
i
]
=
NULL
;
}
av_freep
(
&
eval
->
sample_rate_str
);
}
static
int
config_props
(
AVFilterLink
*
outlink
)
{
EvalContext
*
eval
=
outlink
->
src
->
priv
;
char
buf
[
128
];
outlink
->
time_base
=
(
AVRational
){
1
,
eval
->
sample_rate
};
outlink
->
sample_rate
=
eval
->
sample_rate
;
eval
->
var_values
[
VAR_S
]
=
eval
->
sample_rate
;
av_get_channel_layout_string
(
buf
,
sizeof
(
buf
),
0
,
eval
->
chlayout
);
av_log
(
outlink
->
src
,
AV_LOG_INFO
,
"sample_rate:%d chlayout:%s
\n
"
,
eval
->
sample_rate
,
buf
);
return
0
;
}
static
int
query_formats
(
AVFilterContext
*
ctx
)
{
EvalContext
*
eval
=
ctx
->
priv
;
enum
AVSampleFormat
sample_fmts
[]
=
{
AV_SAMPLE_FMT_DBL
,
AV_SAMPLE_FMT_NONE
};
int64_t
chlayouts
[]
=
{
eval
->
chlayout
,
-
1
};
int
packing_fmts
[]
=
{
AVFILTER_PLANAR
,
-
1
};
avfilter_set_common_sample_formats
(
ctx
,
avfilter_make_format_list
(
sample_fmts
));
avfilter_set_common_channel_layouts
(
ctx
,
avfilter_make_format64_list
(
chlayouts
));
avfilter_set_common_packing_formats
(
ctx
,
avfilter_make_format_list
(
packing_fmts
));
return
0
;
}
static
int
request_frame
(
AVFilterLink
*
outlink
)
{
EvalContext
*
eval
=
outlink
->
src
->
priv
;
AVFilterBufferRef
*
samplesref
;
int
i
,
j
;
samplesref
=
avfilter_get_audio_buffer
(
outlink
,
AV_PERM_WRITE
,
eval
->
nb_samples
);
/* evaluate expression for each single sample and for each channel */
for
(
i
=
0
;
i
<
eval
->
nb_samples
;
i
++
,
eval
->
n
++
)
{
eval
->
var_values
[
VAR_N
]
=
eval
->
n
;
eval
->
var_values
[
VAR_T
]
=
eval
->
var_values
[
VAR_N
]
*
(
double
)
1
/
eval
->
sample_rate
;
for
(
j
=
0
;
j
<
eval
->
nb_channels
;
j
++
)
{
*
((
double
*
)
samplesref
->
data
[
j
]
+
i
)
=
av_expr_eval
(
eval
->
expr
[
j
],
eval
->
var_values
,
NULL
);
}
}
samplesref
->
pts
=
eval
->
pts
;
samplesref
->
pos
=
-
1
;
samplesref
->
audio
->
sample_rate
=
eval
->
sample_rate
;
eval
->
pts
+=
eval
->
nb_samples
;
avfilter_filter_samples
(
outlink
,
samplesref
);
return
0
;
}
AVFilter
avfilter_asrc_aevalsrc
=
{
.
name
=
"aevalsrc"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Generate an audio signal generated by an expression."
),
.
query_formats
=
query_formats
,
.
init
=
init
,
.
uninit
=
uninit
,
.
priv_size
=
sizeof
(
EvalContext
),
.
inputs
=
(
AVFilterPad
[])
{{
.
name
=
NULL
}},
.
outputs
=
(
AVFilterPad
[])
{{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
config_props
=
config_props
,
.
request_frame
=
request_frame
,
},
{
.
name
=
NULL
}},
};
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment