70 #define OFFSET(x) offsetof(CompandContext, x) 
   71 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM 
   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 },
 
   80     { 
"delay", 
"set delay for samples before sending them to volume adjuster", 
OFFSET(delay), 
AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, 0, 20, 
A },
 
  134     for (p = item_str; *p; p++) {
 
  135         if (*p == 
' ' || *p == 
'|')
 
  153     double in_log, out_log;
 
  156     if (in_lin < s->in_min_lin)
 
  159     in_log = log(in_lin);
 
  162         if (in_log <= s->segments[i].x)
 
  166     out_log = cs->
y + in_log * (cs->
a * in_log + cs->
b);
 
  175     const int channels   = inlink->
channels;
 
  197     for (chan = 0; chan < channels; chan++) {
 
  202         for (i = 0; i < nb_samples; i++) {
 
  209     if (frame != out_frame)
 
  215 #define MOD(a, b) (((a) >= (b)) ? (a) - (b) : (a)) 
  221     const int channels = inlink->
channels;
 
  233     for (chan = 0; chan < channels; chan++) {
 
  242         for (i = 0, oindex = 0; i < nb_samples; i++) {
 
  243             const double in = src[i];
 
  266                 dst[oindex++] = av_clipd(dbuf[dindex] *
 
  294     const int channels   = outlink->
channels;
 
  307     for (chan = 0; chan < channels; chan++) {
 
  308         AVFrame *delay_frame = 
s->delay_frame;
 
  313         dindex = 
s->delay_index;
 
  317             dindex = 
MOD(dindex + 1, 
s->delay_samples);
 
  321     s->delay_index = dindex;
 
  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;
 
  349     if (nb_attacks > channels || nb_decays > channels) {
 
  351                 "Number of attacks/decays bigger than number of channels.\n");
 
  367     for (i = 0, new_nb_items = 0; i < nb_attacks; i++) {
 
  368         char *tstr = 
av_strtok(p, 
" |", &saveptr);
 
  376     nb_attacks = new_nb_items;
 
  379     for (i = 0, new_nb_items = 0; i < nb_decays; i++) {
 
  380         char *tstr = 
av_strtok(p, 
" |", &saveptr);
 
  382         new_nb_items += sscanf(tstr, 
"%lf", &s->
channels[i].
decay) == 1;
 
  388     nb_decays = new_nb_items;
 
  390     if (nb_attacks != nb_decays) {
 
  392                 "Number of attacks %d differs from number of decays %d.\n",
 
  393                 nb_attacks, nb_decays);
 
  398 #define S(x) s->segments[2 * ((x) + 1)] 
  400     for (i = 0, new_nb_items = 0; i < nb_points; i++) {
 
  401         char *tstr = 
av_strtok(p, 
" |", &saveptr);
 
  403         if (sscanf(tstr, 
"%lf/%lf", &
S(i).x, &
S(i).
y) != 2) {
 
  405                     "Invalid and/or missing input/output value.\n");
 
  409         if (i && 
S(i - 1).x > 
S(i).x) {
 
  411                     "Transfer function input values must be increasing.\n");
 
  422     if (num == 0 || 
S(num - 1).x)
 
  426 #define S(x) s->segments[2 * (x)] 
  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);
 
  441         for (j = --i; j < num; j++)
 
  445     for (i = 0; !i || s->
segments[i - 2].
x; i += 2) {
 
  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;
 
  456         L(4).b = (
L(2).y - 
L(4).y) / (
L(2).x - 
L(4).x);
 
  459         L(2).b = (
L(0).y - 
L(2).y) / (
L(0).x - 
L(2).x);
 
  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);
 
  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);
 
  473         cx = (
L(3).x + 
L(2).x + x) / 3;
 
  474         cy = (
L(3).y + 
L(2).y + 
y) / 3;
 
  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;
 
  492     for (i = 0; i < channels; i++) {
 
  495         if (cp->
attack > 1.0 / sample_rate)
 
  496             cp->
attack = 1.0 - exp(-1.0 / (sample_rate * cp->
attack));
 
  499         if (cp->
decay > 1.0 / sample_rate)
 
  500             cp->
decay = 1.0 - exp(-1.0 / (sample_rate * cp->
decay));
 
  576             "Compress or expand audio dynamic range."),
 
  579     .priv_class     = &compand_class,