/*
 * Copyright (c) 1998 Juergen Mueller And Sundry Contributors
 * This source code is freely redistributable and may be used for
 * any purpose.  This copyright notice must be maintained.
 * Juergen Mueller And Sundry Contributors are not responsible for
 * the consequences of using this software.
 *
 * Copyright (c) 2015 Paul B Mahol
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * chorus audio filter
 */

#include "libavutil/avstring.h"
#include "libavutil/opt.h"
#include "audio.h"
#include "avfilter.h"
#include "internal.h"
#include "generate_wave_table.h"

typedef struct ChorusContext {
    const AVClass *class;
    float in_gain, out_gain;
    char *delays_str;
    char *decays_str;
    char *speeds_str;
    char *depths_str;
    float *delays;
    float *decays;
    float *speeds;
    float *depths;
    uint8_t **chorusbuf;
    int **phase;
    int *length;
    int32_t **lookup_table;
    int *counter;
    int num_chorus;
    int max_samples;
    int channels;
    int modulation;
    int fade_out;
    int64_t next_pts;
} ChorusContext;

#define OFFSET(x) offsetof(ChorusContext, x)
#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM

static const AVOption chorus_options[] = {
    { "in_gain",  "set input gain",  OFFSET(in_gain),    AV_OPT_TYPE_FLOAT,  {.dbl=.4}, 0, 1, A },
    { "out_gain", "set output gain", OFFSET(out_gain),   AV_OPT_TYPE_FLOAT,  {.dbl=.4}, 0, 1, A },
    { "delays",   "set delays",      OFFSET(delays_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
    { "decays",   "set decays",      OFFSET(decays_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
    { "speeds",   "set speeds",      OFFSET(speeds_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
    { "depths",   "set depths",      OFFSET(depths_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
    { NULL }
};

AVFILTER_DEFINE_CLASS(chorus);

static void count_items(char *item_str, int *nb_items)
{
    char *p;

    *nb_items = 1;
    for (p = item_str; *p; p++) {
        if (*p == '|')
            (*nb_items)++;
    }

}

static void fill_items(char *item_str, int *nb_items, float *items)
{
    char *p, *saveptr = NULL;
    int i, new_nb_items = 0;

    p = item_str;
    for (i = 0; i < *nb_items; i++) {
        char *tstr = av_strtok(p, "|", &saveptr);
        p = NULL;
        new_nb_items += sscanf(tstr, "%f", &items[i]) == 1;
    }

    *nb_items = new_nb_items;
}

static av_cold int init(AVFilterContext *ctx)
{
    ChorusContext *s = ctx->priv;
    int nb_delays, nb_decays, nb_speeds, nb_depths;

    if (!s->delays_str || !s->decays_str || !s->speeds_str || !s->depths_str) {
        av_log(ctx, AV_LOG_ERROR, "Both delays & decays & speeds & depths must be set.\n");
        return AVERROR(EINVAL);
    }

    count_items(s->delays_str, &nb_delays);
    count_items(s->decays_str, &nb_decays);
    count_items(s->speeds_str, &nb_speeds);
    count_items(s->depths_str, &nb_depths);

    s->delays = av_realloc_f(s->delays, nb_delays, sizeof(*s->delays));
    s->decays = av_realloc_f(s->decays, nb_decays, sizeof(*s->decays));
    s->speeds = av_realloc_f(s->speeds, nb_speeds, sizeof(*s->speeds));
    s->depths = av_realloc_f(s->depths, nb_depths, sizeof(*s->depths));

    if (!s->delays || !s->decays || !s->speeds || !s->depths)
        return AVERROR(ENOMEM);

    fill_items(s->delays_str, &nb_delays, s->delays);
    fill_items(s->decays_str, &nb_decays, s->decays);
    fill_items(s->speeds_str, &nb_speeds, s->speeds);
    fill_items(s->depths_str, &nb_depths, s->depths);

    if (nb_delays != nb_decays && nb_delays != nb_speeds && nb_delays != nb_depths) {
        av_log(ctx, AV_LOG_ERROR, "Number of delays & decays & speeds & depths given must be same.\n");
        return AVERROR(EINVAL);
    }

    s->num_chorus = nb_delays;

    if (s->num_chorus < 1) {
        av_log(ctx, AV_LOG_ERROR, "At least one delay & decay & speed & depth must be set.\n");
        return AVERROR(EINVAL);
    }

    s->length = av_calloc(s->num_chorus, sizeof(*s->length));
    s->lookup_table = av_calloc(s->num_chorus, sizeof(*s->lookup_table));

    if (!s->length || !s->lookup_table)
        return AVERROR(ENOMEM);

    s->next_pts = AV_NOPTS_VALUE;

    return 0;
}

static int query_formats(AVFilterContext *ctx)
{
    AVFilterFormats *formats;
    AVFilterChannelLayouts *layouts;
    static const enum AVSampleFormat sample_fmts[] = {
        AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
    };
    int ret;

    layouts = ff_all_channel_counts();
    if (!layouts)
        return AVERROR(ENOMEM);
    ret = ff_set_common_channel_layouts(ctx, layouts);
    if (ret < 0)
        return ret;

    formats = ff_make_format_list(sample_fmts);
    if (!formats)
        return AVERROR(ENOMEM);
    ret = ff_set_common_formats(ctx, formats);
    if (ret < 0)
        return ret;

    formats = ff_all_samplerates();
    if (!formats)
        return AVERROR(ENOMEM);
    return ff_set_common_samplerates(ctx, formats);
}

static int config_output(AVFilterLink *outlink)
{
    AVFilterContext *ctx = outlink->src;
    ChorusContext *s = ctx->priv;
    float sum_in_volume = 1.0;
    int n;

    s->channels = outlink->channels;

    for (n = 0; n < s->num_chorus; n++) {
        int samples = (int) ((s->delays[n] + s->depths[n]) * outlink->sample_rate / 1000.0);
        int depth_samples = (int) (s->depths[n] * outlink->sample_rate / 1000.0);

        s->length[n] = outlink->sample_rate / s->speeds[n];

        s->lookup_table[n] = av_malloc(sizeof(int32_t) * s->length[n]);
        if (!s->lookup_table[n])
            return AVERROR(ENOMEM);

        ff_generate_wave_table(WAVE_SIN, AV_SAMPLE_FMT_S32, s->lookup_table[n],
                               s->length[n], 0., depth_samples, 0);
        s->max_samples = FFMAX(s->max_samples, samples);
    }

    for (n = 0; n < s->num_chorus; n++)
        sum_in_volume += s->decays[n];

    if (s->in_gain * (sum_in_volume) > 1.0 / s->out_gain)
        av_log(ctx, AV_LOG_WARNING, "output gain can cause saturation or clipping of output\n");

    s->counter = av_calloc(outlink->channels, sizeof(*s->counter));
    if (!s->counter)
        return AVERROR(ENOMEM);

    s->phase = av_calloc(outlink->channels, sizeof(*s->phase));
    if (!s->phase)
        return AVERROR(ENOMEM);

    for (n = 0; n < outlink->channels; n++) {
        s->phase[n] = av_calloc(s->num_chorus, sizeof(int));
        if (!s->phase[n])
            return AVERROR(ENOMEM);
    }

    s->fade_out = s->max_samples;

    return av_samples_alloc_array_and_samples(&s->chorusbuf, NULL,
                                              outlink->channels,
                                              s->max_samples,
                                              outlink->format, 0);
}

#define MOD(a, b) (((a) >= (b)) ? (a) - (b) : (a))

static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
    AVFilterContext *ctx = inlink->dst;
    ChorusContext *s = ctx->priv;
    AVFrame *out_frame;
    int c, i, n;

    if (av_frame_is_writable(frame)) {
        out_frame = frame;
    } else {
        out_frame = ff_get_audio_buffer(inlink, frame->nb_samples);
        if (!out_frame) {
            av_frame_free(&frame);
            return AVERROR(ENOMEM);
        }
        av_frame_copy_props(out_frame, frame);
    }

    for (c = 0; c < inlink->channels; c++) {
        const float *src = (const float *)frame->extended_data[c];
        float *dst = (float *)out_frame->extended_data[c];
        float *chorusbuf = (float *)s->chorusbuf[c];
        int *phase = s->phase[c];

        for (i = 0; i < frame->nb_samples; i++) {
            float out, in = src[i];

            out = in * s->in_gain;

            for (n = 0; n < s->num_chorus; n++) {
                out += chorusbuf[MOD(s->max_samples + s->counter[c] -
                                     s->lookup_table[n][phase[n]],
                                     s->max_samples)] * s->decays[n];
                phase[n] = MOD(phase[n] + 1, s->length[n]);
            }

            out *= s->out_gain;

            dst[i] = out;

            chorusbuf[s->counter[c]] = in;
            s->counter[c] = MOD(s->counter[c] + 1, s->max_samples);
        }
    }

    s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base);

    if (frame != out_frame)
        av_frame_free(&frame);

    return ff_filter_frame(ctx->outputs[0], out_frame);
}

static int request_frame(AVFilterLink *outlink)
{
    AVFilterContext *ctx = outlink->src;
    ChorusContext *s = ctx->priv;
    int ret;

    ret = ff_request_frame(ctx->inputs[0]);

    if (ret == AVERROR_EOF && !ctx->is_disabled && s->fade_out) {
        int nb_samples = FFMIN(s->fade_out, 2048);
        AVFrame *frame;

        frame = ff_get_audio_buffer(outlink, nb_samples);
        if (!frame)
            return AVERROR(ENOMEM);
        s->fade_out -= nb_samples;

        av_samples_set_silence(frame->extended_data, 0,
                               frame->nb_samples,
                               outlink->channels,
                               frame->format);

        frame->pts = s->next_pts;
        if (s->next_pts != AV_NOPTS_VALUE)
            s->next_pts += av_rescale_q(nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base);

        ret = filter_frame(ctx->inputs[0], frame);
    }

    return ret;
}

static av_cold void uninit(AVFilterContext *ctx)
{
    ChorusContext *s = ctx->priv;
    int n;

    av_freep(&s->delays);
    av_freep(&s->decays);
    av_freep(&s->speeds);
    av_freep(&s->depths);

    if (s->chorusbuf)
        av_freep(&s->chorusbuf[0]);
    av_freep(&s->chorusbuf);

    if (s->phase)
        for (n = 0; n < s->channels; n++)
            av_freep(&s->phase[n]);
    av_freep(&s->phase);

    av_freep(&s->counter);
    av_freep(&s->length);

    if (s->lookup_table)
        for (n = 0; n < s->num_chorus; n++)
            av_freep(&s->lookup_table[n]);
    av_freep(&s->lookup_table);
}

static const AVFilterPad chorus_inputs[] = {
    {
        .name         = "default",
        .type         = AVMEDIA_TYPE_AUDIO,
        .filter_frame = filter_frame,
    },
    { NULL }
};

static const AVFilterPad chorus_outputs[] = {
    {
        .name          = "default",
        .type          = AVMEDIA_TYPE_AUDIO,
        .request_frame = request_frame,
        .config_props  = config_output,
    },
    { NULL }
};

AVFilter ff_af_chorus = {
    .name          = "chorus",
    .description   = NULL_IF_CONFIG_SMALL("Add a chorus effect to the audio."),
    .query_formats = query_formats,
    .priv_size     = sizeof(ChorusContext),
    .priv_class    = &chorus_class,
    .init          = init,
    .uninit        = uninit,
    .inputs        = chorus_inputs,
    .outputs       = chorus_outputs,
};
