123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- /*************************************************************************
- *
- * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
- * R99 Version 3.3.0
- * REL-4 Version 4.1.0
- *
- ********************************************************************************
- *
- * File : decoder.c
- * Purpose : Speech decoder main program.
- *
- ********************************************************************************
- *
- * Usage : decoder bitstream_file synth_file
- *
- *
- * Format for bitstream_file:
- * 1 word (2-byte) for the frame type
- * (see frame.h for possible values)
- * Normally, the TX frame type is expected.
- * RX frame type can be forced with "-rxframetype"
- * 244 words (2-byte) containing 244 bits.
- * Bit 0 = 0x0000 and Bit 1 = 0x0001
- * 1 word (2-byte) for the mode indication
- * (see mode.h for possible values)
- * 4 words for future use, currently unused
- *
- * Format for synth_file:
- * Synthesis is written to a binary file of 16 bits data.
- *
- ********************************************************************************
- */
- /*
- ********************************************************************************
- * INCLUDE FILES
- ********************************************************************************
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include "typedef.h"
- #include "n_proc.h"
- #include "cnst.h"
- #include "mode.h"
- #include "frame.h"
- #include "strfunc.h"
- #include "sp_dec.h"
- #include "d_homing.h"
- #ifdef MMS_IO
- #define AMR_MAGIC_NUMBER "#!AMR\n"
- #define MAX_PACKED_SIZE (MAX_SERIAL_SIZE / 8 + 2)
- #endif
- const char decoder_id[] = "@(#)$Id $";
- /* frame size in serial bitstream file (frame type + serial stream + flags) */
- #define SERIAL_FRAMESIZE (1+MAX_SERIAL_SIZE+5)
- /*
- ********************************************************************************
- * LOCAL PROGRAM CODE
- ********************************************************************************
- */
- static enum RXFrameType tx_to_rx (enum TXFrameType tx_type)
- {
- switch (tx_type) {
- case TX_SPEECH_GOOD: return RX_SPEECH_GOOD;
- case TX_SPEECH_DEGRADED: return RX_SPEECH_DEGRADED;
- case TX_SPEECH_BAD: return RX_SPEECH_BAD;
- case TX_SID_FIRST: return RX_SID_FIRST;
- case TX_SID_UPDATE: return RX_SID_UPDATE;
- case TX_SID_BAD: return RX_SID_BAD;
- case TX_ONSET: return RX_ONSET;
- case TX_NO_DATA: return RX_NO_DATA;
- default:
- wfprintf(stderr, "tx_to_rx: unknown TX frame type %d\n", tx_type);
- exit(1);
- }
- }
- /*
- ********************************************************************************
- * MAIN PROGRAM
- ********************************************************************************
- */
- int main (int argc, char *argv[])
- {
- Speech_Decode_FrameState *speech_decoder_state = NULL;
-
- Word16 serial[SERIAL_FRAMESIZE]; /* coded bits */
- Word16 synth[L_FRAME]; /* Synthesis */
- Word32 frame;
- char *progname = argv[0];
- char *fileName = NULL;
- char *serialFileName = NULL;
-
- FILE *file_syn, *file_serial;
- int rxframetypeMode = 0; /* use RX frame type codes */
- enum Mode mode = (enum Mode)0;
- enum RXFrameType rx_type = (enum RXFrameType)0;
- enum TXFrameType tx_type = (enum TXFrameType)0;
-
- Word16 reset_flag = 0;
- Word16 reset_flag_old = 1;
- Word16 i;
-
- #ifdef MMS_IO
- UWord8 toc, q, ft;
- Word8 magic[8];
- UWord8 packed_bits[MAX_PACKED_SIZE];
- Word16 packed_size[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0};
- #endif
- proc_head ("Decoder");
- #ifndef MMS_IO
- /*----------------------------------------------------------------------*
- * process command line options *
- *----------------------------------------------------------------------*/
- while (argc > 1) {
- if (strcmp(argv[1], "-rxframetype") == 0)
- rxframetypeMode = 1;
- else break;
- argc--;
- argv++;
- }
- #endif
- /*----------------------------------------------------------------------*
- * check number of arguments *
- *----------------------------------------------------------------------*/
- if (argc != 3)
- {
- wfprintf (stderr,
- " Usage:\n\n"
- #ifndef MMS_IO
- " %s [-rxframetype] bitstream_file synth_file\n\n"
- " -rxframetype expects the RX frame type in bitstream_file (instead of TX)\n\n",
- #else
- " %s bitstream_file synth_file\n\n",
- #endif
- progname);
- exit (1);
- }
-
- serialFileName = argv[1];
- fileName = argv[2];
- /*----------------------------------------------------------------------*
- * Open serial bit stream and output speech file *
- *----------------------------------------------------------------------*/
- if (strcmp(serialFileName, "-") == 0) {
- file_serial = stdin;
- }
- else if ((file_serial = fopen (serialFileName, "rb")) == NULL)
- {
- wfprintf (stderr, "Input file '%s' does not exist !!\n", serialFileName);
- exit (0);
- }
- wfprintf (stderr, "Input bitstream file: %s\n", serialFileName);
- if (strcmp(fileName, "-") == 0) {
- file_syn = stdout;
- }
- else if ((file_syn = fopen (fileName, "wb")) == NULL)
- {
- wfprintf (stderr, "Cannot create output file '%s' !!\n", fileName);
- exit (0);
- }
- wfprintf (stderr, "Synthesis speech file: %s\n", fileName);
- #ifdef MMS_IO
- /* read and verify magic number */
- fread(magic, sizeof(Word8), strlen(AMR_MAGIC_NUMBER), file_serial);
- if (strncmp((const char *)magic, AMR_MAGIC_NUMBER, strlen(AMR_MAGIC_NUMBER)))
- {
- wfprintf(stderr, "%s%s\n", "Invalid magic number: ", magic);
- fclose(file_serial);
- fclose(file_syn);
- return 1;
- }
- #endif
- /*-----------------------------------------------------------------------*
- * Initialization of decoder *
- *-----------------------------------------------------------------------*/
- if (Speech_Decode_Frame_init(&speech_decoder_state, "Decoder"))
- exit(-1);
-
- /*-----------------------------------------------------------------------*
- * process serial bitstream frame by frame *
- *-----------------------------------------------------------------------*/
- frame = 0;
- #ifndef MMS_IO
- while (fread (serial, sizeof (Word16), SERIAL_FRAMESIZE, file_serial)
- == SERIAL_FRAMESIZE)
- {
- /* get frame type and mode information from frame */
- if (rxframetypeMode) {
- rx_type = (enum RXFrameType)serial[0];
- } else {
- tx_type = (enum TXFrameType)serial[0];
- rx_type = tx_to_rx (tx_type);
- }
- mode = (enum Mode) serial[1+MAX_SERIAL_SIZE];
- #else
- while (fread (&toc, sizeof(UWord8), 1, file_serial) == 1)
- {
- /* read rest of the frame based on ToC byte */
- q = (toc >> 2) & 0x01;
- ft = (toc >> 3) & 0x0F;
- fread (packed_bits, sizeof(UWord8), packed_size[ft], file_serial);
- rx_type = UnpackBits(q, ft, packed_bits, &mode, &serial[1]);
- #endif
- ++frame;
- if ( (frame%50) == 0) {
- wfprintf (stderr, "\rframe=%d ", frame);
- }
- if (rx_type == RX_NO_DATA) {
- mode = speech_decoder_state->prev_mode;
- }
- else {
- speech_decoder_state->prev_mode = mode;
- }
- /* if homed: check if this frame is another homing frame */
- if (reset_flag_old == 1)
- {
- /* only check until end of first subframe */
- reset_flag = decoder_homing_frame_test_first(&serial[1], mode);
- }
- /* produce encoder homing frame if homed & input=decoder homing frame */
- if ((reset_flag != 0) && (reset_flag_old != 0))
- {
- for (i = 0; i < L_FRAME; i++)
- {
- synth[i] = EHF_MASK;
- }
- }
- else
- {
- /* decode frame */
- Speech_Decode_Frame(speech_decoder_state, mode, &serial[1],
- rx_type, synth);
- }
-
- /* write synthesized speech to file */
- if (fwrite (synth, sizeof (Word16), L_FRAME, file_syn) != L_FRAME) {
- wfprintf(stderr, "\nerror writing output file: %s\n",
- strerror(errno));
- };
- fflush(file_syn);
- /* if not homed: check whether current frame is a homing frame */
- if (reset_flag_old == 0)
- {
- /* check whole frame */
- reset_flag = decoder_homing_frame_test(&serial[1], mode);
- }
- /* reset decoder if current frame is a homing frame */
- if (reset_flag != 0)
- {
- Speech_Decode_Frame_reset(speech_decoder_state);
- }
- reset_flag_old = reset_flag;
- }
- wfprintf (stderr, "\n%d frame(s) processed\n", frame);
-
- /*-----------------------------------------------------------------------*
- * Close down speech decoder *
- *-----------------------------------------------------------------------*/
- Speech_Decode_Frame_exit(&speech_decoder_state);
-
- return 0;
- }
|