47 int64_t start, int64_t range,
int curve);
51 int curve0,
int curve1);
54 enum CurveType {
NONE = -1,
TRI,
QSIN,
ESIN,
HSIN,
LOG,
IPAR,
QUA,
CUB,
SQU,
CBR,
PAR,
EXP,
IQSIN,
IHSIN,
DESE,
DESI,
LOSI,
SINC,
ISINC,
NB_CURVES };
56 #define OFFSET(x) offsetof(AudioFadeContext, x)
57 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
58 #define TFLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
70 #define CUBE(a) ((a)*(a)*(a))
77 gain = sin(gain *
M_PI / 2.0);
81 gain = 0.6366197723675814 * asin(gain);
84 gain = 1.0 - cos(
M_PI / 4.0 * (
CUBE(2.0*gain - 1) + 1));
87 gain = (1.0 - cos(gain *
M_PI)) / 2.0;
91 gain = 0.3183098861837907 * acos(1 - 2 * gain);
95 gain =
exp(-11.512925464970227 * (1 - gain));
98 gain =
av_clipd(1 + 0.2 * log10(gain), 0, 1.0);
101 gain = 1 - sqrt(1 - gain);
104 gain = (1 - (1 - gain) * (1 - gain));
119 gain = gain <= 0.5 ?
cbrt(2 * gain) / 2: 1 -
cbrt(2 * (1 - gain)) / 2;
122 gain = gain <= 0.5 ?
CUBE(2 * gain) / 2: 1 -
CUBE(2 * (1 - gain)) / 2;
125 const double a = 1. / (1. - 0.787) - 1;
126 double A = 1. / (1.0 +
exp(0 -((gain-0.5) *
a * 2.0)));
127 double B = 1. / (1.0 +
exp(
a));
128 double C = 1. / (1.0 +
exp(0-
a));
129 gain = (
A -
B) / (
C -
B);
133 gain = gain >= 1.0 ? 1.0 : sin(
M_PI * (1.0 - gain)) / (
M_PI * (1.0 - gain));
136 gain = gain <= 0.0 ? 0.0 : 1.0 - sin(
M_PI * gain) / (
M_PI * gain);
146 #define FADE_PLANAR(name, type) \
147 static void fade_samples_## name ##p(uint8_t **dst, uint8_t * const *src, \
148 int nb_samples, int channels, int dir, \
149 int64_t start, int64_t range, int curve) \
153 for (i = 0; i < nb_samples; i++) { \
154 double gain = fade_gain(curve, start + i * dir, range); \
155 for (c = 0; c < channels; c++) { \
156 type *d = (type *)dst[c]; \
157 const type *s = (type *)src[c]; \
159 d[i] = s[i] * gain; \
164 #define FADE(name, type) \
165 static void fade_samples_## name (uint8_t **dst, uint8_t * const *src, \
166 int nb_samples, int channels, int dir, \
167 int64_t start, int64_t range, int curve) \
169 type *d = (type *)dst[0]; \
170 const type *s = (type *)src[0]; \
173 for (i = 0; i < nb_samples; i++) { \
174 double gain = fade_gain(curve, start + i * dir, range); \
175 for (c = 0; c < channels; c++, k++) \
176 d[k] = s[k] * gain; \
195 switch (outlink->format) {
216 #if CONFIG_AFADE_FILTER
218 static const AVOption afade_options[] = {
223 {
"start_sample",
"set number of first sample to start fading",
OFFSET(start_sample),
AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX,
TFLAGS },
262 if (INT64_MAX -
s->nb_samples <
s->start_sample)
276 if ((!
s->type && (
s->start_sample +
s->nb_samples < cur_sample)) ||
277 (
s->type && (cur_sample + nb_samples < s->start_sample)))
289 if ((!
s->type && (cur_sample + nb_samples < s->start_sample)) ||
290 (
s->type && (
s->start_sample +
s->nb_samples < cur_sample))) {
297 start = cur_sample -
s->start_sample;
299 start =
s->start_sample +
s->nb_samples - cur_sample;
303 s->type ? -1 : 1, start,
304 s->nb_samples,
s->curve);
314 char *res,
int res_len,
int flags)
325 static const AVFilterPad avfilter_af_afade_inputs[] = {
333 static const AVFilterPad avfilter_af_afade_outputs[] = {
349 .priv_class = &afade_class,
356 #if CONFIG_ACROSSFADE_FILTER
358 static const AVOption acrossfade_options[] = {
359 {
"nb_samples",
"set number of samples for cross fade duration",
OFFSET(nb_samples),
AV_OPT_TYPE_INT, {.i64 = 44100}, 1, INT32_MAX/10,
FLAGS },
360 {
"ns",
"set number of samples for cross fade duration",
OFFSET(nb_samples),
AV_OPT_TYPE_INT, {.i64 = 44100}, 1, INT32_MAX/10,
FLAGS },
394 #define CROSSFADE_PLANAR(name, type) \
395 static void crossfade_samples_## name ##p(uint8_t **dst, uint8_t * const *cf0, \
396 uint8_t * const *cf1, \
397 int nb_samples, int channels, \
398 int curve0, int curve1) \
402 for (i = 0; i < nb_samples; i++) { \
403 double gain0 = fade_gain(curve0, nb_samples - 1 - i, nb_samples); \
404 double gain1 = fade_gain(curve1, i, nb_samples); \
405 for (c = 0; c < channels; c++) { \
406 type *d = (type *)dst[c]; \
407 const type *s0 = (type *)cf0[c]; \
408 const type *s1 = (type *)cf1[c]; \
410 d[i] = s0[i] * gain0 + s1[i] * gain1; \
415 #define CROSSFADE(name, type) \
416 static void crossfade_samples_## name (uint8_t **dst, uint8_t * const *cf0, \
417 uint8_t * const *cf1, \
418 int nb_samples, int channels, \
419 int curve0, int curve1) \
421 type *d = (type *)dst[0]; \
422 const type *s0 = (type *)cf0[0]; \
423 const type *s1 = (type *)cf1[0]; \
426 for (i = 0; i < nb_samples; i++) { \
427 double gain0 = fade_gain(curve0, nb_samples - 1 - i, nb_samples); \
428 double gain1 = fade_gain(curve1, i, nb_samples); \
429 for (c = 0; c < channels; c++, k++) \
430 d[k] = s0[k] * gain0 + s1[k] * gain1; \
434 CROSSFADE_PLANAR(dbl,
double)
435 CROSSFADE_PLANAR(flt,
float)
436 CROSSFADE_PLANAR(s16, int16_t)
439 CROSSFADE(dbl,
double)
440 CROSSFADE(flt,
float)
441 CROSSFADE(s16, int16_t)
454 if (
s->crossfade_is_over) {
461 }
else if (
ret < 0) {
475 if (nb_samples >
s->nb_samples) {
476 nb_samples -=
s->nb_samples;
484 }
else if (
s->cf0_eof && nb_samples >=
s->nb_samples &&
503 s->crossfade_samples(
out->extended_data, cf[0]->extended_data,
504 cf[1]->extended_data,
505 s->nb_samples,
out->channels,
506 s->curve,
s->curve2);
510 s->crossfade_is_over = 1;
525 s->fade_samples(
out->extended_data, cf[0]->extended_data,
s->nb_samples,
526 outlink->
channels, -1,
s->nb_samples - 1,
s->nb_samples,
s->curve);
545 s->fade_samples(
out->extended_data, cf[1]->extended_data,
s->nb_samples,
546 outlink->
channels, 1, 0,
s->nb_samples,
s->curve2);
550 s->crossfade_is_over = 1;
572 static int acrossfade_config_output(
AVFilterLink *outlink)
579 switch (outlink->
format) {
595 static const AVFilterPad avfilter_af_acrossfade_inputs[] = {
597 .
name =
"crossfade0",
601 .name =
"crossfade1",
606 static const AVFilterPad avfilter_af_acrossfade_outputs[] = {
610 .config_props = acrossfade_config_output,
615 .
name =
"acrossfade",
619 .priv_class = &acrossfade_class,