📄 decoder.c
字号:
/*************************************************************************** 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: fprintf(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) { fprintf (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) { fprintf (stderr, "Input file '%s' does not exist !!\n", serialFileName); exit (0); } fprintf (stderr, "Input bitstream file: %s\n", serialFileName); if (strcmp(fileName, "-") == 0) { file_syn = stdout; } else if ((file_syn = fopen (fileName, "wb")) == NULL) { fprintf (stderr, "Cannot create output file '%s' !!\n", fileName); exit (0); } fprintf (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(magic, AMR_MAGIC_NUMBER, strlen(AMR_MAGIC_NUMBER)))
{
fprintf(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) { fprintf (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) { fprintf(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; } fprintf (stderr, "\n%d frame(s) processed\n", frame); /*-----------------------------------------------------------------------* * Close down speech decoder * *-----------------------------------------------------------------------*/ Speech_Decode_Frame_exit(&speech_decoder_state); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -