/*
 * Copyright (c) 2001-2010 Vladimir Sadovnikov
 *
 * 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
 */

#include "libavutil/channel_layout.h"
#include "libavutil/opt.h"
#include "avfilter.h"
#include "audio.h"
#include "formats.h"

#define MAX_HAAS_DELAY 40

typedef struct HaasContext {
    const AVClass *class;

    int par_m_source;
    double par_delay0;
    double par_delay1;
    int par_phase0;
    int par_phase1;
    int par_middle_phase;
    double par_side_gain;
    double par_gain0;
    double par_gain1;
    double par_balance0;
    double par_balance1;
    double level_in;
    double level_out;

    double *buffer;
    size_t buffer_size;
    uint32_t write_ptr;
    uint32_t delay[2];
    double balance_l[2];
    double balance_r[2];
    double phase0;
    double phase1;
} HaasContext;

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

static const AVOption haas_options[] = {
    { "level_in",      "set level in",      OFFSET(level_in),         AV_OPT_TYPE_DOUBLE,  {.dbl=1}, 0.015625,  64, A },
    { "level_out",     "set level out",     OFFSET(level_out),        AV_OPT_TYPE_DOUBLE,  {.dbl=1}, 0.015625,  64, A },
    { "side_gain",     "set side gain",     OFFSET(par_side_gain),    AV_OPT_TYPE_DOUBLE,  {.dbl=1}, 0.015625,  64, A },
    { "middle_source", "set middle source", OFFSET(par_m_source),     AV_OPT_TYPE_INT,     {.i64=2},        0,   3, A, "source" },
    {   "left",        0,                   0,                        AV_OPT_TYPE_CONST,   {.i64=0},        0,   0, A, "source" },
    {   "right",       0,                   0,                        AV_OPT_TYPE_CONST,   {.i64=1},        0,   0, A, "source" },
    {   "mid",         "L+R",               0,                        AV_OPT_TYPE_CONST,   {.i64=2},        0,   0, A, "source" },
    {   "side",        "L-R",               0,                        AV_OPT_TYPE_CONST,   {.i64=3},        0,   0, A, "source" },
    { "middle_phase",  "set middle phase",  OFFSET(par_middle_phase), AV_OPT_TYPE_BOOL,    {.i64=0},        0,   1, A },
    { "left_delay",    "set left delay",    OFFSET(par_delay0),       AV_OPT_TYPE_DOUBLE,  {.dbl=2.05},     0,  MAX_HAAS_DELAY, A },
    { "left_balance",  "set left balance",  OFFSET(par_balance0),     AV_OPT_TYPE_DOUBLE,  {.dbl=-1.0},    -1,   1, A },
    { "left_gain",     "set left gain",     OFFSET(par_gain0),        AV_OPT_TYPE_DOUBLE,  {.dbl=1}, 0.015625,  64, A },
    { "left_phase",    "set left phase",    OFFSET(par_phase0),       AV_OPT_TYPE_BOOL,    {.i64=0},        0,   1, A },
    { "right_delay",   "set right delay",   OFFSET(par_delay1),       AV_OPT_TYPE_DOUBLE,  {.dbl=2.12},     0,  MAX_HAAS_DELAY, A },
    { "right_balance", "set right balance", OFFSET(par_balance1),     AV_OPT_TYPE_DOUBLE,  {.dbl=1},       -1,   1, A },
    { "right_gain",    "set right gain",    OFFSET(par_gain1),        AV_OPT_TYPE_DOUBLE,  {.dbl=1}, 0.015625,  64, A },
    { "right_phase",   "set right phase",   OFFSET(par_phase1),       AV_OPT_TYPE_BOOL,    {.i64=1},        0,   1, A },
    { NULL }
};

AVFILTER_DEFINE_CLASS(haas);

static int query_formats(AVFilterContext *ctx)
{
    AVFilterFormats *formats = NULL;
    AVFilterChannelLayouts *layout = NULL;
    int ret;

    if ((ret = ff_add_format                 (&formats, AV_SAMPLE_FMT_DBL  )) < 0 ||
        (ret = ff_set_common_formats         (ctx     , formats            )) < 0 ||
        (ret = ff_add_channel_layout         (&layout , AV_CH_LAYOUT_STEREO)) < 0 ||
        (ret = ff_set_common_channel_layouts (ctx     , layout             )) < 0)
        return ret;

    formats = ff_all_samplerates();
    return ff_set_common_samplerates(ctx, formats);
}

static int config_input(AVFilterLink *inlink)
{
    AVFilterContext *ctx = inlink->dst;
    HaasContext *s = ctx->priv;
    size_t min_buf_size = (size_t)(inlink->sample_rate * MAX_HAAS_DELAY * 0.001);
    size_t new_buf_size = 1;

    while (new_buf_size < min_buf_size)
        new_buf_size <<= 1;

    av_freep(&s->buffer);
    s->buffer = av_calloc(new_buf_size, sizeof(*s->buffer));
    if (!s->buffer)
        return AVERROR(ENOMEM);

    s->buffer_size = new_buf_size;
    s->write_ptr = 0;

    s->delay[0] = (uint32_t)(s->par_delay0 * 0.001 * inlink->sample_rate);
    s->delay[1] = (uint32_t)(s->par_delay1 * 0.001 * inlink->sample_rate);

    s->phase0 = s->par_phase0 ? 1.0 : -1.0;
    s->phase1 = s->par_phase1 ? 1.0 : -1.0;

    s->balance_l[0] = (s->par_balance0 + 1) / 2 * s->par_gain0 * s->phase0;
    s->balance_r[0] = (1.0 - (s->par_balance0 + 1) / 2) * (s->par_gain0) * s->phase0;
    s->balance_l[1] = (s->par_balance1 + 1) / 2 * s->par_gain1 * s->phase1;
    s->balance_r[1] = (1.0 - (s->par_balance1 + 1) / 2) * (s->par_gain1) * s->phase1;

    return 0;
}

static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
    AVFilterContext *ctx = inlink->dst;
    AVFilterLink *outlink = ctx->outputs[0];
    HaasContext *s = ctx->priv;
    const double *src = (const double *)in->data[0];
    const double level_in = s->level_in;
    const double level_out = s->level_out;
    const uint32_t mask = s->buffer_size - 1;
    double *buffer = s->buffer;
    AVFrame *out;
    double *dst;
    int n;

    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 += 2, dst += 2) {
        double mid, side[2], side_l, side_r;
        uint32_t s0_ptr, s1_ptr;

        switch (s->par_m_source) {
        case 0: mid = src[0]; break;
        case 1: mid = src[1]; break;
        case 2: mid = (src[0] + src[1]) * 0.5; break;
        case 3: mid = (src[0] - src[1]) * 0.5; break;
        }

        mid *= level_in;

        buffer[s->write_ptr] = mid;

        s0_ptr = (s->write_ptr + s->buffer_size - s->delay[0]) & mask;
        s1_ptr = (s->write_ptr + s->buffer_size - s->delay[1]) & mask;

        if (s->par_middle_phase)
            mid = -mid;

        side[0] = buffer[s0_ptr] * s->par_side_gain;
        side[1] = buffer[s1_ptr] * s->par_side_gain;
        side_l  = side[0] * s->balance_l[0] - side[1] * s->balance_l[1];
        side_r  = side[1] * s->balance_r[1] - side[0] * s->balance_r[0];

        dst[0] = (mid + side_l) * level_out;
        dst[1] = (mid + side_r) * level_out;

        s->write_ptr = (s->write_ptr + 1) & mask;
    }

    if (out != in)
        av_frame_free(&in);
    return ff_filter_frame(outlink, out);
}

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

    av_freep(&s->buffer);
    s->buffer_size = 0;
}

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

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

AVFilter ff_af_haas = {
    .name           = "haas",
    .description    = NULL_IF_CONFIG_SMALL("Apply Haas Stereo Enhancer."),
    .query_formats  = query_formats,
    .priv_size      = sizeof(HaasContext),
    .priv_class     = &haas_class,
    .uninit         = uninit,
    .inputs         = inputs,
    .outputs        = outputs,
};
