/*
 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
 * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
 *
 * 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/common.h"
#include "libavutil/libm.h"
#include "libavutil/log.h"
#include "internal.h"
#include "resample.h"
#include "audio_data.h"

struct ResampleContext {
    AVAudioResampleContext *avr;
    AudioData *buffer;
    uint8_t *filter_bank;
    int filter_length;
    int ideal_dst_incr;
    int dst_incr;
    int index;
    int frac;
    int src_incr;
    int compensation_distance;
    int phase_shift;
    int phase_mask;
    int linear;
    enum AVResampleFilterType filter_type;
    int kaiser_beta;
    double factor;
    void (*set_filter)(void *filter, double *tab, int phase, int tap_count);
    void (*resample_one)(struct ResampleContext *c, int no_filter, void *dst0,
                         int dst_index, const void *src0, int src_size,
                         int index, int frac);
};


/* double template */
#define CONFIG_RESAMPLE_DBL
#include "resample_template.c"
#undef CONFIG_RESAMPLE_DBL

/* float template */
#define CONFIG_RESAMPLE_FLT
#include "resample_template.c"
#undef CONFIG_RESAMPLE_FLT

/* s32 template */
#define CONFIG_RESAMPLE_S32
#include "resample_template.c"
#undef CONFIG_RESAMPLE_S32

/* s16 template */
#include "resample_template.c"


/* 0th order modified bessel function of the first kind. */
static double bessel(double x)
{
    double v     = 1;
    double lastv = 0;
    double t     = 1;
    int i;

    x = x * x / 4;
    for (i = 1; v != lastv; i++) {
        lastv = v;
        t    *= x / (i * i);
        v    += t;
    }
    return v;
}

/* Build a polyphase filterbank. */
static int build_filter(ResampleContext *c)
{
    int ph, i;
    double x, y, w, factor;
    double *tab;
    int tap_count    = c->filter_length;
    int phase_count  = 1 << c->phase_shift;
    const int center = (tap_count - 1) / 2;

    tab = av_malloc(tap_count * sizeof(*tab));
    if (!tab)
        return AVERROR(ENOMEM);

    /* if upsampling, only need to interpolate, no filter */
    factor = FFMIN(c->factor, 1.0);

    for (ph = 0; ph < phase_count; ph++) {
        double norm = 0;
        for (i = 0; i < tap_count; i++) {
            x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
            if (x == 0) y = 1.0;
            else        y = sin(x) / x;
            switch (c->filter_type) {
            case AV_RESAMPLE_FILTER_TYPE_CUBIC: {
                const float d = -0.5; //first order derivative = -0.5
                x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
                if (x < 1.0) y = 1 - 3 * x*x + 2 * x*x*x + d * (                -x*x + x*x*x);
                else         y =                           d * (-4 + 8 * x - 5 * x*x + x*x*x);
                break;
            }
            case AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL:
                w  = 2.0 * x / (factor * tap_count) + M_PI;
                y *= 0.3635819 - 0.4891775 * cos(    w) +
                                 0.1365995 * cos(2 * w) -
                                 0.0106411 * cos(3 * w);
                break;
            case AV_RESAMPLE_FILTER_TYPE_KAISER:
                w  = 2.0 * x / (factor * tap_count * M_PI);
                y *= bessel(c->kaiser_beta * sqrt(FFMAX(1 - w * w, 0)));
                break;
            }

            tab[i] = y;
            norm  += y;
        }
        /* normalize so that an uniform color remains the same */
        for (i = 0; i < tap_count; i++)
            tab[i] = tab[i] / norm;

        c->set_filter(c->filter_bank, tab, ph, tap_count);
    }

    av_free(tab);
    return 0;
}

ResampleContext *ff_audio_resample_init(AVAudioResampleContext *avr)
{
    ResampleContext *c;
    int out_rate    = avr->out_sample_rate;
    int in_rate     = avr->in_sample_rate;
    double factor   = FFMIN(out_rate * avr->cutoff / in_rate, 1.0);
    int phase_count = 1 << avr->phase_shift;
    int felem_size;

    if (avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P &&
        avr->internal_sample_fmt != AV_SAMPLE_FMT_S32P &&
        avr->internal_sample_fmt != AV_SAMPLE_FMT_FLTP &&
        avr->internal_sample_fmt != AV_SAMPLE_FMT_DBLP) {
        av_log(avr, AV_LOG_ERROR, "Unsupported internal format for "
               "resampling: %s\n",
               av_get_sample_fmt_name(avr->internal_sample_fmt));
        return NULL;
    }
    c = av_mallocz(sizeof(*c));
    if (!c)
        return NULL;

    c->avr           = avr;
    c->phase_shift   = avr->phase_shift;
    c->phase_mask    = phase_count - 1;
    c->linear        = avr->linear_interp;
    c->factor        = factor;
    c->filter_length = FFMAX((int)ceil(avr->filter_size / factor), 1);
    c->filter_type   = avr->filter_type;
    c->kaiser_beta   = avr->kaiser_beta;

    switch (avr->internal_sample_fmt) {
    case AV_SAMPLE_FMT_DBLP:
        c->resample_one  = resample_one_dbl;
        c->set_filter    = set_filter_dbl;
        break;
    case AV_SAMPLE_FMT_FLTP:
        c->resample_one  = resample_one_flt;
        c->set_filter    = set_filter_flt;
        break;
    case AV_SAMPLE_FMT_S32P:
        c->resample_one  = resample_one_s32;
        c->set_filter    = set_filter_s32;
        break;
    case AV_SAMPLE_FMT_S16P:
        c->resample_one  = resample_one_s16;
        c->set_filter    = set_filter_s16;
        break;
    }

    felem_size = av_get_bytes_per_sample(avr->internal_sample_fmt);
    c->filter_bank = av_mallocz(c->filter_length * (phase_count + 1) * felem_size);
    if (!c->filter_bank)
        goto error;

    if (build_filter(c) < 0)
        goto error;

    memcpy(&c->filter_bank[(c->filter_length * phase_count + 1) * felem_size],
           c->filter_bank, (c->filter_length - 1) * felem_size);
    memcpy(&c->filter_bank[c->filter_length * phase_count * felem_size],
           &c->filter_bank[(c->filter_length - 1) * felem_size], felem_size);

    c->compensation_distance = 0;
    if (!av_reduce(&c->src_incr, &c->dst_incr, out_rate,
                   in_rate * (int64_t)phase_count, INT32_MAX / 2))
        goto error;
    c->ideal_dst_incr = c->dst_incr;

    c->index = -phase_count * ((c->filter_length - 1) / 2);
    c->frac  = 0;

    /* allocate internal buffer */
    c->buffer = ff_audio_data_alloc(avr->resample_channels, 0,
                                    avr->internal_sample_fmt,
                                    "resample buffer");
    if (!c->buffer)
        goto error;

    av_log(avr, AV_LOG_DEBUG, "resample: %s from %d Hz to %d Hz\n",
           av_get_sample_fmt_name(avr->internal_sample_fmt),
           avr->in_sample_rate, avr->out_sample_rate);

    return c;

error:
    ff_audio_data_free(&c->buffer);
    av_free(c->filter_bank);
    av_free(c);
    return NULL;
}

void ff_audio_resample_free(ResampleContext **c)
{
    if (!*c)
        return;
    ff_audio_data_free(&(*c)->buffer);
    av_free((*c)->filter_bank);
    av_freep(c);
}

int avresample_set_compensation(AVAudioResampleContext *avr, int sample_delta,
                                int compensation_distance)
{
    ResampleContext *c;
    AudioData *fifo_buf = NULL;
    int ret = 0;

    if (compensation_distance < 0)
        return AVERROR(EINVAL);
    if (!compensation_distance && sample_delta)
        return AVERROR(EINVAL);

    if (!avr->resample_needed) {
#if FF_API_RESAMPLE_CLOSE_OPEN
        /* if resampling was not enabled previously, re-initialize the
           AVAudioResampleContext and force resampling */
        int fifo_samples;
        int restore_matrix = 0;
        double matrix[AVRESAMPLE_MAX_CHANNELS * AVRESAMPLE_MAX_CHANNELS] = { 0 };

        /* buffer any remaining samples in the output FIFO before closing */
        fifo_samples = av_audio_fifo_size(avr->out_fifo);
        if (fifo_samples > 0) {
            fifo_buf = ff_audio_data_alloc(avr->out_channels, fifo_samples,
                                           avr->out_sample_fmt, NULL);
            if (!fifo_buf)
                return AVERROR(EINVAL);
            ret = ff_audio_data_read_from_fifo(avr->out_fifo, fifo_buf,
                                               fifo_samples);
            if (ret < 0)
                goto reinit_fail;
        }
        /* save the channel mixing matrix */
        if (avr->am) {
            ret = avresample_get_matrix(avr, matrix, AVRESAMPLE_MAX_CHANNELS);
            if (ret < 0)
                goto reinit_fail;
            restore_matrix = 1;
        }

        /* close the AVAudioResampleContext */
        avresample_close(avr);

        avr->force_resampling = 1;

        /* restore the channel mixing matrix */
        if (restore_matrix) {
            ret = avresample_set_matrix(avr, matrix, AVRESAMPLE_MAX_CHANNELS);
            if (ret < 0)
                goto reinit_fail;
        }

        /* re-open the AVAudioResampleContext */
        ret = avresample_open(avr);
        if (ret < 0)
            goto reinit_fail;

        /* restore buffered samples to the output FIFO */
        if (fifo_samples > 0) {
            ret = ff_audio_data_add_to_fifo(avr->out_fifo, fifo_buf, 0,
                                            fifo_samples);
            if (ret < 0)
                goto reinit_fail;
            ff_audio_data_free(&fifo_buf);
        }
#else
        av_log(avr, AV_LOG_ERROR, "Unable to set resampling compensation\n");
        return AVERROR(EINVAL);
#endif
    }
    c = avr->resample;
    c->compensation_distance = compensation_distance;
    if (compensation_distance) {
        c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr *
                      (int64_t)sample_delta / compensation_distance;
    } else {
        c->dst_incr = c->ideal_dst_incr;
    }
    return 0;

reinit_fail:
    ff_audio_data_free(&fifo_buf);
    return ret;
}

static int resample(ResampleContext *c, void *dst, const void *src,
                    int *consumed, int src_size, int dst_size, int update_ctx)
{
    int dst_index;
    int index         = c->index;
    int frac          = c->frac;
    int dst_incr_frac = c->dst_incr % c->src_incr;
    int dst_incr      = c->dst_incr / c->src_incr;
    int compensation_distance = c->compensation_distance;

    if (!dst != !src)
        return AVERROR(EINVAL);

    if (compensation_distance == 0 && c->filter_length == 1 &&
        c->phase_shift == 0) {
        int64_t index2 = ((int64_t)index) << 32;
        int64_t incr   = (1LL << 32) * c->dst_incr / c->src_incr;
        dst_size       = FFMIN(dst_size,
                               (src_size-1-index) * (int64_t)c->src_incr /
                               c->dst_incr);

        if (dst) {
            for(dst_index = 0; dst_index < dst_size; dst_index++) {
                c->resample_one(c, 1, dst, dst_index, src, 0, index2 >> 32, 0);
                index2 += incr;
            }
        } else {
            dst_index = dst_size;
        }
        index += dst_index * dst_incr;
        index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr;
        frac   = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;
    } else {
        for (dst_index = 0; dst_index < dst_size; dst_index++) {
            int sample_index = index >> c->phase_shift;

            if (sample_index + c->filter_length > src_size ||
                -sample_index >= src_size)
                break;

            if (dst)
                c->resample_one(c, 0, dst, dst_index, src, src_size, index, frac);

            frac  += dst_incr_frac;
            index += dst_incr;
            if (frac >= c->src_incr) {
                frac -= c->src_incr;
                index++;
            }
            if (dst_index + 1 == compensation_distance) {
                compensation_distance = 0;
                dst_incr_frac = c->ideal_dst_incr % c->src_incr;
                dst_incr      = c->ideal_dst_incr / c->src_incr;
            }
        }
    }
    if (consumed)
        *consumed = FFMAX(index, 0) >> c->phase_shift;

    if (update_ctx) {
        if (index >= 0)
            index &= c->phase_mask;

        if (compensation_distance) {
            compensation_distance -= dst_index;
            if (compensation_distance <= 0)
                return AVERROR_BUG;
        }
        c->frac     = frac;
        c->index    = index;
        c->dst_incr = dst_incr_frac + c->src_incr*dst_incr;
        c->compensation_distance = compensation_distance;
    }

    return dst_index;
}

int ff_audio_resample(ResampleContext *c, AudioData *dst, AudioData *src)
{
    int ch, in_samples, in_leftover, consumed = 0, out_samples = 0;
    int ret = AVERROR(EINVAL);

    in_samples  = src ? src->nb_samples : 0;
    in_leftover = c->buffer->nb_samples;

    /* add input samples to the internal buffer */
    if (src) {
        ret = ff_audio_data_combine(c->buffer, in_leftover, src, 0, in_samples);
        if (ret < 0)
            return ret;
    } else if (!in_leftover) {
        /* no remaining samples to flush */
        return 0;
    } else {
        /* TODO: pad buffer to flush completely */
    }

    /* calculate output size and reallocate output buffer if needed */
    /* TODO: try to calculate this without the dummy resample() run */
    if (!dst->read_only && dst->allow_realloc) {
        out_samples = resample(c, NULL, NULL, NULL, c->buffer->nb_samples,
                               INT_MAX, 0);
        ret = ff_audio_data_realloc(dst, out_samples);
        if (ret < 0) {
            av_log(c->avr, AV_LOG_ERROR, "error reallocating output\n");
            return ret;
        }
    }

    /* resample each channel plane */
    for (ch = 0; ch < c->buffer->channels; ch++) {
        out_samples = resample(c, (void *)dst->data[ch],
                               (const void *)c->buffer->data[ch], &consumed,
                               c->buffer->nb_samples, dst->allocated_samples,
                               ch + 1 == c->buffer->channels);
    }
    if (out_samples < 0) {
        av_log(c->avr, AV_LOG_ERROR, "error during resampling\n");
        return out_samples;
    }

    /* drain consumed samples from the internal buffer */
    ff_audio_data_drain(c->buffer, consumed);

    av_dlog(c->avr, "resampled %d in + %d leftover to %d out + %d leftover\n",
            in_samples, in_leftover, out_samples, c->buffer->nb_samples);

    dst->nb_samples = out_samples;
    return 0;
}

int avresample_get_delay(AVAudioResampleContext *avr)
{
    if (!avr->resample_needed || !avr->resample)
        return 0;

    return avr->resample->buffer->nb_samples;
}
