1/* 2 * Copyright (c) 1999 Chris Bagwell 3 * Copyright (c) 1999 Nick Bailey 4 * Copyright (c) 2007 Rob Sykes <robs@users.sourceforge.net> 5 * Copyright (c) 2013 Paul B Mahol 6 * Copyright (c) 2014 Andrew Kelley 7 * 8 * This file is part of FFmpeg. 9 * 10 * FFmpeg is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * FFmpeg is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with FFmpeg; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 */ 24 25/** 26 * @file 27 * audio compand filter 28 */ 29 30#include "libavutil/avassert.h" 31#include "libavutil/avstring.h" 32#include "libavutil/opt.h" 33#include "libavutil/samplefmt.h" 34#include "audio.h" 35#include "avfilter.h" 36#include "internal.h" 37 38typedef struct ChanParam { 39 double attack; 40 double decay; 41 double volume; 42} ChanParam; 43 44typedef struct CompandSegment { 45 double x, y; 46 double a, b; 47} CompandSegment; 48 49typedef struct CompandContext { 50 const AVClass *class; 51 int nb_segments; 52 char *attacks, *decays, *points; 53 CompandSegment *segments; 54 ChanParam *channels; 55 double in_min_lin; 56 double out_min_lin; 57 double curve_dB; 58 double gain_dB; 59 double initial_volume; 60 double delay; 61 AVFrame *delay_frame; 62 int delay_samples; 63 int delay_count; 64 int delay_index; 65 int64_t pts; 66 67 int (*compand)(AVFilterContext *ctx, AVFrame *frame); 68} CompandContext; 69 70#define OFFSET(x) offsetof(CompandContext, x) 71#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM 72 73static const AVOption compand_options[] = { 74 { "attacks", "set time over which increase of volume is determined", OFFSET(attacks), AV_OPT_TYPE_STRING, { .str = "0.3" }, 0, 0, A }, 75 { "decays", "set time over which decrease of volume is determined", OFFSET(decays), AV_OPT_TYPE_STRING, { .str = "0.8" }, 0, 0, A }, 76 { "points", "set points of transfer function", OFFSET(points), AV_OPT_TYPE_STRING, { .str = "-70/-70|-60/-20" }, 0, 0, A }, 77 { "soft-knee", "set soft-knee", OFFSET(curve_dB), AV_OPT_TYPE_DOUBLE, { .dbl = 0.01 }, 0.01, 900, A }, 78 { "gain", "set output gain", OFFSET(gain_dB), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -900, 900, A }, 79 { "volume", "set initial volume", OFFSET(initial_volume), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -900, 0, A }, 80 { "delay", "set delay for samples before sending them to volume adjuster", OFFSET(delay), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, 0, 20, A }, 81 { NULL } 82}; 83 84AVFILTER_DEFINE_CLASS(compand); 85 86static av_cold int init(AVFilterContext *ctx) 87{ 88 CompandContext *s = ctx->priv; 89 s->pts = AV_NOPTS_VALUE; 90 return 0; 91} 92 93static av_cold void uninit(AVFilterContext *ctx) 94{ 95 CompandContext *s = ctx->priv; 96 97 av_freep(&s->channels); 98 av_freep(&s->segments); 99 av_frame_free(&s->delay_frame); 100} 101 102static int query_formats(AVFilterContext *ctx) 103{ 104 AVFilterChannelLayouts *layouts; 105 AVFilterFormats *formats; 106 static const enum AVSampleFormat sample_fmts[] = { 107 AV_SAMPLE_FMT_DBLP, 108 AV_SAMPLE_FMT_NONE 109 }; 110 111 layouts = ff_all_channel_layouts(); 112 if (!layouts) 113 return AVERROR(ENOMEM); 114 ff_set_common_channel_layouts(ctx, layouts); 115 116 formats = ff_make_format_list(sample_fmts); 117 if (!formats) 118 return AVERROR(ENOMEM); 119 ff_set_common_formats(ctx, formats); 120 121 formats = ff_all_samplerates(); 122 if (!formats) 123 return AVERROR(ENOMEM); 124 ff_set_common_samplerates(ctx, formats); 125 126 return 0; 127} 128 129static void count_items(char *item_str, int *nb_items) 130{ 131 char *p; 132 133 *nb_items = 1; 134 for (p = item_str; *p; p++) { 135 if (*p == ' ' || *p == '|') 136 (*nb_items)++; 137 } 138} 139 140static void update_volume(ChanParam *cp, double in) 141{ 142 double delta = in - cp->volume; 143 144 if (delta > 0.0) 145 cp->volume += delta * cp->attack; 146 else 147 cp->volume += delta * cp->decay; 148} 149 150static double get_volume(CompandContext *s, double in_lin) 151{ 152 CompandSegment *cs; 153 double in_log, out_log; 154 int i; 155 156 if (in_lin < s->in_min_lin) 157 return s->out_min_lin; 158 159 in_log = log(in_lin); 160 161 for (i = 1; i < s->nb_segments; i++) 162 if (in_log <= s->segments[i].x) 163 break; 164 cs = &s->segments[i - 1]; 165 in_log -= cs->x; 166 out_log = cs->y + in_log * (cs->a * in_log + cs->b); 167 168 return exp(out_log); 169} 170 171static int compand_nodelay(AVFilterContext *ctx, AVFrame *frame) 172{ 173 CompandContext *s = ctx->priv; 174 AVFilterLink *inlink = ctx->inputs[0]; 175 const int channels = inlink->channels; 176 const int nb_samples = frame->nb_samples; 177 AVFrame *out_frame; 178 int chan, i; 179 int err; 180 181 if (av_frame_is_writable(frame)) { 182 out_frame = frame; 183 } else { 184 out_frame = ff_get_audio_buffer(inlink, nb_samples); 185 if (!out_frame) { 186 av_frame_free(&frame); 187 return AVERROR(ENOMEM); 188 } 189 err = av_frame_copy_props(out_frame, frame); 190 if (err < 0) { 191 av_frame_free(&out_frame); 192 av_frame_free(&frame); 193 return err; 194 } 195 } 196 197 for (chan = 0; chan < channels; chan++) { 198 const double *src = (double *)frame->extended_data[chan]; 199 double *dst = (double *)out_frame->extended_data[chan]; 200 ChanParam *cp = &s->channels[chan]; 201 202 for (i = 0; i < nb_samples; i++) { 203 update_volume(cp, fabs(src[i])); 204 205 dst[i] = av_clipd(src[i] * get_volume(s, cp->volume), -1, 1); 206 } 207 } 208 209 if (frame != out_frame) 210 av_frame_free(&frame); 211 212 return ff_filter_frame(ctx->outputs[0], out_frame); 213} 214 215#define MOD(a, b) (((a) >= (b)) ? (a) - (b) : (a)) 216 217static int compand_delay(AVFilterContext *ctx, AVFrame *frame) 218{ 219 CompandContext *s = ctx->priv; 220 AVFilterLink *inlink = ctx->inputs[0]; 221 const int channels = inlink->channels; 222 const int nb_samples = frame->nb_samples; 223 int chan, i, av_uninit(dindex), oindex, av_uninit(count); 224 AVFrame *out_frame = NULL; 225 int err; 226 227 if (s->pts == AV_NOPTS_VALUE) { 228 s->pts = (frame->pts == AV_NOPTS_VALUE) ? 0 : frame->pts; 229 } 230 231 av_assert1(channels > 0); /* would corrupt delay_count and delay_index */ 232 233 for (chan = 0; chan < channels; chan++) { 234 AVFrame *delay_frame = s->delay_frame; 235 const double *src = (double *)frame->extended_data[chan]; 236 double *dbuf = (double *)delay_frame->extended_data[chan]; 237 ChanParam *cp = &s->channels[chan]; 238 double *dst; 239 240 count = s->delay_count; 241 dindex = s->delay_index; 242 for (i = 0, oindex = 0; i < nb_samples; i++) { 243 const double in = src[i]; 244 update_volume(cp, fabs(in)); 245 246 if (count >= s->delay_samples) { 247 if (!out_frame) { 248 out_frame = ff_get_audio_buffer(inlink, nb_samples - i); 249 if (!out_frame) { 250 av_frame_free(&frame); 251 return AVERROR(ENOMEM); 252 } 253 err = av_frame_copy_props(out_frame, frame); 254 if (err < 0) { 255 av_frame_free(&out_frame); 256 av_frame_free(&frame); 257 return err; 258 } 259 out_frame->pts = s->pts; 260 s->pts += av_rescale_q(nb_samples - i, 261 (AVRational){ 1, inlink->sample_rate }, 262 inlink->time_base); 263 } 264 265 dst = (double *)out_frame->extended_data[chan]; 266 dst[oindex++] = av_clipd(dbuf[dindex] * 267 get_volume(s, cp->volume), -1, 1); 268 } else { 269 count++; 270 } 271 272 dbuf[dindex] = in; 273 dindex = MOD(dindex + 1, s->delay_samples); 274 } 275 } 276 277 s->delay_count = count; 278 s->delay_index = dindex; 279 280 av_frame_free(&frame); 281 282 if (out_frame) { 283 err = ff_filter_frame(ctx->outputs[0], out_frame); 284 return err; 285 } 286 287 return 0; 288} 289 290static int compand_drain(AVFilterLink *outlink) 291{ 292 AVFilterContext *ctx = outlink->src; 293 CompandContext *s = ctx->priv; 294 const int channels = outlink->channels; 295 AVFrame *frame = NULL; 296 int chan, i, dindex; 297 298 /* 2048 is to limit output frame size during drain */ 299 frame = ff_get_audio_buffer(outlink, FFMIN(2048, s->delay_count)); 300 if (!frame) 301 return AVERROR(ENOMEM); 302 frame->pts = s->pts; 303 s->pts += av_rescale_q(frame->nb_samples, 304 (AVRational){ 1, outlink->sample_rate }, outlink->time_base); 305 306 av_assert0(channels > 0); 307 for (chan = 0; chan < channels; chan++) { 308 AVFrame *delay_frame = s->delay_frame; 309 double *dbuf = (double *)delay_frame->extended_data[chan]; 310 double *dst = (double *)frame->extended_data[chan]; 311 ChanParam *cp = &s->channels[chan]; 312 313 dindex = s->delay_index; 314 for (i = 0; i < frame->nb_samples; i++) { 315 dst[i] = av_clipd(dbuf[dindex] * get_volume(s, cp->volume), 316 -1, 1); 317 dindex = MOD(dindex + 1, s->delay_samples); 318 } 319 } 320 s->delay_count -= frame->nb_samples; 321 s->delay_index = dindex; 322 323 return ff_filter_frame(outlink, frame); 324} 325 326static int config_output(AVFilterLink *outlink) 327{ 328 AVFilterContext *ctx = outlink->src; 329 CompandContext *s = ctx->priv; 330 const int sample_rate = outlink->sample_rate; 331 double radius = s->curve_dB * M_LN10 / 20.0; 332 char *p, *saveptr = NULL; 333 const int channels = outlink->channels; 334 int nb_attacks, nb_decays, nb_points; 335 int new_nb_items, num; 336 int i; 337 int err; 338 339 340 count_items(s->attacks, &nb_attacks); 341 count_items(s->decays, &nb_decays); 342 count_items(s->points, &nb_points); 343 344 if (channels <= 0) { 345 av_log(ctx, AV_LOG_ERROR, "Invalid number of channels: %d\n", channels); 346 return AVERROR(EINVAL); 347 } 348 349 if (nb_attacks > channels || nb_decays > channels) { 350 av_log(ctx, AV_LOG_ERROR, 351 "Number of attacks/decays bigger than number of channels.\n"); 352 return AVERROR(EINVAL); 353 } 354 355 uninit(ctx); 356 357 s->channels = av_mallocz_array(channels, sizeof(*s->channels)); 358 s->nb_segments = (nb_points + 4) * 2; 359 s->segments = av_mallocz_array(s->nb_segments, sizeof(*s->segments)); 360 361 if (!s->channels || !s->segments) { 362 uninit(ctx); 363 return AVERROR(ENOMEM); 364 } 365 366 p = s->attacks; 367 for (i = 0, new_nb_items = 0; i < nb_attacks; i++) { 368 char *tstr = av_strtok(p, " |", &saveptr); 369 p = NULL; 370 new_nb_items += sscanf(tstr, "%lf", &s->channels[i].attack) == 1; 371 if (s->channels[i].attack < 0) { 372 uninit(ctx); 373 return AVERROR(EINVAL); 374 } 375 } 376 nb_attacks = new_nb_items; 377 378 p = s->decays; 379 for (i = 0, new_nb_items = 0; i < nb_decays; i++) { 380 char *tstr = av_strtok(p, " |", &saveptr); 381 p = NULL; 382 new_nb_items += sscanf(tstr, "%lf", &s->channels[i].decay) == 1; 383 if (s->channels[i].decay < 0) { 384 uninit(ctx); 385 return AVERROR(EINVAL); 386 } 387 } 388 nb_decays = new_nb_items; 389 390 if (nb_attacks != nb_decays) { 391 av_log(ctx, AV_LOG_ERROR, 392 "Number of attacks %d differs from number of decays %d.\n", 393 nb_attacks, nb_decays); 394 uninit(ctx); 395 return AVERROR(EINVAL); 396 } 397 398#define S(x) s->segments[2 * ((x) + 1)] 399 p = s->points; 400 for (i = 0, new_nb_items = 0; i < nb_points; i++) { 401 char *tstr = av_strtok(p, " |", &saveptr); 402 p = NULL; 403 if (sscanf(tstr, "%lf/%lf", &S(i).x, &S(i).y) != 2) { 404 av_log(ctx, AV_LOG_ERROR, 405 "Invalid and/or missing input/output value.\n"); 406 uninit(ctx); 407 return AVERROR(EINVAL); 408 } 409 if (i && S(i - 1).x > S(i).x) { 410 av_log(ctx, AV_LOG_ERROR, 411 "Transfer function input values must be increasing.\n"); 412 uninit(ctx); 413 return AVERROR(EINVAL); 414 } 415 S(i).y -= S(i).x; 416 av_log(ctx, AV_LOG_DEBUG, "%d: x=%f y=%f\n", i, S(i).x, S(i).y); 417 new_nb_items++; 418 } 419 num = new_nb_items; 420 421 /* Add 0,0 if necessary */ 422 if (num == 0 || S(num - 1).x) 423 num++; 424 425#undef S 426#define S(x) s->segments[2 * (x)] 427 /* Add a tail off segment at the start */ 428 S(0).x = S(1).x - 2 * s->curve_dB; 429 S(0).y = S(1).y; 430 num++; 431 432 /* Join adjacent colinear segments */ 433 for (i = 2; i < num; i++) { 434 double g1 = (S(i - 1).y - S(i - 2).y) * (S(i - 0).x - S(i - 1).x); 435 double g2 = (S(i - 0).y - S(i - 1).y) * (S(i - 1).x - S(i - 2).x); 436 int j; 437 438 if (fabs(g1 - g2)) 439 continue; 440 num--; 441 for (j = --i; j < num; j++) 442 S(j) = S(j + 1); 443 } 444 445 for (i = 0; !i || s->segments[i - 2].x; i += 2) { 446 s->segments[i].y += s->gain_dB; 447 s->segments[i].x *= M_LN10 / 20; 448 s->segments[i].y *= M_LN10 / 20; 449 } 450 451#define L(x) s->segments[i - (x)] 452 for (i = 4; s->segments[i - 2].x; i += 2) { 453 double x, y, cx, cy, in1, in2, out1, out2, theta, len, r; 454 455 L(4).a = 0; 456 L(4).b = (L(2).y - L(4).y) / (L(2).x - L(4).x); 457 458 L(2).a = 0; 459 L(2).b = (L(0).y - L(2).y) / (L(0).x - L(2).x); 460 461 theta = atan2(L(2).y - L(4).y, L(2).x - L(4).x); 462 len = sqrt(pow(L(2).x - L(4).x, 2.) + pow(L(2).y - L(4).y, 2.)); 463 r = FFMIN(radius, len); 464 L(3).x = L(2).x - r * cos(theta); 465 L(3).y = L(2).y - r * sin(theta); 466 467 theta = atan2(L(0).y - L(2).y, L(0).x - L(2).x); 468 len = sqrt(pow(L(0).x - L(2).x, 2.) + pow(L(0).y - L(2).y, 2.)); 469 r = FFMIN(radius, len / 2); 470 x = L(2).x + r * cos(theta); 471 y = L(2).y + r * sin(theta); 472 473 cx = (L(3).x + L(2).x + x) / 3; 474 cy = (L(3).y + L(2).y + y) / 3; 475 476 L(2).x = x; 477 L(2).y = y; 478 479 in1 = cx - L(3).x; 480 out1 = cy - L(3).y; 481 in2 = L(2).x - L(3).x; 482 out2 = L(2).y - L(3).y; 483 L(3).a = (out2 / in2 - out1 / in1) / (in2 - in1); 484 L(3).b = out1 / in1 - L(3).a * in1; 485 } 486 L(3).x = 0; 487 L(3).y = L(2).y; 488 489 s->in_min_lin = exp(s->segments[1].x); 490 s->out_min_lin = exp(s->segments[1].y); 491 492 for (i = 0; i < channels; i++) { 493 ChanParam *cp = &s->channels[i]; 494 495 if (cp->attack > 1.0 / sample_rate) 496 cp->attack = 1.0 - exp(-1.0 / (sample_rate * cp->attack)); 497 else 498 cp->attack = 1.0; 499 if (cp->decay > 1.0 / sample_rate) 500 cp->decay = 1.0 - exp(-1.0 / (sample_rate * cp->decay)); 501 else 502 cp->decay = 1.0; 503 cp->volume = pow(10.0, s->initial_volume / 20); 504 } 505 506 s->delay_samples = s->delay * sample_rate; 507 if (s->delay_samples <= 0) { 508 s->compand = compand_nodelay; 509 return 0; 510 } 511 512 s->delay_frame = av_frame_alloc(); 513 if (!s->delay_frame) { 514 uninit(ctx); 515 return AVERROR(ENOMEM); 516 } 517 518 s->delay_frame->format = outlink->format; 519 s->delay_frame->nb_samples = s->delay_samples; 520 s->delay_frame->channel_layout = outlink->channel_layout; 521 522 err = av_frame_get_buffer(s->delay_frame, 32); 523 if (err) 524 return err; 525 526 outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP; 527 s->compand = compand_delay; 528 return 0; 529} 530 531static int filter_frame(AVFilterLink *inlink, AVFrame *frame) 532{ 533 AVFilterContext *ctx = inlink->dst; 534 CompandContext *s = ctx->priv; 535 536 return s->compand(ctx, frame); 537} 538 539static int request_frame(AVFilterLink *outlink) 540{ 541 AVFilterContext *ctx = outlink->src; 542 CompandContext *s = ctx->priv; 543 int ret = 0; 544 545 ret = ff_request_frame(ctx->inputs[0]); 546 547 if (ret == AVERROR_EOF && !ctx->is_disabled && s->delay_count) 548 ret = compand_drain(outlink); 549 550 return ret; 551} 552 553static const AVFilterPad compand_inputs[] = { 554 { 555 .name = "default", 556 .type = AVMEDIA_TYPE_AUDIO, 557 .filter_frame = filter_frame, 558 }, 559 { NULL } 560}; 561 562static const AVFilterPad compand_outputs[] = { 563 { 564 .name = "default", 565 .request_frame = request_frame, 566 .config_props = config_output, 567 .type = AVMEDIA_TYPE_AUDIO, 568 }, 569 { NULL } 570}; 571 572 573AVFilter ff_af_compand = { 574 .name = "compand", 575 .description = NULL_IF_CONFIG_SMALL( 576 "Compress or expand audio dynamic range."), 577 .query_formats = query_formats, 578 .priv_size = sizeof(CompandContext), 579 .priv_class = &compand_class, 580 .init = init, 581 .uninit = uninit, 582 .inputs = compand_inputs, 583 .outputs = compand_outputs, 584}; 585