/*==================================================================================== EVS Codec 3GPP TS26.443 Jun 30, 2015. Version CR 26.443-0006 ====================================================================================*/ #include "options.h" #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" #include "prot.h" #include "stl.h" #include "basop_util.h" /*--------------------------------------------------------------------------* * Local functions *--------------------------------------------------------------------------*/ static short small_symbol_enc( Encoder_State *st, const int *qbidx, const short bands, short *hLCmode, const short flag_pack, const short is_transient ); static short small_symbol_enc_tran( Encoder_State *st, const int *qbidx, const short bands, short *hLCmode, const short flag_pack ,const short is_transient ); static float band_energy_quant( Encoder_State *st, const float *t_audio, const short band_start[], const short band_end[], float band_energy[], const short bands, const Word32 L_qint, const Word16 eref_fx, const short is_transient ); static short p2a_threshold_quant( Encoder_State *st, const float *t_audio, const short band_start[], const short band_end[], const short band_width[], const short bands, const short p2a_bands, const float p2a_th, short *p2a_flags ); static void mdct_spectrum_fine_gain_enc( Encoder_State *st, const float ybuf[], float y2[], const short band_start[], const short band_end[], const short k_sort[], const short bands, const Word32 L_qint, const short Ngq, const short gqlevs, const short gqbits ); /*--------------------------------------------------------------------------* * spt_shorten_domain_set() * * Track the spectral peak based on peak -avg analysis *--------------------------------------------------------------------------*/ static void spt_shorten_domain_set( Encoder_State *st, /* i: encoder state structure */ const float t_audio[], /* i: input spectrum */ const short p2a_flags[], /* i: p2a anlysis information */ const short new_band_start[], /* i: new band start position */ const short new_band_end[], /* i: new band end position */ const short new_band_width[], /* i: new subband band width */ const short bands, /* i: total number of subbands */ short band_start[], /* i/o: band start position */ short band_end[], /* i/o: band end position */ short band_width[], /* i: sub band band width */ short *bit_budget /* i/o: bit budget */ ) { short i, j, k; short kpos; float max_y2; short max_y2_pos; short spt_shorten_flag[SPT_SHORTEN_SBNUM]; kpos = 0; j = 0; for( k=bands-SPT_SHORTEN_SBNUM; kprev_SWB_peak_pos[kpos] != 0) { max_y2 = 0.0f; max_y2_pos = 0; for( i=band_start[k]; i<=band_end[k]; i++ ) { if( max_y2 < fabs(t_audio[i]) ) { max_y2 =(float) fabs(t_audio[i]); max_y2_pos = i; } } if( max_y2_pos >= new_band_start[j] && max_y2_pos <= new_band_end[j] ) { band_start[k] = new_band_start[j]; band_end[k] = new_band_end[j]; band_width[k] = new_band_width[j]; spt_shorten_flag[j] = 1; } } push_indice( st, IND_HQ2_SPT_SHORTEN, spt_shorten_flag[j], 1 ); *bit_budget -= 1; } kpos++; j++; } return; } /*--------------------------------------------------------------------------* * hq_lr_enc() * * HQ low rate encoding routine *--------------------------------------------------------------------------*/ void hq_lr_enc( Encoder_State *st, /* i/o: encoder state structure */ float t_audio[], /* i/o: transform-domain coefs. */ const short inner_frame, /* i : inner frame length */ short *num_bits, /* i/o: number of available bits */ const short is_transient /* i : transient flag */ ) { short i, k1, k2; short bit_budget, pbits; short bands, length, ni_seed, gqlevs, gqbits, Ngq, p2a_bands; short p2a_flags[BANDS_MAX]; short band_start[BANDS_MAX], band_end[BANDS_MAX], band_width[BANDS_MAX]; float band_energy[BANDS_MAX], Rk[BANDS_MAX]; Word32 Rk_fx[BANDS_MAX]; float ebits; float p2a_th, ni_coef, ni_pd_th, pd_thresh, ld_slope; Word32 L_qint; /* Q29 */ Word16 eref_fx; /* Q10 */ Word16 bit_alloc_weight_fx; /* Q13 */ short k_sort[BANDS_MAX]; int npulses[BANDS_MAX]; int inp_vector[L_FRAME48k]; float y2[L_FRAME48k]; float y2_ni[L_FRAME48k]; short hqswb_clas; short lowlength; short highlength; float m[L_FRAME32k]; short har_bands; float Ep[BANDS_MAX], enerH = 0.0f, enerL = 0.0f; short lowband, highband, bw_low = 0, bw_high = 20; float band_energy_tmp[BANDS_MAX]; long bwe_br; short trans_bit, p2a_flags_tmp[BANDS_MAX]; short adjustFlag = 0; short prev_SWB_peak_pos_tmp[SPT_SHORTEN_SBNUM]; int k,j; short flag_spt; short org_band_start[SPT_SHORTEN_SBNUM]; short org_band_end[SPT_SHORTEN_SBNUM]; short org_band_width[SPT_SHORTEN_SBNUM]; short new_band_start[SPT_SHORTEN_SBNUM]; short new_band_end[SPT_SHORTEN_SBNUM]; short new_band_width[SPT_SHORTEN_SBNUM]; short bws_cnt=0; Word32 L_tmp,L_tmp2,L_tmp3; Word16 exp,tmp,exp2,tmp1,tmp2,tmp3,alpha_fx,frac1; Word32 enerH_fx; Word32 enerL_fx; Word32 Ep_fx[BANDS_MAX]; Word32 Ep_avrg_fx, Ep_vari_fx; Word32 Ep_avrgL_fx; Word32 Ep_peak_fx; Word32 Ep_tmp_fx[BANDS_MAX]; Word16 gama_fx;/*Q15 0.85f; */ Word16 beta_fx;/*Q14 1.05f; */ Word32 L_band_energy[BANDS_MAX],L_band_energy_tmp[BANDS_MAX]; UWord16 lo; Word16 Q_band_energy; set_f( y2, 0.0f, L_FRAME48k ); set_i( inp_vector, 0, inner_frame ); flag_spt = 0; set_s(prev_SWB_peak_pos_tmp, 0, SPT_SHORTEN_SBNUM); bwe_br = st->core_brate; hqswb_clas = HQ_NORMAL; if( st->bwidth == SWB && (bwe_br == HQ_16k40 || bwe_br == HQ_13k20) ) { if ( is_transient == 1 ) { hqswb_clas = HQ_TRANSIENT; } else { /* classification of HQ_HARMONIC and HQ_NORMAL frames for SWB BWE */ hqswb_clas = peak_avrg_ratio( st->total_brate, t_audio, NUMC_N, &st->mode_count, &st->mode_count1); } /* write the classification information into the bitstream */ push_indice( st, IND_HQ2_SWB_CLAS, hqswb_clas, 2 ); (*num_bits) -= 2; if( hqswb_clas == HQ_NORMAL ) { flag_spt = 1; } } else { /* write the transient bit into the bitstream */ push_indice( st, IND_HQ2_SWB_CLAS, is_transient, 1 ); /* subtract one bit for the transient flag */ (*num_bits)--; } /* Configure encoder for different bandwidths, bit rates, etc. */ hq2_core_configure( inner_frame, *num_bits, is_transient, &bands, &length, band_width, band_start, band_end, &L_qint, &eref_fx, &bit_alloc_weight_fx, &gqlevs, &Ngq, &p2a_bands, &p2a_th, &pd_thresh, &ld_slope, &ni_coef, &ni_pd_th, bwe_br ); highlength = band_end[bands-1]; har_bands = bands; if( st->bwidth == SWB && is_transient == 0 && (bwe_br == HQ_16k40 || bwe_br == HQ_13k20) ) { /* reserve bits for HQ_NORMAL and HQ_HARMONIC modes */ if( hqswb_clas == HQ_NORMAL || hqswb_clas == HQ_HARMONIC ) { (*num_bits) -= (short)get_usebit_npswb(hqswb_clas); } } if( (bwe_br == HQ_16k40 || bwe_br == HQ_13k20) && st->bwidth == SWB ) { if( st->prev_hqswb_clas != HQ_NORMAL ) { j = 0; for( k=bands-SPT_SHORTEN_SBNUM; kprev_SWB_peak_pos[j] = 0; j++; } } } /* Check if input frame is larger than coded bandwidth */ if( inner_frame > length && is_transient ) { /* If so, collapse transient frame (4 short transforms) to remove uncoded coefficients */ for( i = 1; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) { k1 = i*length/NUM_TIME_SWITCHING_BLOCKS; k2 = i*inner_frame/NUM_TIME_SWITCHING_BLOCKS; mvr2r( &t_audio[k2], &t_audio[k1], length/NUM_TIME_SWITCHING_BLOCKS ); } } /* Spectral energy calculation/quantization */ ebits = band_energy_quant( st, t_audio, band_start, band_end, band_energy, bands, L_qint, eref_fx, is_transient ); for( i = 0; i < bands; i++) { L_band_energy[i] = (Word32)(band_energy[i] * pow(2.0f, SWB_BWE_LR_Qbe)); } /* First pass bit budget for TCQ of spectral band information */ gqbits = (short int) log2_f ((float) gqlevs); bit_budget = (*num_bits) - (short) ceil (ebits) - Ngq * gqbits; pbits = 0; if( st->bwidth == SWB && (bwe_br == HQ_16k40 || bwe_br == HQ_13k20) ) { if( hqswb_clas == HQ_HARMONIC ) { set_s( p2a_flags, 1, har_bands ); } else { /* High band tonality detector based on per band peak-to-average ratio */ pbits = p2a_threshold_quant( st, t_audio, band_start, band_end, band_width, bands, p2a_bands, p2a_th, p2a_flags ); bit_budget -= pbits; if( hqswb_clas == HQ_NORMAL ) { return_bits_normal2( &bit_budget, p2a_flags, bands, bits_lagIndices ); } } } else { /* High band tonality detector based on per band peak-to-average ratio */ pbits = p2a_threshold_quant( st, t_audio, band_start, band_end, band_width, bands, p2a_bands, p2a_th, p2a_flags ); bit_budget -= pbits; } if( flag_spt == 1 ) { /* initalize the desired parameters for SPT */ spt_shorten_domain_band_save( bands, band_start, band_end, band_width, org_band_start, org_band_end, org_band_width ); spt_shorten_domain_pre( band_start, band_end, st->prev_SWB_peak_pos, bands, bwe_br, new_band_start, new_band_end, new_band_width ); spt_shorten_domain_set( st, t_audio, p2a_flags, new_band_start, new_band_end, new_band_width, bands, band_start, band_end, band_width, &bit_budget ); } /* Estimate number of bits per band */ Q_band_energy = SWB_BWE_LR_Qbe; FOR(i = 0; i < bands; i++) { L_tmp = L_shl(L_band_energy[i],sub(16,Q_band_energy));/*Q16 */ frac1 = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */ L_tmp = Pow2(30, frac1); exp = sub(exp, 30); Ep_fx[i] = L_shl(L_tmp , sub(exp,6)); /* Q -6 */ Ep[i] = (float)(Ep_fx[i]/pow(2.0,-6)); } FOR( i = 0; i < bands; i++ ) { L_tmp2 = Ep_fx[i]; L_tmp = L_max(1, L_tmp2); exp = norm_l(L_tmp); tmp = extract_h(L_shl(L_tmp, exp)); L_tmp3 = (Word32)band_width[i]; exp2 = norm_l(L_tmp3); tmp2 = extract_h(L_shl(L_tmp3, exp2)); exp2 = sub(exp, exp2); /* Denormalize and substract */ tmp3 = sub(tmp2, tmp); IF (tmp3 > 0) { tmp2 = shr(tmp2, 1); } IF (tmp3 > 0) { exp2 = add(exp2, 1); } tmp = div_s(tmp2, tmp); L_tmp = L_deposit_h(tmp); L_tmp = Isqrt_lc1(L_tmp, &exp2); move32();/*Q(31-exp2) */ Ep_tmp_fx[i] = L_shr(L_tmp,sub(15,exp2));/*Q13 */ } if ( is_transient == 0 && inner_frame == L_FRAME8k && st->core_brate <= ACELP_13k20 ) { lowband = 6; move16(); trans_bit = 2; move16(); bit_budget =sub(bit_budget,trans_bit); gama_fx = 27852; /*Q15 0.85f; */ beta_fx = 17203; move16();/*Q14 1.05f; */ set_s( &p2a_flags_tmp[bands-trans_bit], 0, 2 ); IF( st->core_brate == ACELP_13k20 ) { beta_fx = 13107; move16();/*14 1.25f; */ gama_fx = 31130; move16();/*0.95f; */ mvs2s(&p2a_flags[sub(bands,trans_bit)], &p2a_flags_tmp[sub(bands,trans_bit)], trans_bit); } /* calculate the the low band/high band energy and the variance/avrage of the envelopes */ Ep_vari_fx = 0; move32(); Ep_avrg_fx = 0; move32(); Ep_avrgL_fx = 0; move32(); Ep_peak_fx = 0; move32(); FOR( i = 0; i < bands; i++ ) { IF( sub(i,lowband) >= 0) { Ep_vari_fx = L_add(Ep_vari_fx,L_abs(L_sub(Ep_tmp_fx[i],Ep_tmp_fx[sub(i,1)])));/*Q15 */ Ep_avrg_fx = L_add(Ep_avrg_fx,Ep_tmp_fx[i]);/*Q15 */ } ELSE { Ep_avrgL_fx = L_add(Ep_avrgL_fx,Ep_tmp_fx[i]);/*Q15 */ IF(L_sub(Ep_tmp_fx[i],Ep_peak_fx) > 0) { Ep_peak_fx = Ep_tmp_fx[i]; move32();/*Q15 */ } } } /* modify the last p2a_bands subbands band_energies */ k = (int)bands; mvi2i( L_band_energy,L_band_energy_tmp,k); /*Q_band_energy */ Mpy_32_16_ss(Ep_peak_fx,24576,&L_tmp,&lo); Mpy_32_16_ss(Ep_peak_fx,shl(sub(bands,lowband),9),&L_tmp2,&lo); Mpy_32_16_ss(Ep_avrg_fx,1126,&L_tmp3,&lo); IF(( (L_sub(L_tmp, L_shr(Ep_avrgL_fx,1)) < 0 && st->core_brate == ACELP_13k20 ) || st->core_brate < ACELP_13k20 )&& L_sub(L_tmp2, L_tmp3) < 0 && L_sub(L_tmp2, L_shr(Ep_avrg_fx,7)) > 0) { FOR(i = lowband; i < bands; i++) { Mpy_32_16_ss(Ep_avrg_fx,24576,&L_tmp,&lo); IF(L_sub(L_shr(Ep_tmp_fx[i],1), L_tmp) < 0) { Mpy_32_16_ss(Ep_peak_fx,sub(bands,lowband),&L_tmp,&lo); tmp = extract_h(L_shl(L_tmp,14));/*Q-4 */ IF(tmp != 0) { exp = norm_s(tmp); tmp = shl(tmp,exp);/*Q(exp) */ tmp = div_s(16384,tmp);/*Q(15+14-exp=29-exp) */ exp = sub(29,exp); } ELSE { tmp = 0x7fff; move16(); exp = 0; move16(); } Mpy_32_16_ss(Ep_avrg_fx,tmp,&L_tmp,&lo); L_tmp = L_shl(L_tmp,sub(13,exp));/*Q(13+exp-15 +13-exp +4 = 15) */ L_tmp2 = L_add(L_tmp,13107); /*15 */ tmp2 = extract_l(L_min(L_max(L_tmp2,16384),gama_fx)); /*15 = 15 */ Mpy_32_16_ss(L_band_energy_tmp[i],tmp2,&L_band_energy_tmp[i],&lo); } } } ELSE { FOR(i = sub(bands,trans_bit); i < bands; i++) { alpha_fx = 16384; move16();/*Q14 */ IF( sub(p2a_flags_tmp[i],1) == 0) { Mpy_32_16_ss(Ep_tmp_fx[i],sub(bands,lowband),&L_tmp,&lo); tmp = extract_h(L_shl(L_tmp,14));/*Q-4 */ IF(tmp != 0) { exp = norm_s(tmp); tmp = shl(tmp,exp);/*Q(exp) */ tmp = div_s(16384,tmp);/*Q(15+14-exp=29-exp) */ exp = sub(29,exp); } ELSE { tmp = 0x7fff; move16(); exp = 0; move16(); } Mpy_32_16_ss(Ep_vari_fx,3277,&L_tmp,&lo); Mpy_32_16_ss(L_tmp,tmp,&L_tmp,&lo); L_tmp = L_shl(L_tmp,sub(12,exp));/*Q(13+exp-15 +12-exp +4 = 14) */ tmp2 = extract_h(Ep_avrg_fx);/*Q13-16=-3 */ IF(tmp2 != 0) { exp = norm_s(tmp2); tmp2 = shl(tmp2,exp);/*Q(exp) */ tmp2 = div_s(16384,tmp2);/*Q(15+14-exp=29-exp) */ exp = sub(29,exp); } ELSE { tmp2 = 0x7fff; move16(); exp = 0; move16(); } Mpy_32_16_ss(Ep_vari_fx,6554,&L_tmp2,&lo); Mpy_32_16_ss(L_tmp2,tmp2,&L_tmp2,&lo); L_tmp2 = L_shl(L_tmp2,sub(13,exp));/*Q(13+exp-15 +13-exp +3 = 14) */ L_tmp=L_min(L_tmp,L_tmp2);/*14 */ tmp=extract_l(L_min(L_tmp,13107));/*14 */ alpha_fx =add(16384,tmp); } IF(sub(st->last_bitalloc_max_band[i],1) == 0) { Mpy_32_16_ss(Ep_tmp_fx[i],sub(bands,lowband),&L_tmp,&lo); tmp = extract_h(L_shl(L_tmp,14));/*Q-2 */ IF(tmp != 0) { exp = norm_s(tmp); tmp = shl(tmp,exp);/*Q(exp) */ tmp = div_s(16384,tmp);/*Q(15+14-exp=29-exp) */ exp = sub(29,exp); } ELSE { tmp = 0x7fff; move16(); exp = 0; move16(); } Mpy_32_16_ss(Ep_avrg_fx,tmp,&L_tmp,&lo); L_tmp = L_shl(L_tmp,sub(14,exp));/*Q(13+exp-15 +14-exp+2 = 14) */ L_tmp =L_max(L_tmp,16384); /*14 */ tmp=extract_l(L_min(L_tmp,beta_fx)); /*14 */ alpha_fx=shl(mult(alpha_fx,tmp),1);/*14+14-15 +1=14 */ } ELSE { tmp2 = extract_h(Ep_avrg_fx);/*13 -16 =-3 */ IF(tmp2 != 0) { exp = norm_s(tmp2); tmp2 = shl(tmp2,exp);/*Q(exp) */ tmp2 = div_s(16384,tmp2);/*Q(15+14-exp=29-exp) */ exp = sub(29,exp); } ELSE { tmp2 = 0x7fff; move16(); exp = 0; move16(); } Mpy_32_16_ss(Ep_tmp_fx[i],tmp2,&L_tmp,&lo); L_tmp = L_shl(L_tmp,sub(19,exp));/*Q(13+exp-15 +19-exp +3 = 20) */ Mpy_32_16_ss(L_tmp,shl(sub(bands,lowband),9),&L_tmp,&lo); L_tmp =L_max(L_tmp,13926); /*14 */ tmp2 =extract_l(L_min(L_tmp,16384)); /*14 */ alpha_fx=shl(mult(alpha_fx,tmp2),1);/*14+14-15+1 =14 */ } Mpy_32_16_ss(L_band_energy_tmp[i],alpha_fx,&L_tmp,&lo); L_band_energy_tmp[i] = L_shl(L_tmp,1);/*Q(Q_band_energy+14-15 +1= Q_band_energy) */ } } lowband = 3; move16(); Ep_avrg_fx = 0; move32(); Ep_avrgL_fx = 0; move32(); Ep_peak_fx = 0; move32(); FOR(i = 0; i < bands; i++) { IF(sub(i,lowband) >=0 ) { Ep_avrg_fx = L_add(Ep_avrg_fx,Ep_tmp_fx[i]);/*Q15 */ } ELSE { Ep_avrgL_fx = L_add(Ep_avrgL_fx,L_shr(Ep_tmp_fx[i],1));/*Q12 */ IF(L_sub(Ep_tmp_fx[i],Ep_peak_fx) > 0) { Ep_peak_fx = Ep_tmp_fx[i]; move32();/*Q13 */ } } } Mpy_32_16_ss(Ep_peak_fx,28262,&L_tmp,&lo); Mpy_32_16_ss(Ep_avrgL_fx,24576,&L_tmp2,&lo); IF( L_sub(L_shr(Ep_avrg_fx,2), L_tmp2) > 0 && L_sub(L_shr(Ep_avrg_fx,4), L_tmp2) < 0 && L_sub(L_tmp, Ep_avrgL_fx)>0) { adjustFlag = 1; move16(); FOR (i = 0; i < lowband; i++) { tmp = extract_h(Ep_avrgL_fx);/*Q-4 */ IF(tmp != 0) { exp = norm_s(tmp); tmp = shl(tmp,exp);/*Q(exp) */ tmp = div_s(16384,tmp);/*Q(15+14-exp=29-exp) */ exp = sub(29,exp); } ELSE { tmp = 0x7fff; move16(); exp = 0; move16(); } Mpy_32_16_ss(Ep_peak_fx,tmp,&L_tmp,&lo); Mpy_32_16_ss(L_tmp,lowband,&L_tmp,&lo); Mpy_32_16_ss(L_tmp,18842,&L_tmp,&lo); L_tmp = L_shl(L_tmp,sub(27,exp));/*Q14 0.5 */ tmp2=extract_l(L_min(L_tmp,19661));/*14 */ Mpy_32_16_ss(L_band_energy_tmp[i],tmp2,&L_tmp,&lo); L_band_energy_tmp[i] = L_shl(L_tmp,1); /*Q_band_energy */ } } for (i = 0; i < bands; i++) { band_energy_tmp[i] = (float)(L_band_energy_tmp[i]/pow(2.0f, SWB_BWE_LR_Qbe)); } hq2_bit_alloc( band_energy_tmp, bands, Rk_fx, &bit_budget, p2a_flags, bit_alloc_weight_fx, band_width, *num_bits, hqswb_clas, st->bwidth, is_transient ); /* encode the last p2a_bands-1 subbands bit-allocation index of the previous frame */ for(i = 1; i <= trans_bit; i++) { push_indice ( st, IND_HQ2_LAST_BA_MAX_BAND, st->last_bitalloc_max_band[bands-i], 1 ); } } else if( is_transient == 0 && inner_frame == L_FRAME16k ) { bit_budget = sub(bit_budget,2);/* bits in high bands to indicate the last 2 subbands is allocated bits or not */ FOR( i = 0; i < bands; i++ ) { Ep_tmp_fx[i] = L_shl(Ep_tmp_fx[i],2); } IF( st->core_brate == ACELP_13k20 ) { lowband = 8; move16(); highband = 15; move16(); bw_low = sub(band_start[highband],band_start[lowband]); bw_high = sub(add(band_end[sub(bands,1)],1),band_start[highband]); } ELSE { lowband = 8; move16(); highband = 16; move16(); bw_low = sub(band_start[highband],band_start[lowband]); bw_high = sub(add(band_end[sub(bands,1)],1),band_start[highband]); } /* calculate the the low band/high band energy and the variance/avrage of the envelopes */ enerL_fx = 0; move32(); enerH_fx = 0; move32(); Ep_vari_fx = 0; move32(); Ep_avrg_fx = 0; move32(); FOR( i = 0; i < bands; i++ ) { IF( sub(i,lowband) >= 0 && add(sub(i,bands),p2a_bands) < 0) { Ep_vari_fx = L_add(Ep_vari_fx,L_abs(L_sub(Ep_tmp_fx[i],Ep_tmp_fx[sub(i,1)])));/*Q15 */ Ep_avrg_fx = L_add(Ep_avrg_fx,Ep_tmp_fx[i]);/*Q15 */ } IF(sub(i,highband) >= 0) { enerH_fx = L_add(enerH_fx,L_shl(Ep_fx[i],2));/*Q0 */ } ELSE IF(sub(i,lowband) >= 0) { enerL_fx = L_add(enerL_fx,L_shl(Ep_fx[i],2));/*Q0 */ } } enerL = (float)(enerL_fx/pow(2.0,-4)); enerH = (float)(enerH_fx/pow(2.0,-4)); /* modify the last p2a_bands subbands band_energies */ k = (int)bands; mvi2i( L_band_energy,L_band_energy_tmp,k); /*Q_band_energy */ L_tmp = L_max(enerH_fx,enerL_fx); tmp = s_max(bw_low,bw_high); i = norm_l(L_tmp); j = norm_s(tmp); Mpy_32_16_ss(L_shl(enerH_fx,i),shl(bw_low,j),&L_tmp,&lo); Mpy_32_16_ss(L_shl(enerL_fx,i),shl(bw_high,j),&L_tmp2,&lo); L_tmp2 = L_sub(L_tmp,L_tmp2); FOR( i = sub(bands,p2a_bands); i < bands; i++ ) { IF( sub(p2a_flags[i],1) == 0 || L_tmp2 > 0 ) { tmp = sub(bands,p2a_bands); tmp = sub(tmp,lowband);/*Q0 */ tmp1 = extract_h(L_shl(Ep_avrg_fx,1));/*Q0 */ IF(tmp1 != 0) { exp = norm_s(tmp1); tmp1 = shl(tmp1,exp);/*Q(exp) */ tmp1 = div_s(16384,tmp1);/*Q(15+14-exp = 29-exp) */ exp = sub(29,exp); } ELSE { tmp1 = 0x7fff; move16(); exp = 0; move16(); } Mpy_32_16_ss(Ep_tmp_fx[i],tmp1,&L_tmp,&lo); Mpy_32_16_ss(L_tmp,tmp,&L_tmp,&lo); Mpy_32_16_ss(L_tmp,16384,&L_tmp,&lo); L_tmp = L_shl(L_tmp,sub(32,exp));/*Q15 */ tmp = extract_l(L_min(L_tmp,6554));/*Q15 */ Mpy_32_16_ss(Ep_vari_fx,tmp1,&L_tmp,&lo); Mpy_32_16_ss(L_tmp,tmp,&L_tmp,&lo); L_tmp = L_shl(L_tmp,sub(15,exp));/*Q15 */ tmp = extract_l(L_shr(L_min(L_tmp,13107),1));/*Q14 */ alpha_fx = add(tmp,16384);/*Q14 */ } ELSE { alpha_fx = 16384; move16();/*Q14 */ } IF(add(sub(i,bands),p2a_bands) > 0) { IF(sub(st->last_bitalloc_max_band[i],1) == 0) { tmp = sub(bands,p2a_bands); tmp = sub(tmp,lowband); Mpy_32_16_ss(Ep_tmp_fx[i],tmp,&L_tmp,&lo); tmp = extract_h(L_shl(L_tmp,16));/*Q0 */ IF(tmp != 0) { exp = norm_s(tmp); tmp = shl(tmp,exp);/*Q(exp) */ tmp = div_s(16384,tmp);/*Q(15+14-exp=29-exp) */ exp = sub(29,exp); } ELSE { tmp = 0x7fff; move16(); exp = 0; move16(); } Mpy_32_16_ss(Ep_avrg_fx,tmp,&L_tmp,&lo); L_tmp = L_shl(L_tmp,sub(14,exp));/*Q14 */ tmp = extract_l(L_min(L_max(L_tmp,16384),20480));/*Q14 */ L_tmp = L_mult(alpha_fx,tmp);/*Q(14+14+1=29) */ alpha_fx = extract_l(L_shr(L_tmp,15)); /*Q14*/ } ELSE { tmp = sub(bands,p2a_bands); tmp = sub(tmp,lowband); tmp1 = extract_h(L_shl(Ep_avrg_fx,1));/*Q0 */ IF(tmp1 != 0) { exp = norm_s(tmp1); tmp1 = shl(tmp1,exp);/*Q(exp) */ tmp1 = div_s(16384,tmp1);/*Q(15+14-exp=29-exp) */ exp = sub(29,exp); } ELSE { tmp1 = 0x7fff; move16(); exp = 0; move16(); } Mpy_32_16_ss(Ep_tmp_fx[i],tmp1,&L_tmp,&lo); Mpy_32_16_ss(L_tmp,tmp,&L_tmp,&lo); L_tmp = L_shl(L_tmp,sub(29,exp));/*Q14 */ tmp = extract_l(L_min(L_max(L_tmp,13926),16384));/*Q14 */ L_tmp = L_mult(alpha_fx,tmp);/*Q(14+14+1=29) */ alpha_fx = extract_l(L_shr(L_tmp,15)); /*Q14 */ } } Mpy_32_16_ss(L_band_energy_tmp[i],alpha_fx,&L_tmp,&lo); L_band_energy_tmp[i] = L_shl(L_tmp,1);/*Q Q_band_energy */ } lowband = 6; move16(); Ep_avrg_fx = 0; move32(); Ep_avrgL_fx = 0; move32(); Ep_peak_fx = 0; move32(); FOR(i = 0; i < bands; i++) { IF(sub(i,lowband) >= 0) { Ep_avrg_fx = L_add(Ep_avrg_fx,Ep_tmp_fx[i]);/*Q15 */ } ELSE { Ep_avrgL_fx = L_add(Ep_avrgL_fx,Ep_tmp_fx[i]);/*Q15 */ IF(L_sub(Ep_tmp_fx[i],Ep_peak_fx) > 0) { Ep_peak_fx = Ep_tmp_fx[i]; move32();/*Q15 */ } } } Mpy_32_16_ss(Ep_peak_fx,24576,&L_tmp,&lo); Mpy_32_16_ss(Ep_peak_fx,19661,&L_tmp2,&lo); Mpy_32_16_ss(Ep_avrgL_fx,24576,&L_tmp3,&lo); IF( (L_sub(L_shr(Ep_avrgL_fx,1), Ep_avrg_fx)>0 && L_sub(L_tmp,L_shr(Ep_avrgL_fx,2)) > 0 && L_sub(L_shr(Ep_avrgL_fx,1),L_tmp2) < 0 ) || (L_sub(L_shr(Ep_avrg_fx,1), Ep_avrgL_fx)>0 && L_sub(L_shr(Ep_avrg_fx,3),L_tmp3) < 0 && L_sub(L_tmp,L_shr(Ep_avrgL_fx,2)) > 0 ) ) { adjustFlag = 1; move16(); FOR (i = 0; i < lowband; i++) { tmp = extract_h(L_shl(Ep_avrgL_fx,1));/*Q0 */ IF(tmp != 0) { exp = norm_s(tmp); tmp = shl(tmp,exp);/*Q(exp) */ tmp = div_s(16384,tmp);/*Q(15+14-exp=29-exp) */ exp = sub(29,exp); } ELSE { tmp = 0x7fff; move16(); exp = 0; move16(); } Mpy_32_16_ss(Ep_peak_fx,tmp,&L_tmp,&lo); Mpy_32_16_ss(L_tmp,lowband,&L_tmp,&lo); L_tmp = L_shl(L_tmp,sub(28,exp));/*Q14 0.5 */ tmp = extract_l(L_min(L_tmp,19661));/*Q14 */ Mpy_32_16_ss(L_band_energy_tmp[i],tmp,&L_tmp,&lo); L_band_energy_tmp[i] = L_shl(L_tmp,1); /*Q_band_energy */ } } for (i = 0; i < bands; i++) { band_energy_tmp[i] = (float)(L_band_energy_tmp[i]/pow(2.0f, SWB_BWE_LR_Qbe)); } hq2_bit_alloc( band_energy_tmp, bands, Rk_fx, &bit_budget, p2a_flags, bit_alloc_weight_fx, band_width, *num_bits, hqswb_clas, st->bwidth, is_transient ); /* encode the last p2a_bands-1 subbands bit-allocation index of the previous frame */ for(i = 1; i < p2a_bands; i++) { push_indice( st, IND_HQ2_LAST_BA_MAX_BAND, st->last_bitalloc_max_band[bands-i], 1 ); } } else if( st->bwidth == SWB && hqswb_clas == HQ_HARMONIC && (bwe_br == HQ_16k40 || bwe_br == HQ_13k20) ) { /* bit allocation for harmonic mode */ hq2_bit_alloc_har( band_energy, bit_budget, bands, Rk_fx, p2a_bands,bwe_br, p2a_flags, band_width); } else { set_s(st->last_bitalloc_max_band, 0, BANDS_MAX); /* estimate number of bits per band */ hq2_bit_alloc( band_energy, bands, Rk_fx, &bit_budget, p2a_flags, bit_alloc_weight_fx, band_width, *num_bits, hqswb_clas, st->bwidth, is_transient ); } tcq_core_LR_enc( st, inp_vector, t_audio, y2, bit_budget, bands, band_start, band_end, band_width, Rk_fx, npulses, k_sort, p2a_flags, p2a_bands, st->last_bitalloc_max_band, inner_frame, adjustFlag, is_transient ); for(i = 1; i < p2a_bands; i++) { if(npulses[bands-i] > 0) { st->last_bitalloc_max_band[bands-i] = 1; } else { st->last_bitalloc_max_band[bands-i] = 0; } } /* Prepare floating Rk for next modules */ for( k = 0; k < bands; k++) { Rk[k] = WORD322FL_SCALE( Rk_fx[k], SWB_BWE_LR_QRk - 1); } /* Denormalize the coded MDCT spectrum */ mdct_spectrum_denorm( inp_vector, y2, band_start, band_end, band_width, band_energy, npulses, bands, ld_slope, pd_thresh ); /* Apply fine gain quantization to denormalized coded spectrum */ mdct_spectrum_fine_gain_enc( st, t_audio, y2, band_start, band_end, k_sort, bands, L_qint, Ngq, gqlevs, gqbits ); /* reStore the subband information*/ if(flag_spt == 1) { spt_shorten_domain_band_restore(bands, band_start, band_end, band_width, org_band_start, org_band_end, org_band_width); } /* Inject noise into components having relatively low pulse energy per band */ ni_seed = npulses[0] + npulses[1] + npulses[2] + npulses[3]; for(i=0; ilast_ni_gain, st->last_env, &st->last_max_pos_pulse, p2a_flags, p2a_bands, hqswb_clas, st->bwidth, bwe_br ); if( st->bwidth == SWB && (bwe_br == HQ_16k40 || bwe_br == HQ_13k20) ) { if( hqswb_clas == HQ_NORMAL || hqswb_clas == HQ_HARMONIC ) { preset_hq2_swb( hqswb_clas, band_end, &har_bands, p2a_bands,length, bands, &lowlength, &highlength, m ); swb_bwe_enc_lr( st, y2, t_audio, m , bwe_br, bands, band_start, band_end, band_energy, p2a_flags, hqswb_clas, lowlength, highlength, st->prev_frm_index, har_bands, &st->prev_frm_hfe2, &st->prev_stab_hfe2,band_width, y2_ni, &ni_seed ); post_hq2_swb( m, lowlength, highlength, hqswb_clas, har_bands, bands, p2a_flags, band_start, band_end, y2, npulses ); if( hqswb_clas == HQ_NORMAL ) { spt_swb_peakpos_tmp_save(y2, bands, band_start, band_end, prev_SWB_peak_pos_tmp); for( k=0; kbwidth, is_transient, hqswb_clas, &st->prev_hqswb_clas, st->prev_SWB_peak_pos, prev_SWB_peak_pos_tmp, &st->prev_frm_hfe2, &st->prev_stab_hfe2, bws_cnt ); if( st->bwidth != SWB ) { /* reset HQ classifier memories */ st->mode_count = 0; st->mode_count1 = 0; } if( hqswb_clas != HQ_HARMONIC && (bwe_br == HQ_16k40 || bwe_br == HQ_13k20) && st->bwidth == SWB ) { st->prev_frm_index[0] = -1; st->prev_frm_index[1] = -1; } /* update number of unused bits */ *num_bits = 0; st->hvq_hangover = 0; return; } /*--------------------------------------------------------------------------* * small_symbol_enc_tran() * * Huffman encoding of differential energies, estimating or packing bits * if flag_pack = 0, LC mode info. is output else LC mode info. is input * if flag_pack = 0, estimatng else packing bits *--------------------------------------------------------------------------*/ static short small_symbol_enc_tran( /* o : bits */ Encoder_State *st, /* i/o: encoder state structure */ const int *qbidx, /* i : input of dequantized differential energy */ const short BANDS, /* i : number of bands */ short *hLCmode, /* i/o: LC mode info */ const short flag_pack, /* i : indicator of packing or estimating bits */ const short is_transient ) { short i, bits; short difidx[BANDS_MAX]; for( i=0; iLRMDCT_BE_LIMIT || difidx[i]<0) { /* Huffman cannot encode this vector */ return -1; } } /* Preparing lossless coding input */ if ( flag_pack == 0 ) { /* estimating # of bits */ bits = encode_envelope_indices(st, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN , is_transient ); bits += BITS_DE_FCOMP; /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ } else { bits = 0; encode_envelope_indices(st, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN ,is_transient ); } return bits + BITS_DE_HMODE; /* xx bits for diff. energies + 1 bit for LC coding mode */ } /*--------------------------------------------------------------------------* * small_symbol_enc() * * Huffman encoding of differential energies, estimating or packing bits * if flag_pack = 0, LC mode info. is output else LC mode info. is input * if flag_pack = 0, estimatng else packing bits *--------------------------------------------------------------------------*/ static short small_symbol_enc( /* o : bits */ Encoder_State *st, /* i/o: encoder state structure */ const int *qbidx, /* i : input of dequantized differential energy */ const short BANDS, /* i : number of bands */ short *hLCmode, /* i/o: LC mode info */ const short flag_pack, /* i : indicator of packing or estimating bits */ const short is_transient ) { short i, bits; short difidx[BANDS_MAX], LSB[BANDS_MAX]; /* Preparing lossless coding input */ difidx[0] = (short)(qbidx[0]+DE_OFFSET0); for( i=1; i=DE_LIMIT || difidx[i]<0) { /* Huffman cannot encode this vector */ return -1; } } /* splitting MSB and LSB */ for( i=0; i>= 1; } /* Preparing lossless coding input */ if ( flag_pack == 0 ) { /* estimating # of bits */ /* Encoding MSB bits */ bits = encode_envelope_indices( st, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE, is_transient ); bits += BITS_DE_FCOMP; /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ /* Encoding LSB bit packing */ bits += BANDS; } else { /* Encoding MSB bits */ bits = 0; encode_envelope_indices( st, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE, is_transient ); /* Encoding LSB bit packing */ for( i=0; iABS_ENG_OFFSET-1 || qbidx[0]<-ABS_ENG_OFFSET) { cnt_outlyer0 = 2; } else if (qbidx[0]>3 || qbidx[0]<-4) { cnt_outlyer0 = 1; } else { cnt_outlyer0 = 0; } cnt_outlyer=0; pos_outlyer = -1; for( i=1; i3 || qbidx[i]<-4) { cnt_outlyer++; pos_outlyer = i; } if (qbidx[i]>ABS_ENG_OFFSET-1 || qbidx[i]<-ABS_ENG_OFFSET) { cnt_outlyer++; } } if (cnt_outlyer0 == 0 && cnt_outlyer<=1) { bitsmode0 = BITS_DE_8SMODE + BITS_DE_8SMODE_N0 + BITS_DE_8SMODE_N1; if (cnt_outlyer == 1) { /* 01 */ bitsmode0 += BITS_DE_8SPOS + BITS_ABS_ENG; } for( i=0; imax_q) { max_q = (short)qbidx[i]; } if (qbidx[i]= -(2<<(i+1))) { break; } } basic_shift = i; min_bits=1000; min_bits_pos = basic_shift; for(offset0=basic_shift; offset0>offset0)+4]+(offset0)); } if (min_bits>bitsmode1) { min_bits_pos = offset0; min_bits = bitsmode1; } } bitsmode1 = min_bits; lsbdepth1 = min_bits_pos; for( i=0; i>lsbdepth1; } } /* Preparing lossless coding input */ if ( flag_pack == 0 ) { /* estimating # of bits */ /* Encoding MSB bits */ if (bitsmode0 0) { for(i=0; iMAXIMUM_ENERGY_LOWBRATE) { bq2[i] = MAXIMUM_ENERGY_LOWBRATE; } if (bq2[i] Qbe(Q14) */ band_energy[k] = (float)(L_band_energy[k]/pow(2.0f, SWB_BWE_LR_Qbe)); } if( is_transient ) { reverse_transient_frame_energies( band_energy, bands ); } return( deng_bits ); } /*-------------------------------------------------------------------* * p2a_threshold_quant() * * *-------------------------------------------------------------------*/ static short p2a_threshold_quant( Encoder_State *st, /* i/o: encoder state structure */ const float *t_audio, const short band_start[], const short band_end[], const short band_width[], const short bands, const short p2a_bands, const float p2a_th, short *p2a_flags ) { short i, j, k; float p, a, e; float p2a; set_s( p2a_flags, 1, bands ); j = 0; for (k = bands - p2a_bands; k < bands; k++) { a = 0.0f; p = 0.0f; for (i = band_start[k]; i <= band_end[k]; i++) { e = t_audio[i] * t_audio[i]; if (e > p) { p = e; } a += e; } if (a > 0.0f) { a /= band_width[k]; p2a = 10.0f * (float) log10 (p / a); if (p2a <= p2a_th) { p2a_flags[k] = 0; } } push_indice( st, IND_HQ2_P2A_FLAGS, p2a_flags[k], 1 ); j++; } return( j ); } /*-------------------------------------------------------------------* * mdct_spectrum_fine_gain_enc() * * *-------------------------------------------------------------------*/ static void mdct_spectrum_fine_gain_enc( Encoder_State *st, /* i/o: encoder state structure */ const float ybuf[], float y2[], const short band_start[], const short band_end[], const short k_sort[], const short bands, const Word32 L_qint, const short Ngq, const short gqlevs, const short gqbits ) { short i, k, imin; float Eyy, Exy, gamma; float dmin, d; float gain_table[MAX_GQLEVS]; Word16 exp_normn, exp_normd; Word16 delta_fx, Qdelta; Word32 L_delta, L_q; Word32 L_temp; Word16 gain_table_fx[MAX_GQLEVS]; Word16 Qgt; Word16 temp_lo_fx, temp_hi_fx; /* Fine gain quantization on only the most significant energy bands */ /*delta = qint / gqlevs; */ exp_normn = norm_l(L_qint); exp_normn = sub(exp_normn, 1); exp_normd = norm_s(gqlevs); delta_fx = div_l(L_shl(L_qint, exp_normn), shl(gqlevs, exp_normd)); Qdelta = add(sub(exp_normn, exp_normd), 28); /* 29+exp_normn-(exp_normd)-1; */ L_delta = L_shl(L_deposit_h(delta_fx), sub(13, Qdelta)); /*q = (-qint + delta) / 2.0f; */ L_q = L_shr(L_sub(L_delta, L_qint), 1); FOR (i = 0; i < gqlevs; i++) { /*gain_table[i] = (float) pow (2.0f, q * 0.5f); */ L_temp = L_shr(L_shr(L_q, 1), sub(29, 16)); temp_lo_fx = L_Extract_lc(L_temp, &temp_hi_fx); Qgt = sub(14, temp_hi_fx); gain_table_fx[i] = extract_l(Pow2(14, temp_lo_fx)); /* Qgt */ /*q += delta; */ L_q = L_add(L_q, L_delta); gain_table_fx[i] = shl(gain_table_fx[i], sub(14, Qgt)); /* Qgt -> Q14 */ gain_table[i] = (float)(gain_table_fx[i]/pow(2.0f, 14)); } for (k = bands - Ngq; k < bands; k++) { Eyy = 0.0f; Exy = 0.0f; for (i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++) { Eyy += y2[i] * y2[i]; Exy += ybuf[i] * y2[i]; } if (Eyy > 0.0f && Exy > 0.0f) { gamma = Exy / Eyy; dmin = FLT_MAX; imin = -1; for (i = 0; i < gqlevs; i++) { d = (float) fabs (gamma - gain_table[i]); if (d < dmin) { dmin = d; imin = i; } } gamma = gain_table[imin]; for (i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++) { y2[i] *= gamma; } } else { imin = 0; } push_indice( st, IND_HQ2_SUBBAND_GAIN, imin, gqbits ); } return; }