/*
***********************************************************************
*
* 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.
* 
***********************************************************************
*/

/***************************************************************************
 *
 *  FILE NAME:  CODER.C
 *
 *  Main program of the EFR-ACELP coder at 6.7 kbit/s.
 *
 *    Usage : coder speech_file bitstream_file <vox vox_file VAD_file>
 *
 *    Format for speech_file:
 *      Speech is read from a binary file of 16 bits data.
 *
 *    Format for bitstream_file:
 *      One word (2-byte) for bad frame indication (BFI) flag bit
 *          0x0000 -> good frame;  0x0001 -> bad frame
 *      Two words used for VOX frame type signalling.
 *          (only used if vox option is set)
 *          14 MSB of each word is zero and the LSB's means:
 *          00 = Normal speech frame or POST1
 *          01 = POST0
 *          10 = PRE
 *          11 = No transmission
 *      134  words (2-byte) containing 134 bits.
 *          Bit 0 = 0x0000 and Bit 1 = 0x0001
 *
 ***************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "typedef.h"
#include "basic_op.h"
#include "sig_proc.h"
#include "codec.h"
#include "cnst.h"
#if defined(__BORLANDC__)
#include "n_stack.h"
#endif

int main(int argc, char *argv[])
{
    FILE *f_speech;             /* File of speech data                   */
    FILE *f_serial;             /* File of serial bits for transmission  */
    FILE *f_vox_ctrl;           /* File of vox control flag              */
    FILE *f_vad_ctrl;           /* File of VAD control flag              */

    extern Word16 *new_speech;  /* Pointer to new speech data            */

    Word16 prm[PRM_SIZE];       /* Analysis parameters.                  */
    Word16 serial[SERIAL_SIZE]; /* Output bitstream buffer               */
    Word16 syn[L_FRAME];        /* Buffer for synthesis speech           */

    Word16 frame;
    Word16 vox_mode = 0;
    char vox_char;
    Word16 vox_ctrl = 0;
    char vad_char;
    Word16 vad_ctrl = 0;

    proc_head("Speech Encoder");

/*--------------------------------------------------------------------------*
 * Open speech file and result file (output serial bit stream)              *
 *--------------------------------------------------------------------------*/

    if (!(argc == 3 || argc== 6)) {
        fprintf(stderr, "Usage : coder  speech_file  bitstream_file <vox vox_file VAD_file>\n");
        fprintf(stderr, "\n");
        exit(1);
    }
    if ((f_speech = fopen(argv[1], "rb")) == NULL) {
        fprintf(stderr, "Error opening input file  %s !!\n", argv[1]);
        exit(0);
    }
    fprintf(stderr, " Input speech file    :  %s\n", argv[1]);

    if ((f_serial = fopen(argv[2], "wb")) == NULL) {
        fprintf(stderr, "Error opening output bitstream file %s !!\n", argv[2]);
        exit(0);
    }
    fprintf(stderr, " Output bitstream file:  %s\n", argv[2]);

    if (argc == 6) {
       if (strcmp(argv[3],"vox")==0) {
          fprintf(stderr, " VOX operation\n");
          vox_mode = 1;
       } else {
          fprintf(stderr,
                  "Usage : coder  speech_file  bitstream_file <vox vox_file VAD_file>\n");
          exit(0);
       }
       if ((f_vox_ctrl = fopen(argv[4], "rt")) == NULL) {
           fprintf(stderr, "Error opening vox control input file  %s !!\n", argv[4]);
           exit(0);
       }
       if ((f_vad_ctrl = fopen(argv[5], "rt")) == NULL) {
           fprintf(stderr, "Error opening VAD control input file  %s !!\n", argv[5]);
           exit(0);
       }
    }
    fprintf(stderr,"\n");

/*--------------------------------------------------------------------------*
 * Initialisation of the coder.                                             *
 *--------------------------------------------------------------------------*/

    Init_Pre_Process();
    Init_Coder_6k7();

    fread(&new_speech[-L_NEXT], sizeof(Word16), L_NEXT, f_speech);
    Pre_Process(&new_speech[-L_NEXT], L_NEXT);

    /* Loop for each "L_FRAME" speech data. */

    frame = 0;
    while (fread(new_speech, sizeof(Word16), L_FRAME, f_speech) == L_FRAME) {
        fprintf(stderr, "frame = %-6d", frame++);

        if (argc == 6) {
           if (fread(&vox_char, sizeof(char), 1, f_vox_ctrl) != 1) {
              fprintf(stderr, "Error reading vox control input file  %s !!\n", argv[4]);
              exit(0);
           }
           if (vox_char == '0')
              vox_ctrl=0;
           else
              vox_ctrl=1;

           if (fread(&vad_char, sizeof(char), 1, f_vad_ctrl) != 1) {
              fprintf(stderr, "Error reading VAD control input file  %s !!\n", argv[5]);
              exit(0);
           }
           if (vad_char == '0')
              vad_ctrl=0;
           else
              vad_ctrl=1;
	}

        Pre_Process(new_speech, L_FRAME);    /* filter + 16->15 bits */

        Coder_6k7(vox_mode, vox_ctrl, vad_ctrl, prm, syn); /* Find speech parameters   */

        Prm2bits_6k7(prm, serial);    /* Parameters to serial bits */

        reorderEFRtoFRchannelFormat(serial);

        fprintf(stderr, "\r");

        fwrite(serial, sizeof(Word16), SERIAL_SIZE, f_serial);
    }

    fprintf(stderr, "Number of encoded frames : %-6d", frame++);

    fprintf(stderr, "\n");

    fclose(f_serial);
    fclose(f_speech);
    return 0;
}
