/*====================================================================*/
/*         MPEG-4 Audio (ISO/IEC 14496-3) Copyright Header            */
/*====================================================================*/
/*
This software module was originally developed by Rakesh Taori and Andy
Gerrits (Philips Research Laboratories, Eindhoven, The Netherlands) in
the course of development of the MPEG-4 Audio (ISO/IEC 14496-3). This
software module is an implementation of a part of one or more MPEG-4
Audio (ISO/IEC 14496-3) tools as specified by the MPEG-4 Audio
(ISO/IEC 14496-3). ISO/IEC gives users of the MPEG-4 Audio (ISO/IEC
14496-3) free license to this software module or modifications thereof
for use in hardware or software products claiming conformance to the
MPEG-4 Audio (ISO/IEC 14496-3). Those intending to use this software
module in hardware or software products are advised that its use may
infringe existing patents. The original developer of this software
module and his/her company, the subsequent editors and their
companies, and ISO/IEC have no liability for use of this software
module or modifications thereof in an implementation. Copyright is not
released for non MPEG-4 Audio (ISO/IEC 14496-3) conforming products.
CN1 retains full right to use the code for his/her own purpose, assign
or donate the code to a third party and to inhibit third parties from
using the code for non MPEG-4 Audio (ISO/IEC 14496-3) conforming
products.  This copyright notice must be included in all copies or
derivative works. Copyright 1996.
*/
/*====================================================================*/
/*====================================================================*/
/*                                                                    */
/*      SOURCE_FILE:    PHI_BS2P.C                                    */
/*      PACKAGE:        WDBxx                                         */
/*      COMPONENT:      Bitstream to Parameter converter              */
/*                                                                    */
/*====================================================================*/
    
/*====================================================================*/
/*      I N C L U D E S                                               */
/*====================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "phi_cons.h"      
#include "lpc_common.h"  /* Common LPC core Defined Constants           */
#include "celp_bitstream_demux.h"    /* Parameter to bitstream conversion routines  */

#include "phi_freq.h"   
#include "vlr_enc.h"

/*======================================================================*/
/*      G L O B A L    D A T A   D E F I N I T I O N S                  */
/*======================================================================*/
static int levels[ORDER_LPC+1] =
{
    0, 36, 28, 15, 14, 13, 
    13, 12, 11,  9,  8, 
     8,  7,  7,  8,  7,
     6,  6,  7,  6,  6       

}; 

static short freq[ORDER_LPC+1][36];
static int counter[ORDER_LPC+1];
static long frame_count = 1;
static long ft = 1;

static long huff_tab[ORDER_LPC + 1][36];
static short codesize[ORDER_LPC + 1][36];

/*======================================================================*/
/* Function Definition: read_celp_bitstream_header                     */
/*======================================================================*/
void read_celp_bitstream_header(
    BITSTREAM  * const p_bitstream,  /* In/Out: Bitstream               */
    long * const SampleRateMode, 	 /* In: SampleRate Mode 			*/
    long * const QuantizationMode,	 /* In: Type of Quantization		*/
    long * const FineRateControl,	 /* In: Fine Rate Control switch	*/
	long * const LosslessCodingMode,  /* In: Lossless Coding Mode		*/
    long * const WB_Configuration,	 /* In: Wideband configuration  	*/
    long * const Wideband_VQ,		 /* In: Wideband VQ mode			*/
    long * const NB_Configuration,	 /* In: Narrowband configuration	*/
	long * const NumEnhLayers,		 /* In: Number of Enhancement Layers*/
	long * const BandwidthScalabilityMode, /* In: bandwidth switch		 */
	long * const BWS_Configuration	 /* In: BWS_configuration			*/
)
{
    /* -----------------------------------------------------------------*/
	/* Read Sampling Rate mode                                          */
    /* -----------------------------------------------------------------*/
    GetBit(p_bitstream, SampleRateMode, 1);
	
    /* -----------------------------------------------------------------*/
	/* Read Quantisation mode                                          */
    /* -----------------------------------------------------------------*/
    GetBit(p_bitstream, QuantizationMode, 1);
	
    /* -----------------------------------------------------------------*/
	/* Read FineRateControl                                             */
    /* -----------------------------------------------------------------*/
    GetBit(p_bitstream, FineRateControl, 1);

    /* -----------------------------------------------------------------*/
	/* Read LosslessCodingMode                                          */
    /* -----------------------------------------------------------------*/
    if ((*QuantizationMode == ScalarQuantizer) && 
	    (*FineRateControl == ON)
	   )
	{
        GetBit(p_bitstream, LosslessCodingMode, 1);
	}
	
    /* -----------------------------------------------------------------*/
	/* Read Configuration                                               */
    /* -----------------------------------------------------------------*/
	if (*SampleRateMode == fs16kHz)   /* 16 khz sampling frequency */
	{
        /* -------------------------------------------------------------*/
	    /* If 16 kHz; read WB_configuration                             */
        /* -------------------------------------------------------------*/
        GetBit(p_bitstream, WB_Configuration, 3);
        GetBit(p_bitstream, Wideband_VQ, 1);
	}
	
	if (*SampleRateMode == fs8kHz)   /* 8 khz sampling frequency */
	{
        /* -------------------------------------------------------------*/
	    /* If 8 kHz; read NB_configuration                              */
        /* -------------------------------------------------------------*/
        GetBit(p_bitstream, NB_Configuration, 5);
        GetBit(p_bitstream, NumEnhLayers, 2);
		
        /* -------------------------------------------------------------*/
	    /* Read Bandwidth Scalability Mode                              */
        /* -------------------------------------------------------------*/
        GetBit(p_bitstream, BandwidthScalabilityMode, 1);
		if (*BandwidthScalabilityMode == ON)
		{
            /* ---------------------------------------------------------*/
	        /* If Bandwidth Scalability Mode, read BWS_Configuration    */
            /* ---------------------------------------------------------*/
            GetBit(p_bitstream, BWS_Configuration, 2);
		}
	}

    /*------------------------------------------------------------------*/
	/* Initialize Huffman Table                                         */
    /*------------------------------------------------------------------*/
    if (*LosslessCodingMode == ON)
	{
        int i, j, index;

        index = 0;
        for(i=1; i <= ORDER_LPC; i++)
        {
            counter[i] = 0;
            for (j=0; j < (int)levels[i]; j++)
            {
                 freq[i][j]  = init_freq[index];  
                 counter[i] += init_freq[index];
                 index++; 
            }
        }

        /* Calculate tables */
        for (i=1; i < ORDER_LPC + 1; i++)
        {
            short freq_copy[36];
            int j;

            for(j=0; j < levels[i]; j++)
            {
                 freq_copy[j] = freq[i][j];
            }

            hufflen(levels[i], freq_copy, codesize[i]);
            huff_len_to_cwrds(levels[i], codesize[i], huff_tab[i]);                
        }
	}
	
}

/*======================================================================*/
/* Get huffman decoded indices                                          */
/*======================================================================*/
void get_huffman_bits_from_bitstream(int n, long *val, short *codesize, long *codeword, BITSTREAM * const bs){
        int     i, code_len, ready;
        long    samplecode = 0;
        long    bit;
        code_len = 0; ready = 0; samplecode = 0;
        while(!ready){
                samplecode <<= 1;
                GetBit(bs, &bit, 1);
                samplecode |= bit; 

                code_len++;
                for (i = 0; i < n; i++){
                        if ((code_len == codesize[i]) && (samplecode == codeword[i])){
                                *val  = (long)i;
                                ready = 1;
                                break;
                        }
                }
        }
}

/*======================================================================*/
/* Function Definition: Read_LosslessCoded_LPC                          */
/*======================================================================*/
void Read_LosslessCoded_LPC
(
    BITSTREAM * p_bitstream,           /* In: Bitstream                 */
	const long num_lpc_indices,        /* In: Number of LPC indices     */
	      long lpc_indices[]           /* Out: indices to rfc_table[]   */
)
{
    /* Read statistics bit */
    long receive_stats_flag;
    long k;
	
    GetBit(p_bitstream, &(receive_stats_flag), 1);

    /* If set, read table and make table */
    if (receive_stats_flag)
    {
        int i, j;

        for (i=1; i < num_lpc_indices + 1; i++)
        {
            for(j=0; j < levels[i]; j++)
            {
                long tmp;
                GetBit(p_bitstream, &tmp, MAX_VLC_BITS);
                codesize[i][j] = (short)(tmp+1);
            }
            huff_len_to_cwrds(levels[i], codesize[i], huff_tab[i]);
        }
    }
	
    for (k = 1; k <= num_lpc_indices; k++)
    {
        get_huffman_bits_from_bitstream(levels[k], &(lpc_indices[k-1]),
				codesize[k], huff_tab[k], p_bitstream);
    }
	
}

    
/*======================================================================*/
/* Function Definition: Read_WidebandPacked_LPC                         */
/*======================================================================*/
void Read_WidebandPacked_LPC
(
    BITSTREAM * p_bitstream,           /* In: Bitstream                 */
	const long num_lpc_indices,        /* In: Number of LPC indices     */
	      long indices[]               /* Out: indices to rfc_table[]   */
)
{
    long lpc_indices[9];
	long k;
		
    /*==================================================================*/
    /*     Read the Parameters from the Bitstream                       */
	/*           These represent the packed LPC Indices                 */           
    /*==================================================================*/
	GetBit(p_bitstream, &lpc_indices[0], 9);
	GetBit(p_bitstream, &lpc_indices[1], 15);
	GetBit(p_bitstream, &lpc_indices[2], 11);
	GetBit(p_bitstream, &lpc_indices[3], 6);
	GetBit(p_bitstream, &lpc_indices[4], 3);
	GetBit(p_bitstream, &lpc_indices[5], 3);
	GetBit(p_bitstream, &lpc_indices[6], 3);
	GetBit(p_bitstream, &lpc_indices[7], 8);
	GetBit(p_bitstream, &lpc_indices[8], 8);

    for (k=0; k < num_lpc_indices; k++)
	{
		indices[k] = lpc_indices[k];
	}	
	
}

/*======================================================================*/
/* Function Definition: Read_NarrowbandPacked_LPC                       */
/*======================================================================*/
void Read_NarrowbandPacked_LPC
(
    BITSTREAM * p_bitstream,           /* In: Bitstream                 */
	      long  indices[]              /* Out: indices                  */
)
{
    /*==================================================================*/
    /*     Read the Parameters from the Bitstream                       */
	/*           These represent the packed LPC Indices                 */           
    /*==================================================================*/
	GetBit(p_bitstream, &indices[0], 12);
	GetBit(p_bitstream, &indices[1], 12);
	GetBit(p_bitstream, &indices[2], 12);
	GetBit(p_bitstream, &indices[3], 3);
}

/*======================================================================*/
/* Function Definition: Read_Narrowband_LSP                             */
/*======================================================================*/
void Read_NarrowBand_LSP
(
    BITSTREAM * p_bitstream,           /* In: Bitstream                 */
	      long indices[]               /* Out: indices to rfc_table[]   */
)
{
    /*==================================================================*/
    /*     Read the Parameters from the Bitstream                       */
	/*           These represent the packed LPC Indices                 */           
    /*==================================================================*/
	GetBit(p_bitstream, &indices[0], 4);
	GetBit(p_bitstream, &indices[1], 4);
	GetBit(p_bitstream, &indices[2], 7);
	GetBit(p_bitstream, &indices[3], 6);
	GetBit(p_bitstream, &indices[4], 1);
}

/*======================================================================*/
/* Function Definition: Read_Narrowband_LSP                             */
/*======================================================================*/
void Read_BandScalable_LSP
(
    BITSTREAM * p_bitstream,           /* In: Bitstream                 */
	      long indices[]               /* Out: indices                  */
)
{
    /*==================================================================*/
    /*     Read the Parameters from the Bitstream                       */
	/*           These represent the packed LPC Indices                 */           
    /*==================================================================*/
	GetBit(p_bitstream, &indices[0], 4);
	GetBit(p_bitstream, &indices[1], 7);
	GetBit(p_bitstream, &indices[2], 4);
	GetBit(p_bitstream, &indices[3], 6);
	GetBit(p_bitstream, &indices[4], 7);
	GetBit(p_bitstream, &indices[5], 4);
}

/*======================================================================*/
/* Function Definition: Read_Wideband_LSP                               */
/*======================================================================*/
void Read_Wideband_LSP
(
    BITSTREAM * p_bitstream,           /* In: Bitstream                 */
	      long indices[]               /* Out: indices                  */
)
{
    /*==================================================================*/
    /*     This mode is reserved for future use                         */
    /*==================================================================*/
	fprintf(stderr,"The wideband optimized VQ mode is reserved for future use\n");
	exit(0);
}

/*======================================================================*/
/* GetBit: Reads a number of bits from the bitstream                    */
/*======================================================================*/
void GetBit(
   BITSTREAM * const bs,     /* In:  Bitstream Pointer                  */
   long   * const c,         /* Out: Value read off the bitstream       */
   const  long num_bits      /* In:  #bits to be read                   */
   )
{
    int j;
    unsigned int temp = 0;
    
    if (bs != NULL)
    {
        for (j=(int)num_bits-1; j>=0; j -=1)
        {
            int index = (bs->start_offset)/8;
            int bit = 7-((bs->start_offset)%8);
			
            if ((bs->p_bitstream_buffer_start[index] >> bit) & 1)
               temp |= (unsigned int)(1 << j);

            bs->start_offset += 1;
            
            if (bs->start_offset > bs->valid_bits)
            {
                fprintf(stderr,"More bits decoded than present: %d %d\n",
                bs->start_offset, bs->valid_bits);
                fprintf(stderr,"Exitting.....\n");
                exit(0);
            }
        }

        *c = (long)temp;
    }
    else
    {
        *c = 0;
    }

}

/*======================================================================*/
/*      H I S T O R Y                                                   */
/*======================================================================*/
/* 07-06-96  R. Taori & A.Gerrits    Initial Version                    */
/* 18-09-96  R. Taori & A.Gerrits    MPEG bitstream used                */
