dec_if.c
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:13k
- /*
- *===================================================================
- * 3GPP AMR Wideband Floating-point Speech Codec
- *===================================================================
- */
- #include "hlxclib/stdlib.h"
- #include "hlxclib/memory.h"
- #include "typedef.h"
- #include "dec_if.h"
- #include "if_rom.h"
- #include "dec.h"
- #define L_FRAME16k 320 /* Frame size at 16kHz */
- #define MODE_7k 0 /* modes */
- #define MODE_9k 1
- #define MODE_12k 2
- #define MODE_14k 3
- #define MODE_16k 4
- #define MODE_18k 5
- #define MODE_20k 6
- #define MODE_23k 7
- #define MODE_24k 8
- #define MRDTX 10
- #define NUM_OF_MODES 11
- #define LOST_FRAME 14
- #define MRNO_DATA 15
- #define EHF_MASK (Word16)0x0008 /* homing frame pattern */
- typedef struct
- {
- Word16 reset_flag_old; /* previous was homing frame */
- Word16 prev_ft; /* previous frame type */
- Word16 prev_mode; /* previous mode */
- void *decoder_state; /* Points decoder state */
- } WB_dec_if_state;
- const Word16 nb_of_param_first[NUM_OF_SPMODES]=
- {
- 9, 14, 15,
- 15, 15, 19,
- 19, 19, 19
- };
- extern const Word16 mode_7k[];
- extern const Word16 mode_9k[];
- extern const Word16 mode_12k[];
- extern const Word16 mode_14k[];
- extern const Word16 mode_16k[];
- extern const Word16 mode_18k[];
- extern const Word16 mode_20k[];
- extern const Word16 mode_23k[];
- extern const Word16 mode_24k[];
- extern const Word16 mode_DTX[];
- extern const Word16 nb_of_param[];
- extern const Word16 dfh_M7k[];
- extern const Word16 dfh_M9k[];
- extern const Word16 dfh_M12k[];
- extern const Word16 dfh_M14k[];
- extern const Word16 dfh_M16k[];
- extern const Word16 dfh_M18k[];
- extern const Word16 dfh_M20k[];
- extern const Word16 dfh_M23k[];
- extern const Word16 dfh_M24k[];
- /* overall table with the parameters of the
- decoder homing frames for all modes */
- extern const Word16* const dhf[10];
- /*
- * Decoder_Interface_Homing_Frame_test
- *
- * Parameters:
- * input_frame I: input parameters
- * mode I: speech mode
- *
- * Function:
- * Check parameters for matching homing frame
- *
- * Returns:
- * If homing frame
- */
- Word16 D_IF_homing_frame_test(Word16 input_frame[], Word16 mode)
- {
- if (mode != MODE_24k)
- {
- /* perform test for COMPLETE parameter frame */
- return (Word16)!memcmp(input_frame, dhf[mode], nb_of_param[mode] * sizeof(Word16));
- }
- else
- {
- /* discard high-band energy */
- return (Word16)!(
- (memcmp(input_frame, dhf[MODE_24k], 19 * sizeof(Word16))) |
- (memcmp(input_frame + 20, dhf[MODE_24k] + 20, 11 * sizeof(Word16))) |
- (memcmp(input_frame + 32, dhf[MODE_24k] + 32, 11 * sizeof(Word16))) |
- (memcmp(input_frame + 44, dhf[MODE_24k] + 44, 11 * sizeof(Word16))) );
- }
- }
- Word16 D_IF_homing_frame_test_first(Word16 input_frame[], Word16 mode)
- {
- /* perform test for FIRST SUBFRAME of parameter frame ONLY */
- return (Word16)!memcmp(input_frame, dhf[mode], nb_of_param_first[mode] * sizeof(Word16));
- }
- /*
- * D_IF_conversion
- *
- *
- * Parameters:
- * param O: AMR parameters
- * stream I: input bitstream
- * frame_type O: frame type
- * speech_mode O: speech mode in DTX
- * fqi O: frame quality indicator
- *
- * Function:
- * Unpacks IF2 octet stream
- *
- * Returns:
- * mode used mode
- */
- Word16 D_IF_conversion(Word16 *param, UWord8 *stream, UWord8 *frame_type,
- Word16 *speech_mode, Word16 *fqi)
- {
- Word32 mode;
- Word32 j;
- Word16 const *mask;
- memset(param, 0, PRMNO_24k << 1);
- mode = *stream >> 4;
- /* SID indication IF2 corresponds to mode 10 */
- if (mode == 9)
- {
- mode ++;
- }
- *fqi = (Word16)((*stream >> 3) & 0x1);
- *stream <<= (HEADER_SIZE - 1);
- switch (mode)
- {
- case MRDTX:
- mask = mode_DTX;
- for (j = HEADER_SIZE; j < T_NBBITS_SID; j++)
- {
- if (*stream & 0x80)
- {
- param[*mask] = (Word16)(param[*mask] + *(mask + 1));
- }
- mask += 2;
- if ( j % 8 )
- {
- *stream <<= 1;
- }
- else
- {
- stream++;
- }
- }
- /* get SID type bit */
- *frame_type = RX_SID_FIRST;
- if (*stream & 0x80)
- {
- *frame_type = RX_SID_UPDATE;
- }
- *stream <<= 1;
- /* speech mode indicator */
- *speech_mode = (Word16)(*stream >> 4);
- break;
- case MRNO_DATA:
- *frame_type = RX_NO_DATA;
- break;
- case LOST_FRAME:
- *frame_type = RX_SPEECH_LOST;
- break;
- case MODE_7k:
- mask = mode_7k;
- for (j = HEADER_SIZE; j < T_NBBITS_7k; j++)
- {
- if ( *stream & 0x80 )
- {
- param[*mask] = (Word16)(param[*mask] + *(mask + 1));
- }
- mask += 2;
- if (j % 8)
- {
- *stream <<= 1;
- }
- else
- {
- stream++;
- }
- }
- *frame_type = RX_SPEECH_GOOD;
- break;
- case MODE_9k:
- mask = mode_9k;
- for (j = HEADER_SIZE; j < T_NBBITS_9k; j++)
- {
- if (*stream & 0x80)
- {
- param[*mask] = (Word16)(param[*mask] + *(mask + 1));
- }
- mask += 2;
- if (j % 8)
- {
- *stream <<= 1;
- }
- else
- {
- stream++;
- }
- }
- *frame_type = RX_SPEECH_GOOD;
- break;
- case MODE_12k:
- mask = mode_12k;
- for (j = HEADER_SIZE; j < T_NBBITS_12k; j++)
- {
- if (*stream & 0x80)
- {
- param[*mask] = (Word16)(param[*mask] + *(mask + 1));
- }
- mask += 2;
- if ( j % 8 )
- {
- *stream <<= 1;
- }
- else
- {
- stream++;
- }
- }
- *frame_type = RX_SPEECH_GOOD;
- break;
- case MODE_14k:
- mask = mode_14k;
- for (j = HEADER_SIZE; j < T_NBBITS_14k; j++)
- {
- if (*stream & 0x80)
- {
- param[*mask] = (Word16)(param[*mask] + *(mask + 1));
- }
- mask += 2;
- if ( j % 8 )
- {
- *stream <<= 1;
- }
- else
- {
- stream++;
- }
- }
- *frame_type = RX_SPEECH_GOOD;
- break;
- case MODE_16k:
- mask = mode_16k;
- for (j = HEADER_SIZE; j < T_NBBITS_16k; j++)
- {
- if (*stream & 0x80)
- {
- param[*mask] = (Word16)(param[*mask] + *(mask + 1));
- }
- mask += 2;
- if (j % 8)
- {
- *stream <<= 1;
- }
- else
- {
- stream++;
- }
- }
- *frame_type = RX_SPEECH_GOOD;
- break;
- case MODE_18k:
- mask = mode_18k;
- for (j = HEADER_SIZE; j < T_NBBITS_18k; j++)
- {
- if (*stream & 0x80)
- {
- param[*mask] = (Word16)(param[*mask] + *(mask + 1));
- }
- mask += 2;
- if (j % 8)
- {
- *stream <<= 1;
- }
- else
- {
- stream++;
- }
- }
- *frame_type = RX_SPEECH_GOOD;
- break;
- case MODE_20k:
- mask = mode_20k;
- for (j = HEADER_SIZE; j < T_NBBITS_20k; j++)
- {
- if (*stream & 0x80)
- {
- param[*mask] = (Word16)(param[*mask] + *(mask + 1));
- }
- mask += 2;
- if (j % 8)
- {
- *stream <<= 1;
- }
- else
- {
- stream++;
- }
- }
- *frame_type = RX_SPEECH_GOOD;
- break;
- case MODE_23k:
- mask = mode_23k;
- for (j = HEADER_SIZE; j < T_NBBITS_23k; j++)
- {
- if (*stream & 0x80)
- {
- param[*mask] = (Word16)(param[*mask] + *(mask + 1));
- }
- mask += 2;
- if (j % 8)
- {
- *stream <<= 1;
- }
- else
- {
- stream++;
- }
- }
- *frame_type = RX_SPEECH_GOOD;
- break;
- case MODE_24k:
- mask = mode_24k;
- for (j = HEADER_SIZE; j < T_NBBITS_24k; j++)
- {
- if (*stream & 0x80)
- {
- param[*mask] = (Word16)(param[*mask] + *(mask + 1));
- }
- mask += 2;
- if (j % 8)
- {
- *stream <<= 1;
- }
- else
- {
- stream++;
- }
- }
- *frame_type = RX_SPEECH_GOOD;
- break;
- default:
- *frame_type = RX_SPEECH_LOST;
- *fqi = 0;
- break;
- }
- if (*fqi == 0)
- {
- if (*frame_type == RX_SPEECH_GOOD)
- {
- *frame_type = RX_SPEECH_BAD;
- }
- if ((*frame_type == RX_SID_FIRST) | (*frame_type == RX_SID_UPDATE))
- {
- *frame_type = RX_SID_BAD;
- }
- }
- return (Word16)mode;
- }
- /*
- * D_IF_decode
- *
- *
- * Parameters:
- * st B: pointer to state structure
- * bits I: bitstream form the encoder
- * synth O: decoder output
- * lfi I: lost frame indicator
- * _good_frame, _bad_frame, _lost_frame, _no_frame
- *
- * Function:
- * Decoding one frame of speech. Lost frame indicator can be used
- * to inform encoder about the problems in the received frame.
- * _good_frame:good speech or sid frame is received.
- * _bad_frame: frame with possible bit errors
- * _lost_frame:speech of sid frame is lost in transmission
- * _no_frame: indicates non-received frames in dtx-operation
- * Returns:
- *
- */
- void D_IF_decode( void *st, UWord8 *bits, Word16 *synth, Word32 lfi)
- {
- Word32 i;
- Word16 mode = 0; /* AMR mode */
- Word16 speech_mode = MODE_7k; /* speech mode */
- Word16 fqi; /* frame quality indicator */
- Word16 prm[PRMNO_24k]; /* AMR parameters */
- UWord8 frame_type; /* frame type */
- Word16 reset_flag = 0; /* reset flag */
- WB_dec_if_state * s; /* pointer to structure */
- s = (WB_dec_if_state*)st;
- /* bits -> param, if needed */
- if ((lfi == _good_frame) | (lfi == _bad_frame))
- {
- /* add fqi data */
- *bits = (UWord8)((Word32)*bits & ~(lfi << 3));
- /*
- * extract mode information and frame_type,
- * octets to parameters
- */
- mode = D_IF_conversion( prm, bits, &frame_type, &speech_mode, &fqi);
- }
- else if (lfi == _no_frame)
- {
- frame_type = RX_NO_DATA;
- }
- else
- {
- frame_type = RX_SPEECH_LOST;
- }
- /*
- * if no mode information
- * guess one from the previous frame
- */
- if ((frame_type == RX_SPEECH_LOST) | (frame_type == RX_NO_DATA))
- {
- mode = s->prev_mode;
- }
- if (mode == MRDTX)
- {
- mode = speech_mode;
- }
- /* if homed: check if this frame is another homing frame */
- if (s->reset_flag_old == 1)
- {
- /* only check until end of first subframe */
- reset_flag = D_IF_homing_frame_test_first(prm, mode);
- }
- /* produce encoder homing frame if homed & input=decoder homing frame */
- if ((reset_flag != 0) && (s->reset_flag_old != 0))
- {
- for (i = 0; i < L_FRAME16k; i++)
- {
- synth[i] = EHF_MASK;
- }
- }
- else
- {
- D_MAIN_decode(mode, prm, synth, s->decoder_state, frame_type);
- }
- for (i = 0; i < L_FRAME16k; i++) /* Delete the 2 LSBs (14-bit input) */
- {
- synth[i] = (Word16) (synth[i] & 0xfffC);
- }
- /* if not homed: check whether current frame is a homing frame */
- if ((s->reset_flag_old == 0) & (mode < 9))
- {
- /* check whole frame */
- reset_flag = D_IF_homing_frame_test(prm, mode);
- }
- /* reset decoder if current frame is a homing frame */
- if (reset_flag != 0)
- {
- D_MAIN_reset(s->decoder_state, 1);
- }
- s->reset_flag_old = reset_flag;
- s->prev_ft = frame_type;
- s->prev_mode = mode;
- }
- /*
- * D_IF_reset
- *
- * Parameters:
- * st O: state struct
- *
- * Function:
- * Reset homing frame counter
- *
- * Returns:
- * void
- */
- void D_IF_reset(WB_dec_if_state *st)
- {
- st->reset_flag_old = 1;
- st->prev_ft = RX_SPEECH_GOOD;
- st->prev_mode = MODE_7k; /* minimum bitrate */
- }
- /*
- * D_IF_init
- *
- * Parameters:
- *
- * Function:
- * Allocates state memory and initializes state memory
- *
- * Returns:
- * pointer to encoder interface structure
- */
- void *D_IF_init( void)
- {
- WB_dec_if_state *s = NULL;
- /* allocate memory */
- if ((s = (WB_dec_if_state*) malloc(sizeof(WB_dec_if_state))) == NULL)
- {
- return NULL;
- }
- D_MAIN_init(&(s->decoder_state));
- if (s->decoder_state == NULL)
- {
- free(s);
- return NULL;
- }
- D_IF_reset(s);
- return s;
- }
- /*
- * D_IF_exit
- *
- * Parameters:
- * state I: state structure
- *
- * Function:
- * The memory used for state memory is freed
- *
- * Returns:
- * Void
- */
- void D_IF_exit(void *state)
- {
- WB_dec_if_state *s;
- s = (WB_dec_if_state *)state;
- /* free memory */
- D_MAIN_close(&s->decoder_state);
- free(s);
- state = NULL;
- }