static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; AudioGateContext *s = ctx->priv; const double *src = (const double *)in->data[0]; const double makeup = s->makeup; const double attack_coeff = s->attack_coeff; const double release_coeff = s->release_coeff; const double level_in = s->level_in; AVFrame *out; double *dst; int n, c; if (av_frame_is_writable(in)) { out = in; } else { out = ff_get_audio_buffer(inlink, in->nb_samples); if (!out) { av_frame_free(&in); return AVERROR(ENOMEM); } av_frame_copy_props(out, in); } dst = (double *)out->data[0]; for (n = 0; n < in->nb_samples; n++, src += inlink->channels, dst += inlink->channels) { double abs_sample = fabs(src[0]), gain = 1.0; for (c = 0; c < inlink->channels; c++) dst[c] = src[c] * level_in; if (s->link == 1) { for (c = 1; c < inlink->channels; c++) abs_sample = FFMAX(fabs(src[c]), abs_sample); } else { for (c = 1; c < inlink->channels; c++) abs_sample += fabs(src[c]); abs_sample /= inlink->channels; } if (s->detection) abs_sample *= abs_sample; s->lin_slope += (abs_sample - s->lin_slope) * (abs_sample > s->lin_slope ? attack_coeff : release_coeff); if (s->lin_slope > 0.0) gain = output_gain(s->lin_slope, s->ratio, s->thres, s->knee, s->knee_start, s->knee_stop, s->lin_knee_stop, s->range); for (c = 0; c < inlink->channels; c++) dst[c] *= gain * makeup; } if (out != in) av_frame_free(&in); return ff_filter_frame(outlink, out); }
static void compressor(SidechainCompressContext *s, const double *src, double *dst, const double *scsrc, int nb_samples, double level_in, double level_sc, AVFilterLink *inlink, AVFilterLink *sclink) { const double makeup = s->makeup; const double mix = s->mix; int i, c; for (i = 0; i < nb_samples; i++) { double abs_sample, gain = 1.0; abs_sample = fabs(scsrc[0] * level_sc); if (s->link == 1) { for (c = 1; c < sclink->channels; c++) abs_sample = FFMAX(fabs(scsrc[c] * level_sc), abs_sample); } else { for (c = 1; c < sclink->channels; c++) abs_sample += fabs(scsrc[c] * level_sc); abs_sample /= sclink->channels; } if (s->detection) abs_sample *= abs_sample; s->lin_slope += (abs_sample - s->lin_slope) * (abs_sample > s->lin_slope ? s->attack_coeff : s->release_coeff); if (s->lin_slope > 0.0 && s->lin_slope > (s->detection ? s->adj_knee_start : s->lin_knee_start)) gain = output_gain(s->lin_slope, s->ratio, s->thres, s->knee, s->knee_start, s->knee_stop, s->compressed_knee_stop, s->detection); for (c = 0; c < inlink->channels; c++) dst[c] = src[c] * level_in * (gain * makeup * mix + (1. - mix)); src += inlink->channels; dst += inlink->channels; scsrc += sclink->channels; } }