/*
 * Copyright (c) 2012-2013 Clément Bœsch
 * Copyright (c) 2013 Rudolf Polzer <divverent@xonotic.org>
 *
 * 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
 * audio to spectrum (video) transmedia filter, based on ffplay rdft showmode
 * (by Michael Niedermayer) and lavfi/avf_showwaves (by Stefano Sabatini).
 */

#include <math.h>

#include "libavcodec/avfft.h"
#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/opt.h"
#include "avfilter.h"
#include "internal.h"

enum DisplayMode  { COMBINED, SEPARATE, NB_MODES };
enum DisplayScale { LINEAR, SQRT, CBRT, LOG, NB_SCALES };
enum ColorMode    { CHANNEL, INTENSITY, NB_CLMODES };
enum WindowFunc   { WFUNC_NONE, WFUNC_HANN, WFUNC_HAMMING, WFUNC_BLACKMAN, NB_WFUNC };
enum SlideMode    { REPLACE, SCROLL, FULLFRAME, NB_SLIDES };

typedef struct {
    const AVClass *class;
    int w, h;
    AVFrame *outpicref;
    int req_fullfilled;
    int nb_display_channels;
    int channel_height;
    int sliding;                ///< 1 if sliding mode, 0 otherwise
    enum DisplayMode mode;      ///< channel display mode
    enum ColorMode color_mode;  ///< display color scheme
    enum DisplayScale scale;
    float saturation;           ///< color saturation multiplier
    int xpos;                   ///< x position (current column)
    RDFTContext *rdft;          ///< Real Discrete Fourier Transform context
    int rdft_bits;              ///< number of bits (RDFT window size = 1<<rdft_bits)
    FFTSample **rdft_data;      ///< bins holder for each (displayed) channels
    float *window_func_lut;     ///< Window function LUT
    enum WindowFunc win_func;
    float *combine_buffer;      ///< color combining buffer (3 * h items)
} ShowSpectrumContext;

#define OFFSET(x) offsetof(ShowSpectrumContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM

static const AVOption showspectrum_options[] = {
    { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS },
    { "s",    "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS },
    { "slide", "set sliding mode", OFFSET(sliding), AV_OPT_TYPE_INT, {.i64 = 0}, 0, NB_SLIDES, FLAGS, "slide" },
        { "replace", "replace old columns with new", 0, AV_OPT_TYPE_CONST, {.i64=REPLACE}, 0, 0, FLAGS, "slide" },
        { "scroll", "scroll from right to left", 0, AV_OPT_TYPE_CONST, {.i64=SCROLL}, 0, 0, FLAGS, "slide" },
        { "fullframe", "return full frames", 0, AV_OPT_TYPE_CONST, {.i64=FULLFRAME}, 0, 0, FLAGS, "slide" },
    { "mode", "set channel display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=COMBINED}, COMBINED, NB_MODES-1, FLAGS, "mode" },
        { "combined", "combined mode", 0, AV_OPT_TYPE_CONST, {.i64=COMBINED}, 0, 0, FLAGS, "mode" },
        { "separate", "separate mode", 0, AV_OPT_TYPE_CONST, {.i64=SEPARATE}, 0, 0, FLAGS, "mode" },
    { "color", "set channel coloring", OFFSET(color_mode), AV_OPT_TYPE_INT, {.i64=CHANNEL}, CHANNEL, NB_CLMODES-1, FLAGS, "color" },
        { "channel",   "separate color for each channel", 0, AV_OPT_TYPE_CONST, {.i64=CHANNEL},   0, 0, FLAGS, "color" },
        { "intensity", "intensity based coloring",        0, AV_OPT_TYPE_CONST, {.i64=INTENSITY}, 0, 0, FLAGS, "color" },
    { "scale", "set display scale", OFFSET(scale), AV_OPT_TYPE_INT, {.i64=SQRT}, LINEAR, NB_SCALES-1, FLAGS, "scale" },
        { "sqrt", "square root", 0, AV_OPT_TYPE_CONST, {.i64=SQRT},   0, 0, FLAGS, "scale" },
        { "cbrt", "cubic root",  0, AV_OPT_TYPE_CONST, {.i64=CBRT},   0, 0, FLAGS, "scale" },
        { "log",  "logarithmic", 0, AV_OPT_TYPE_CONST, {.i64=LOG},    0, 0, FLAGS, "scale" },
        { "lin",  "linear",      0, AV_OPT_TYPE_CONST, {.i64=LINEAR}, 0, 0, FLAGS, "scale" },
    { "saturation", "color saturation multiplier", OFFSET(saturation), AV_OPT_TYPE_FLOAT, {.dbl = 1}, -10, 10, FLAGS },
    { "win_func", "set window function", OFFSET(win_func), AV_OPT_TYPE_INT, {.i64 = WFUNC_HANN}, 0, NB_WFUNC-1, FLAGS, "win_func" },
        { "hann",     "Hann window",     0, AV_OPT_TYPE_CONST, {.i64 = WFUNC_HANN},     0, 0, FLAGS, "win_func" },
        { "hamming",  "Hamming window",  0, AV_OPT_TYPE_CONST, {.i64 = WFUNC_HAMMING},  0, 0, FLAGS, "win_func" },
        { "blackman", "Blackman window", 0, AV_OPT_TYPE_CONST, {.i64 = WFUNC_BLACKMAN}, 0, 0, FLAGS, "win_func" },
    { NULL }
};

AVFILTER_DEFINE_CLASS(showspectrum);

static const struct {
    float a, y, u, v;
} intensity_color_table[] = {
    {    0,                  0,                  0,                   0 },
    { 0.13, .03587126228984074,  .1573300977624594, -.02548747583751842 },
    { 0.30, .18572281794568020,  .1772436246393981,  .17475554840414750 },
    { 0.60, .28184980583656130, -.1593064119945782,  .47132074554608920 },
    { 0.73, .65830621175547810, -.3716070802232764,  .24352759331252930 },
    { 0.78, .76318535758242900, -.4307467689263783,  .16866496622310430 },
    { 0.91, .95336363636363640, -.2045454545454546,  .03313636363636363 },
    {    1,                  1,                  0,                   0 }
};

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

    av_freep(&s->combine_buffer);
    av_rdft_end(s->rdft);
    for (i = 0; i < s->nb_display_channels; i++)
        av_freep(&s->rdft_data[i]);
    av_freep(&s->rdft_data);
    av_freep(&s->window_func_lut);
    av_frame_free(&s->outpicref);
}

static int query_formats(AVFilterContext *ctx)
{
    AVFilterFormats *formats = NULL;
    AVFilterChannelLayouts *layouts = NULL;
    AVFilterLink *inlink = ctx->inputs[0];
    AVFilterLink *outlink = ctx->outputs[0];
    static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE };
    static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE };

    /* set input audio formats */
    formats = ff_make_format_list(sample_fmts);
    if (!formats)
        return AVERROR(ENOMEM);
    ff_formats_ref(formats, &inlink->out_formats);

    layouts = ff_all_channel_layouts();
    if (!layouts)
        return AVERROR(ENOMEM);
    ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);

    formats = ff_all_samplerates();
    if (!formats)
        return AVERROR(ENOMEM);
    ff_formats_ref(formats, &inlink->out_samplerates);

    /* set output video format */
    formats = ff_make_format_list(pix_fmts);
    if (!formats)
        return AVERROR(ENOMEM);
    ff_formats_ref(formats, &outlink->in_formats);

    return 0;
}

static int config_output(AVFilterLink *outlink)
{
    AVFilterContext *ctx = outlink->src;
    AVFilterLink *inlink = ctx->inputs[0];
    ShowSpectrumContext *s = ctx->priv;
    int i, rdft_bits, win_size, h;

    outlink->w = s->w;
    outlink->h = s->h;

    h = (s->mode == COMBINED) ? outlink->h : outlink->h / inlink->channels;
    s->channel_height = h;

    /* RDFT window size (precision) according to the requested output frame height */
    for (rdft_bits = 1; 1 << rdft_bits < 2 * h; rdft_bits++);
    win_size = 1 << rdft_bits;

    /* (re-)configuration if the video output changed (or first init) */
    if (rdft_bits != s->rdft_bits) {
        size_t rdft_size, rdft_listsize;
        AVFrame *outpicref;

        av_rdft_end(s->rdft);
        s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
        if (!s->rdft) {
            av_log(ctx, AV_LOG_ERROR, "Unable to create RDFT context. "
                   "The window size might be too high.\n");
            return AVERROR(EINVAL);
        }
        s->rdft_bits = rdft_bits;

        /* RDFT buffers: x2 for each (display) channel buffer.
         * Note: we use free and malloc instead of a realloc-like function to
         * make sure the buffer is aligned in memory for the FFT functions. */
        for (i = 0; i < s->nb_display_channels; i++)
            av_freep(&s->rdft_data[i]);
        av_freep(&s->rdft_data);
        s->nb_display_channels = inlink->channels;

        if (av_size_mult(sizeof(*s->rdft_data),
                         s->nb_display_channels, &rdft_listsize) < 0)
            return AVERROR(EINVAL);
        if (av_size_mult(sizeof(**s->rdft_data),
                         win_size, &rdft_size) < 0)
            return AVERROR(EINVAL);
        s->rdft_data = av_malloc(rdft_listsize);
        if (!s->rdft_data)
            return AVERROR(ENOMEM);
        for (i = 0; i < s->nb_display_channels; i++) {
            s->rdft_data[i] = av_malloc(rdft_size);
            if (!s->rdft_data[i])
                return AVERROR(ENOMEM);
        }

        /* pre-calc windowing function */
        s->window_func_lut =
            av_realloc_f(s->window_func_lut, win_size,
                         sizeof(*s->window_func_lut));
        if (!s->window_func_lut)
            return AVERROR(ENOMEM);
        switch (s->win_func) {
        case WFUNC_NONE:
            for (i = 0; i < win_size; i++)
                s->window_func_lut[i] = 1.;
            break;
        case WFUNC_HANN:
            for (i = 0; i < win_size; i++)
                s->window_func_lut[i] = .5f * (1 - cos(2*M_PI*i / (win_size-1)));
            break;
        case WFUNC_HAMMING:
            for (i = 0; i < win_size; i++)
                s->window_func_lut[i] = .54f - .46f * cos(2*M_PI*i / (win_size-1));
            break;
        case WFUNC_BLACKMAN: {
            for (i = 0; i < win_size; i++)
                s->window_func_lut[i] = .42f - .5f*cos(2*M_PI*i / (win_size-1)) + .08f*cos(4*M_PI*i / (win_size-1));
            break;
        }
        default:
            av_assert0(0);
        }

        /* prepare the initial picref buffer (black frame) */
        av_frame_free(&s->outpicref);
        s->outpicref = outpicref =
            ff_get_video_buffer(outlink, outlink->w, outlink->h);
        if (!outpicref)
            return AVERROR(ENOMEM);
        outlink->sample_aspect_ratio = (AVRational){1,1};
        for (i = 0; i < outlink->h; i++) {
            memset(outpicref->data[0] + i * outpicref->linesize[0],   0, outlink->w);
            memset(outpicref->data[1] + i * outpicref->linesize[1], 128, outlink->w);
            memset(outpicref->data[2] + i * outpicref->linesize[2], 128, outlink->w);
        }
    }

    if (s->xpos >= outlink->w)
        s->xpos = 0;

    outlink->frame_rate = av_make_q(inlink->sample_rate, win_size);
    if (s->sliding == FULLFRAME)
        outlink->frame_rate.den *= outlink->w;

    inlink->min_samples = inlink->max_samples = inlink->partial_buf_size =
        win_size;

    s->combine_buffer =
        av_realloc_f(s->combine_buffer, outlink->h * 3,
                     sizeof(*s->combine_buffer));

    av_log(ctx, AV_LOG_VERBOSE, "s:%dx%d RDFT window size:%d\n",
           s->w, s->h, win_size);
    return 0;
}

static int request_frame(AVFilterLink *outlink)
{
    ShowSpectrumContext *s = outlink->src->priv;
    AVFilterLink *inlink = outlink->src->inputs[0];
    unsigned i;
    int ret;

    s->req_fullfilled = 0;
    do {
        ret = ff_request_frame(inlink);
        if (ret == AVERROR_EOF && s->sliding == FULLFRAME && s->xpos > 0 &&
            s->outpicref) {
            for (i = 0; i < outlink->h; i++) {
                memset(s->outpicref->data[0] + i * s->outpicref->linesize[0] + s->xpos,   0, outlink->w - s->xpos);
                memset(s->outpicref->data[1] + i * s->outpicref->linesize[1] + s->xpos, 128, outlink->w - s->xpos);
                memset(s->outpicref->data[2] + i * s->outpicref->linesize[2] + s->xpos, 128, outlink->w - s->xpos);
            }
            ret = ff_filter_frame(outlink, s->outpicref);
            s->outpicref = NULL;
            s->req_fullfilled = 1;
        }
    } while (!s->req_fullfilled && ret >= 0);

    return ret;
}

static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
{
    int ret;
    AVFilterContext *ctx = inlink->dst;
    AVFilterLink *outlink = ctx->outputs[0];
    ShowSpectrumContext *s = ctx->priv;
    AVFrame *outpicref = s->outpicref;

    /* nb_freq contains the power of two superior or equal to the output image
     * height (or half the RDFT window size) */
    const int nb_freq = 1 << (s->rdft_bits - 1);
    const int win_size = nb_freq << 1;
    const double w = 1. / (sqrt(nb_freq) * 32768.);
    int h = s->channel_height;

    int ch, plane, n, y;

    av_assert0(insamples->nb_samples == win_size);

    /* fill RDFT input with the number of samples available */
    for (ch = 0; ch < s->nb_display_channels; ch++) {
        const int16_t *p = (int16_t *)insamples->extended_data[ch];

        for (n = 0; n < win_size; n++)
            s->rdft_data[ch][n] = p[n] * s->window_func_lut[n];
    }

    /* TODO reindent */

        /* run RDFT on each samples set */
        for (ch = 0; ch < s->nb_display_channels; ch++)
            av_rdft_calc(s->rdft, s->rdft_data[ch]);

        /* fill a new spectrum column */
#define RE(y, ch) s->rdft_data[ch][2 * (y) + 0]
#define IM(y, ch) s->rdft_data[ch][2 * (y) + 1]
#define MAGNITUDE(y, ch) hypot(RE(y, ch), IM(y, ch))

        /* initialize buffer for combining to black */
        for (y = 0; y < outlink->h; y++) {
            s->combine_buffer[3 * y    ] = 0;
            s->combine_buffer[3 * y + 1] = 127.5;
            s->combine_buffer[3 * y + 2] = 127.5;
        }

        for (ch = 0; ch < s->nb_display_channels; ch++) {
            float yf, uf, vf;

            /* decide color range */
            switch (s->mode) {
            case COMBINED:
                // reduce range by channel count
                yf = 256.0f / s->nb_display_channels;
                switch (s->color_mode) {
                case INTENSITY:
                    uf = yf;
                    vf = yf;
                    break;
                case CHANNEL:
                    /* adjust saturation for mixed UV coloring */
                    /* this factor is correct for infinite channels, an approximation otherwise */
                    uf = yf * M_PI;
                    vf = yf * M_PI;
                    break;
                default:
                    av_assert0(0);
                }
                break;
            case SEPARATE:
                // full range
                yf = 256.0f;
                uf = 256.0f;
                vf = 256.0f;
                break;
            default:
                av_assert0(0);
            }

            if (s->color_mode == CHANNEL) {
                if (s->nb_display_channels > 1) {
                    uf *= 0.5 * sin((2 * M_PI * ch) / s->nb_display_channels);
                    vf *= 0.5 * cos((2 * M_PI * ch) / s->nb_display_channels);
                } else {
                    uf = 0.0f;
                    vf = 0.0f;
                }
            }
            uf *= s->saturation;
            vf *= s->saturation;

            /* draw the channel */
            for (y = 0; y < h; y++) {
                int row = (s->mode == COMBINED) ? y : ch * h + y;
                float *out = &s->combine_buffer[3 * row];

                /* get magnitude */
                float a = w * MAGNITUDE(y, ch);

                /* apply scale */
                switch (s->scale) {
                case LINEAR:
                    break;
                case SQRT:
                    a = sqrt(a);
                    break;
                case CBRT:
                    a = cbrt(a);
                    break;
                case LOG:
                    a = 1 - log(FFMAX(FFMIN(1, a), 1e-6)) / log(1e-6); // zero = -120dBFS
                    break;
                default:
                    av_assert0(0);
                }

                if (s->color_mode == INTENSITY) {
                    float y, u, v;
                    int i;

                    for (i = 1; i < sizeof(intensity_color_table) / sizeof(*intensity_color_table) - 1; i++)
                        if (intensity_color_table[i].a >= a)
                            break;
                    // i now is the first item >= the color
                    // now we know to interpolate between item i - 1 and i
                    if (a <= intensity_color_table[i - 1].a) {
                        y = intensity_color_table[i - 1].y;
                        u = intensity_color_table[i - 1].u;
                        v = intensity_color_table[i - 1].v;
                    } else if (a >= intensity_color_table[i].a) {
                        y = intensity_color_table[i].y;
                        u = intensity_color_table[i].u;
                        v = intensity_color_table[i].v;
                    } else {
                        float start = intensity_color_table[i - 1].a;
                        float end = intensity_color_table[i].a;
                        float lerpfrac = (a - start) / (end - start);
                        y = intensity_color_table[i - 1].y * (1.0f - lerpfrac)
                          + intensity_color_table[i].y * lerpfrac;
                        u = intensity_color_table[i - 1].u * (1.0f - lerpfrac)
                          + intensity_color_table[i].u * lerpfrac;
                        v = intensity_color_table[i - 1].v * (1.0f - lerpfrac)
                          + intensity_color_table[i].v * lerpfrac;
                    }

                    out[0] += y * yf;
                    out[1] += u * uf;
                    out[2] += v * vf;
                } else {
                    out[0] += a * yf;
                    out[1] += a * uf;
                    out[2] += a * vf;
                }
            }
        }

        /* copy to output */
        if (s->sliding == SCROLL) {
            for (plane = 0; plane < 3; plane++) {
                for (y = 0; y < outlink->h; y++) {
                    uint8_t *p = outpicref->data[plane] +
                                 y * outpicref->linesize[plane];
                    memmove(p, p + 1, outlink->w - 1);
                }
            }
            s->xpos = outlink->w - 1;
        }
        for (plane = 0; plane < 3; plane++) {
            uint8_t *p = outpicref->data[plane] +
                         (outlink->h - 1) * outpicref->linesize[plane] +
                         s->xpos;
            for (y = 0; y < outlink->h; y++) {
                *p = rint(FFMAX(0, FFMIN(s->combine_buffer[3 * y + plane], 255)));
                p -= outpicref->linesize[plane];
            }
        }

        if (s->sliding != FULLFRAME || s->xpos == 0)
            outpicref->pts = insamples->pts;

        s->xpos++;
        if (s->xpos >= outlink->w)
            s->xpos = 0;
        if (s->sliding != FULLFRAME || s->xpos == 0) {
            s->req_fullfilled = 1;
            ret = ff_filter_frame(outlink, av_frame_clone(s->outpicref));
            if (ret < 0)
                return ret;
        }

    return win_size;
}

static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
{
    AVFilterContext *ctx = inlink->dst;
    ShowSpectrumContext *s = ctx->priv;
    unsigned win_size = 1 << s->rdft_bits;
    int ret = 0;

    av_assert0(insamples->nb_samples <= win_size);
    if (insamples->nb_samples == win_size)
        ret = plot_spectrum_column(inlink, insamples);

    av_frame_free(&insamples);
    return ret;
}

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

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

AVFilter ff_avf_showspectrum = {
    .name          = "showspectrum",
    .description   = NULL_IF_CONFIG_SMALL("Convert input audio to a spectrum video output."),
    .uninit        = uninit,
    .query_formats = query_formats,
    .priv_size     = sizeof(ShowSpectrumContext),
    .inputs        = showspectrum_inputs,
    .outputs       = showspectrum_outputs,
    .priv_class    = &showspectrum_class,
};
