/*
 * LSP routines for ACELP-based codecs
 *
 * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet (QCELP decoder)
 * Copyright (c) 2008 Vladimir Voroshilov
 *
 * 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 <inttypes.h>

#include "avcodec.h"
#define FRAC_BITS 14
#include "mathops.h"
#include "lsp.h"
#include "libavcodec/mips/lsp_mips.h"
#include "libavutil/avassert.h"

void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order)
{
    int i, j;

    /* sort lsfq in ascending order. float bubble algorithm,
       O(n) if data already sorted, O(n^2) - otherwise */
    for(i=0; i<lp_order-1; i++)
        for(j=i; j>=0 && lsfq[j] > lsfq[j+1]; j--)
            FFSWAP(int16_t, lsfq[j], lsfq[j+1]);

    for(i=0; i<lp_order; i++)
    {
        lsfq[i] = FFMAX(lsfq[i], lsfq_min);
        lsfq_min = lsfq[i] + lsfq_min_distance;
    }
    lsfq[lp_order-1] = FFMIN(lsfq[lp_order-1], lsfq_max);//Is warning required ?
}

void ff_set_min_dist_lsf(float *lsf, double min_spacing, int size)
{
    int i;
    float prev = 0.0;
    for (i = 0; i < size; i++)
        prev = lsf[i] = FFMAX(lsf[i], prev + min_spacing);
}


/* Cosine table: base_cos[i] = (1 << 15) * cos(i * PI / 64) */
static const int16_t tab_cos[65] =
{
  32767,  32738,  32617,  32421,  32145,  31793,  31364,  30860,
  30280,  29629,  28905,  28113,  27252,  26326,  25336,  24285,
  23176,  22011,  20793,  19525,  18210,  16851,  15451,  14014,
  12543,  11043,   9515,   7965,   6395,   4810,   3214,   1609,
      1,  -1607,  -3211,  -4808,  -6393,  -7962,  -9513, -11040,
 -12541, -14012, -15449, -16848, -18207, -19523, -20791, -22009,
 -23174, -24283, -25334, -26324, -27250, -28111, -28904, -29627,
 -30279, -30858, -31363, -31792, -32144, -32419, -32616, -32736, -32768,
};

static int16_t ff_cos(uint16_t arg)
{
    uint8_t offset= arg;
    uint8_t ind = arg >> 8;

    av_assert2(arg <= 0x3fff);

    return tab_cos[ind] + (offset * (tab_cos[ind+1] - tab_cos[ind]) >> 8);
}

void ff_acelp_lsf2lsp(int16_t *lsp, const int16_t *lsf, int lp_order)
{
    int i;

    /* Convert LSF to LSP, lsp=cos(lsf) */
    for(i=0; i<lp_order; i++)
        // 20861 = 2.0 / PI in (0.15)
        lsp[i] = ff_cos(lsf[i] * 20861 >> 15); // divide by PI and (0,13) -> (0,14)
}

void ff_acelp_lsf2lspd(double *lsp, const float *lsf, int lp_order)
{
    int i;

    for(i = 0; i < lp_order; i++)
        lsp[i] = cos(2.0 * M_PI * lsf[i]);
}

/**
 * @brief decodes polynomial coefficients from LSP
 * @param[out] f decoded polynomial coefficients (-0x20000000 <= (3.22) <= 0x1fffffff)
 * @param lsp LSP coefficients (-0x8000 <= (0.15) <= 0x7fff)
 */
static void lsp2poly(int* f, const int16_t* lsp, int lp_half_order)
{
    int i, j;

    f[0] = 0x400000;          // 1.0 in (3.22)
    f[1] = -lsp[0] << 8;      // *2 and (0.15) -> (3.22)

    for(i=2; i<=lp_half_order; i++)
    {
        f[i] = f[i-2];
        for(j=i; j>1; j--)
            f[j] -= MULL(f[j-1], lsp[2*i-2], FRAC_BITS) - f[j-2];

        f[1] -= lsp[2*i-2] << 8;
    }
}

void ff_acelp_lsp2lpc(int16_t* lp, const int16_t* lsp, int lp_half_order)
{
    int i;
    int f1[MAX_LP_HALF_ORDER+1]; // (3.22)
    int f2[MAX_LP_HALF_ORDER+1]; // (3.22)

    lsp2poly(f1, lsp  , lp_half_order);
    lsp2poly(f2, lsp+1, lp_half_order);

    /* 3.2.6 of G.729, Equations 25 and  26*/
    lp[0] = 4096;
    for(i=1; i<lp_half_order+1; i++)
    {
        int ff1 = f1[i] + f1[i-1]; // (3.22)
        int ff2 = f2[i] - f2[i-1]; // (3.22)

        ff1 += 1 << 10; // for rounding
        lp[i]    = (ff1 + ff2) >> 11; // divide by 2 and (3.22) -> (3.12)
        lp[(lp_half_order << 1) + 1 - i] = (ff1 - ff2) >> 11; // divide by 2 and (3.22) -> (3.12)
    }
}

void ff_amrwb_lsp2lpc(const double *lsp, float *lp, int lp_order)
{
    int lp_half_order = lp_order >> 1;
    double buf[MAX_LP_HALF_ORDER + 1];
    double pa[MAX_LP_HALF_ORDER + 1];
    double *qa = buf + 1;
    int i,j;

    qa[-1] = 0.0;

    ff_lsp2polyf(lsp    , pa, lp_half_order    );
    ff_lsp2polyf(lsp + 1, qa, lp_half_order - 1);

    for (i = 1, j = lp_order - 1; i < lp_half_order; i++, j--) {
        double paf =  pa[i]            * (1 + lsp[lp_order - 1]);
        double qaf = (qa[i] - qa[i-2]) * (1 - lsp[lp_order - 1]);
        lp[i-1]  = (paf + qaf) * 0.5;
        lp[j-1]  = (paf - qaf) * 0.5;
    }

    lp[lp_half_order - 1] = (1.0 + lsp[lp_order - 1]) *
        pa[lp_half_order] * 0.5;

    lp[lp_order - 1] = lsp[lp_order - 1];
}

void ff_acelp_lp_decode(int16_t* lp_1st, int16_t* lp_2nd, const int16_t* lsp_2nd, const int16_t* lsp_prev, int lp_order)
{
    int16_t lsp_1st[MAX_LP_ORDER]; // (0.15)
    int i;

    /* LSP values for first subframe (3.2.5 of G.729, Equation 24)*/
    for(i=0; i<lp_order; i++)
#ifdef G729_BITEXACT
        lsp_1st[i] = (lsp_2nd[i] >> 1) + (lsp_prev[i] >> 1);
#else
        lsp_1st[i] = (lsp_2nd[i] + lsp_prev[i]) >> 1;
#endif

    ff_acelp_lsp2lpc(lp_1st, lsp_1st, lp_order >> 1);

    /* LSP values for second subframe (3.2.5 of G.729)*/
    ff_acelp_lsp2lpc(lp_2nd, lsp_2nd, lp_order >> 1);
}

#ifndef ff_lsp2polyf
void ff_lsp2polyf(const double *lsp, double *f, int lp_half_order)
{
    int i, j;

    f[0] = 1.0;
    f[1] = -2 * lsp[0];
    lsp -= 2;
    for(i=2; i<=lp_half_order; i++)
    {
        double val = -2 * lsp[2*i];
        f[i] = val * f[i-1] + 2*f[i-2];
        for(j=i-1; j>1; j--)
            f[j] += f[j-1] * val + f[j-2];
        f[1] += val;
    }
}
#endif /* ff_lsp2polyf */

void ff_acelp_lspd2lpc(const double *lsp, float *lpc, int lp_half_order)
{
    double pa[MAX_LP_HALF_ORDER+1], qa[MAX_LP_HALF_ORDER+1];
    float *lpc2 = lpc + (lp_half_order << 1) - 1;

    av_assert2(lp_half_order <= MAX_LP_HALF_ORDER);

    ff_lsp2polyf(lsp,     pa, lp_half_order);
    ff_lsp2polyf(lsp + 1, qa, lp_half_order);

    while (lp_half_order--) {
        double paf = pa[lp_half_order+1] + pa[lp_half_order];
        double qaf = qa[lp_half_order+1] - qa[lp_half_order];

        lpc [ lp_half_order] = 0.5*(paf+qaf);
        lpc2[-lp_half_order] = 0.5*(paf-qaf);
    }
}

void ff_sort_nearly_sorted_floats(float *vals, int len)
{
    int i,j;

    for (i = 0; i < len - 1; i++)
        for (j = i; j >= 0 && vals[j] > vals[j+1]; j--)
            FFSWAP(float, vals[j], vals[j+1]);
}
