/***************************************************************************
 *
 *  FILE NAME:  decoder.c
 *
 *         Usage : decoder  bitstream_file  synth_file
 *
 *         Format for bitstream_file:
 *           244  words (2-byte) containing 244 bits.
 *               Bit 0 = 0x0000 and Bit 1 = 0x0001
 *
 *         Format for synth_file:
 *           Synthesis is written to a binary file of 16 bits data.
 *
 ***************************************************************************/

#include <string.h>

#include "typedef.h"
#include "basic_op.h"
#include "sig_proc.h"
#include "codec.h"
#include "cnst.h"
#include "d_homing.h"


/* These constants define the number of consecutive parameters
   that function decoder_homing_frame_test() checks */

#define WHOLE_FRAME 57
#define TO_FIRST_SUBFRAME 18


Word16 synth_buf[L_FRAME + M];

/* L_FRAME, M, PRM_SIZE, AZ_SIZE, SERIAL_SIZE: defined in "cnst.h" */

/*-----------------------------------------------------------------*
 *             Global variables                                    *
 *-----------------------------------------------------------------*/

/*-----------------------------------------------------------------*
 *            Main decoder routine                                 *
 *-----------------------------------------------------------------*/

void Decode( Word16 *in, Word32 size, Word32 filter, Word32 mask, Word16 *out )
{
    Word16 *synth;              /* Synthesis                  */
    Word16 parm[PRM_SIZE + 1];  /* Synthesis parameters       */
    Word16 serial[SERIAL_SIZE+1]; /* Serial stream              */
    Word16 Az_dec[AZ_SIZE];     /* Decoded Az for post-filter */
                                /* in 4 subframes, length= 44 */
    Word16 i, frame, temp;

    Word16 TAF, SID_flag;

    Word16 reset_flag;
    static Word16 reset_flag_old = 1;

    /*-----------------------------------------------------------------*
     *           Read passed arguments and open in/out files           *
     *-----------------------------------------------------------------*/

    /*-----------------------------------------------------------------*
     *           Initialization of decoder                             *
     *-----------------------------------------------------------------*/

    synth = synth_buf + M;

    reset_dec (); /* Bring the decoder and receive DTX to the initial state */

    /*-----------------------------------------------------------------*
     *            Loop for each "L_FRAME" speech data                  *
     *-----------------------------------------------------------------*/

    frame = 0;

    while (size > 0)
    {
				serial[0] = 0;
				memcpy( &serial[1], in, SERIAL_SIZE*2 );
				in += SERIAL_SIZE;
				size -= L_FRAME;

        SID_flag = 0;//serial[245];         /* Receive SID flag */
        TAF = 0;//serial[246];              /* Receive TAF flag */

        Bits2prm_12k2 (serial, parm);   /* serial to parameters   */

        if (parm[0] == 0)               /* BFI == 0, perform DHF check */
        {
            if (reset_flag_old == 1)    /* Check for second and further
                                           successive DHF (to first subfr.) */
            {
                reset_flag = decoder_homing_frame_test (&parm[1],
                                                        TO_FIRST_SUBFRAME);
            }
            else
            {
                reset_flag = 0;
            }
        }
        else                          /* BFI==1, bypass DHF check (frame
                                           is taken as not being a DHF) */
        {
            reset_flag = 0;
        }

        if ((reset_flag != 0) && (reset_flag_old != 0))
        {
            /* Force the output to be the encoder homing frame pattern */

            for (i = 0; i < L_FRAME; i++)
            {
                synth[i] = EHF_MASK;
            }
        }
        else
        {
            Decoder_12k2 (parm, synth, Az_dec, TAF, SID_flag);/* Synthesis */

						if (filter)
							Post_Filter (synth, Az_dec);                      /* Post-filter */

            for (i = 0; i < L_FRAME; i++) 
                /* Upscale the 15 bit linear PCM to 16 bits,
                   then truncate to 13 bits */
            {
                temp = shl (synth[i], 1);
								if (mask)
									synth[i] = temp & 0xfff8;
            }

        }                       /* else */

				memcpy( out, synth, L_FRAME*2 );
				out += L_FRAME;

        /* BFI == 0, perform check for first DHF (whole frame) */
        if ((parm[0] == 0) && (reset_flag_old == 0))
        {
            reset_flag = decoder_homing_frame_test (&parm[1], WHOLE_FRAME);
        }

        if (reset_flag != 0)
        {
            /* Bring the decoder and receive DTX to the home state */
            reset_dec ();
        }
        reset_flag_old = reset_flag;

    }                           /* while */
}
