Beispiel #1
0
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);
}
Beispiel #2
0
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;
    }
}