/*
 * audio encoder psychoacoustic model
 * Copyright (C) 2008 Konstantin Shishkov
 *
 * 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 <string.h>

#include "avcodec.h"
#include "psymodel.h"
#include "iirfilter.h"
#include "libavutil/mem.h"

extern const FFPsyModel ff_aac_psy_model;

av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens,
                        const uint8_t **bands, const int* num_bands,
                        int num_groups, const uint8_t *group_map)
{
    int i, j, k = 0;

    ctx->avctx = avctx;
    ctx->ch        = av_calloc(avctx->ch_layout.nb_channels, 2 * sizeof(ctx->ch[0]));
    ctx->group     = av_calloc(num_groups, sizeof(ctx->group[0]));
    ctx->bands     = av_malloc_array (sizeof(ctx->bands[0]),      num_lens);
    ctx->num_bands = av_malloc_array (sizeof(ctx->num_bands[0]),  num_lens);
    ctx->cutoff    = avctx->cutoff;

    if (!ctx->ch || !ctx->group || !ctx->bands || !ctx->num_bands) {
        ff_psy_end(ctx);
        return AVERROR(ENOMEM);
    }

    memcpy(ctx->bands,     bands,     sizeof(ctx->bands[0])     *  num_lens);
    memcpy(ctx->num_bands, num_bands, sizeof(ctx->num_bands[0]) *  num_lens);

    /* assign channels to groups (with virtual channels for coupling) */
    for (i = 0; i < num_groups; i++) {
        /* NOTE: Add 1 to handle the AAC chan_config without modification.
         *       This has the side effect of allowing an array of 0s to map
         *       to one channel per group.
         */
        ctx->group[i].num_ch = group_map[i] + 1;
        for (j = 0; j < ctx->group[i].num_ch * 2; j++)
            ctx->group[i].ch[j]  = &ctx->ch[k++];
    }

    switch (ctx->avctx->codec_id) {
    case AV_CODEC_ID_AAC:
        ctx->model = &ff_aac_psy_model;
        break;
    }
    if (ctx->model->init)
        return ctx->model->init(ctx);
    return 0;
}

FFPsyChannelGroup *ff_psy_find_group(FFPsyContext *ctx, int channel)
{
    int i = 0, ch = 0;

    while (ch <= channel)
        ch += ctx->group[i++].num_ch;

    return &ctx->group[i-1];
}

av_cold void ff_psy_end(FFPsyContext *ctx)
{
    if (ctx->model && ctx->model->end)
        ctx->model->end(ctx);
    av_freep(&ctx->bands);
    av_freep(&ctx->num_bands);
    av_freep(&ctx->group);
    av_freep(&ctx->ch);
}

typedef struct FFPsyPreprocessContext{
    AVCodecContext *avctx;
    float stereo_att;
    struct FFIIRFilterCoeffs *fcoeffs;
    struct FFIIRFilterState **fstate;
    struct FFIIRFilterContext fiir;
}FFPsyPreprocessContext;

#define FILT_ORDER 4

av_cold struct FFPsyPreprocessContext* ff_psy_preprocess_init(AVCodecContext *avctx)
{
    FFPsyPreprocessContext *ctx;
    int i;
    float cutoff_coeff = 0;
    ctx        = av_mallocz(sizeof(FFPsyPreprocessContext));
    if (!ctx)
        return NULL;
    ctx->avctx = avctx;

    /* AAC has its own LP method */
    if (avctx->codec_id != AV_CODEC_ID_AAC) {
        if (avctx->cutoff > 0)
            cutoff_coeff = 2.0 * avctx->cutoff / avctx->sample_rate;

        if (cutoff_coeff && cutoff_coeff < 0.98)
        ctx->fcoeffs = ff_iir_filter_init_coeffs(avctx, FF_FILTER_TYPE_BUTTERWORTH,
                                                 FF_FILTER_MODE_LOWPASS, FILT_ORDER,
                                                 cutoff_coeff, 0.0, 0.0);
        if (ctx->fcoeffs) {
            ctx->fstate = av_calloc(avctx->ch_layout.nb_channels, sizeof(ctx->fstate[0]));
            if (!ctx->fstate) {
                av_free(ctx->fcoeffs);
                av_free(ctx);
                return NULL;
            }
            for (i = 0; i < avctx->ch_layout.nb_channels; i++)
                ctx->fstate[i] = ff_iir_filter_init_state(FILT_ORDER);
        }
    }

    ff_iir_filter_init(&ctx->fiir);

    return ctx;
}

void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx, float **audio, int channels)
{
    int ch;
    int frame_size = ctx->avctx->frame_size;
    FFIIRFilterContext *iir = &ctx->fiir;

    if (ctx->fstate) {
        for (ch = 0; ch < channels; ch++)
            iir->filter_flt(ctx->fcoeffs, ctx->fstate[ch], frame_size,
                            &audio[ch][frame_size], 1, &audio[ch][frame_size], 1);
    }
}

av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx)
{
    int i;
    ff_iir_filter_free_coeffsp(&ctx->fcoeffs);
    if (ctx->fstate)
        for (i = 0; i < ctx->avctx->ch_layout.nb_channels; i++)
            ff_iir_filter_free_statep(&ctx->fstate[i]);
    av_freep(&ctx->fstate);
    av_free(ctx);
}
