Commit 10db70d5 authored by Stefano Sabatini's avatar Stefano Sabatini

lavfi: drop af_volume_stefano.c in favor of af_volume_justin.c

Justin's version has more features but is otherwise equivalent from the
point of view of the syntax.
parent 759e7a23
...@@ -829,56 +829,6 @@ out ...@@ -829,56 +829,6 @@ out
Convert the audio sample format, sample rate and channel layout. This filter is Convert the audio sample format, sample rate and channel layout. This filter is
not meant to be used directly. not meant to be used directly.
@section volume
Adjust the input audio volume.
The filter accepts exactly one parameter @var{vol}, which expresses
how the audio volume will be increased or decreased.
Output values are clipped to the maximum value.
If @var{vol} is expressed as a decimal number, the output audio
volume is given by the relation:
@example
@var{output_volume} = @var{vol} * @var{input_volume}
@end example
If @var{vol} is expressed as a decimal number followed by the string
"dB", the value represents the requested change in decibels of the
input audio power, and the output audio volume is given by the
relation:
@example
@var{output_volume} = 10^(@var{vol}/20) * @var{input_volume}
@end example
Otherwise @var{vol} is considered an expression and its evaluated
value is used for computing the output audio volume according to the
first relation.
Default value for @var{vol} is 1.0.
@subsection Examples
@itemize
@item
Half the input audio volume:
@example
volume=0.5
@end example
The above example is equivalent to:
@example
volume=1/2
@end example
@item
Decrease input audio power by 12 decibels:
@example
volume=-12dB
@end example
@end itemize
@section volumedetect @section volumedetect
Detect the volume of the input video. Detect the volume of the input video.
...@@ -919,7 +869,7 @@ There are 6 samples at -4 dB, 62 at -5 dB, 286 at -6 dB, etc. ...@@ -919,7 +869,7 @@ There are 6 samples at -4 dB, 62 at -5 dB, 286 at -6 dB, etc.
In other words, raising the volume by +4 dB does not cause any clipping, In other words, raising the volume by +4 dB does not cause any clipping,
raising it by +5 dB causes clipping for 6 samples, etc. raising it by +5 dB causes clipping for 6 samples, etc.
@section volume_justin @section volume
Adjust the input audio volume. Adjust the input audio volume.
...@@ -966,15 +916,21 @@ precision of the volume scaling. ...@@ -966,15 +916,21 @@ precision of the volume scaling.
@item @item
Halve the input audio volume: Halve the input audio volume:
@example @example
volume_justin=volume=0.5 volume=volume=0.5
volume_justin=volume=1/2 volume=volume=1/2
volume_justin=volume=-6.0206dB volume=volume=-6.0206dB
@end example
In all the above example the named key for @option{volume} can be
omitted, for example like in:
@example
volume=0.5
@end example @end example
@item @item
Increase input audio power by 6 decibels using fixed-point precision: Increase input audio power by 6 decibels using fixed-point precision:
@example @example
volume_justin=volume=6dB:precision=fixed volume=volume=6dB:precision=fixed
@end example @end example
@end itemize @end itemize
......
...@@ -71,8 +71,7 @@ OBJS-$(CONFIG_JOIN_FILTER) += af_join.o ...@@ -71,8 +71,7 @@ OBJS-$(CONFIG_JOIN_FILTER) += af_join.o
OBJS-$(CONFIG_PAN_FILTER) += af_pan.o OBJS-$(CONFIG_PAN_FILTER) += af_pan.o
OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o
OBJS-$(CONFIG_SILENCEDETECT_FILTER) += af_silencedetect.o OBJS-$(CONFIG_SILENCEDETECT_FILTER) += af_silencedetect.o
OBJS-$(CONFIG_VOLUME_FILTER) += af_volume_stefano.o OBJS-$(CONFIG_VOLUME_FILTER) += af_volume.o
OBJS-$(CONFIG_VOLUME_JUSTIN_FILTER) += af_volume_justin.o
OBJS-$(CONFIG_VOLUMEDETECT_FILTER) += af_volumedetect.o OBJS-$(CONFIG_VOLUMEDETECT_FILTER) += af_volumedetect.o
OBJS-$(CONFIG_AEVALSRC_FILTER) += asrc_aevalsrc.o OBJS-$(CONFIG_AEVALSRC_FILTER) += asrc_aevalsrc.o
......
...@@ -299,8 +299,8 @@ static const AVFilterPad avfilter_af_volume_outputs[] = { ...@@ -299,8 +299,8 @@ static const AVFilterPad avfilter_af_volume_outputs[] = {
{ NULL } { NULL }
}; };
AVFilter avfilter_af_volume_justin = { AVFilter avfilter_af_volume = {
.name = "volume_justin", .name = "volume",
.description = NULL_IF_CONFIG_SMALL("Change input volume."), .description = NULL_IF_CONFIG_SMALL("Change input volume."),
.query_formats = query_formats, .query_formats = query_formats,
.priv_size = sizeof(VolumeContext), .priv_size = sizeof(VolumeContext),
......
/*
* 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
* audio volume filter
* based on ffmpeg.c code
*/
#include "libavutil/channel_layout.h"
#include "libavutil/eval.h"
#include "audio.h"
#include "avfilter.h"
#include "formats.h"
typedef struct {
double volume;
int volume_i;
} VolumeContext;
static av_cold int init(AVFilterContext *ctx, const char *args)
{
VolumeContext *vol = ctx->priv;
char *tail;
int ret = 0;
vol->volume = 1.0;
if (args) {
/* parse the number as a decimal number */
double d = strtod(args, &tail);
if (*tail) {
if (!strcmp(tail, "dB")) {
/* consider the argument an adjustement in decibels */
d = pow(10, d/20);
} else {
/* parse the argument as an expression */
ret = av_expr_parse_and_eval(&d, args, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, 0, ctx);
}
}
if (ret < 0) {
av_log(ctx, AV_LOG_ERROR,
"Invalid volume argument '%s'\n", args);
return AVERROR(EINVAL);
}
if (d < 0 || d > 65536) { /* 65536 = INT_MIN / (128 * 256) */
av_log(ctx, AV_LOG_ERROR,
"Negative or too big volume value %f\n", d);
return AVERROR(EINVAL);
}
vol->volume = d;
}
vol->volume_i = (int)(vol->volume * 256 + 0.5);
av_log(ctx, AV_LOG_VERBOSE, "volume=%f\n", vol->volume);
return 0;
}
static int query_formats(AVFilterContext *ctx)
{
AVFilterFormats *formats = NULL;
AVFilterChannelLayouts *layouts;
enum AVSampleFormat sample_fmts[] = {
AV_SAMPLE_FMT_U8,
AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_S32,
AV_SAMPLE_FMT_FLT,
AV_SAMPLE_FMT_DBL,
AV_SAMPLE_FMT_NONE
};
layouts = ff_all_channel_layouts();
if (!layouts)
return AVERROR(ENOMEM);
ff_set_common_channel_layouts(ctx, layouts);
formats = ff_make_format_list(sample_fmts);
if (!formats)
return AVERROR(ENOMEM);
ff_set_common_formats(ctx, formats);
formats = ff_all_samplerates();
if (!formats)
return AVERROR(ENOMEM);
ff_set_common_samplerates(ctx, formats);
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
{
VolumeContext *vol = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
const int nb_samples = insamples->audio->nb_samples *
av_get_channel_layout_nb_channels(insamples->audio->channel_layout);
const double volume = vol->volume;
const int volume_i = vol->volume_i;
int i;
if (volume_i != 256) {
switch (insamples->format) {
case AV_SAMPLE_FMT_U8:
{
uint8_t *p = (void *)insamples->data[0];
for (i = 0; i < nb_samples; i++) {
int v = (((*p - 128) * volume_i + 128) >> 8) + 128;
*p++ = av_clip_uint8(v);
}
break;
}
case AV_SAMPLE_FMT_S16:
{
int16_t *p = (void *)insamples->data[0];
for (i = 0; i < nb_samples; i++) {
int v = ((int64_t)*p * volume_i + 128) >> 8;
*p++ = av_clip_int16(v);
}
break;
}
case AV_SAMPLE_FMT_S32:
{
int32_t *p = (void *)insamples->data[0];
for (i = 0; i < nb_samples; i++) {
int64_t v = (((int64_t)*p * volume_i + 128) >> 8);
*p++ = av_clipl_int32(v);
}
break;
}
case AV_SAMPLE_FMT_FLT:
{
float *p = (void *)insamples->data[0];
float scale = (float)volume;
for (i = 0; i < nb_samples; i++) {
*p++ *= scale;
}
break;
}
case AV_SAMPLE_FMT_DBL:
{
double *p = (void *)insamples->data[0];
for (i = 0; i < nb_samples; i++) {
*p *= volume;
p++;
}
break;
}
}
}
return ff_filter_frame(outlink, insamples);
}
static const AVFilterPad volume_inputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ | AV_PERM_WRITE,
},
{ NULL },
};
static const AVFilterPad volume_outputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
},
{ NULL },
};
AVFilter avfilter_af_volume = {
.name = "volume",
.description = NULL_IF_CONFIG_SMALL("Change input volume."),
.query_formats = query_formats,
.priv_size = sizeof(VolumeContext),
.init = init,
.inputs = volume_inputs,
.outputs = volume_outputs,
};
...@@ -64,7 +64,6 @@ void avfilter_register_all(void) ...@@ -64,7 +64,6 @@ void avfilter_register_all(void)
REGISTER_FILTER (RESAMPLE, resample, af); REGISTER_FILTER (RESAMPLE, resample, af);
REGISTER_FILTER (SILENCEDETECT, silencedetect, af); REGISTER_FILTER (SILENCEDETECT, silencedetect, af);
REGISTER_FILTER (VOLUME, volume, af); REGISTER_FILTER (VOLUME, volume, af);
REGISTER_FILTER (VOLUME_JUSTIN, volume_justin, af);
REGISTER_FILTER (VOLUMEDETECT,volumedetect,af); REGISTER_FILTER (VOLUMEDETECT,volumedetect,af);
REGISTER_FILTER (AEVALSRC, aevalsrc, asrc); REGISTER_FILTER (AEVALSRC, aevalsrc, asrc);
......
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
#include "libavutil/avutil.h" #include "libavutil/avutil.h"
#define LIBAVFILTER_VERSION_MAJOR 3 #define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MINOR 25 #define LIBAVFILTER_VERSION_MINOR 26
#define LIBAVFILTER_VERSION_MICRO 102 #define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \ LIBAVFILTER_VERSION_MINOR, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment