📄 g729ev_tdac_spectenv.c
字号:
/* ITU-T G.729EV Optimization/Characterization Candidate *//* Version: 1.0.a *//* Revision Date: June 28, 2006 *//* ITU-T G.729EV Optimization/Characterization Candidate ANSI-C Source Code Copyright (c) 2006 France Telecom, Matsushita Electric, Mindspeed, Siemens AG, ETRI, VoiceAge Corp. All rights reserved*/#include <assert.h>#include <stdlib.h>#include "G729EV_G729_defines.h"#include "G729EV_MAIN_defines.h"#include "G729EV_TDAC_spectenv.h"#include "G729EV_TDAC_util.h"#include "G729EV_TDAC_lib_vq.h"#include "G729EV_TDAC_vq.h"#include "stl.h"#include "G729EV_MAIN_OPER_32B.h"#include "G729EV_MAIN_DSPFUNC.h"/*--------------------------------------------------------------------------* * Function G729EV_TDAC_calc_specEnv() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Compute log2 rms for each subband * *--------------------------------------------------------------------------*/void G729EV_TDAC_calc_specEnv(Word16 * y, /* (i) transform coefficients of the difference */ Word16 * log_rms, /* (o) log2 of the spectrum envelope */ Word16 n, /* (i) number of subbands */ Word16 norm_lo, /* (i) norm_shift of low bands */ Word16 norm_hi, /* (i) norm_shift of high bands */ Word16 norm_MDCT /* (i) norm_shift transmitted to decoder */ ){ Word32 ener; Word16 i, j; Word16 log_int, log_frac; Word16 norm; FOR(j = 0; j < n; j++) { /* compute subband energy */ ener = (Word32) 0;#if(WMOPS) move32();#endif FOR(i = G729EV_TDAC_sb_bound[j]; i < G729EV_TDAC_sb_bound[j + 1]; i++) { ener = L_mac(ener, y[i], y[i]); /* sum of squared coef */ } /* divide energy by number of coef in each band : taken into account in the norm value normalize result before log2 operation */ norm = norm_l(ener); ener = L_shl(ener, norm); norm = add(norm, add(G729EV_TDAC_nb_coef_div[j], 1)); IF(sub(j, G729EV_TDAC_NB_SB_NB) < 0) /* norm_lo */ { norm = add(norm, shl(sub(norm_lo, norm_MDCT), 1)); } ELSE /* norm_hi */ { norm = add(norm, shl(sub(norm_hi, norm_MDCT), 1)); } IF(ener == 0) { log_rms[j] = (Word16) - 24576; /* -12 in Q11 */#if(WMOPS) move16();#endif } ELSE { /* Log2 */ Log2(ener, &log_int, &log_frac); ener = L_Comp(sub(log_int, norm), log_frac); log_rms[j] = extract_h(L_shl(ener, 10));#if(WMOPS) move16();#endif } }}/*--------------------------------------------------------------------------** cod_specEnv : encoding of the spectrum envelope **--------------------------------------------------------------------------*//* subroutines: - G729EV_TDAC_quant_3dB - G729EV_TDAC_compute_diff_index - G729EV_TDAC_encode_spenv - G729EV_TDAC_writ_specEnv *//*--------------------------------------------------------------------------* * Function G729EV_TDAC_quant_3dB() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Quantize with 3dB step * *--------------------------------------------------------------------------*/void G729EV_TDAC_quant_3dB(Word16 * index, /* (o) code words number */ Word16 * log_rms, /* (i) log2 of the spectrum envelope */ Word16 norm_MDCT /* (i) MDCT norm value */ ){ Word16 tmp; Word16 min_RMS, max_RMS; IF(sub(norm_MDCT, G729EV_TDAC_NORM_MDCT_TRESH) < 0) { min_RMS = add(G729EV_TDAC_MIN_RMS, shl(norm_MDCT, 1)); max_RMS = add(G729EV_TDAC_MAX_RMS, shl(norm_MDCT, 1)); } ELSE { min_RMS = add(G729EV_TDAC_MIN_RMS, G729EV_TDAC_RMS_OFFSET); max_RMS = add(G729EV_TDAC_MAX_RMS, G729EV_TDAC_RMS_OFFSET); } /* rounding */ tmp = mult(*log_rms, G729EV_TDAC_Q3db_INV); tmp = add(tmp, 0x100); /* 0.5 in Q9 */ *index = shr(tmp, 9);#if(WMOPS) move16();#endif /* overload (<5 bits) */ if (sub(*index, min_RMS) < 0) { *index = min_RMS;#if (WMOPS) move16();#endif } if (sub(*index, max_RMS) > 0) { *index = max_RMS;#if (WMOPS) move16();#endif } return;}/*--------------------------------------------------------------------------* * Function G729EV_TDAC_compute_diff_index() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Compute differential indices and detect saturation * *--------------------------------------------------------------------------*/Word16 G729EV_TDAC_compute_diff_index(Word16 * rms_index, /* (i) indices of quantized rms */ Word16 n, /* (i) number of subbands */ Word16 * diff_index /* (o) differential indices */ ){ Word16 j, tmp; FOR(j = 0; j < n; j++) { tmp = sub(rms_index[j], rms_index[j - 1]); if ((add(tmp, 12) < 0) || (sub(tmp, 12) > 0)) { return (1); } diff_index[j] = tmp;#if (WMOPS) move16();#endif /* update index to take into account overload in difference */ rms_index[j] = add(rms_index[j - 1], tmp);#if (WMOPS) move16();#endif } return (0);}/*--------------------------------------------------------------------------* * Function G729EV_TDAC_encode_spenv() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * encode spectral envelope * *--------------------------------------------------------------------------*/void G729EV_TDAC_encode_spenv(Word16 * rms_index, /* (i) indices of quantized rms */ Word16 * diff_index, /* (i) differential indices */ Word16 * bitstream, /* (o) bitstream */ Word16 * nbit_env, /* (o) number of bits used for spectral envelope */ Word16 n, /* (i) number of subbands */ Word16 satur, /* (i) saturation flag */ Word16 norm_MDCT /* (i) MDCT normalization factor */ ){ Word16 bitstream_eq[1 + G729EV_TDAC_NB_SB_NB * 5]; Word16 nbit_env_eq[G729EV_TDAC_NB_SB_NB]; Word16 *pBit, *pBit_eq; Word16 nbit_eq, nbit, j, k, i; Word16 min_RMS; Word16 len; Word16 tmp; IF(sub(norm_MDCT, G729EV_TDAC_NORM_MDCT_TRESH) < 0) { min_RMS = add(G729EV_TDAC_MIN_RMS, shl(norm_MDCT, 1)); } ELSE { min_RMS = add(G729EV_TDAC_MIN_RMS, G729EV_TDAC_RMS_OFFSET); } /* mode 1: equiprobable */ pBit_eq = bitstream_eq; G729EV_TDAC_pushBit(1, &pBit_eq, 1); nbit_eq = (Word16) 1;#if (WMOPS) move16();#endif FOR(j = 0; j < n; j++) { /* write equiprobable code (mode 1) */ tmp = sub(rms_index[j], min_RMS); G729EV_TDAC_pushBit(tmp, &pBit_eq, 5); nbit_eq = add(nbit_eq, 5); nbit_env_eq[j] = (Word16) 5;#if (WMOPS) move16();#endif } /* bypass mode 0 in case of overload in difference coding */ IF(sub(satur, 1) != 0) { /* mode 0: differential Huffman */ pBit = bitstream; /* first band */ G729EV_TDAC_pushBit(0, &pBit, 1); tmp = sub(rms_index[0], min_RMS); G729EV_TDAC_pushBit(tmp, &pBit, 5); nbit = add(5, 1); nbit_env[0] = (Word16) 5;#if (WMOPS) move16();#endif /* next bands */ FOR(j = 1; j < n; j++) { k = add(diff_index[j], 12); len = G729EV_TDAC_len_huff_diff[k]; G729EV_TDAC_pushBit(G729EV_TDAC_code_huff_diff[k], &pBit, len); nbit = add(nbit, len); nbit_env[j] = len;#if (WMOPS) move16();#endif } } ELSE { nbit = (Word16) 0;#if (WMOPS) move16();#endif } /* select best sequence */#if (WMOPS) test();#endif IF((sub(satur, 1) == 0) || (sub(nbit_eq, nbit) < 0)) { pBit = bitstream; FOR(i = 0; i < nbit_eq; i++) { *pBit++ = bitstream_eq[i];#if (WMOPS) move16();#endif } FOR(j = 0; j < n; j++) { nbit_env[j] = nbit_env_eq[j];#if (WMOPS) move16();#endif } } return;}/*--------------------------------------------------------------------------* * Function G729EV_TDAC_writ_specEnv() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Write spectral envelope to bitstream * *--------------------------------------------------------------------------*/void G729EV_TDAC_writ_specEnv(Word16 * bits_env, /* (i) encoded spectral envelope (per subband) */ Word16 * nb_bits_env, /* (i) number of bits per subbands */ Word16 n, /* (i) dimension */ Word16 nbit, /* (i) maximal number of bits for TDAC */ Word16 ** bitstream, /* (o) bistream */ Word16 * bit_cnt /* (o) number of bits written to bitstream */ ){ Word16 *pBit; Word16 ki, j, ii, i; Word16 tmp; pBit = *bitstream; ki = (Word16) 0; *pBit++ = bits_env[ki++]; /* eq_switch bit */ *bit_cnt = add(*bit_cnt, 1);#if (WMOPS) move16(); move16();#endif /* write encoded spectral envelope to bitstream */ FOR(j = 0; j < n; j++) { tmp = add(*bit_cnt, nb_bits_env[j]); IF(sub(tmp, nbit) <= 0) { *bit_cnt = tmp;#if (WMOPS) move16();#endif FOR(i = 0; i < nb_bits_env[j]; i++) /* save the whole Huffman code */ { *pBit++ = bits_env[ki++];#if (WMOPS) move16();#endif } } ELSE { ii = sub(nbit, *bit_cnt); /* remaining bits */ *bit_cnt = add(*bit_cnt, ii); /* bit_cnt = bits4vq */#if(WMOPS) move16();#endif FOR(i = 0; i < ii; i++) /* save the beginning of the Huffman code, to complete bitstream */ { *pBit++ = bits_env[ki++];#if (WMOPS) move16();#endif } } } *bitstream = pBit;#if (WMOPS) move16();#endif return;}/*--------------------------------------------------------------------------* * Function G729EV_TDAC_cod_spenv() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Encode spectral envelope * *--------------------------------------------------------------------------*/void G729EV_TDAC_cod_spenv(Word16 * log_rms, /* (i) log2 of the spectrum envelope */ Word16 * rms_index, /* (o) decoded spectrum enveloppe */ Word16 ** pBit, /* (i/o) bitstream */ Word16 * bit_cnt, /* (o) number of bits written to bitstream */ Word16 nbit_to_encode, /* (i) maximal number of bits for TDAC */ Word16 norm_MDCT /* (i) MDCT normalization factor */ ){ Word16 nbit_env[G729EV_TDAC_NB_SB]; Word16 diff_index[G729EV_TDAC_NB_SB]; Word16 bit_nb[1 + 10 * 14], bit_wb[1 + 8 * 14]; /* 1+max. length of Huffman code * nb subbands */ Word16 j; Word16 satur; /* initialize the number of bits used to encode each spectral factor (subband gain) */ FOR(j = 0; j < G729EV_TDAC_NB_SB; j++) { nbit_env[j] = (Word16) 0;#if (WMOPS) move16();#endif } /* round with 3dB step */ FOR(j = 0; j < G729EV_TDAC_NB_SB; j++) { G729EV_TDAC_quant_3dB(&rms_index[j], &log_rms[j], norm_MDCT); } /* compute spectral envelope parameters in lower band */ satur = G729EV_TDAC_compute_diff_index(&rms_index[1], G729EV_TDAC_NB_SB_NB - 1, &diff_index[1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -