📄 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((const char *)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 + -