/*
***********************************************************************
*
* Copyright (C) 1999 Ericsson Radio Systems AB
* 
* The Association of Radio Industries and Businesses (ARIB) has the
* licence to reproduce, distribute and publish the Bit Exact C Code
* programs in this CD-ROM together with the other parts of the RCR
* STD-27 (Personal Digital Cellular Telecommunication System)
* specification.
* 
* Ericsson has declared Option 1 (royalty-free licence) to ARIB for
* its Essential Industrial Property Rights related to the ACELP
* specification and the Bit Exact C Code programs. The royalty-free
* licence is limited to the development and manufacturing of
* products complying with the RCR STD-27H specification (or
* subsequent versions) for sale and use in Japan. Copying of the
* program(s) for any other purpose requires the prior written
* permission from Ericsson.
* 
* The user of the Bit Exact C Code hereby acknowledges the
* following:
* 
* 1.  Ericsson does not provide the user with any warranties,
*     whether express or implied, including but not limited to
*     warranties of merchantability and fitness for a particular
*     purpose relating to the Bit Exact C Code.
* 
* 2.  Ericsson shall have no responsibility whatsoever to indemnify
*     the user against actions or claims for infringement of any
*     intellectual property rights, e.g. patents, copyrights,
*     registered designs or any other rights, by reason of the
*     user's use of the Bit Exact C Code.
* 
***********************************************************************
*/

/*************************************************************************
 *
 *   FUNCTIONS:  Lsp_lsf and Lsf_lsp
 *
 *   PURPOSE:
 *      Lsp_lsf:   Transformation lsp to lsf
 *      Lsf_lsp:   Transformation lsf to lsp
 *
 *   The transformation from lsp[i] to lsf[i] and lsf[i] to lsp[i] are
 *   approximated by a look-up table and interpolation.
 *
 *************************************************************************/


#include "typedef.h"
#include "basic_op.h"

#include "lsp_lsf.tab"          /* Look-up table for transformations */

void Lsf_lsp(
    Word16 lsf[],  /* (i)  : lsf[m] normalized (range: 0.0<=val<=0.5) */
    Word16 lsp[],  /* (o)  : lsp[m] (range: -1<=val<1)                */
    Word16 m       /* (i)  : LPC order                                */
)
{
    Word16 i, ind, offset;
    Word32 L_tmp;

    for (i = 0; i < m; i++) {
        ind = shr(lsf[i], 8);     /* ind    = b8-b15 of lsf[i] */
        offset = lsf[i] & 0x00ff; /* offset = b0-b7  of lsf[i] */

        /* lsp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 256 */

        L_tmp = L_mult(sub(table[ind + 1], table[ind]), offset);
        lsp[i] = add(table[ind], extract_l(L_shr(L_tmp, 9)));
    }
    return;
}


void Lsp_lsf(
    Word16 lsp[],  /* (i)  : lsp[m] (range: -1<=val<1)                */
    Word16 lsf[],  /* (o)  : lsf[m] normalized (range: 0.0<=val<=0.5) */
    Word16 m       /* (i)  : LPC order                                */
)
{
    Word16 i, ind;
    Word32 L_tmp;

    ind = 63;       /* beging at end of table -1 */

    for (i = m - 1; i >= 0; i--) {
        /* find value in table that is just greater than lsp[i] */
        while (sub(table[ind], lsp[i]) < 0) {
            ind--;
        }

        /* acos(lsp[i])= ind*256 + ( ( lsp[i]-table[ind] ) * slope[ind] )/4096 */

        L_tmp = L_mult(sub(lsp[i], table[ind]), slope[ind]);
        lsf[i] = round(L_shl(L_tmp, 3));  /*(lsp[i]-table[ind])*slope[ind])>>12*/
        lsf[i] = add(lsf[i], shl(ind, 8));
    }
    return;
}
