static Word16 Vq_subvec (/* o : quantization index, Q0 */ Word16 *lsf_r1, /* i : 1st LSF residual vector, Q15 */ Word16 *lsf_r2, /* i : 2nd LSF residual vector, Q15 */ const Word16 *dico, /* i : quantization codebook, Q15 */ Word16 *wf1, /* i : 1st LSF weighting factors Q13 */ Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */ Word16 dico_size /* i : size of quantization codebook, Q0 */ ) { Word16 index = 0; /* initialization only needed to keep gcc silent */ Word16 i, temp; const Word16 *p_dico; Word32 dist_min, dist; dist_min = MAX_32; move32 (); p_dico = dico; move16 (); for (i = 0; i < dico_size; i++) { temp = sub (lsf_r1[0], *p_dico++); temp = mult (wf1[0], temp); dist = L_mult (temp, temp); temp = sub (lsf_r1[1], *p_dico++); temp = mult (wf1[1], temp); dist = L_mac (dist, temp, temp); temp = sub (lsf_r2[0], *p_dico++); temp = mult (wf2[0], temp); dist = L_mac (dist, temp, temp); temp = sub (lsf_r2[1], *p_dico++); temp = mult (wf2[1], temp); dist = L_mac (dist, temp, temp); test (); if (L_sub (dist, dist_min) < (Word32) 0) { dist_min = dist; move32 (); index = i; move16 (); } } /* Reading the selected vector */ p_dico = &dico[shl (index, 2)]; move16 (); lsf_r1[0] = *p_dico++; move16 (); lsf_r1[1] = *p_dico++; move16 (); lsf_r2[0] = *p_dico++; move16 (); lsf_r2[1] = *p_dico++; move16 (); return index; }
void dtx_dec_activity_update(dtx_decState *st, Word16 lsf[], Word16 frame[]) { Word16 i; Word32 L_frame_en; Word16 log_en_e, log_en_m, log_en; /* update lsp history */ st->lsf_hist_ptr = add(st->lsf_hist_ptr,M); move16(); test(); if (sub(st->lsf_hist_ptr, 80) == 0) { st->lsf_hist_ptr = 0; move16(); } Copy(lsf, &st->lsf_hist[st->lsf_hist_ptr], M); /* compute log energy based on frame energy */ L_frame_en = 0; /* Q0 */ move32(); for (i=0; i < L_FRAME; i++) { L_frame_en = L_mac(L_frame_en, frame[i], frame[i]); } Log2(L_frame_en, &log_en_e, &log_en_m); /* convert exponent and mantissa to Word16 Q10 */ log_en = shl(log_en_e, 10); /* Q10 */ log_en = add(log_en, shr(log_en_m, 15-10)); /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */ log_en = sub(log_en, 7497+1024); /* insert into log energy buffer, no division by two as * * log_en in decoder is Q11 */ st->log_en_hist_ptr = add(st->log_en_hist_ptr, 1); test(); if (sub(st->log_en_hist_ptr, DTX_HIST_SIZE) == 0) { st->log_en_hist_ptr = 0; move16(); } st->log_en_hist[st->log_en_hist_ptr] = log_en; /* Q11 */ move16(); }
/************************************************************************* * * FUNCTION: Pitch_ol * * PURPOSE: Compute the open loop pitch lag. * * DESCRIPTION: * The open-loop pitch lag is determined based on the perceptually * weighted speech signal. This is done in the following steps: * - find three maxima of the correlation <sw[n],sw[n-T]>, * dividing the search range into three parts: * pit_min ... 2*pit_min-1 * 2*pit_min ... 4*pit_min-1 * 4*pit_min ... pit_max * - divide each maximum by <sw[n-t], sw[n-t]> where t is the delay at * that maximum correlation. * - select the delay of maximum normalized correlation (among the * three candidates) while favoring the lower delay ranges. * *************************************************************************/ Word16 Pitch_ol ( /* o : open loop pitch lag */ vadState *vadSt, /* i/o : VAD state struct */ enum Mode mode, /* i : coder mode */ Word16 signal[], /* i : signal used to compute the open loop pitch */ /* signal[-pit_max] to signal[-1] should be known */ Word16 pit_min, /* i : minimum pitch lag */ Word16 pit_max, /* i : maximum pitch lag */ Word16 L_frame, /* i : length of frame to compute pitch */ Word16 idx, /* i : frame index */ Flag dtx /* i : dtx flag; use dtx=1, do not use dtx=0 */ ) { Word16 i, j; Word16 max1, max2, max3; Word16 p_max1, p_max2, p_max3; Word16 scal_flag = 0; Word32 t0; #ifdef VAD2 Word32 r01, r02, r03; Word32 rmax1, rmax2, rmax3; #else Word16 corr_hp_max; #endif Word32 corr[PIT_MAX+1], *corr_ptr; /* Scaled signal */ Word16 scaled_signal[L_FRAME + PIT_MAX]; Word16 *scal_sig, scal_fac; #ifndef VAD2 if (dtx) { /* no test() call since this if is only in simulation env */ /* update tone detection */ test(); test(); if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0)) { vad_tone_detection_update (vadSt, 1); } else { vad_tone_detection_update (vadSt, 0); } } #endif scal_sig = &scaled_signal[pit_max]; move16 (); t0 = 0L; move32 (); for (i = -pit_max; i < L_frame; i++) { t0 = L_mac (t0, signal[i], signal[i]); } /*--------------------------------------------------------* * Scaling of input signal. * * * * if Overflow -> scal_sig[i] = signal[i]>>3 * * else if t0 < 1^20 -> scal_sig[i] = signal[i]<<3 * * else -> scal_sig[i] = signal[i] * *--------------------------------------------------------*/ /*--------------------------------------------------------* * Verification for risk of overflow. * *--------------------------------------------------------*/ test (); if (L_sub (t0, MAX_32) == 0L) /* Test for overflow */ { for (i = -pit_max; i < L_frame; i++) { scal_sig[i] = shr (signal[i], 3); move16 (); } scal_fac = 3; move16 (); } else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0) /* if (t0 < 2^20) */ { test (); for (i = -pit_max; i < L_frame; i++) { scal_sig[i] = shl (signal[i], 3); move16 (); } scal_fac = -3; move16 (); } else { test (); for (i = -pit_max; i < L_frame; i++) { scal_sig[i] = signal[i]; move16 (); } scal_fac = 0; move16 (); } /* calculate all coreelations of scal_sig, from pit_min to pit_max */ corr_ptr = &corr[pit_max]; move32 (); comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr); /*--------------------------------------------------------------------* * The pitch lag search is divided in three sections. * * Each section cannot have a pitch multiple. * * We find a maximum for each section. * * We compare the maximum of each section by favoring small lags. * * * * First section: lag delay = pit_max downto 4*pit_min * * Second section: lag delay = 4*pit_min-1 downto 2*pit_min * * Third section: lag delay = 2*pit_min-1 downto pit_min * *--------------------------------------------------------------------*/ /* mode dependent scaling in Lag_max */ test (); if (sub(mode, MR122) == 0) { scal_flag = 1; move16 (); } else { scal_flag = 0; move16 (); } #ifdef VAD2 j = shl (pit_min, 2); p_max1 = Lag_max (corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, pit_max, j, &max1, &rmax1, &r01, dtx); move16 (); /* function result */ i = sub (j, 1); j = shl (pit_min, 1); p_max2 = Lag_max (corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, i, j, &max2, &rmax2, &r02, dtx); move16 (); /* function result */ i = sub (j, 1); p_max3 = Lag_max (corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, i, pit_min, &max3, &rmax3, &r03, dtx); move16 (); /* function result */ #else j = shl (pit_min, 2); p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, pit_max, j, &max1, dtx); move16 (); /* function result */ i = sub (j, 1); j = shl (pit_min, 1); p_max2 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, i, j, &max2, dtx); move16 (); /* function result */ i = sub (j, 1); p_max3 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, i, pit_min, &max3, dtx); move16 (); /* function result */ if (dtx) { /* no test() call since this if is only in simulation env */ test (); if (sub(idx, 1) == 0) { /* calculate max high-passed filtered correlation of all lags */ hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max); /* update complex background detector */ vad_complex_detection_update(vadSt, corr_hp_max); } } #endif /*--------------------------------------------------------------------* * Compare the 3 sections maximum, and favor small lag. * *--------------------------------------------------------------------*/ test (); if (sub (mult (max1, THRESHOLD), max2) < 0) { max1 = max2; move16 (); p_max1 = p_max2; move16 (); #ifdef VAD2 if (dtx) { rmax1 = rmax2; move32 (); r01 = r02; move32 (); } #endif } test (); if (sub (mult (max1, THRESHOLD), max3) < 0) { p_max1 = p_max3; move16 (); #ifdef VAD2 if (dtx) { rmax1 = rmax3; move32 (); r01 = r03; move32 (); } #endif } #ifdef VAD2 if (dtx) { vadSt->L_Rmax = L_add(vadSt->L_Rmax, rmax1); /* Save max correlation */ vadSt->L_R0 = L_add(vadSt->L_R0, r01); /* Save max energy */ } #endif return (p_max1); }
/*************************************************************************** Function: vector_huffman Syntax: Word16 vector_huffman(Word16 category, Word16 power_index, Word16 *raw_mlt_ptr, UWord32 *word_ptr) inputs: Word16 category Word16 power_index Word16 *raw_mlt_ptr outputs: number_of_region_bits *word_ptr Description: Huffman encoding for each region based on category and power_index WMOPS: 7kHz | 24kbit | 32kbit -------|--------------|---------------- AVG | 0.03 | 0.03 -------|--------------|---------------- MAX | 0.04 | 0.04 -------|--------------|---------------- 14kHz | 24kbit | 32kbit | 48kbit -------|--------------|----------------|---------------- AVG | 0.03 | 0.03 | 0.03 -------|--------------|----------------|---------------- MAX | 0.04 | 0.04 | 0.04 -------|--------------|----------------|---------------- ***************************************************************************/ Word16 vector_huffman(Word16 category, Word16 power_index, Word16 *raw_mlt_ptr, UWord32 *word_ptr) { Word16 inv_of_step_size_times_std_dev; Word16 j,n; Word16 k; Word16 number_of_region_bits; Word16 number_of_non_zero; Word16 vec_dim; Word16 num_vecs; Word16 kmax, kmax_plus_one; Word16 index,signs_index; Word16 *bitcount_table_ptr; UWord16 *code_table_ptr; Word32 code_bits; Word16 number_of_code_bits; UWord32 current_word; Word16 current_word_bits_free; Word32 acca; Word32 accb; Word16 temp; Word16 mytemp; /* new variable in Release 1.2 */ Word16 myacca; /* new variable in Release 1.2 */ /* initialize variables */ vec_dim = vector_dimension[category]; move16(); num_vecs = number_of_vectors[category]; move16(); kmax = max_bin[category]; move16(); kmax_plus_one = add(kmax,1); move16(); current_word = 0L; move16(); current_word_bits_free = 32; move16(); number_of_region_bits = 0; move16(); /* set up table pointers */ bitcount_table_ptr = (Word16 *)table_of_bitcount_tables[category]; code_table_ptr = (UWord16 *) table_of_code_tables[category]; /* compute inverse of step size * standard deviation */ acca = L_mult(step_size_inverse_table[category],standard_deviation_inverse_table[power_index]); acca = L_shr_nocheck(acca,1); acca = L_add(acca,4096); acca = L_shr_nocheck(acca,13); /* * The next two lines are new to Release 1.2 */ mytemp = (Word16)(acca & 0x3); acca = L_shr_nocheck(acca,2); inv_of_step_size_times_std_dev = extract_l(acca); for (n=0; n<num_vecs; n++) { index = 0; move16(); signs_index = 0; move16(); number_of_non_zero = 0; move16(); for (j=0; j<vec_dim; j++) { k = abs_s(*raw_mlt_ptr); acca = L_mult(k,inv_of_step_size_times_std_dev); acca = L_shr_nocheck(acca,1); /* * The next four lines are new to Release 1.2 */ myacca = (Word16)L_mult(k,mytemp); myacca = (Word16)L_shr_nocheck(myacca,1); myacca = (Word16)L_add(myacca,int_dead_zone_low_bits[category]); myacca = (Word16)L_shr_nocheck(myacca,2); acca = L_add(acca,int_dead_zone[category]); /* * The next two lines are new to Release 1.2 */ acca = L_add(acca,myacca); acca = L_shr_nocheck(acca,13); k = extract_l(acca); test(); if (k != 0) { number_of_non_zero = add(number_of_non_zero,1); signs_index = shl_nocheck(signs_index,1); test(); if (*raw_mlt_ptr > 0) { signs_index = add(signs_index,1); } temp = sub(k,kmax); test(); if (temp > 0) { k = kmax; move16(); } } acca = L_shr_nocheck(L_mult(index,(kmax_plus_one)),1); index = extract_l(acca); index = add(index,k); raw_mlt_ptr++; } code_bits = *(code_table_ptr+index); number_of_code_bits = add((*(bitcount_table_ptr+index)),number_of_non_zero); number_of_region_bits = add(number_of_region_bits,number_of_code_bits); acca = code_bits << number_of_non_zero; accb = L_deposit_l(signs_index); acca = L_add(acca,accb); code_bits = acca; move32(); /* msb of codebits is transmitted first. */ j = sub(current_word_bits_free,number_of_code_bits); test(); if (j >= 0) { test(); acca = code_bits << j; current_word = L_add(current_word,acca); current_word_bits_free = j; move16(); } else { j = negate(j); acca = L_shr_nocheck(code_bits,j); current_word = L_add(current_word,acca); *word_ptr++ = current_word; move16(); current_word_bits_free = sub(32,j); test(); current_word = code_bits << current_word_bits_free; } } *word_ptr++ = current_word; move16(); return (number_of_region_bits); }
/*************************************************************************** Function: bits_to_words Syntax: bits_to_words(UWord32 *region_mlt_bits, Word16 *region_mlt_bit_counts, Word16 *drp_num_bits, UWord16 *drp_code_bits, Word16 *out_words, Word16 categorization_control, Word16 number_of_regions, Word16 num_categorization_control_bits, Word16 number_of_bits_per_frame) Description: Stuffs the bits into words for output WMOPS: 7kHz | 24kbit | 32kbit -------|--------------|---------------- AVG | 0.09 | 0.12 -------|--------------|---------------- MAX | 0.10 | 0.13 -------|--------------|---------------- 14kHz | 24kbit | 32kbit | 48kbit -------|--------------|----------------|---------------- AVG | 0.12 | 0.15 | 0.19 -------|--------------|----------------|---------------- MAX | 0.14 | 0.17 | 0.21 -------|--------------|----------------|---------------- ***************************************************************************/ void bits_to_words(UWord32 *region_mlt_bits, Word16 *region_mlt_bit_counts, Word16 *drp_num_bits, UWord16 *drp_code_bits, Word16 *out_words, Word16 categorization_control, Word16 number_of_regions, Word16 num_categorization_control_bits, Word16 number_of_bits_per_frame) { Word16 out_word_index = 0; Word16 j; Word16 region; Word16 out_word; Word16 region_bit_count; Word16 current_word_bits_left; UWord16 slice; Word16 out_word_bits_free = 16; UWord32 *in_word_ptr; UWord32 current_word; Word32 acca = 0; Word32 accb; Word16 temp; /* First set up the categorization control bits to look like one more set of region power bits. */ out_word = 0; move16(); drp_num_bits[number_of_regions] = num_categorization_control_bits; move16(); drp_code_bits[number_of_regions] = (UWord16)categorization_control; move16(); /* These code bits are right justified. */ for (region=0; region <= number_of_regions; region++) { current_word_bits_left = drp_num_bits[region]; move16(); current_word = (UWord32)drp_code_bits[region]; move16(); j = sub(current_word_bits_left,out_word_bits_free); test(); if (j >= 0) { temp = extract_l(L_shr_nocheck(current_word,j)); out_word = add(out_word,temp); out_words[out_word_index++] = out_word; move16(); out_word_bits_free = 16; move16(); out_word_bits_free = sub(out_word_bits_free,j); acca = (current_word << out_word_bits_free); out_word = extract_l(acca); } else { j = negate(j); acca = (current_word << j); accb = L_deposit_l(out_word); acca = L_add(accb,acca); out_word = extract_l(acca); out_word_bits_free = sub(out_word_bits_free,current_word_bits_left); } } /* These code bits are left justified. */ for (region=0;region<number_of_regions; region++) { accb = L_deposit_l(out_word_index); accb = L_shl_nocheck(accb,4); accb = L_sub(accb,number_of_bits_per_frame); test(); if(accb < 0) { temp = shl_nocheck(region,2); in_word_ptr = ®ion_mlt_bits[temp]; region_bit_count = region_mlt_bit_counts[region]; move16(); temp = sub(32,region_bit_count); test(); if(temp > 0) current_word_bits_left = region_bit_count; else current_word_bits_left = 32; current_word = *in_word_ptr++; acca = L_deposit_l(out_word_index); acca = L_shl_nocheck(acca,4); acca = L_sub(acca,number_of_bits_per_frame); /* from while loop */ test(); test(); logic16(); while ((region_bit_count > 0) && (acca < 0)) { /* from while loop */ test(); test(); logic16(); temp = sub(current_word_bits_left,out_word_bits_free); test(); if (temp >= 0) { temp = sub(32,out_word_bits_free); accb = LU_shr(current_word,temp); slice = (UWord16)extract_l(accb); out_word = add(out_word,slice); test(); current_word <<= out_word_bits_free; current_word_bits_left = sub(current_word_bits_left,out_word_bits_free); out_words[out_word_index++] = extract_l(out_word); move16(); out_word = 0; move16(); out_word_bits_free = 16; move16(); } else { temp = sub(32,current_word_bits_left); accb = LU_shr(current_word,temp); slice = (UWord16)extract_l(accb); temp = sub(out_word_bits_free,current_word_bits_left); test(); accb = slice << temp; acca = L_deposit_l(out_word); acca = L_add(acca,accb); out_word = extract_l(acca); out_word_bits_free = sub(out_word_bits_free,current_word_bits_left); current_word_bits_left = 0; move16(); } test(); if (current_word_bits_left == 0) { current_word = *in_word_ptr++; region_bit_count = sub(region_bit_count,32); /* current_word_bits_left = MIN(32,region_bit_count); */ temp = sub(32,region_bit_count); test(); if(temp > 0) current_word_bits_left = region_bit_count; else current_word_bits_left = 32; } acca = L_deposit_l(out_word_index); acca = L_shl_nocheck(acca,4); acca = L_sub(acca,number_of_bits_per_frame); } accb = L_deposit_l(out_word_index); accb = L_shl_nocheck(accb,4); accb = L_sub(accb,number_of_bits_per_frame); } } /* Fill out with 1's. */ test(); while (acca < 0) { test(); current_word = 0x0000ffff; move32(); temp = sub(16,out_word_bits_free); acca = LU_shr(current_word,temp); slice = (UWord16)extract_l(acca); out_word = add(out_word,slice); out_words[out_word_index++] = out_word; move16(); out_word = 0; move16(); out_word_bits_free = 16; move16(); acca = L_deposit_l(out_word_index); acca = L_shl_nocheck(acca,4); acca = L_sub(acca,number_of_bits_per_frame); } }
/* ************************************************************************** * * Function : dtx_dec * ************************************************************************** */ int dtx_dec( dtx_decState *st, /* i/o : State struct */ Word16 mem_syn[], /* i/o : AMR decoder state */ D_plsfState* lsfState, /* i/o : decoder lsf states */ gc_predState* predState, /* i/o : prediction states */ Cb_gain_averageState* averState, /* i/o : CB gain average states */ enum DTXStateType new_state, /* i : new DTX state */ enum Mode mode, /* i : AMR mode */ Word16 parm[], /* i : Vector of synthesis parameters */ Word16 synth[], /* o : synthesised speech */ Word16 A_t[] /* o : decoded LP filter in 4 subframes*/ ) { Word16 log_en_index; Word16 i, j; Word16 int_fac; Word32 L_log_en_int; Word16 lsp_int[M]; Word16 log_en_int_e; Word16 log_en_int_m; Word16 level; Word16 acoeff[M + 1]; Word16 refl[M]; Word16 pred_err; Word16 ex[L_SUBFR]; Word16 ma_pred_init; Word16 log_pg_e, log_pg_m; Word16 log_pg; Flag negative; Word16 lsf_mean; Word32 L_lsf_mean; Word16 lsf_variab_index; Word16 lsf_variab_factor; Word16 lsf_int[M]; Word16 lsf_int_variab[M]; Word16 lsp_int_variab[M]; Word16 acoeff_variab[M + 1]; Word16 lsf[M]; Word32 L_lsf[M]; Word16 ptr; Word16 tmp_int_length; /* This function is called if synthesis state is not SPEECH * the globally passed inputs to this function are * st->sid_frame * st->valid_data * st->dtxHangoverAdded * new_state (SPEECH, DTX, DTX_MUTE) */ test(); test(); if ((st->dtxHangoverAdded != 0) && (st->sid_frame != 0)) { /* sid_first after dtx hangover period */ /* or sid_upd after dtxhangover */ /* set log_en_adjust to correct value */ st->log_en_adjust = dtx_log_en_adjust[mode]; ptr = add(st->lsf_hist_ptr, M); move16(); test(); if (sub(ptr, 80) == 0) { ptr = 0; move16(); } Copy( &st->lsf_hist[st->lsf_hist_ptr],&st->lsf_hist[ptr],M); ptr = add(st->log_en_hist_ptr,1); move16(); test(); if (sub(ptr, DTX_HIST_SIZE) == 0) { ptr = 0; move16(); } move16(); st->log_en_hist[ptr] = st->log_en_hist[st->log_en_hist_ptr]; /* Q11 */ /* compute mean log energy and lsp * * from decoded signal (SID_FIRST) */ st->log_en = 0; move16(); for (i = 0; i < M; i++) { L_lsf[i] = 0; move16(); } /* average energy and lsp */ for (i = 0; i < DTX_HIST_SIZE; i++) { st->log_en = add(st->log_en, shr(st->log_en_hist[i],3)); for (j = 0; j < M; j++) { L_lsf[j] = L_add(L_lsf[j], L_deposit_l(st->lsf_hist[i * M + j])); } } for (j = 0; j < M; j++) { lsf[j] = extract_l(L_shr(L_lsf[j],3)); /* divide by 8 */ move16(); } Lsf_lsp(lsf, st->lsp, M); /* make log_en speech coder mode independent */ /* added again later before synthesis */ st->log_en = sub(st->log_en, st->log_en_adjust); /* compute lsf variability vector */ Copy(st->lsf_hist, st->lsf_hist_mean, 80); for (i = 0; i < M; i++) { L_lsf_mean = 0; move32(); /* compute mean lsf */ for (j = 0; j < 8; j++) { L_lsf_mean = L_add(L_lsf_mean, L_deposit_l(st->lsf_hist_mean[i+j*M])); } lsf_mean = extract_l(L_shr(L_lsf_mean, 3)); move16(); /* subtract mean and limit to within reasonable limits * * moreover the upper lsf's are attenuated */ for (j = 0; j < 8; j++) { /* subtract mean */ st->lsf_hist_mean[i+j*M] = sub(st->lsf_hist_mean[i+j*M], lsf_mean); /* attenuate deviation from mean, especially for upper lsf's */ st->lsf_hist_mean[i+j*M] = mult(st->lsf_hist_mean[i+j*M], lsf_hist_mean_scale[i]); /* limit the deviation */ test(); if (st->lsf_hist_mean[i+j*M] < 0) { negative = 1; move16(); } else { negative = 0; move16(); } st->lsf_hist_mean[i+j*M] = abs_s(st->lsf_hist_mean[i+j*M]); /* apply soft limit */ test(); if (sub(st->lsf_hist_mean[i+j*M], 655) > 0) { st->lsf_hist_mean[i+j*M] = add(655, shr(sub(st->lsf_hist_mean[i+j*M], 655), 2)); } /* apply hard limit */ test(); if (sub(st->lsf_hist_mean[i+j*M], 1310) > 0) { st->lsf_hist_mean[i+j*M] = 1310; move16(); } test(); if (negative != 0) { st->lsf_hist_mean[i+j*M] = -st->lsf_hist_mean[i+j*M];move16(); } } } } test(); if (st->sid_frame != 0 ) { /* Set old SID parameters, always shift */ /* even if there is no new valid_data */ Copy(st->lsp, st->lsp_old, M); st->old_log_en = st->log_en; move16(); test(); if (st->valid_data != 0 ) /* new data available (no CRC) */ { /* Compute interpolation factor, since the division only works * * for values of since_last_sid < 32 we have to limit the * * interpolation to 32 frames */ tmp_int_length = st->since_last_sid; move16(); st->since_last_sid = 0; move16(); test(); if (sub(tmp_int_length, 32) > 0) { tmp_int_length = 32; move16(); } test(); if (sub(tmp_int_length, 2) >= 0) { move16(); st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10)); } else { st->true_sid_period_inv = 1 << 14; /* 0.5 it Q15 */ move16(); } Init_D_plsf_3(lsfState, parm[0]); /* temporay initialization */ D_plsf_3(lsfState, MRDTX, 0, &parm[1], st->lsp); Set_zero(lsfState->past_r_q, M); /* reset for next speech frame */ log_en_index = parm[4]; move16(); /* Q11 and divide by 4 */ st->log_en = shl(log_en_index, (11 - 2)); move16(); /* Subtract 2.5 in Q11 */ st->log_en = sub(st->log_en, (2560 * 2)); /* Index 0 is reserved for silence */ test(); if (log_en_index == 0) { st->log_en = MIN_16; move16(); } /* no interpolation at startup after coder reset */ /* or when SID_UPD has been received right after SPEECH */ test(); test(); if ((st->data_updated == 0) || (sub(st->dtxGlobalState, SPEECH) == 0) ) { Copy(st->lsp, st->lsp_old, M); st->old_log_en = st->log_en; move16(); } } /* endif valid_data */ /* initialize gain predictor memory of other modes */ ma_pred_init = sub(shr(st->log_en,1), 9000); move16(); test(); if (ma_pred_init > 0) { ma_pred_init = 0; move16(); } test(); if (sub(ma_pred_init, -14436) < 0) { ma_pred_init = -14436; move16(); } predState->past_qua_en[0] = ma_pred_init; move16(); predState->past_qua_en[1] = ma_pred_init; move16(); predState->past_qua_en[2] = ma_pred_init; move16(); predState->past_qua_en[3] = ma_pred_init; move16(); /* past_qua_en for other modes than MR122 */ ma_pred_init = mult(5443, ma_pred_init); /* scale down by factor 20*log10(2) in Q15 */ predState->past_qua_en_MR122[0] = ma_pred_init; move16(); predState->past_qua_en_MR122[1] = ma_pred_init; move16(); predState->past_qua_en_MR122[2] = ma_pred_init; move16(); predState->past_qua_en_MR122[3] = ma_pred_init; move16(); } /* endif sid_frame */ /* CN generation */ /* recompute level adjustment factor Q11 * * st->log_en_adjust = 0.9*st->log_en_adjust + * * 0.1*dtx_log_en_adjust[mode]); */ move16(); st->log_en_adjust = add(mult(st->log_en_adjust, 29491), shr(mult(shl(dtx_log_en_adjust[mode],5),3277),5)); /* Interpolate SID info */ int_fac = shl(add(1,st->since_last_sid), 10); /* Q10 */ move16(); int_fac = mult(int_fac, st->true_sid_period_inv); /* Q10 * Q15 -> Q10 */ /* Maximize to 1.0 in Q10 */ test(); if (sub(int_fac, 1024) > 0) { int_fac = 1024; move16(); } int_fac = shl(int_fac, 4); /* Q10 -> Q14 */ L_log_en_int = L_mult(int_fac, st->log_en); /* Q14 * Q11->Q26 */ move32(); for(i = 0; i < M; i++) { lsp_int[i] = mult(int_fac, st->lsp[i]);/* Q14 * Q15 -> Q14 */ move16(); } int_fac = sub(16384, int_fac); /* 1-k in Q14 */ move16(); /* (Q14 * Q11 -> Q26) + Q26 -> Q26 */ L_log_en_int = L_mac(L_log_en_int, int_fac, st->old_log_en); for(i = 0; i < M; i++) { /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */ lsp_int[i] = add(lsp_int[i], mult(int_fac, st->lsp_old[i])); move16(); lsp_int[i] = shl(lsp_int[i], 1); /* Q14 -> Q15 */ move16(); } /* compute the amount of lsf variability */ lsf_variab_factor = sub(st->log_pg_mean,2457); /* -0.6 in Q12 */ move16(); /* *0.3 Q12*Q15 -> Q12 */ lsf_variab_factor = sub(4096, mult(lsf_variab_factor, 9830)); /* limit to values between 0..1 in Q12 */ test(); if (sub(lsf_variab_factor, 4096) > 0) { lsf_variab_factor = 4096; move16(); } test(); if (lsf_variab_factor < 0) { lsf_variab_factor = 0; move16(); } lsf_variab_factor = shl(lsf_variab_factor, 3); /* -> Q15 */ move16(); /* get index of vector to do variability with */ lsf_variab_index = pseudonoise(&st->L_pn_seed_rx, 3); move16(); /* convert to lsf */ Lsp_lsf(lsp_int, lsf_int, M); /* apply lsf variability */ Copy(lsf_int, lsf_int_variab, M); for(i = 0; i < M; i++) { move16(); lsf_int_variab[i] = add(lsf_int_variab[i], mult(lsf_variab_factor, st->lsf_hist_mean[i+lsf_variab_index*M])); } /* make sure that LSP's are ordered */ Reorder_lsf(lsf_int, LSF_GAP, M); Reorder_lsf(lsf_int_variab, LSF_GAP, M); /* copy lsf to speech decoders lsf state */ Copy(lsf_int, lsfState->past_lsf_q, M); /* convert to lsp */ Lsf_lsp(lsf_int, lsp_int, M); Lsf_lsp(lsf_int_variab, lsp_int_variab, M); /* Compute acoeffs Q12 acoeff is used for level * * normalization and postfilter, acoeff_variab is * * used for synthesis filter * * by doing this we make sure that the level * * in high frequenncies does not jump up and down */ Lsp_Az(lsp_int, acoeff); Lsp_Az(lsp_int_variab, acoeff_variab); /* For use in postfilter */ Copy(acoeff, &A_t[0], M + 1); Copy(acoeff, &A_t[M + 1], M + 1); Copy(acoeff, &A_t[2 * (M + 1)], M + 1); Copy(acoeff, &A_t[3 * (M + 1)], M + 1); /* Compute reflection coefficients Q15 */ A_Refl(&acoeff[1], refl); /* Compute prediction error in Q15 */ pred_err = MAX_16; /* 0.99997 in Q15 */ move16(); for (i = 0; i < M; i++) { pred_err = mult(pred_err, sub(MAX_16, mult(refl[i], refl[i]))); } /* compute logarithm of prediction gain */ Log2(L_deposit_l(pred_err), &log_pg_e, &log_pg_m); /* convert exponent and mantissa to Word16 Q12 */ log_pg = shl(sub(log_pg_e,15), 12); /* Q12 */ move16(); log_pg = shr(sub(0,add(log_pg, shr(log_pg_m, 15-12))), 1); move16(); st->log_pg_mean = add(mult(29491,st->log_pg_mean), mult(3277, log_pg)); move16(); /* Compute interpolated log energy */ L_log_en_int = L_shr(L_log_en_int, 10); /* Q26 -> Q16 */ move32(); /* Add 4 in Q16 */ L_log_en_int = L_add(L_log_en_int, 4 * 65536L); move32(); /* subtract prediction gain */ L_log_en_int = L_sub(L_log_en_int, L_shl(L_deposit_l(log_pg), 4));move32(); /* adjust level to speech coder mode */ L_log_en_int = L_add(L_log_en_int, L_shl(L_deposit_l(st->log_en_adjust), 5)); move32(); log_en_int_e = extract_h(L_log_en_int); move16(); move16(); log_en_int_m = extract_l(L_shr(L_sub(L_log_en_int, L_deposit_h(log_en_int_e)), 1)); level = extract_l(Pow2(log_en_int_e, log_en_int_m)); /* Q4 */ move16(); for (i = 0; i < 4; i++) { /* Compute innovation vector */ build_CN_code(&st->L_pn_seed_rx, ex); for (j = 0; j < L_SUBFR; j++) { ex[j] = mult(level, ex[j]); move16(); } /* Synthesize */ Syn_filt(acoeff_variab, ex, &synth[i * L_SUBFR], L_SUBFR, mem_syn, 1); } /* next i */ /* reset codebook averaging variables */ averState->hangVar = 20; move16(); averState->hangCount = 0; move16(); test(); if (sub(new_state, DTX_MUTE) == 0) { /* mute comfort noise as it has been quite a long time since * last SID update was performed */ tmp_int_length = st->since_last_sid; move16(); test(); if (sub(tmp_int_length, 32) > 0) { tmp_int_length = 32; move16(); } /* safety guard against division by zero */ test(); if(tmp_int_length <= 0) { tmp_int_length = 8; move16(); } move16(); st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10)); st->since_last_sid = 0; move16(); Copy(st->lsp, st->lsp_old, M); st->old_log_en = st->log_en; move16(); /* subtract 1/8 in Q11 i.e -6/8 dB */ st->log_en = sub(st->log_en, 256); move16(); } /* reset interpolation length timer * if data has been updated. */ test(); test(); test(); test(); if ((st->sid_frame != 0) && ((st->valid_data != 0) || ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0))) { st->since_last_sid = 0; move16(); st->data_updated = 1; move16(); } return 0; }
/************************************************************************* * * FUNCTION set_sign12k2() * * PURPOSE: Builds sign[] vector according to "dn[]" and "cn[]", and modifies * dn[] to include the sign information (dn[i]=sign[i]*dn[i]). * Also finds the position of maximum of correlation in each track * and the starting position for each pulse. * *************************************************************************/ void set_sign12k2 ( Word16 dn[], /* i/o : correlation between target and h[] */ Word16 cn[], /* i : residual after long term prediction */ Word16 sign[], /* o : sign of d[n] */ Word16 pos_max[], /* o : position of maximum correlation */ Word16 nb_track, /* i : number of tracks tracks */ Word16 ipos[], /* o : starting position for each pulse */ Word16 step /* i : the step size in the tracks */ ) { Word16 i, j; Word16 val, cor, k_cn, k_dn, max, max_of_all; Word16 pos = 0; /* initialization only needed to keep gcc silent */ Word16 en[L_CODE]; /* correlation vector */ Word32 s; /* calculate energy for normalization of cn[] and dn[] */ s = 256; move32 (); for (i = 0; i < L_CODE; i++) { s = L_mac (s, cn[i], cn[i]); } s = Inv_sqrt (s); move32 (); k_cn = extract_h (L_shl (s, 5)); s = 256; move32 (); for (i = 0; i < L_CODE; i++) { s = L_mac (s, dn[i], dn[i]); } s = Inv_sqrt (s); move32 (); k_dn = extract_h (L_shl (s, 5)); for (i = 0; i < L_CODE; i++) { val = dn[i]; move16 (); cor = round (L_shl (L_mac (L_mult (k_cn, cn[i]), k_dn, val), 10)); test (); if (cor >= 0) { sign[i] = 32767; move16 (); /* sign = +1 */ } else { sign[i] = -32767; move16 (); /* sign = -1 */ cor = negate (cor); val = negate (val); } /* modify dn[] according to the fixed sign */ dn[i] = val; move16 (); en[i] = cor; move16 (); } max_of_all = -1; move16 (); for (i = 0; i < nb_track; i++) { max = -1; move16 (); for (j = i; j < L_CODE; j += step) { cor = en[j]; move16 (); val = sub (cor, max); test (); if (val > 0) { max = cor; move16 (); pos = j; move16 (); } } /* store maximum correlation position */ pos_max[i] = pos; move16 (); val = sub (max, max_of_all); test (); if (val > 0) { max_of_all = max; move16 (); /* starting position for i0 */ ipos[0] = i; move16 (); } } /*----------------------------------------------------------------* * Set starting position of each pulse. * *----------------------------------------------------------------*/ pos = ipos[0]; move16 (); ipos[nb_track] = pos; move16 (); for (i = 1; i < nb_track; i++) { pos = add (pos, 1); test (); if (sub (pos, nb_track) >= 0) { pos = 0; move16 (); } ipos[i] = pos; move16 (); ipos[add(i, nb_track)] = pos; move16 (); } }
void Java_org_robovm_rt_VM_memmove64(Env* env, Class* c, jlong s1, jlong s2, jlong n) { move32(LONG_TO_PTR(s1), LONG_TO_PTR(s2), (size_t) (n << 1)); }
/************************************************************************* * * FUNCTION: calc_filt_energies * * PURPOSE: calculation of several energy coefficients for filtered * excitation signals * * Compute coefficients need for the quantization and the optimum * codebook gain gcu (for MR475 only). * * coeff[0] = y1 y1 * coeff[1] = -2 xn y1 * coeff[2] = y2 y2 * coeff[3] = -2 xn y2 * coeff[4] = 2 y1 y2 * * * gcu = <xn2, y2> / <y2, y2> (0 if <xn2, y2> <= 0) * * Product <y1 y1> and <xn y1> have been computed in G_pitch() and * are in vector g_coeff[]. * *************************************************************************/ void calc_filt_energies( enum Mode mode, /* i : coder mode */ Word16 xn[], /* i : LTP target vector, Q0 */ Word16 xn2[], /* i : CB target vector, Q0 */ Word16 y1[], /* i : Adaptive codebook, Q0 */ Word16 Y2[], /* i : Filtered innovative vector, Q12 */ Word16 g_coeff[], /* i : Correlations <xn y1> <y1 y1> */ /* computed in G_pitch() */ Word16 frac_coeff[],/* o : energy coefficients (5), fraction part, Q15 */ Word16 exp_coeff[], /* o : energy coefficients (5), exponent part, Q0 */ Word16 *cod_gain_frac,/* o: optimum codebook gain (fraction part), Q15 */ Word16 *cod_gain_exp /* o: optimum codebook gain (exponent part), Q0 */ ) { Word32 s, ener_init; Word16 i, exp, frac; Word16 y2[L_SUBFR]; if (test(), sub(mode, MR795) == 0 || sub(mode, MR475) == 0) { ener_init = 0L; move32 (); } else { ener_init = 1L; move32 (); } for (i = 0; i < L_SUBFR; i++) { y2[i] = shr(Y2[i], 3); move16 (); } frac_coeff[0] = g_coeff[0]; move16 (); exp_coeff[0] = g_coeff[1]; move16 (); frac_coeff[1] = negate(g_coeff[2]); move16 (); /* coeff[1] = -2 xn y1 */ exp_coeff[1] = add(g_coeff[3], 1); move16 (); /* Compute scalar product <y2[],y2[]> */ s = L_mac(ener_init, y2[0], y2[0]); for (i = 1; i < L_SUBFR; i++) s = L_mac(s, y2[i], y2[i]); exp = norm_l(s); frac_coeff[2] = extract_h(L_shl(s, exp)); move16 (); exp_coeff[2] = sub(15 - 18, exp); move16(); /* Compute scalar product -2*<xn[],y2[]> */ s = L_mac(ener_init, xn[0], y2[0]); for (i = 1; i < L_SUBFR; i++) s = L_mac(s, xn[i], y2[i]); exp = norm_l(s); frac_coeff[3] = negate(extract_h(L_shl(s, exp))); move16 (); exp_coeff[3] = sub(15 - 9 + 1, exp); move16 (); /* Compute scalar product 2*<y1[],y2[]> */ s = L_mac(ener_init, y1[0], y2[0]); for (i = 1; i < L_SUBFR; i++) s = L_mac(s, y1[i], y2[i]); exp = norm_l(s); frac_coeff[4] = extract_h(L_shl(s, exp)); move16 (); exp_coeff[4] = sub(15 - 9 + 1, exp); move16(); if (test(), test (), sub(mode, MR475) == 0 || sub(mode, MR795) == 0) { /* Compute scalar product <xn2[],y2[]> */ s = L_mac(ener_init, xn2[0], y2[0]); for (i = 1; i < L_SUBFR; i++) s = L_mac(s, xn2[i], y2[i]); exp = norm_l(s); frac = extract_h(L_shl(s, exp)); exp = sub(15 - 9, exp); if (test (), frac <= 0) { *cod_gain_frac = 0; move16 (); *cod_gain_exp = 0; move16 (); } else { /* gcu = <xn2, y2> / c[2] = (frac>>1)/frac[2] * 2^(exp+1-exp[2]) = div_s(frac>>1, frac[2])*2^-15 * 2^(exp+1-exp[2]) = div_s * 2^(exp-exp[2]-14) */ *cod_gain_frac = div_s (shr (frac,1), frac_coeff[2]); move16 (); *cod_gain_exp = sub (sub (exp, exp_coeff[2]), 14); move16 (); } } }
Word16 samples_to_rmlt_coefs(const Word16 *new_samples,Word16 *old_samples,Word16 *coefs,Word16 dct_length) { Word16 index, vals_left,mag_shift,n; Word16 windowed_data[MAX_DCT_LENGTH]; Word16 *old_ptr; const Word16 *new_ptr, *sam_low, *sam_high; Word16 *win_low, *win_high; Word16 *dst_ptr; Word16 neg_win_low; Word16 samp_high; Word16 half_dct_size; Word32 acca; Word32 accb; Word16 temp; Word16 temp1; Word16 temp2; Word16 temp5; half_dct_size = shr_nocheck(dct_length,1); /*++++++++++++++++++++++++++++++++++++++++++++*/ /* Get the first half of the windowed samples */ /*++++++++++++++++++++++++++++++++++++++++++++*/ dst_ptr = windowed_data; move16(); /* address arithmetic */ test(); if (dct_length==DCT_LENGTH) { win_high = samples_to_rmlt_window + half_dct_size; } else { win_high = max_samples_to_rmlt_window + half_dct_size; } win_low = win_high; move16(); /* address arithmetic */ sam_high = old_samples + half_dct_size; sam_low = sam_high; move16(); for (vals_left = half_dct_size;vals_left > 0;vals_left--) { acca = 0L; move32(); acca = L_mac(acca,*--win_low, *--sam_low); acca = L_mac(acca,*win_high++, *sam_high++); temp = itu_round(acca); *dst_ptr++ = temp; move16(); } /*+++++++++++++++++++++++++++++++++++++++++++++*/ /* Get the second half of the windowed samples */ /*+++++++++++++++++++++++++++++++++++++++++++++*/ sam_low = new_samples; move16(); /* address arithmetic */ sam_high = new_samples + dct_length; for (vals_left = half_dct_size; vals_left > 0; vals_left--) { acca = 0L; move32(); acca = L_mac(acca,*--win_high, *sam_low++); neg_win_low = negate(*win_low++); samp_high = *--sam_high; acca = L_mac(acca, neg_win_low, samp_high); temp = itu_round(acca); *dst_ptr++=temp; move16(); } /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* Save the new samples for next time, when they will be the old samples */ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ new_ptr = new_samples; move16(); old_ptr = old_samples; move16(); for (vals_left = dct_length;vals_left > 0;vals_left--) { *old_ptr++ = *new_ptr++; move16(); } /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* Calculate how many bits to shift up the input to the DCT. */ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ temp1=0; move16(); for(index=0;index<dct_length;index++) { temp2 = abs_s(windowed_data[index]); temp = sub(temp2,temp1); test(); if(temp > 0) { move16(); temp1 = temp2; } } mag_shift=0; move16(); temp = sub(temp1,14000); test(); if (temp >= 0) { mag_shift = 0; move16(); } else { temp = sub(temp1,438); test(); if(temp < 0) temp = add(temp1,1); else { temp = temp1; move16(); } accb = L_mult(temp,9587); acca = L_shr_nocheck(accb,20); temp5 = extract_l(acca); temp = norm_s(temp5); test(); if (temp == 0) { mag_shift = 9; move16(); } else mag_shift = sub(temp,6); } acca = 0L; move32(); for(index=0; index<dct_length; index++) { temp = abs_s( windowed_data[index]); acca = L_add(acca,temp); } acca = L_shr_nocheck(acca,7); test(); if (temp1 < acca) { mag_shift = sub(mag_shift,1); } test(); if (mag_shift > 0) { for(index=0;index<dct_length;index++) { windowed_data[index] = shl_nocheck(windowed_data[index],mag_shift); } } else { test(); if (mag_shift < 0) { n = negate(mag_shift); for(index=0;index<dct_length;index++) { windowed_data[index] = shr_nocheck(windowed_data[index],n); move16(); } } } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* Perform a Type IV DCT on the windowed data to get the coefficients */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ dct_type_iv_a(windowed_data, coefs, dct_length); return(mag_shift); }
/*************************************************************************** * FUNCTION: cod_amr * * PURPOSE: Main encoder routine. * * DESCRIPTION: This function is called every 20 ms speech frame, * operating on the newly read 160 speech samples. It performs the * principle encoding functions to produce the set of encoded parameters * which include the LSP, adaptive codebook, and fixed codebook * quantization indices (addresses and gains). * * INPUTS: * No input argument are passed to this function. However, before * calling this function, 160 new speech data should be copied to the * vector new_speech[]. This is a global pointer which is declared in * this file (it points to the end of speech buffer minus 160). * * OUTPUTS: * * ana[]: vector of analysis parameters. * synth[]: Local synthesis speech (for debugging purposes) * ***************************************************************************/ int cod_amr( cod_amrState *st, /* i/o : State struct */ enum Mode mode, /* i : AMR mode */ Word16 new_speech[], /* i : speech input (L_FRAME) */ Word16 ana[], /* o : Analysis parameters */ enum Mode *usedMode, /* o : used mode */ Word16 synth[] /* o : Local synthesis */ ) { /* LPC coefficients */ Word16 A_t[(MP1) * 4]; /* A(z) unquantized for the 4 subframes */ Word16 Aq_t[(MP1) * 4]; /* A(z) quantized for the 4 subframes */ Word16 *A, *Aq; /* Pointer on A_t and Aq_t */ Word16 lsp_new[M]; /* Other vectors */ Word16 xn[L_SUBFR]; /* Target vector for pitch search */ Word16 xn2[L_SUBFR]; /* Target vector for codebook search */ Word16 code[L_SUBFR]; /* Fixed codebook excitation */ Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */ Word16 y2[L_SUBFR]; /* Filtered fixed codebook excitation */ Word16 gCoeff[6]; /* Correlations between xn, y1, & y2: */ Word16 res[L_SUBFR]; /* Short term (LPC) prediction residual */ Word16 res2[L_SUBFR]; /* Long term (LTP) prediction residual */ /* Vector and scalars needed for the MR475 */ Word16 xn_sf0[L_SUBFR]; /* Target vector for pitch search */ Word16 y2_sf0[L_SUBFR]; /* Filtered codebook innovation */ Word16 code_sf0[L_SUBFR]; /* Fixed codebook excitation */ Word16 h1_sf0[L_SUBFR]; /* The impulse response of sf0 */ Word16 mem_syn_save[M]; /* Filter memory */ Word16 mem_w0_save[M]; /* Filter memory */ Word16 mem_err_save[M]; /* Filter memory */ Word16 sharp_save; /* Sharpening */ Word16 evenSubfr; /* Even subframe indicator */ Word16 T0_sf0 = 0; /* Integer pitch lag of sf0 */ Word16 T0_frac_sf0 = 0; /* Fractional pitch lag of sf0 */ Word16 i_subfr_sf0 = 0; /* Position in exc[] for sf0 */ Word16 gain_pit_sf0; /* Quantized pitch gain for sf0 */ Word16 gain_code_sf0; /* Quantized codebook gain for sf0 */ /* Scalars */ Word16 i_subfr, subfrNr; Word16 T_op[L_FRAME/L_FRAME_BY2]; Word16 T0, T0_frac; Word16 gain_pit, gain_code; /* Flags */ Word16 lsp_flag = 0; /* indicates resonance in LPC filter */ Word16 gp_limit; /* pitch gain limit value */ Word16 vad_flag; /* VAD decision flag */ Word16 compute_sid_flag; /* SID analysis flag */ Copy(new_speech, st->new_speech, L_FRAME); *usedMode = mode; move16 (); /* DTX processing */ if (st->dtx) { /* no test() call since this if is only in simulation env */ /* Find VAD decision */ #ifdef VAD2 vad_flag = vad2 (st->new_speech, st->vadSt); vad_flag = vad2 (st->new_speech+80, st->vadSt) || vad_flag; logic16(); #else vad_flag = vad1(st->vadSt, st->new_speech); #endif fwc (); /* function worst case */ /* NB! usedMode may change here */ compute_sid_flag = tx_dtx_handler(st->dtx_encSt, vad_flag, usedMode); } else { compute_sid_flag = 0; move16 (); } /*------------------------------------------------------------------------* * - Perform LPC analysis: * * * autocorrelation + lag windowing * * * Levinson-durbin algorithm to find a[] * * * convert a[] to lsp[] * * * quantize and code the LSPs * * * find the interpolated LSPs and convert to a[] for all * * subframes (both quantized and unquantized) * *------------------------------------------------------------------------*/ /* LP analysis */ lpc(st->lpcSt, mode, st->p_window, st->p_window_12k2, A_t); fwc (); /* function worst case */ /* From A(z) to lsp. LSP quantization and interpolation */ lsp(st->lspSt, mode, *usedMode, A_t, Aq_t, lsp_new, &ana); fwc (); /* function worst case */ /* Buffer lsp's and energy */ dtx_buffer(st->dtx_encSt, lsp_new, st->new_speech); /* Check if in DTX mode */ test(); if (sub(*usedMode, MRDTX) == 0) { dtx_enc(st->dtx_encSt, compute_sid_flag, st->lspSt->qSt, st->gainQuantSt->gc_predSt, &ana); Set_zero(st->old_exc, PIT_MAX + L_INTERPOL); Set_zero(st->mem_w0, M); Set_zero(st->mem_err, M); Set_zero(st->zero, L_SUBFR); Set_zero(st->hvec, L_SUBFR); /* set to zero "h1[-L_SUBFR..-1]" */ /* Reset lsp states */ lsp_reset(st->lspSt); Copy(lsp_new, st->lspSt->lsp_old, M); Copy(lsp_new, st->lspSt->lsp_old_q, M); /* Reset clLtp states */ cl_ltp_reset(st->clLtpSt); st->sharp = SHARPMIN; move16 (); } else { /* check resonance in the filter */ lsp_flag = check_lsp(st->tonStabSt, st->lspSt->lsp_old); move16 (); } /*----------------------------------------------------------------------* * - Find the weighted input speech w_sp[] for the whole speech frame * * - Find the open-loop pitch delay for first 2 subframes * * - Set the range for searching closed-loop pitch in 1st subframe * * - Find the open-loop pitch delay for last 2 subframes * *----------------------------------------------------------------------*/ #ifdef VAD2 if (st->dtx) { /* no test() call since this if is only in simulation env */ st->vadSt->L_Rmax = 0; move32 (); st->vadSt->L_R0 = 0; move32 (); } #endif for(subfrNr = 0, i_subfr = 0; subfrNr < L_FRAME/L_FRAME_BY2; subfrNr++, i_subfr += L_FRAME_BY2) { /* Pre-processing on 80 samples */ pre_big(mode, gamma1, gamma1_12k2, gamma2, A_t, i_subfr, st->speech, st->mem_w, st->wsp); test (); test (); if ((sub(mode, MR475) != 0) && (sub(mode, MR515) != 0)) { /* Find open loop pitch lag for two subframes */ ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[i_subfr], &T_op[subfrNr], st->old_lags, st->ol_gain_flg, subfrNr, st->dtx); } } fwc (); /* function worst case */ test (); test(); if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0)) { /* Find open loop pitch lag for ONE FRAME ONLY */ /* search on 160 samples */ ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[0], &T_op[0], st->old_lags, st->ol_gain_flg, 1, st->dtx); T_op[1] = T_op[0]; move16 (); } fwc (); /* function worst case */ #ifdef VAD2 if (st->dtx) { /* no test() call since this if is only in simulation env */ LTP_flag_update(st->vadSt, mode); } #endif #ifndef VAD2 /* run VAD pitch detection */ if (st->dtx) { /* no test() call since this if is only in simulation env */ vad_pitch_detection(st->vadSt, T_op); } #endif fwc (); /* function worst case */ if (sub(*usedMode, MRDTX) == 0) { goto the_end; } /*------------------------------------------------------------------------* * Loop for every subframe in the analysis frame * *------------------------------------------------------------------------* * To find the pitch and innovation parameters. The subframe size is * * L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times. * * - find the weighted LPC coefficients * * - find the LPC residual signal res[] * * - compute the target signal for pitch search * * - compute impulse response of weighted synthesis filter (h1[]) * * - find the closed-loop pitch parameters * * - encode the pitch dealy * * - update the impulse response h1[] by including fixed-gain pitch * * - find target vector for codebook search * * - codebook search * * - encode codebook address * * - VQ of pitch and codebook gains * * - find synthesis speech * * - update states of weighting filter * *------------------------------------------------------------------------*/ A = A_t; /* pointer to interpolated LPC parameters */ Aq = Aq_t; /* pointer to interpolated quantized LPC parameters */ evenSubfr = 0; move16 (); subfrNr = -1; move16 (); for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { subfrNr = add(subfrNr, 1); evenSubfr = sub(1, evenSubfr); /* Save states for the MR475 mode */ test(); test(); if ((evenSubfr != 0) && (sub(*usedMode, MR475) == 0)) { Copy(st->mem_syn, mem_syn_save, M); Copy(st->mem_w0, mem_w0_save, M); Copy(st->mem_err, mem_err_save, M); sharp_save = st->sharp; } /*-----------------------------------------------------------------* * - Preprocessing of subframe * *-----------------------------------------------------------------*/ test(); if (sub(*usedMode, MR475) != 0) { subframePreProc(*usedMode, gamma1, gamma1_12k2, gamma2, A, Aq, &st->speech[i_subfr], st->mem_err, st->mem_w0, st->zero, st->ai_zero, &st->exc[i_subfr], st->h1, xn, res, st->error); } else { /* MR475 */ subframePreProc(*usedMode, gamma1, gamma1_12k2, gamma2, A, Aq, &st->speech[i_subfr], st->mem_err, mem_w0_save, st->zero, st->ai_zero, &st->exc[i_subfr], st->h1, xn, res, st->error); /* save impulse response (modified in cbsearch) */ test (); if (evenSubfr != 0) { Copy (st->h1, h1_sf0, L_SUBFR); } } /* copy the LP residual (res2 is modified in the CL LTP search) */ Copy (res, res2, L_SUBFR); fwc (); /* function worst case */ /*-----------------------------------------------------------------* * - Closed-loop LTP search * *-----------------------------------------------------------------*/ cl_ltp(st->clLtpSt, st->tonStabSt, *usedMode, i_subfr, T_op, st->h1, &st->exc[i_subfr], res2, xn, lsp_flag, xn2, y1, &T0, &T0_frac, &gain_pit, gCoeff, &ana, &gp_limit); /* update LTP lag history */ move16 (); test(); test (); if ((subfrNr == 0) && (st->ol_gain_flg[0] > 0)) { st->old_lags[1] = T0; move16 (); } move16 (); test(); test (); if ((sub(subfrNr, 3) == 0) && (st->ol_gain_flg[1] > 0)) { st->old_lags[0] = T0; move16 (); } fwc (); /* function worst case */ /*-----------------------------------------------------------------* * - Inovative codebook search (find index and gain) * *-----------------------------------------------------------------*/ cbsearch(xn2, st->h1, T0, st->sharp, gain_pit, res2, code, y2, &ana, *usedMode, subfrNr); fwc (); /* function worst case */ /*------------------------------------------------------* * - Quantization of gains. * *------------------------------------------------------*/ gainQuant(st->gainQuantSt, *usedMode, res, &st->exc[i_subfr], code, xn, xn2, y1, y2, gCoeff, evenSubfr, gp_limit, &gain_pit_sf0, &gain_code_sf0, &gain_pit, &gain_code, &ana); fwc (); /* function worst case */ /* update gain history */ update_gp_clipping(st->tonStabSt, gain_pit); test(); if (sub(*usedMode, MR475) != 0) { /* Subframe Post Porcessing */ subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, gain_code, Aq, synth, xn, code, y1, y2, st->mem_syn, st->mem_err, st->mem_w0, st->exc, &st->sharp); } else { test(); if (evenSubfr != 0) { i_subfr_sf0 = i_subfr; move16 (); Copy(xn, xn_sf0, L_SUBFR); Copy(y2, y2_sf0, L_SUBFR); Copy(code, code_sf0, L_SUBFR); T0_sf0 = T0; move16 (); T0_frac_sf0 = T0_frac; move16 (); /* Subframe Post Porcessing */ subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, gain_code, Aq, synth, xn, code, y1, y2, mem_syn_save, st->mem_err, mem_w0_save, st->exc, &st->sharp); st->sharp = sharp_save; move16(); } else { /* update both subframes for the MR475 */ /* Restore states for the MR475 mode */ Copy(mem_err_save, st->mem_err, M); /* re-build excitation for sf 0 */ Pred_lt_3or6(&st->exc[i_subfr_sf0], T0_sf0, T0_frac_sf0, L_SUBFR, 1); Convolve(&st->exc[i_subfr_sf0], h1_sf0, y1, L_SUBFR); Aq -= MP1; subframePostProc(st->speech, *usedMode, i_subfr_sf0, gain_pit_sf0, gain_code_sf0, Aq, synth, xn_sf0, code_sf0, y1, y2_sf0, st->mem_syn, st->mem_err, st->mem_w0, st->exc, &sharp_save); /* overwrites sharp_save */ Aq += MP1; /* re-run pre-processing to get xn right (needed by postproc) */ /* (this also reconstructs the unsharpened h1 for sf 1) */ subframePreProc(*usedMode, gamma1, gamma1_12k2, gamma2, A, Aq, &st->speech[i_subfr], st->mem_err, st->mem_w0, st->zero, st->ai_zero, &st->exc[i_subfr], st->h1, xn, res, st->error); /* re-build excitation sf 1 (changed if lag < L_SUBFR) */ Pred_lt_3or6(&st->exc[i_subfr], T0, T0_frac, L_SUBFR, 1); Convolve(&st->exc[i_subfr], st->h1, y1, L_SUBFR); subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, gain_code, Aq, synth, xn, code, y1, y2, st->mem_syn, st->mem_err, st->mem_w0, st->exc, &st->sharp); } } fwc (); /* function worst case */ A += MP1; /* interpolated LPC parameters for next subframe */ Aq += MP1; } Copy(&st->old_exc[L_FRAME], &st->old_exc[0], PIT_MAX + L_INTERPOL); the_end: /*--------------------------------------------------* * Update signal for next frame. * *--------------------------------------------------*/ Copy(&st->old_wsp[L_FRAME], &st->old_wsp[0], PIT_MAX); Copy(&st->old_speech[L_FRAME], &st->old_speech[0], L_TOTAL - L_FRAME); fwc (); /* function worst case */ return 0; }
void fastiva_Dalvik_java_lang_System_arraycopy(java_lang_Object_p arg0, jint srcPos, java_lang_Object_p arg2, jint dstPos, jint length) { ArrayObject* srcArray = (ArrayObject*) arg0; ArrayObject* dstArray = (ArrayObject*) arg2; #endif /* Check for null pointers. */ if (srcArray == NULL) { dvmThrowNullPointerException("src == null"); THROW_VOID(); } if (dstArray == NULL) { dvmThrowNullPointerException("dst == null"); THROW_VOID(); } /* Make sure source and destination are arrays. */ if (!dvmIsArray(srcArray)) { dvmThrowArrayStoreExceptionNotArray(((Object*)srcArray)->clazz, "source"); THROW_VOID(); } if (!dvmIsArray(dstArray)) { dvmThrowArrayStoreExceptionNotArray(((Object*)dstArray)->clazz, "destination"); THROW_VOID(); } /* avoid int overflow */ if (srcPos < 0 || dstPos < 0 || length < 0 || srcPos > (int) srcArray->length - length || dstPos > (int) dstArray->length - length) { dvmThrowExceptionFmt(gDvm.exArrayIndexOutOfBoundsException, "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d", srcArray->length, srcPos, dstArray->length, dstPos, length); THROW_VOID(); } ClassObject* srcClass = srcArray->clazz; ClassObject* dstClass = dstArray->clazz; char srcType = srcClass->descriptor[1]; char dstType = dstClass->descriptor[1]; /* * If one of the arrays holds a primitive type, the other array must * hold the same type. */ bool srcPrim = (srcType != '[' && srcType != 'L'); bool dstPrim = (dstType != '[' && dstType != 'L'); if (srcPrim || dstPrim) { if (srcPrim != dstPrim || srcType != dstType) { dvmThrowArrayStoreExceptionIncompatibleArrays(srcClass, dstClass); THROW_VOID(); } if (false) ALOGD("arraycopy prim[%c] dst=%p %d src=%p %d len=%d", srcType, dstArray->contents, dstPos, srcArray->contents, srcPos, length); switch (srcType) { case 'B': case 'Z': /* 1 byte per element */ memmove((u1*) dstArray->contents + dstPos, (const u1*) srcArray->contents + srcPos, length); break; case 'C': case 'S': /* 2 bytes per element */ move16((u1*) dstArray->contents + dstPos * 2, (const u1*) srcArray->contents + srcPos * 2, length * 2); break; case 'F': case 'I': /* 4 bytes per element */ move32((u1*) dstArray->contents + dstPos * 4, (const u1*) srcArray->contents + srcPos * 4, length * 4); break; case 'D': case 'J': /* * 8 bytes per element. We don't need to guarantee atomicity * of the entire 64-bit word, so we can use the 32-bit copier. */ move32((u1*) dstArray->contents + dstPos * 8, (const u1*) srcArray->contents + srcPos * 8, length * 8); break; default: /* illegal array type */ ALOGE("Weird array type '%s'", srcClass->descriptor); dvmAbort(); } } else { /* * Neither class is primitive. See if elements in "src" are instances * of elements in "dst" (e.g. copy String to String or String to * Object). */ const int width = sizeof(Object*); if (srcClass->arrayDim == dstClass->arrayDim && dvmInstanceof(srcClass, dstClass)) { /* * "dst" can hold "src"; copy the whole thing. */ if (false) ALOGD("arraycopy ref dst=%p %d src=%p %d len=%d", dstArray->contents, dstPos * width, srcArray->contents, srcPos * width, length * width); move32((u1*)dstArray->contents + dstPos * width, (const u1*)srcArray->contents + srcPos * width, length * width); dvmWriteBarrierArray(dstArray, dstPos, dstPos+length); } else { /* * The arrays are not fundamentally compatible. However, we * may still be able to do this if the destination object is * compatible (e.g. copy Object[] to String[], but the Object * being copied is actually a String). We need to copy elements * one by one until something goes wrong. * * Because of overlapping moves, what we really want to do * is compare the types and count up how many we can move, * then call move32() to shift the actual data. If we just * start from the front we could do a smear rather than a move. */ Object** srcObj; int copyCount; ClassObject* clazz = NULL; srcObj = ((Object**)(void*)srcArray->contents) + srcPos; if (length > 0 && srcObj[0] != NULL) { clazz = srcObj[0]->clazz; if (!dvmCanPutArrayElement(clazz, dstClass)) clazz = NULL; } for (copyCount = 0; copyCount < length; copyCount++) { if (srcObj[copyCount] != NULL && srcObj[copyCount]->clazz != clazz && !dvmCanPutArrayElement(srcObj[copyCount]->clazz, dstClass)) { /* can't put this element into the array */ break; } } if (false) ALOGD("arraycopy iref dst=%p %d src=%p %d count=%d of %d", dstArray->contents, dstPos * width, srcArray->contents, srcPos * width, copyCount, length); move32((u1*)dstArray->contents + dstPos * width, (const u1*)srcArray->contents + srcPos * width, copyCount * width); dvmWriteBarrierArray(dstArray, 0, copyCount); if (copyCount != length) { dvmThrowArrayStoreExceptionIncompatibleArrayElement(srcPos + copyCount, srcObj[copyCount]->clazz, dstClass); THROW_VOID(); } } } RETURN_VOID(); }
/************************************************************************* * * FUNCTION: G_pitch * * PURPOSE: Compute the pitch (adaptive codebook) gain. * Result in Q14 (NOTE: 12.2 bit exact using Q12) * * DESCRIPTION: * The adaptive codebook gain is given by * * g = <x[], y[]> / <y[], y[]> * * where x[] is the target vector, y[] is the filtered adaptive * codevector, and <> denotes dot product. * The gain is limited to the range [0,1.2] (=0..19661 Q14) * *************************************************************************/ Word16 G_pitch ( /* o : Gain of pitch lag saturated to 1.2 */ enum Mode mode, /* i : AMR mode */ Word16 xn[], /* i : Pitch target. */ Word16 y1[], /* i : Filtered adaptive codebook. */ Word16 g_coeff[], /* i : Correlations need for gain quantization */ Word16 L_subfr /* i : Length of subframe. */ ) { Word16 i; Word16 xy, yy, exp_xy, exp_yy, gain; Word32 s; Word16 scaled_y1[L_SUBFR]; /* Usually dynamic allocation of (L_subfr) */ /* divide "y1[]" by 4 to avoid overflow */ for (i = 0; i < L_subfr; i++) { scaled_y1[i] = shr (y1[i], 2); move16 (); } /* Compute scalar product <y1[],y1[]> */ /* Q12 scaling / MR122 */ Overflow = 0; move16 (); s = 1L; move32 (); /* Avoid case of all zeros */ for (i = 0; i < L_subfr; i++) { s = L_mac (s, y1[i], y1[i]); } test (); if (Overflow == 0) /* Test for overflow */ { exp_yy = norm_l (s); yy = round (L_shl (s, exp_yy)); } else { s = 1L; move32 (); /* Avoid case of all zeros */ for (i = 0; i < L_subfr; i++) { s = L_mac (s, scaled_y1[i], scaled_y1[i]); } exp_yy = norm_l (s); yy = round (L_shl (s, exp_yy)); exp_yy = sub (exp_yy, 4); } /* Compute scalar product <xn[],y1[]> */ Overflow = 0; move16 (); s = 1L; move32 (); /* Avoid case of all zeros */ for (i = 0; i < L_subfr; i++) { s = L_mac(s, xn[i], y1[i]); } test (); if (Overflow == 0) { exp_xy = norm_l (s); xy = round (L_shl (s, exp_xy)); } else { s = 1L; move32 (); /* Avoid case of all zeros */ for (i = 0; i < L_subfr; i++) { s = L_mac (s, xn[i], scaled_y1[i]); } exp_xy = norm_l (s); xy = round (L_shl (s, exp_xy)); exp_xy = sub (exp_xy, 2); } g_coeff[0] = yy; move16 (); g_coeff[1] = sub (15, exp_yy); move16 (); g_coeff[2] = xy; move16 (); g_coeff[3] = sub (15, exp_xy); move16 (); /* If (xy < 4) gain = 0 */ i = sub (xy, 4); test (); if (i < 0) return ((Word16) 0); /* compute gain = xy/yy */ xy = shr (xy, 1); /* Be sure xy < yy */ gain = div_s (xy, yy); i = sub (exp_xy, exp_yy); /* Denormalization of division */ gain = shr (gain, i); /* if(gain >1.2) gain = 1.2 */ test (); if (sub (gain, 19661) > 0) { gain = 19661; move16 (); } test (); if (sub(mode, MR122) == 0) { /* clear 2 LSBits */ gain = gain & 0xfffC; logic16 (); } return (gain); }
/************************************************************************* * * FUNCTION: Qua_gain() * * PURPOSE: Quantization of pitch and codebook gains. * (using predicted codebook gain) * *************************************************************************/ Word16 Qua_gain( /* o : index of quantization. */ enum Mode mode, /* i : AMR mode */ Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ Word16 frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */ Word16 exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */ /* (frac_coeff and exp_coeff computed in */ /* calc_filt_energies()) */ Word16 gp_limit, /* i : pitch gain limit */ Word16 *gain_pit, /* o : Pitch gain, Q14 */ Word16 *gain_cod, /* o : Code gain, Q1 */ Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ /* (for MR122 MA predictor update) */ Word16 *qua_ener /* o : quantized energy error, Q10 */ /* (for other MA predictor update) */ ) { const Word16 *p; Word16 i, j, index = 0; Word16 gcode0, e_max, exp_code; Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod; Word16 coeff[5], coeff_lo[5]; Word16 exp_max[5]; Word32 L_tmp, dist_min; const Word16 *table_gain; Word16 table_len; test(); test(); test(); if ( sub (mode, MR102) == 0 || sub (mode, MR74) == 0 || sub (mode, MR67) == 0) { table_len = VQ_SIZE_HIGHRATES; move16 (); table_gain = table_gain_highrates; move16 (); } else { table_len = VQ_SIZE_LOWRATES; move16 (); table_gain = table_gain_lowrates; move16 (); } /*-------------------------------------------------------------------* * predicted codebook gain * * ~~~~~~~~~~~~~~~~~~~~~~~ * * gc0 = 2^exp_gcode0 + 2^frac_gcode0 * * * * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) * *-------------------------------------------------------------------*/ gcode0 = extract_l(Pow2(14, frac_gcode0)); /*-------------------------------------------------------------------* * Scaling considerations: * * ~~~~~~~~~~~~~~~~~~~~~~~ * *-------------------------------------------------------------------*/ /* * The error energy (sum) to be minimized consists of five terms, t[0..4]. * * t[0] = gp^2 * <y1 y1> * t[1] = -2*gp * <xn y1> * t[2] = gc^2 * <y2 y2> * t[3] = -2*gc * <xn y2> * t[4] = 2*gp*gc * <y1 y2> * */ /* determine the scaling exponent for g_code: ec = ec0 - 11 */ exp_code = sub(exp_gcode0, 11); /* calculate exp_max[i] = s[i]-1 */ exp_max[0] = sub(exp_coeff[0], 13); move16 (); exp_max[1] = sub(exp_coeff[1], 14); move16 (); exp_max[2] = add(exp_coeff[2], add(15, shl(exp_code, 1))); move16 (); exp_max[3] = add(exp_coeff[3], exp_code); move16 (); exp_max[4] = add(exp_coeff[4], add(1, exp_code)); move16 (); /*-------------------------------------------------------------------* * Find maximum exponent: * * ~~~~~~~~~~~~~~~~~~~~~~ * * * * For the sum operation, all terms must have the same scaling; * * that scaling should be low enough to prevent overflow. There- * * fore, the maximum scale is determined and all coefficients are * * re-scaled: * * * * e_max = max(exp_max[i]) + 1; * * e = exp_max[i]-e_max; e <= 0! * * c[i] = c[i]*2^e * *-------------------------------------------------------------------*/ e_max = exp_max[0]; move16 (); for (i = 1; i < 5; i++) { move16(); test(); if (sub(exp_max[i], e_max) > 0) { e_max = exp_max[i]; move16 (); } } e_max = add(e_max, 1); /* To avoid overflow */ for (i = 0; i < 5; i++) { j = sub(e_max, exp_max[i]); L_tmp = L_deposit_h(frac_coeff[i]); L_tmp = L_shr(L_tmp, j); L_Extract(L_tmp, &coeff[i], &coeff_lo[i]); } /*-------------------------------------------------------------------* * Codebook search: * * ~~~~~~~~~~~~~~~~ * * * * For each pair (g_pitch, g_fac) in the table calculate the * * terms t[0..4] and sum them up; the result is the mean squared * * error for the quantized gains from the table. The index for the * * minimum MSE is stored and finally used to retrieve the quantized * * gains * *-------------------------------------------------------------------*/ /* start with "infinite" MSE */ dist_min = MAX_32; move32(); p = &table_gain[0]; move16 (); for (i = 0; i < table_len; i++) { g_pitch = *p++; move16 (); g_code = *p++; move16 (); /* this is g_fac */ p++; /* skip log2(g_fac) */ p++; /* skip 20*log10(g_fac) */ test (); if (sub(g_pitch, gp_limit) <= 0) { g_code = mult(g_code, gcode0); g2_pitch = mult(g_pitch, g_pitch); g2_code = mult(g_code, g_code); g_pit_cod = mult(g_code, g_pitch); L_tmp = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch); L_tmp = L_add(L_tmp, Mpy_32_16(coeff[1], coeff_lo[1], g_pitch)); L_tmp = L_add(L_tmp, Mpy_32_16(coeff[2], coeff_lo[2], g2_code)); L_tmp = L_add(L_tmp, Mpy_32_16(coeff[3], coeff_lo[3], g_code)); L_tmp = L_add(L_tmp, Mpy_32_16(coeff[4], coeff_lo[4], g_pit_cod)); /* store table index if MSE for this index is lower than the minimum MSE seen so far */ test (); if (L_sub(L_tmp, dist_min) < (Word32) 0) { dist_min = L_tmp; move32 (); index = i; move16 (); } } } /*------------------------------------------------------------------* * read quantized gains and new values for MA predictor memories * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *------------------------------------------------------------------*/ /* Read the quantized gains */ p = &table_gain[shl (index, 2)]; move16 (); *gain_pit = *p++; move16(); g_code = *p++; move16(); *qua_ener_MR122 = *p++; move16(); *qua_ener = *p; move16(); /*------------------------------------------------------------------* * calculate final fixed codebook gain: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * gc = gc0 * g * *------------------------------------------------------------------*/ L_tmp = L_mult(g_code, gcode0); L_tmp = L_shr(L_tmp, sub(10, exp_gcode0)); *gain_cod = extract_h(L_tmp); return index; }
static Word16 Lag_max ( /* o : lag found */ vadState *vadSt, /* i/o : VAD state struct */ Word32 corr[], /* i : correlation vector. */ Word16 scal_sig[], /* i : scaled signal. */ Word16 scal_fac, /* i : scaled signal factor. */ Word16 scal_flag, /* i : if 1 use EFR compatible scaling */ Word16 L_frame, /* i : length of frame to compute pitch */ Word16 lag_max, /* i : maximum lag */ Word16 lag_min, /* i : minimum lag */ Word16 *cor_max, /* o : normalized correlation of selected lag */ Flag dtx /* i : dtx flag; use dtx=1, do not use dtx=0 */ ) #endif { Word16 i, j; Word16 *p; Word32 max, t0; Word16 max_h, max_l, ener_h, ener_l; Word16 p_max = 0; /* initialization only needed to keep gcc silent */ max = MIN_32; move32 (); p_max = lag_max; move16 (); for (i = lag_max, j = (PIT_MAX-lag_max-1); i >= lag_min; i--, j--) { test (); if (L_sub (corr[-i], max) >= 0) { max = corr[-i]; move32 (); p_max = i; move16 (); } } /* compute energy */ t0 = 0; move32 (); p = &scal_sig[-p_max]; move16 (); for (i = 0; i < L_frame; i++, p++) { t0 = L_mac (t0, *p, *p); } /* 1/sqrt(energy) */ if (dtx) { /* no test() call since this if is only in simulation env */ #ifdef VAD2 *rmax = max; move32(); *r0 = t0; move32(); #else /* check tone */ vad_tone_detection (vadSt, max, t0); #endif } t0 = Inv_sqrt (t0); move32 (); /* function result */ test(); if (scal_flag) { t0 = L_shl (t0, 1); } /* max = max/sqrt(energy) */ L_Extract (max, &max_h, &max_l); L_Extract (t0, &ener_h, &ener_l); t0 = Mpy_32 (max_h, max_l, ener_h, ener_l); test(); if (scal_flag) { t0 = L_shr (t0, scal_fac); *cor_max = extract_h (L_shl (t0, 15)); /* divide by 2 */ } else { *cor_max = extract_l(t0); } return (p_max); }
/************************************************************************* * * FUNCTION: calc_unfilt_energies * * PURPOSE: calculation of several energy coefficients for unfiltered * excitation signals and the LTP coding gain * * frac_en[0]*2^exp_en[0] = <res res> // LP residual energy * frac_en[1]*2^exp_en[1] = <exc exc> // LTP residual energy * frac_en[2]*2^exp_en[2] = <exc code> // LTP/CB innovation dot product * frac_en[3]*2^exp_en[3] = <lres lres> // LTP residual energy * // (lres = res - gain_pit*exc) * ltpg = log2(LP_res_en / LTP_res_en) * *************************************************************************/ void calc_unfilt_energies( Word16 res[], /* i : LP residual, Q0 */ Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ Word16 code[], /* i : CB innovation (unfiltered), Q13 */ Word16 gain_pit, /* i : pitch gain, Q14 */ Word16 L_subfr, /* i : Subframe length */ Word16 frac_en[], /* o : energy coefficients (4), fraction part, Q15 */ Word16 exp_en[], /* o : energy coefficients (4), exponent part, Q0 */ Word16 *ltpg /* o : LTP coding gain (log2()), Q13 */ ) { Word32 s, L_temp; Word16 i, exp, tmp; Word16 ltp_res_en, pred_gain; Word16 ltpg_exp, ltpg_frac; /* Compute residual energy */ s = L_mac((Word32) 0, res[0], res[0]); for (i = 1; i < L_subfr; i++) s = L_mac(s, res[i], res[i]); /* ResEn := 0 if ResEn < 200.0 (= 400 Q1) */ test(); if (L_sub (s, 400L) < 0) { frac_en[0] = 0; move16 (); exp_en[0] = -15; move16 (); } else { exp = norm_l(s); frac_en[0] = extract_h(L_shl(s, exp)); move16 (); exp_en[0] = sub(15, exp); move16 (); } /* Compute ltp excitation energy */ s = L_mac((Word32) 0, exc[0], exc[0]); for (i = 1; i < L_subfr; i++) s = L_mac(s, exc[i], exc[i]); exp = norm_l(s); frac_en[1] = extract_h(L_shl(s, exp)); move16 (); exp_en[1] = sub(15, exp); move16 (); /* Compute scalar product <exc[],code[]> */ s = L_mac((Word32) 0, exc[0], code[0]); for (i = 1; i < L_subfr; i++) s = L_mac(s, exc[i], code[i]); exp = norm_l(s); frac_en[2] = extract_h(L_shl(s, exp)); move16 (); exp_en[2] = sub(16-14, exp); move16 (); /* Compute energy of LTP residual */ s = 0L; move32 (); for (i = 0; i < L_subfr; i++) { L_temp = L_mult(exc[i], gain_pit); L_temp = L_shl(L_temp, 1); tmp = sub(res[i], round(L_temp)); /* LTP residual, Q0 */ s = L_mac (s, tmp, tmp); } exp = norm_l(s); ltp_res_en = extract_h (L_shl (s, exp)); exp = sub (15, exp); frac_en[3] = ltp_res_en; move16 (); exp_en[3] = exp; move16 (); /* calculate LTP coding gain, i.e. energy reduction LP res -> LTP res */ test (); test (); if (ltp_res_en > 0 && frac_en[0] != 0) { /* gain = ResEn / LTPResEn */ pred_gain = div_s (shr (frac_en[0], 1), ltp_res_en); exp = sub (exp, exp_en[0]); /* L_temp = ltpGain * 2^(30 + exp) */ L_temp = L_deposit_h (pred_gain); /* L_temp = ltpGain * 2^27 */ L_temp = L_shr (L_temp, add (exp, 3)); /* Log2 = log2() + 27 */ Log2(L_temp, <pg_exp, <pg_frac); /* ltpg = log2(LtpGain) * 2^13 --> range: +- 4 = +- 12 dB */ L_temp = L_Comp (sub (ltpg_exp, 27), ltpg_frac); *ltpg = round (L_shl (L_temp, 13)); /* Q13 */ } else { *ltpg = 0; move16 (); } }
static void build_code ( Word16 codvec[], /* i : position of pulses */ Word16 sign[], /* i : sign of d[n] */ Word16 cod[], /* o : innovative code vector */ Word16 h[], /* i : impulse response of weighted synthesis filter*/ Word16 y[], /* o : filtered innovative code */ Word16 sign_indx[], /* o : signs of 4 pulses (signs only) */ Word16 pos_indx[] /* o : position index of 8 pulses(position only) */ ) { Word16 i, j, k, track, sign_index, pos_index, _sign[NB_PULSE]; Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7; Word32 s; for (i = 0; i < L_CODE; i++) { cod[i] = 0; move16 (); } for (i = 0; i < NB_TRACK_MR102; i++) { pos_indx[i] = -1; move16 (); sign_indx[i] = -1; move16 (); } for (k = 0; k < NB_PULSE; k++) { /* read pulse position */ i = codvec[k]; move16 (); /* read sign */ j = sign[i]; move16 (); pos_index = shr(i, 2); /* index = pos/4 */ track = i & 3; logic16 (); /* track = pos%4 */ test (); if (j > 0) { cod[i] = add (cod[i], POS_CODE); move16 (); _sign[k] = POS_SIGN; move16 (); sign_index = 0; /* bit=0 -> positive pulse */ move16 (); } else { cod[i] = sub (cod[i], NEG_CODE); move16 (); _sign[k] = NEG_SIGN; move16 (); sign_index = 1; move16 (); /* bit=1 => negative pulse */ /* index = add (index, 8); 1 = negative old code */ } test (); move16 (); if (pos_indx[track] < 0) { /* first set first NB_TRACK pulses */ pos_indx[track] = pos_index; move16 (); sign_indx[track] = sign_index; move16 (); } else { /* 2nd row of pulses , test if positions needs to be switched */ test (); logic16 (); logic16 (); if (((sign_index ^ sign_indx[track]) & 1) == 0) { /* sign of 1st pulse == sign of 2nd pulse */ test (); if (sub (pos_indx[track], pos_index) <= 0) { /* no swap */ pos_indx[track + NB_TRACK_MR102] = pos_index; move16 (); } else { /* swap*/ pos_indx[track + NB_TRACK_MR102] = pos_indx[track]; move16 (); pos_indx[track] = pos_index; move16 (); sign_indx[track] = sign_index; move16 (); } } else { /* sign of 1st pulse != sign of 2nd pulse */ test (); if (sub (pos_indx[track], pos_index) <= 0) { /*swap*/ pos_indx[track + NB_TRACK_MR102] = pos_indx[track]; move16 (); pos_indx[track] = pos_index; move16 (); sign_indx[track] = sign_index; move16 (); } else { /*no swap */ pos_indx[track + NB_TRACK_MR102] = pos_index; move16 (); } } } } p0 = h - codvec[0]; move16 (); p1 = h - codvec[1]; move16 (); p2 = h - codvec[2]; move16 (); p3 = h - codvec[3]; move16 (); p4 = h - codvec[4]; move16 (); p5 = h - codvec[5]; move16 (); p6 = h - codvec[6]; move16 (); p7 = h - codvec[7]; move16 (); for (i = 0; i < L_CODE; i++) { s = 0; move32 (); s = L_mac (s, *p0++, _sign[0]); s = L_mac (s, *p1++, _sign[1]); s = L_mac (s, *p2++, _sign[2]); s = L_mac (s, *p3++, _sign[3]); s = L_mac (s, *p4++, _sign[4]); s = L_mac (s, *p5++, _sign[5]); s = L_mac (s, *p6++, _sign[6]); s = L_mac (s, *p7++, _sign[7]); y[i] = round (s); move16 (); } }
Word16 vad2 (Word16 * farray_ptr, vadState2 * st) { /* * The channel table is defined below. In this table, the * lower and higher frequency coefficients for each of the 16 * channels are specified. The table excludes the coefficients * with numbers 0 (DC), 1, and 64 (Foldover frequency). */ const static Word16 ch_tbl[NUM_CHAN][2] = { {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, {14, 16}, {17, 19}, {20, 22}, {23, 26}, {27, 30}, {31, 35}, {36, 41}, {42, 48}, {49, 55}, {56, 63} }; /* channel energy scaling table - allows efficient division by number * of DFT bins in the channel: 1/2, 1/3, 1/4, etc. */ const static Word16 ch_tbl_sh[NUM_CHAN] = { 16384, 16384, 16384, 16384, 16384, 16384, 10923, 10923, 10923, 8192, 8192, 6554, 5461, 4681, 4681, 4096 }; /* * The voice metric table is defined below. It is a non- * linear table with a deadband near zero. It maps the SNR * index (quantized SNR value) to a number that is a measure * of voice quality. */ const static Word16 vm_tbl[90] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 23, 24, 24, 25, 26, 27, 28, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50 }; /* hangover as a function of peak SNR (3 dB steps) */ const static Word16 hangover_table[20] = { 30, 30, 30, 30, 30, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 8, 8, 8 }; /* burst sensitivity as a function of peak SNR (3 dB steps) */ const static Word16 burstcount_table[20] = { 8, 8, 8, 8, 8, 8, 8, 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4 }; /* voice metric sensitivity as a function of peak SNR (3 dB steps) */ const static Word16 vm_threshold_table[20] = { 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 40, 51, 71, 100, 139, 191, 257, 337, 432 }; /* State tables that use 22,9 or 27,4 scaling for ch_enrg[] */ const static Word16 noise_floor_chan[2] = {NOISE_FLOOR_CHAN_0, NOISE_FLOOR_CHAN_1}; const static Word16 min_chan_enrg[2] = {MIN_CHAN_ENRG_0, MIN_CHAN_ENRG_1}; const static Word16 ine_noise[2] = {INE_NOISE_0, INE_NOISE_1}; const static Word16 fbits[2] = {FRACTIONAL_BITS_0, FRACTIONAL_BITS_1}; const static Word16 state_change_shift_r[2] = {STATE_1_TO_0_SHIFT_R, STATE_0_TO_1_SHIFT_R}; /* Energy scale table given 30,1 input scaling (also account for -6 dB shift on input) */ const static Word16 enrg_norm_shift[2] = {(FRACTIONAL_BITS_0-1+2), (FRACTIONAL_BITS_1-1+2)}; /* Automatic variables */ Word32 Lenrg; /* scaled as 30,1 */ Word32 Ltne; /* scaled as 22,9 */ Word32 Ltce; /* scaled as 22,9 or 27,4 */ Word16 tne_db; /* scaled as 7,8 */ Word16 tce_db; /* scaled as 7,8 */ Word16 input_buffer[FRM_LEN]; /* used for block normalising input data */ Word16 data_buffer[FFT_LEN]; /* used for in-place FFT */ Word16 ch_snr[NUM_CHAN]; /* scaled as 7,8 */ Word16 ch_snrq; /* scaled as 15,0 (in 0.375 dB steps) */ Word16 vm_sum; /* scaled as 15,0 */ Word16 ch_enrg_dev; /* scaled as 7,8 */ Word32 Lpeak; /* maximum channel energy */ Word16 p2a_flag; /* flag to indicate spectral peak-to-average ratio > 10 dB */ Word16 ch_enrg_db[NUM_CHAN]; /* scaled as 7,8 */ Word16 ch_noise_db; /* scaled as 7,8 */ Word16 alpha; /* scaled as 0,15 */ Word16 one_m_alpha; /* scaled as 0,15 */ Word16 update_flag; /* set to indicate a background noise estimate update */ Word16 i, j, j1, j2; /* Scratch variables */ Word16 hi1, lo1; Word32 Ltmp, Ltmp1, Ltmp2; Word16 tmp; Word16 normb_shift; /* block norm shift count */ Word16 ivad; /* intermediate VAD decision (return value) */ Word16 tsnrq; /* total signal-to-noise ratio (quantized 3 dB steps) scaled as 15,0 */ Word16 xt; /* instantaneous frame SNR in dB, scaled as 7,8 */ Word16 state_change; /* Increment frame counter */ st->Lframe_cnt = L_add(st->Lframe_cnt, 1); /* Block normalize the input */ normb_shift = block_norm(farray_ptr, input_buffer, FRM_LEN, FFT_HEADROOM); /* Pre-emphasize the input data and store in the data buffer with the appropriate offset */ for (i = 0; i < DELAY; i++) { data_buffer[i] = 0; move16(); } st->pre_emp_mem = shr_r(st->pre_emp_mem, sub(st->last_normb_shift, normb_shift)); st->last_normb_shift = normb_shift; move16(); data_buffer[DELAY] = add(input_buffer[0], mult(PRE_EMP_FAC, st->pre_emp_mem)); move16(); for (i = DELAY + 1, j = 1; i < DELAY + FRM_LEN; i++, j++) { data_buffer[i] = add(input_buffer[j], mult(PRE_EMP_FAC, input_buffer[j-1])); move16(); } st->pre_emp_mem = input_buffer[FRM_LEN-1]; move16(); for (i = DELAY + FRM_LEN; i < FFT_LEN; i++) { data_buffer[i] = 0; move16(); } /* Perform FFT on the data buffer */ r_fft(data_buffer); /* Use normb_shift factor to determine the scaling of the energy estimates */ state_change = 0; move16(); test(); if (st->shift_state == 0) { test(); if (sub(normb_shift, -FFT_HEADROOM+2) <= 0) { state_change = 1; move16(); st->shift_state = 1; move16(); } } else { test(); if (sub(normb_shift, -FFT_HEADROOM+5) >= 0) { state_change = 1; move16(); st->shift_state = 0; move16(); } } /* Scale channel energy estimate */ test(); if (state_change) { for (i = LO_CHAN; i <= HI_CHAN; i++) { st->Lch_enrg[i] = L_shr(st->Lch_enrg[i], state_change_shift_r[st->shift_state]); move32(); } } /* Estimate the energy in each channel */ test(); if (L_sub(st->Lframe_cnt, 1) == 0) { alpha = 32767; move16(); one_m_alpha = 0; move16(); } else { alpha = CEE_SM_FAC; move16(); one_m_alpha = ONE_MINUS_CEE_SM_FAC; move16(); } for (i = LO_CHAN; i <= HI_CHAN; i++) { Lenrg = 0; move16(); j1 = ch_tbl[i][0]; move16(); j2 = ch_tbl[i][1]; move16(); for (j = j1; j <= j2; j++) { Lenrg = L_mac(Lenrg, data_buffer[2 * j], data_buffer[2 * j]); Lenrg = L_mac(Lenrg, data_buffer[2 * j + 1], data_buffer[2 * j + 1]); } /* Denorm energy & scale 30,1 according to the state */ Lenrg = L_shr_r(Lenrg, sub(shl(normb_shift, 1), enrg_norm_shift[st->shift_state])); /* integrate over time: e[i] = (1-alpha)*e[i] + alpha*enrg/num_bins_in_chan */ tmp = mult(alpha, ch_tbl_sh[i]); L_Extract (Lenrg, &hi1, &lo1); Ltmp = Mpy_32_16(hi1, lo1, tmp); L_Extract (st->Lch_enrg[i], &hi1, &lo1); st->Lch_enrg[i] = L_add(Ltmp, Mpy_32_16(hi1, lo1, one_m_alpha)); move32(); test(); if (L_sub(st->Lch_enrg[i], min_chan_enrg[st->shift_state]) < 0) { st->Lch_enrg[i] = min_chan_enrg[st->shift_state]; move32(); } } /* Compute the total channel energy estimate (Ltce) */ Ltce = 0; move16(); for (i = LO_CHAN; i <= HI_CHAN; i++) { Ltce = L_add(Ltce, st->Lch_enrg[i]); } /* Calculate spectral peak-to-average ratio, set flag if p2a > 10 dB */ Lpeak = 0; move32(); for (i = LO_CHAN+2; i <= HI_CHAN; i++) /* Sine waves not valid for low frequencies */ { test(); if (L_sub(st->Lch_enrg [i], Lpeak) > 0) { Lpeak = st->Lch_enrg [i]; move32(); } } /* Set p2a_flag if peak (dB) > average channel energy (dB) + 10 dB */ /* Lpeak > Ltce/num_channels * 10^(10/10) */ /* Lpeak > (10/16)*Ltce */ L_Extract (Ltce, &hi1, &lo1); Ltmp = Mpy_32_16(hi1, lo1, 20480); test(); if (L_sub(Lpeak, Ltmp) > 0) { p2a_flag = TRUE; move16(); } else { p2a_flag = FALSE; move16(); } /* Initialize channel noise estimate to either the channel energy or fixed level */ /* Scale the energy appropriately to yield state 0 (22,9) scaling for noise */ test(); if (L_sub(st->Lframe_cnt, 4) <= 0) { test(); if (p2a_flag == TRUE) { for (i = LO_CHAN; i <= HI_CHAN; i++) { st->Lch_noise[i] = INE_NOISE_0; move32(); } } else { for (i = LO_CHAN; i <= HI_CHAN; i++) { test(); if (L_sub(st->Lch_enrg[i], ine_noise[st->shift_state]) < 0) { st->Lch_noise[i] = INE_NOISE_0; move32(); } else { test(); if (st->shift_state == 1) { st->Lch_noise[i] = L_shr(st->Lch_enrg[i], state_change_shift_r[0]); move32(); } else { st->Lch_noise[i] = st->Lch_enrg[i]; move32(); } } } } } /* Compute the channel energy (in dB), the channel SNRs, and the sum of voice metrics */ vm_sum = 0; move16(); for (i = LO_CHAN; i <= HI_CHAN; i++) { ch_enrg_db[i] = fn10Log10(st->Lch_enrg[i], fbits[st->shift_state]); move16(); ch_noise_db = fn10Log10(st->Lch_noise[i], FRACTIONAL_BITS_0); ch_snr[i] = sub(ch_enrg_db[i], ch_noise_db); move16(); /* quantize channel SNR in 3/8 dB steps (scaled 7,8 => 15,0) */ /* ch_snr = round((snr/(3/8))>>8) */ /* = round(((0.6667*snr)<<2)>>8) */ /* = round((0.6667*snr)>>6) */ ch_snrq = shr_r(mult(21845, ch_snr[i]), 6); /* Accumulate the sum of voice metrics */ test(); if (sub(ch_snrq, 89) < 0) { test(); if (ch_snrq > 0) { j = ch_snrq; move16(); } else { j = 0; move16(); } } else { j = 89; move16(); } vm_sum = add(vm_sum, vm_tbl[j]); } /* Initialize NOMINAL peak voice energy and average noise energy, calculate instantaneous SNR */ test(),test(),logic16(); if (L_sub(st->Lframe_cnt, 4) <= 0 || st->fupdate_flag == TRUE) { /* tce_db = (96 - 22 - 10*log10(64) (due to FFT)) scaled as 7,8 */ tce_db = 14320; move16(); st->negSNRvar = 0; move16(); st->negSNRbias = 0; move16(); /* Compute the total noise estimate (Ltne) */ Ltne = 0; move32(); for (i = LO_CHAN; i <= HI_CHAN; i++) { Ltne = L_add(Ltne, st->Lch_noise[i]); } /* Get total noise in dB */ tne_db = fn10Log10(Ltne, FRACTIONAL_BITS_0); /* Initialise instantaneous and long-term peak signal-to-noise ratios */ xt = sub(tce_db, tne_db); st->tsnr = xt; move16(); } else { /* Calculate instantaneous frame signal-to-noise ratio */ /* xt = 10*log10( sum(2.^(ch_snr*0.1*log2(10)))/length(ch_snr) ) */ Ltmp1 = 0; move32(); for (i=LO_CHAN; i<=HI_CHAN; i++) { /* Ltmp2 = ch_snr[i] * 0.1 * log2(10); (ch_snr scaled as 7,8) */ Ltmp2 = L_shr(L_mult(ch_snr[i], 10885), 8); L_Extract(Ltmp2, &hi1, &lo1); hi1 = add(hi1, 3); /* 2^3 to compensate for negative SNR */ Ltmp1 = L_add(Ltmp1, Pow2(hi1, lo1)); } xt = fn10Log10(Ltmp1, 4+3); /* average by 16, inverse compensation 2^3 */ /* Estimate long-term "peak" SNR */ test(),test(); if (sub(xt, st->tsnr) > 0) { /* tsnr = 0.9*tsnr + 0.1*xt; */ st->tsnr = round(L_add(L_mult(29491, st->tsnr), L_mult(3277, xt))); } /* else if (xt > 0.625*tsnr) */ else if (sub(xt, mult(20480, st->tsnr)) > 0) { /* tsnr = 0.998*tsnr + 0.002*xt; */ st->tsnr = round(L_add(L_mult(32702, st->tsnr), L_mult(66, xt))); } } /* Quantize the long-term SNR in 3 dB steps, limit to 0 <= tsnrq <= 19 */ tsnrq = shr(mult(st->tsnr, 10923), 8); /* tsnrq = min(19, max(0, tsnrq)); */ test(),test(); if (sub(tsnrq, 19) > 0) { tsnrq = 19; move16(); } else if (tsnrq < 0) { tsnrq = 0; move16(); } /* Calculate the negative SNR sensitivity bias */ test(); if (xt < 0) { /* negSNRvar = 0.99*negSNRvar + 0.01*xt*xt; */ /* xt scaled as 7,8 => xt*xt scaled as 14,17, shift to 7,8 and round */ tmp = round(L_shl(L_mult(xt, xt), 7)); st->negSNRvar = round(L_add(L_mult(32440, st->negSNRvar), L_mult(328, tmp))); /* if (negSNRvar > 4.0) negSNRvar = 4.0; */ test(); if (sub(st->negSNRvar, 1024) > 0) { st->negSNRvar = 1024; move16(); } /* negSNRbias = max(12.0*(negSNRvar - 0.65), 0.0); */ tmp = mult_r(shl(sub(st->negSNRvar, 166), 4), 24576); test(); if (tmp < 0) { st->negSNRbias = 0; move16(); } else { st->negSNRbias = shr(tmp, 8); } } /* Determine VAD as a function of the voice metric sum and quantized SNR */ tmp = add(vm_threshold_table[tsnrq], st->negSNRbias); test(); if (sub(vm_sum, tmp) > 0) { ivad = 1; move16(); st->burstcount = add(st->burstcount, 1); test(); if (sub(st->burstcount, burstcount_table[tsnrq]) > 0) { st->hangover = hangover_table[tsnrq]; move16(); } } else { st->burstcount = 0; move16(); st->hangover = sub(st->hangover, 1); test(); if (st->hangover <= 0) { ivad = 0; move16(); st->hangover = 0; move16(); } else { ivad = 1; move16(); } } /* Calculate log spectral deviation */ ch_enrg_dev = 0; move16(); test(); if (L_sub(st->Lframe_cnt, 1) == 0) { for (i = LO_CHAN; i <= HI_CHAN; i++) { st->ch_enrg_long_db[i] = ch_enrg_db[i]; move16(); } } else { for (i = LO_CHAN; i <= HI_CHAN; i++) { tmp = abs_s(sub(st->ch_enrg_long_db[i], ch_enrg_db[i])); ch_enrg_dev = add(ch_enrg_dev, tmp); } } /* * Calculate long term integration constant as a function of instantaneous SNR * (i.e., high SNR (tsnr dB) -> slower integration (alpha = HIGH_ALPHA), * low SNR (0 dB) -> faster integration (alpha = LOW_ALPHA) */ /* alpha = HIGH_ALPHA - ALPHA_RANGE * (tsnr - xt) / tsnr, low <= alpha <= high */ tmp = sub(st->tsnr, xt); test(),logic16(),test(),test(); if (tmp <= 0 || st->tsnr <= 0) { alpha = HIGH_ALPHA; move16(); one_m_alpha = 32768L-HIGH_ALPHA; move16(); } else if (sub(tmp, st->tsnr) > 0) { alpha = LOW_ALPHA; move16(); one_m_alpha = 32768L-LOW_ALPHA; move16(); } else { tmp = div_s(tmp, st->tsnr); alpha = sub(HIGH_ALPHA, mult(ALPHA_RANGE, tmp)); one_m_alpha = sub(32767, alpha); } /* Calc long term log spectral energy */ for (i = LO_CHAN; i <= HI_CHAN; i++) { Ltmp1 = L_mult(one_m_alpha, ch_enrg_db[i]); Ltmp2 = L_mult(alpha, st->ch_enrg_long_db[i]); st->ch_enrg_long_db[i] = round(L_add(Ltmp1, Ltmp2)); } /* Set or clear the noise update flags */ update_flag = FALSE; move16(); st->fupdate_flag = FALSE; move16(); test(),test(); if (sub(vm_sum, UPDATE_THLD) <= 0) { test(); if (st->burstcount == 0) { update_flag = TRUE; move16(); st->update_cnt = 0; move16(); } } else if (L_sub(Ltce, noise_floor_chan[st->shift_state]) > 0) { test(); if (sub(ch_enrg_dev, DEV_THLD) < 0) { test(); if (p2a_flag == FALSE) { test(); if (st->LTP_flag == FALSE) { st->update_cnt = add(st->update_cnt, 1); test(); if (sub(st->update_cnt, UPDATE_CNT_THLD) >= 0) { update_flag = TRUE; move16(); st->fupdate_flag = TRUE; move16(); } } } } } test(); if (sub(st->update_cnt, st->last_update_cnt) == 0) { st->hyster_cnt = add(st->hyster_cnt, 1); } else { st->hyster_cnt = 0; move16(); } st->last_update_cnt = st->update_cnt; move16(); test(); if (sub(st->hyster_cnt, HYSTER_CNT_THLD) > 0) { st->update_cnt = 0; move16(); } /* Conditionally update the channel noise estimates */ test(); if (update_flag == TRUE) { /* Check shift state */ test(); if (st->shift_state == 1) { /* get factor to shift ch_enrg[] from state 1 to 0 (noise always state 0) */ tmp = state_change_shift_r[0]; move16(); } else { /* No shift if already state 0 */ tmp = 0; move16(); } /* Update noise energy estimate */ for (i = LO_CHAN; i <= HI_CHAN; i++) { test(); /* integrate over time: en[i] = (1-alpha)*en[i] + alpha*e[n] */ /* (extract with shift compensation for state 1) */ L_Extract (L_shr(st->Lch_enrg[i], tmp), &hi1, &lo1); Ltmp = Mpy_32_16(hi1, lo1, CNE_SM_FAC); L_Extract (st->Lch_noise[i], &hi1, &lo1); st->Lch_noise[i] = L_add(Ltmp, Mpy_32_16(hi1, lo1, ONE_MINUS_CNE_SM_FAC)); move32(); /* Limit low level noise */ test(); if (L_sub(st->Lch_noise[i], MIN_NOISE_ENRG_0) < 0) { st->Lch_noise[i] = MIN_NOISE_ENRG_0; move32(); } } } return(ivad); } /* end of vad2 () */
static Word16 Vq_subvec_s ( /* o : quantization index Q0 */ Word16 *lsf_r1, /* i : 1st LSF residual vector Q15 */ Word16 *lsf_r2, /* i : and LSF residual vector Q15 */ const Word16 *dico, /* i : quantization codebook Q15 */ Word16 *wf1, /* i : 1st LSF weighting factors Q13 */ Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */ Word16 dico_size) /* i : size of quantization codebook Q0 */ { Word16 index = 0; /* initialization only needed to keep gcc silent */ Word16 sign = 0; /* initialization only needed to keep gcc silent */ Word16 i, temp; const Word16 *p_dico; Word32 dist_min, dist; dist_min = MAX_32; move32 (); p_dico = dico; move16 (); for (i = 0; i < dico_size; i++) { /* test positive */ temp = sub (lsf_r1[0], *p_dico++); temp = mult (wf1[0], temp); dist = L_mult (temp, temp); temp = sub (lsf_r1[1], *p_dico++); temp = mult (wf1[1], temp); dist = L_mac (dist, temp, temp); temp = sub (lsf_r2[0], *p_dico++); temp = mult (wf2[0], temp); dist = L_mac (dist, temp, temp); temp = sub (lsf_r2[1], *p_dico++); temp = mult (wf2[1], temp); dist = L_mac (dist, temp, temp); test (); if (L_sub (dist, dist_min) < (Word32) 0) { dist_min = dist; move32 (); index = i; move16 (); sign = 0; move16 (); } /* test negative */ p_dico -= 4; move16 (); temp = add (lsf_r1[0], *p_dico++); temp = mult (wf1[0], temp); dist = L_mult (temp, temp); temp = add (lsf_r1[1], *p_dico++); temp = mult (wf1[1], temp); dist = L_mac (dist, temp, temp); temp = add (lsf_r2[0], *p_dico++); temp = mult (wf2[0], temp); dist = L_mac (dist, temp, temp); temp = add (lsf_r2[1], *p_dico++); temp = mult (wf2[1], temp); dist = L_mac (dist, temp, temp); test (); if (L_sub (dist, dist_min) < (Word32) 0) { dist_min = dist; move32 (); index = i; move16 (); sign = 1; move16 (); } } /* Reading the selected vector */ p_dico = &dico[shl (index, 2)]; move16 (); test (); if (sign == 0) { lsf_r1[0] = *p_dico++; move16 (); lsf_r1[1] = *p_dico++; move16 (); lsf_r2[0] = *p_dico++; move16 (); lsf_r2[1] = *p_dico++; move16 (); } else { lsf_r1[0] = negate (*p_dico++); move16 (); lsf_r1[1] = negate (*p_dico++); move16 (); lsf_r2[0] = negate (*p_dico++); move16 (); lsf_r2[1] = negate (*p_dico++); move16 (); } index = shl (index, 1); index = add (index, sign); return index; }
/************************************************************************* * * FUNCTION: gc_pred() * * PURPOSE: MA prediction of the innovation energy * (in dB/(20*log10(2))) with mean removed). * *************************************************************************/ void gc_pred( gc_predState *st, /* i/o: State struct */ enum Mode mode, /* i : AMR mode */ Word16 *code, /* i : innovative codebook vector (L_SUBFR) */ /* MR122: Q12, other modes: Q13 */ Word16 *exp_gcode0, /* o : exponent of predicted gain factor, Q0 */ Word16 *frac_gcode0,/* o : fraction of predicted gain factor Q15 */ Word16 *exp_en, /* o : exponent of innovation energy, Q0 */ /* (only calculated for MR795) */ Word16 *frac_en /* o : fraction of innovation energy, Q15 */ /* (only calculated for MR795) */ ) { Word16 i; Word32 ener_code; Word16 exp, frac; /*-------------------------------------------------------------------* * energy of code: * * ~~~~~~~~~~~~~~~ * * ener_code = sum(code[i]^2) * *-------------------------------------------------------------------*/ ener_code = L_mac((Word32) 0, code[0], code[0]); /* MR122: Q12*Q12 -> Q25 */ /* others: Q13*Q13 -> Q27 */ for (i = 1; i < L_SUBFR; i++) ener_code = L_mac(ener_code, code[i], code[i]); test (); if (sub (mode, MR122) == 0) { Word32 ener; /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 */ ener_code = L_mult (round (ener_code), 26214); /* Q9 * Q20 -> Q30 */ /*-------------------------------------------------------------------* * energy of code: * * ~~~~~~~~~~~~~~~ * * ener_code(Q17) = 10 * Log10(energy) / constant * * = 1/2 * Log2(energy) * * constant = 20*Log10(2) * *-------------------------------------------------------------------*/ /* ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 */ Log2(ener_code, &exp, &frac); ener_code = L_Comp (sub (exp, 30), frac); /* Q16 for log() */ /* ->Q17 for 1/2 log()*/ /*-------------------------------------------------------------------* * predicted energy: * * ~~~~~~~~~~~~~~~~~ * * ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant * * = MEAN_ENER + sum(pred[i]*past_qua_en[i]) * * constant = 20*Log10(2) * *-------------------------------------------------------------------*/ ener = MEAN_ENER_MR122; move32 (); /* Q24 (Q17) */ for (i = 0; i < NPRED; i++) { ener = L_mac (ener, st->past_qua_en_MR122[i], pred_MR122[i]); /* Q10 * Q13 -> Q24 */ /* Q10 * Q6 -> Q17 */ } /*-------------------------------------------------------------------* * predicted codebook gain * * ~~~~~~~~~~~~~~~~~~~~~~~ * * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 ) * * = Pow2(ener-ener_code) * * = Pow2(int(d)+frac(d)) * * * * (store exp and frac for pow2()) * *-------------------------------------------------------------------*/ ener = L_shr (L_sub (ener, ener_code), 1); /* Q16 */ L_Extract(ener, exp_gcode0, frac_gcode0); } else /* all modes except 12.2 */ { Word32 L_tmp; Word16 exp_code, gcode0; /*-----------------------------------------------------------------* * Compute: means_ener - 10log10(ener_code/ L_sufr) * *-----------------------------------------------------------------*/ exp_code = norm_l (ener_code); ener_code = L_shl (ener_code, exp_code); /* Log2 = log2 + 27 */ Log2_norm (ener_code, exp_code, &exp, &frac); /* fact = 10/log2(10) = 3.01 = 24660 Q13 */ L_tmp = Mpy_32_16(exp, frac, -24660); /* Q0.Q15 * Q13 -> Q14 */ /* L_tmp = means_ener - 10log10(ener_code/L_SUBFR) * = means_ener - 10log10(ener_code) + 10log10(L_SUBFR) * = K - fact * Log2(ener_code) * = K - fact * log2(ener_code) - fact*27 * * ==> K = means_ener + fact*27 + 10log10(L_SUBFR) * * means_ener = 33 = 540672 Q14 (MR475, MR515, MR59) * means_ener = 28.75 = 471040 Q14 (MR67) * means_ener = 30 = 491520 Q14 (MR74) * means_ener = 36 = 589824 Q14 (MR795) * means_ener = 33 = 540672 Q14 (MR102) * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14 * fact * 27 = 1331640 Q14 * ----------------------------------------- * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2 * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2 * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2 * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2 * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2 */ if (test (), sub (mode, MR102) == 0) { /* mean = 33 dB */ L_tmp = L_mac(L_tmp, 16678, 64); /* Q14 */ } else if (test (), sub (mode, MR795) == 0) { /* ener_code = <xn xn> * 2^27*2^exp_code frac_en = ener_code / 2^16 = <xn xn> * 2^11*2^exp_code <xn xn> = <xn xn>*2^11*2^exp * 2^exp_en := frac_en * 2^exp_en ==> exp_en = -11-exp_code; */ *frac_en = extract_h (ener_code); move16 (); *exp_en = sub (-11, exp_code); move16 (); /* mean = 36 dB */ L_tmp = L_mac(L_tmp, 17062, 64); /* Q14 */ } else if (test (), sub (mode, MR74) == 0) { /* mean = 30 dB */ L_tmp = L_mac(L_tmp, 32588, 32); /* Q14 */ } else if (test (), sub (mode, MR67) == 0) { /* mean = 28.75 dB */ L_tmp = L_mac(L_tmp, 32268, 32); /* Q14 */ } else /* MR59, MR515, MR475 */ { /* mean = 33 dB */ L_tmp = L_mac(L_tmp, 16678, 64); /* Q14 */ } /*-----------------------------------------------------------------* * Compute gcode0. * * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener * *-----------------------------------------------------------------*/ L_tmp = L_shl(L_tmp, 10); /* Q24 */ for (i = 0; i < 4; i++) L_tmp = L_mac(L_tmp, pred[i], st->past_qua_en[i]); /* Q13 * Q10 -> Q24 */ gcode0 = extract_h(L_tmp); /* Q8 */ /*-----------------------------------------------------------------* * gcode0 = pow(10.0, gcode0/20) * * = pow(2, 3.3219*gcode0/20) * * = pow(2, 0.166*gcode0) * *-----------------------------------------------------------------*/ /* 5439 Q15 = 0.165985 */ /* (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15) */ test (); if (sub (mode, MR74) == 0) /* For IS641 bitexactness */ L_tmp = L_mult(gcode0, 5439); /* Q8 * Q15 -> Q24 */ else L_tmp = L_mult(gcode0, 5443); /* Q8 * Q15 -> Q24 */ L_tmp = L_shr(L_tmp, 8); /* -> Q16 */ L_Extract(L_tmp, exp_gcode0, frac_gcode0); /* -> Q0.Q15 */ } }
void dct_type_iv_a (Word16 *input,Word16 *output,Word16 dct_length) { Word16 buffer_a[MAX_DCT_LENGTH], buffer_b[MAX_DCT_LENGTH], buffer_c[MAX_DCT_LENGTH]; Word16 *in_ptr, *in_ptr_low, *in_ptr_high, *next_in_base; Word16 *out_ptr_low, *out_ptr_high, *next_out_base; Word16 *out_buffer, *in_buffer, *buffer_swap; Word16 in_val_low, in_val_high; Word16 out_val_low, out_val_high; Word16 in_low_even, in_low_odd; Word16 in_high_even, in_high_odd; Word16 out_low_even, out_low_odd; Word16 out_high_even, out_high_odd; Word16 *pair_ptr; Word16 cos_even, cos_odd, msin_even, msin_odd; Word16 neg_cos_odd; Word16 neg_msin_even; Word32 sum; Word16 set_span, set_count, set_count_log, pairs_left, sets_left; Word16 i,k; Word16 index; cos_msin_t **table_ptr_ptr, *cos_msin_ptr; Word16 temp; Word32 acca; Word16 dct_length_log; /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* Do the sum/difference butterflies, the first part of */ /* converting one N-point transform into N/2 two-point */ /* transforms, where N = 1 << DCT_LENGTH_LOG. = 64/128 */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ test(); if (dct_length==DCT_LENGTH) { dct_length_log = DCT_LENGTH_LOG; /* Add bias offsets */ for (i=0;i<dct_length;i++) { input[i] = add(input[i],anal_bias[i]); move16(); } } else dct_length_log = MAX_DCT_LENGTH_LOG; index = 0L; move16(); in_buffer = input; move16(); out_buffer = buffer_a; move16(); temp = sub(dct_length_log,2); for (set_count_log=0;set_count_log<=temp;set_count_log++) { /*===========================================================*/ /* Initialization for the loop over sets at the current size */ /*===========================================================*/ /* set_span = 1 << (DCT_LENGTH_LOG - set_count_log); */ set_span = shr_nocheck(dct_length,set_count_log); set_count = shl_nocheck(1,set_count_log); in_ptr = in_buffer; move16(); next_out_base = out_buffer; move16(); /*=====================================*/ /* Loop over all the sets of this size */ /*=====================================*/ for (sets_left=set_count;sets_left>0;sets_left--) { /*||||||||||||||||||||||||||||||||||||||||||||*/ /* Set up output pointers for the current set */ /*||||||||||||||||||||||||||||||||||||||||||||*/ out_ptr_low = next_out_base; next_out_base = next_out_base + set_span; out_ptr_high = next_out_base; /*||||||||||||||||||||||||||||||||||||||||||||||||||*/ /* Loop over all the butterflies in the current set */ /*||||||||||||||||||||||||||||||||||||||||||||||||||*/ do { in_val_low = *in_ptr++; in_val_high = *in_ptr++; // blp: addition of two 16bits vars, there's no way // they'll overflow a 32bit var //acca = L_add(in_val_low,in_val_high); acca = (in_val_low + in_val_high); acca = L_shr_nocheck(acca,1); out_val_low = extract_l(acca); acca = L_sub(in_val_low,in_val_high); acca = L_shr_nocheck(acca,1); out_val_high = extract_l(acca); *out_ptr_low++ = out_val_low; *--out_ptr_high = out_val_high; test(); } while (out_ptr_low < out_ptr_high); } /* End of loop over sets of the current size */ /*============================================================*/ /* Decide which buffers to use as input and output next time. */ /* Except for the first time (when the input buffer is the */ /* subroutine input) we just alternate the local buffers. */ /*============================================================*/ in_buffer = out_buffer; move16(); if (out_buffer == buffer_a) out_buffer = buffer_b; else out_buffer = buffer_a; index = add(index,1); } /* End of loop over set sizes */ /*++++++++++++++++++++++++++++++++*/ /* Do N/2 two-point transforms, */ /* where N = 1 << DCT_LENGTH_LOG */ /*++++++++++++++++++++++++++++++++*/ pair_ptr = in_buffer; move16(); buffer_swap = buffer_c; move16(); temp = sub(dct_length_log,1); temp = shl_nocheck(1,temp); for (pairs_left=temp; pairs_left > 0; pairs_left--) { for ( k=0; k<CORE_SIZE; k++ ) { #if PJ_HAS_INT64 /* blp: danger danger! not really compatible but faster */ pj_int64_t sum64=0; move32(); for ( i=0; i<CORE_SIZE; i++ ) { sum64 += L_mult(pair_ptr[i], dct_core_a[i][k]); } sum = L_saturate(sum64); #else sum=0L; move32(); for ( i=0; i<CORE_SIZE; i++ ) { sum = L_mac(sum, pair_ptr[i],dct_core_a[i][k]); } #endif buffer_swap[k] = itu_round(sum); } /* address arithmetic */ pair_ptr += CORE_SIZE; buffer_swap += CORE_SIZE; } for (i=0;i<dct_length;i++) { in_buffer[i] = buffer_c[i]; move16(); } table_ptr_ptr = a_cos_msin_table; /*++++++++++++++++++++++++++++++*/ /* Perform rotation butterflies */ /*++++++++++++++++++++++++++++++*/ temp = sub(dct_length_log,2); for (set_count_log = temp; set_count_log >= 0; set_count_log--) { /*===========================================================*/ /* Initialization for the loop over sets at the current size */ /*===========================================================*/ /* set_span = 1 << (DCT_LENGTH_LOG - set_count_log); */ set_span = shr_nocheck(dct_length,set_count_log); set_count = shl_nocheck(1,set_count_log); next_in_base = in_buffer; move16(); test(); if (set_count_log == 0) { next_out_base = output; } else { next_out_base = out_buffer; } /*=====================================*/ /* Loop over all the sets of this size */ /*=====================================*/ for (sets_left = set_count; sets_left > 0;sets_left--) { /*|||||||||||||||||||||||||||||||||||||||||*/ /* Set up the pointers for the current set */ /*|||||||||||||||||||||||||||||||||||||||||*/ in_ptr_low = next_in_base; move16(); temp = shr_nocheck(set_span,1); /* address arithmetic */ in_ptr_high = in_ptr_low + temp; next_in_base += set_span; out_ptr_low = next_out_base; next_out_base += set_span; out_ptr_high = next_out_base; cos_msin_ptr = *table_ptr_ptr; /*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/ /* Loop over all the butterfly pairs in the current set */ /*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/ do { /* address arithmetic */ in_low_even = *in_ptr_low++; in_low_odd = *in_ptr_low++; in_high_even = *in_ptr_high++; in_high_odd = *in_ptr_high++; cos_even = cos_msin_ptr[0].cosine; move16(); msin_even = cos_msin_ptr[0].minus_sine; move16(); cos_odd = cos_msin_ptr[1].cosine; move16(); msin_odd = cos_msin_ptr[1].minus_sine; move16(); cos_msin_ptr += 2; sum = 0L; sum=L_mac(sum,cos_even,in_low_even); neg_msin_even = negate(msin_even); sum=L_mac(sum,neg_msin_even,in_high_even); out_low_even = itu_round(sum); sum = 0L; sum=L_mac(sum,msin_even,in_low_even); sum=L_mac(sum,cos_even,in_high_even); out_high_even= itu_round(sum); sum = 0L; sum=L_mac(sum,cos_odd,in_low_odd); sum=L_mac(sum,msin_odd,in_high_odd); out_low_odd= itu_round(sum); sum = 0L; sum=L_mac(sum,msin_odd,in_low_odd); neg_cos_odd = negate(cos_odd); sum=L_mac(sum,neg_cos_odd,in_high_odd); out_high_odd= itu_round(sum); *out_ptr_low++ = out_low_even; *--out_ptr_high = out_high_even; *out_ptr_low++ = out_low_odd; *--out_ptr_high = out_high_odd; test(); } while (out_ptr_low < out_ptr_high); } /* End of loop over sets of the current size */ /*=============================================*/ /* Swap input and output buffers for next time */ /*=============================================*/ buffer_swap = in_buffer; in_buffer = out_buffer; out_buffer = buffer_swap; table_ptr_ptr++; } }
/* ******************************************************************************** * PUBLIC PROGRAM CODE ******************************************************************************** */ Word16 hp_max ( Word32 corr[], /* i : correlation vector. */ Word16 scal_sig[], /* i : scaled signal. */ Word16 L_frame, /* i : length of frame to compute pitch */ Word16 lag_max, /* i : maximum lag */ Word16 lag_min, /* i : minimum lag */ Word16 *cor_hp_max) /* o : max high-pass filtered norm. correlation */ { Word16 i; Word16 *p, *p1; Word32 max, t0, t1; Word16 max16, t016, cor_max; Word16 shift, shift1, shift2; max = MIN_32; move32 (); t0 = 0L; move32 (); for (i = lag_max-1; i > lag_min; i--) { /* high-pass filtering */ t0 = L_sub (L_sub(L_shl(corr[-i], 1), corr[-i-1]), corr[-i+1]); t0 = L_abs (t0); test (); if (L_sub (t0, max) >= 0) { max = t0; move32 (); } } /* compute energy */ p = scal_sig; move16 (); p1 = &scal_sig[0]; move16 (); t0 = 0L; move32 (); for (i = 0; i < L_frame; i++, p++, p1++) { t0 = L_mac (t0, *p, *p1); } p = scal_sig; move16 (); p1 = &scal_sig[-1]; move16 (); t1 = 0L; move32 (); for (i = 0; i < L_frame; i++, p++, p1++) { t1 = L_mac (t1, *p, *p1); } /* high-pass filtering */ t0 = L_sub(L_shl(t0, 1), L_shl(t1, 1)); t0 = L_abs (t0); /* max/t0 */ shift1 = sub(norm_l(max), 1); max16 = extract_h(L_shl(max, shift1)); shift2 = norm_l(t0); t016 = extract_h(L_shl(t0, shift2)); test (); if (t016 != 0) { cor_max = div_s(max16, t016); } else { cor_max = 0; move16 (); } shift = sub(shift1, shift2); test (); if (shift >= 0) { *cor_hp_max = shr(cor_max, shift); move16 (); /* Q15 */ } else { *cor_hp_max = shl(cor_max, negate(shift)); move16 (); /* Q15 */ } return 0; }
/* ************************************************************************** * * Function : Bgn_scd * Purpose : Charaterice synthesis speech and detect background noise * Returns : background noise decision; 0 = no bgn, 1 = bgn * ************************************************************************** */ Word16 Bgn_scd (Bgn_scdState *st, /* i : State variables for bgn SCD */ Word16 ltpGainHist[], /* i : LTP gain history */ Word16 speech[], /* o : synthesis speech frame */ Word16 *voicedHangover /* o : # of frames after last voiced frame */ ) { Word16 i; Word16 prevVoiced, inbgNoise; Word16 temp; Word16 ltpLimit, frameEnergyMin; Word16 currEnergy, noiseFloor, maxEnergy, maxEnergyLastPart; Word32 s; /* Update the inBackgroundNoise flag (valid for use in next frame if BFI) */ /* it now works as a energy detector floating on top */ /* not as good as a VAD. */ currEnergy = 0; move16 (); s = (Word32) 0; move32 (); for (i = 0; i < L_FRAME; i++) { s = L_mac (s, speech[i], speech[i]); } s = L_shl(s, 2); currEnergy = extract_h (s); frameEnergyMin = 32767; move16 (); for (i = 0; i < L_ENERGYHIST; i++) { test (); if (sub(st->frameEnergyHist[i], frameEnergyMin) < 0) frameEnergyMin = st->frameEnergyHist[i]; move16 (); } noiseFloor = shl (frameEnergyMin, 4); /* Frame Energy Margin of 16 */ maxEnergy = st->frameEnergyHist[0]; move16 (); for (i = 1; i < L_ENERGYHIST-4; i++) { test (); if ( sub (maxEnergy, st->frameEnergyHist[i]) < 0) { maxEnergy = st->frameEnergyHist[i]; move16 (); } } maxEnergyLastPart = st->frameEnergyHist[2*L_ENERGYHIST/3]; move16 (); for (i = 2*L_ENERGYHIST/3+1; i < L_ENERGYHIST; i++) { test (); if ( sub (maxEnergyLastPart, st->frameEnergyHist[i] ) < 0) { maxEnergyLastPart = st->frameEnergyHist[i]; move16 (); } } inbgNoise = 0; /* false */ move16 (); /* Do not consider silence as noise */ /* Do not consider continuous high volume as noise */ /* Or if the current noise level is very low */ /* Mark as noise if under current noise limit */ /* OR if the maximum energy is below the upper limit */ test (); test (); test (); test (); test (); if ( (sub(maxEnergy, LOWERNOISELIMIT) > 0) && (sub(currEnergy, FRAMEENERGYLIMIT) < 0) && (sub(currEnergy, LOWERNOISELIMIT) > 0) && ( (sub(currEnergy, noiseFloor) < 0) || (sub(maxEnergyLastPart, UPPERNOISELIMIT) < 0))) { test (); if (sub(add(st->bgHangover, 1), 30) > 0) { st->bgHangover = 30; move16 (); } else { st->bgHangover = add(st->bgHangover, 1); } } else { st->bgHangover = 0; move16 (); } /* make final decision about frame state , act somewhat cautiosly */ test (); if (sub(st->bgHangover,1) > 0) inbgNoise = 1; /* true */ move16 (); for (i = 0; i < L_ENERGYHIST-1; i++) { st->frameEnergyHist[i] = st->frameEnergyHist[i+1]; move16 (); } st->frameEnergyHist[L_ENERGYHIST-1] = currEnergy; move16 (); /* prepare for voicing decision; tighten the threshold after some time in noise */ ltpLimit = 13926; /* 0.85 Q14 */ move16 (); test (); if (sub(st->bgHangover, 8) > 0) { ltpLimit = 15565; /* 0.95 Q14 */ move16 (); } test (); if (sub(st->bgHangover, 15) > 0) { ltpLimit = 16383; /* 1.00 Q14 */ move16 (); } /* weak sort of voicing indication. */ prevVoiced = 0; /* false */ move16 (); test (); if (sub(gmed_n(<pGainHist[4], 5), ltpLimit) > 0) { prevVoiced = 1; /* true */ move16 (); } test (); if (sub(st->bgHangover, 20) > 0) { if (sub(gmed_n(ltpGainHist, 9), ltpLimit) > 0) { prevVoiced = 1; /* true */ move16 (); } else { prevVoiced = 0; /* false */ move16 (); } } test (); if (prevVoiced) { *voicedHangover = 0; move16 (); } else { temp = add(*voicedHangover, 1); test (); if (sub(temp, 10) > 0) { *voicedHangover = 10; move16 (); } else { *voicedHangover = temp; move16 (); } } return inbgNoise; }
/* ************************************************************************** * * Function : Decoder_amr * Purpose : Speech decoder routine. * ************************************************************************** */ int Decoder_amr ( Decoder_amrState *st, /* i/o : State variables */ enum Mode mode, /* i : AMR mode */ Word16 parm[], /* i : vector of synthesis parameters (PRM_SIZE) */ enum RXFrameType frame_type, /* i : received frame type */ Word16 synth[], /* o : synthesis speech (L_FRAME) */ Word16 A_t[] /* o : decoded LP filter in 4 subframes (AZ_SIZE) */ ) { /* LPC coefficients */ Word16 *Az; /* Pointer on A_t */ /* LSPs */ Word16 lsp_new[M]; Word16 lsp_mid[M]; /* LSFs */ Word16 prev_lsf[M]; Word16 lsf_i[M]; /* Algebraic codevector */ Word16 code[L_SUBFR]; /* excitation */ Word16 excp[L_SUBFR]; Word16 exc_enhanced[L_SUBFR]; /* Scalars */ Word16 i, i_subfr; Word16 T0, T0_frac, index, index_mr475 = 0; Word16 gain_pit, gain_code, gain_code_mix, pit_sharp, pit_flag, pitch_fac; Word16 t0_min, t0_max; Word16 delta_frc_low, delta_frc_range; Word16 tmp_shift; Word16 temp; Word32 L_temp; Word16 flag4; Word16 carefulFlag; Word16 excEnergy; Word16 subfrNr; Word16 evenSubfr = 0; Word16 bfi = 0; /* bad frame indication flag */ Word16 pdfi = 0; /* potential degraded bad frame flag */ enum DTXStateType newDTXState; /* SPEECH , DTX, DTX_MUTE */ /* find the new DTX state SPEECH OR DTX */ newDTXState = rx_dtx_handler(st->dtxDecoderState, frame_type); move16 (); /* function result */ /* DTX actions */ test(); if (sub(newDTXState, SPEECH) != 0 ) { Decoder_amr_reset (st, MRDTX); dtx_dec(st->dtxDecoderState, st->mem_syn, st->lsfState, st->pred_state, st->Cb_gain_averState, newDTXState, mode, parm, synth, A_t); /* update average lsp */ Lsf_lsp(st->lsfState->past_lsf_q, st->lsp_old, M); lsp_avg(st->lsp_avg_st, st->lsfState->past_lsf_q); goto the_end; } /* SPEECH action state machine */ test (); test (); test (); if ((sub(frame_type, RX_SPEECH_BAD) == 0) || (sub(frame_type, RX_NO_DATA) == 0) || (sub(frame_type, RX_ONSET) == 0)) { bfi = 1; move16 (); test(); test(); if ((sub(frame_type, RX_NO_DATA) == 0) || (sub(frame_type, RX_ONSET) == 0)) { build_CN_param(&st->nodataSeed, prmno[mode], bitno[mode], parm); } } else if (sub(frame_type, RX_SPEECH_DEGRADED) == 0) { pdfi = 1; move16 (); } test(); if (bfi != 0) { st->state = add (st->state, 1); } else if (sub (st->state, 6) == 0) { st->state = 5; move16 (); } else { st->state = 0; move16 (); } test (); if (sub (st->state, 6) > 0) { st->state = 6; move16 (); } /* If this frame is the first speech frame after CNI period, */ /* set the BFH state machine to an appropriate state depending */ /* on whether there was DTX muting before start of speech or not */ /* If there was DTX muting, the first speech frame is muted. */ /* If there was no DTX muting, the first speech frame is not */ /* muted. The BFH state machine starts from state 5, however, to */ /* keep the audible noise resulting from a SID frame which is */ /* erroneously interpreted as a good speech frame as small as */ /* possible (the decoder output in this case is quickly muted) */ test(); if (sub(st->dtxDecoderState->dtxGlobalState, DTX) == 0) { st->state = 5; move16 (); st->prev_bf = 0; move16 (); } else if (test (), sub(st->dtxDecoderState->dtxGlobalState, DTX_MUTE) == 0) { st->state = 5; move16 (); st->prev_bf = 1; move16 (); } /* save old LSFs for CB gain smoothing */ Copy (st->lsfState->past_lsf_q, prev_lsf, M); /* decode LSF parameters and generate interpolated lpc coefficients for the 4 subframes */ test (); if (sub (mode, MR122) != 0) { D_plsf_3(st->lsfState, mode, bfi, parm, lsp_new); fwc (); /* function worst case */ /* Advance synthesis parameters pointer */ parm += 3; move16 (); Int_lpc_1to3(st->lsp_old, lsp_new, A_t); } else { D_plsf_5 (st->lsfState, bfi, parm, lsp_mid, lsp_new); fwc (); /* function worst case */ /* Advance synthesis parameters pointer */ parm += 5; move16 (); Int_lpc_1and3 (st->lsp_old, lsp_mid, lsp_new, A_t); } /* update the LSPs for the next frame */ for (i = 0; i < M; i++) { st->lsp_old[i] = lsp_new[i]; move16 (); } fwc (); /* function worst case */ /*------------------------------------------------------------------------* * Loop for every subframe in the analysis frame * *------------------------------------------------------------------------* * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * * times * * - decode the pitch delay * * - decode algebraic code * * - decode pitch and codebook gains * * - find the excitation and compute synthesis speech * *------------------------------------------------------------------------*/ /* pointer to interpolated LPC parameters */ Az = A_t; move16 (); evenSubfr = 0; move16(); subfrNr = -1; move16(); for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { subfrNr = add(subfrNr, 1); evenSubfr = sub(1, evenSubfr); /* flag for first and 3th subframe */ pit_flag = i_subfr; move16 (); test(); if (sub (i_subfr, L_FRAME_BY2) == 0) { test(); test(); if (sub(mode, MR475) != 0 && sub(mode, MR515) != 0) { pit_flag = 0; move16 (); } } /* pitch index */ index = *parm++; move16 (); /*-------------------------------------------------------* * - decode pitch lag and find adaptive codebook vector. * *-------------------------------------------------------*/ test (); if (sub(mode, MR122) != 0) { /* flag4 indicates encoding with 4 bit resolution; */ /* this is needed for mode MR475, MR515, MR59 and MR67 */ flag4 = 0; move16 (); test (); test (); test (); test (); if ((sub (mode, MR475) == 0) || (sub (mode, MR515) == 0) || (sub (mode, MR59) == 0) || (sub (mode, MR67) == 0) ) { flag4 = 1; move16 (); } /*-------------------------------------------------------* * - get ranges for the t0_min and t0_max * * - only needed in delta decoding * *-------------------------------------------------------*/ delta_frc_low = 5; move16(); delta_frc_range = 9; move16(); test (); if ( sub(mode, MR795) == 0 ) { delta_frc_low = 10; move16(); delta_frc_range = 19; move16(); } t0_min = sub(st->old_T0, delta_frc_low); test (); if (sub(t0_min, PIT_MIN) < 0) { t0_min = PIT_MIN; move16(); } t0_max = add(t0_min, delta_frc_range); test (); if (sub(t0_max, PIT_MAX) > 0) { t0_max = PIT_MAX; move16(); t0_min = sub(t0_max, delta_frc_range); } Dec_lag3 (index, t0_min, t0_max, pit_flag, st->old_T0, &T0, &T0_frac, flag4); st->T0_lagBuff = T0; move16 (); test (); if (bfi != 0) { test (); if (sub (st->old_T0, PIT_MAX) < 0) { /* Graceful pitch */ st->old_T0 = add(st->old_T0, 1); /* degradation */ } T0 = st->old_T0; move16 (); T0_frac = 0; move16 (); test (); test (); test (); test (); test (); if ( st->inBackgroundNoise != 0 && sub(st->voicedHangover, 4) > 0 && ((sub(mode, MR475) == 0 ) || (sub(mode, MR515) == 0 ) || (sub(mode, MR59) == 0) ) ) { T0 = st->T0_lagBuff; move16 (); } } fwc (); /* function worst case */ Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 1); } else { Dec_lag6 (index, PIT_MIN_MR122, PIT_MAX, pit_flag, &T0, &T0_frac); test (); test (); test (); if ( bfi == 0 && (pit_flag == 0 || sub (index, 61) < 0)) { } else { st->T0_lagBuff = T0; move16 (); T0 = st->old_T0; move16 (); T0_frac = 0; move16 (); } fwc (); /* function worst case */ Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 0); } fwc (); /* function worst case */ /*-------------------------------------------------------* * - (MR122 only: Decode pitch gain.) * * - Decode innovative codebook. * * - set pitch sharpening factor * *-------------------------------------------------------*/ test (); test (); if (sub (mode, MR475) == 0 || sub (mode, MR515) == 0) { /* MR475, MR515 */ index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); fwc (); /* function worst case */ decode_2i40_9bits (subfrNr, i, index, code); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR59) == 0) { /* MR59 */ test (); index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); fwc (); /* function worst case */ decode_2i40_11bits (i, index, code); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR67) == 0) { /* MR67 */ test (); test (); index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); fwc (); /* function worst case */ decode_3i40_14bits (i, index, code); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR795) <= 0) { /* MR74, MR795 */ test (); test (); test (); index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); fwc (); /* function worst case */ decode_4i40_17bits (i, index, code); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR102) == 0) { /* MR102 */ test (); test (); test (); fwc (); /* function worst case */ dec_8i40_31bits (parm, code); parm += 7; move16 (); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else { /* MR122 */ test (); test (); test (); index = *parm++; move16 (); test(); if (bfi != 0) { ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); } else { gain_pit = d_gain_pitch (mode, index); move16 (); } ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit); fwc (); /* function worst case */ dec_10i40_35bits (parm, code); parm += 10; move16 (); fwc (); /* function worst case */ /* pit_sharp = gain_pit; */ /* if (pit_sharp > 1.0) pit_sharp = 1.0; */ pit_sharp = shl (gain_pit, 1); } /*-------------------------------------------------------* * - Add the pitch contribution to code[]. * *-------------------------------------------------------*/ for (i = T0; i < L_SUBFR; i++) { temp = mult (code[i - T0], pit_sharp); code[i] = add (code[i], temp); move16 (); } fwc (); /* function worst case */ /*------------------------------------------------------------* * - Decode codebook gain (MR122) or both pitch * * gain and codebook gain (all others) * * - Update pitch sharpening "sharp" with quantized gain_pit * *------------------------------------------------------------*/ if (test(), sub (mode, MR475) == 0) { /* read and decode pitch and code gain */ test(); if (evenSubfr != 0) { index_mr475 = *parm++; move16 (); /* index of gain(s) */ } test(); if (bfi == 0) { Dec_gain(st->pred_state, mode, index_mr475, code, evenSubfr, &gain_pit, &gain_code); } else { ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, &gain_code); } ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit); ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, &gain_code); fwc (); /* function worst case */ pit_sharp = gain_pit; move16 (); test (); if (sub (pit_sharp, SHARPMAX) > 0) { pit_sharp = SHARPMAX; move16 (); } } else if (test(), test(), (sub (mode, MR74) <= 0) || (sub (mode, MR102) == 0)) { /* read and decode pitch and code gain */ index = *parm++; move16 (); /* index of gain(s) */ test(); if (bfi == 0) { Dec_gain(st->pred_state, mode, index, code, evenSubfr, &gain_pit, &gain_code); } else { ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, &gain_code); } ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit); ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, &gain_code); fwc (); /* function worst case */ pit_sharp = gain_pit; move16 (); test (); if (sub (pit_sharp, SHARPMAX) > 0) { pit_sharp = SHARPMAX; move16 (); } if (sub (mode, MR102) == 0) { if (sub (st->old_T0, add(L_SUBFR, 5)) > 0) { pit_sharp = shr(pit_sharp, 2); } } } else { /* read and decode pitch gain */ index = *parm++; move16 (); /* index of gain(s) */ test (); if (sub (mode, MR795) == 0) { /* decode pitch gain */ test(); if (bfi != 0) { ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); } else { gain_pit = d_gain_pitch (mode, index); move16 (); } ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit); /* read and decode code gain */ index = *parm++; move16 (); test(); if (bfi == 0) { d_gain_code (st->pred_state, mode, index, code, &gain_code); } else { ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, &gain_code); } ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, &gain_code); fwc (); /* function worst case */ pit_sharp = gain_pit; move16 (); test (); if (sub (pit_sharp, SHARPMAX) > 0) { pit_sharp = SHARPMAX; move16 (); } } else { /* MR122 */ test(); if (bfi == 0) { d_gain_code (st->pred_state, mode, index, code, &gain_code); } else { ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, &gain_code); } ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, &gain_code); fwc (); /* function worst case */ pit_sharp = gain_pit; move16 (); } } /* store pitch sharpening for next subframe */ /* (for modes which use the previous pitch gain for pitch sharpening in the search phase) */ /* do not update sharpening in even subframes for MR475 */ test(); test(); if (sub(mode, MR475) != 0 || evenSubfr == 0) { st->sharp = gain_pit; move16 (); test (); if (sub (st->sharp, SHARPMAX) > 0) { st->sharp = SHARPMAX; move16 (); } } pit_sharp = shl (pit_sharp, 1); test (); if (sub (pit_sharp, 16384) > 0) { for (i = 0; i < L_SUBFR; i++) { temp = mult (st->exc[i], pit_sharp); L_temp = L_mult (temp, gain_pit); test (); if (sub(mode, MR122)==0) { L_temp = L_shr (L_temp, 1); } excp[i] = round (L_temp); move16 (); } } /*-------------------------------------------------------* * - Store list of LTP gains needed in the source * * characteristic detector (SCD) * *-------------------------------------------------------*/ test (); if ( bfi == 0 ) { for (i = 0; i < 8; i++) { st->ltpGainHistory[i] = st->ltpGainHistory[i+1]; move16 (); } st->ltpGainHistory[8] = gain_pit; move16 (); } /*-------------------------------------------------------* * - Limit gain_pit if in background noise and BFI * * for MR475, MR515, MR59 * *-------------------------------------------------------*/ test (); test (); test (); test (); test (); test (); if ( (st->prev_bf != 0 || bfi != 0) && st->inBackgroundNoise != 0 && ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0) || (sub(mode, MR59) == 0)) ) { test (); if ( sub (gain_pit, 12288) > 0) /* if (gain_pit > 0.75) in Q14*/ gain_pit = add( shr( sub(gain_pit, 12288), 1 ), 12288 ); /* gain_pit = (gain_pit-0.75)/2.0 + 0.75; */ test (); if ( sub (gain_pit, 14745) > 0) /* if (gain_pit > 0.90) in Q14*/ { gain_pit = 14745; move16 (); } } /*-------------------------------------------------------* * Calculate CB mixed gain * *-------------------------------------------------------*/ Int_lsf(prev_lsf, st->lsfState->past_lsf_q, i_subfr, lsf_i); gain_code_mix = Cb_gain_average( st->Cb_gain_averState, mode, gain_code, lsf_i, st->lsp_avg_st->lsp_meanSave, bfi, st->prev_bf, pdfi, st->prev_pdf, st->inBackgroundNoise, st->voicedHangover); move16 (); /* make sure that MR74, MR795, MR122 have original code_gain*/ test(); if ((sub(mode, MR67) > 0) && (sub(mode, MR102) != 0) ) /* MR74, MR795, MR122 */ { gain_code_mix = gain_code; move16 (); } /*-------------------------------------------------------* * - Find the total excitation. * * - Find synthesis speech corresponding to st->exc[]. * *-------------------------------------------------------*/ test (); if (sub(mode, MR102) <= 0) /* MR475, MR515, MR59, MR67, MR74, MR795, MR102*/ { pitch_fac = gain_pit; move16 (); tmp_shift = 1; move16 (); } else /* MR122 */ { pitch_fac = shr (gain_pit, 1); move16 (); tmp_shift = 2; move16 (); } /* copy unscaled LTP excitation to exc_enhanced (used in phase * dispersion below) and compute total excitation for LTP feedback */ for (i = 0; i < L_SUBFR; i++) { exc_enhanced[i] = st->exc[i]; move16 (); /* st->exc[i] = gain_pit*st->exc[i] + gain_code*code[i]; */ L_temp = L_mult (st->exc[i], pitch_fac); /* 12.2: Q0 * Q13 */ /* 7.4: Q0 * Q14 */ L_temp = L_mac (L_temp, code[i], gain_code); /* 12.2: Q12 * Q1 */ /* 7.4: Q13 * Q1 */ L_temp = L_shl (L_temp, tmp_shift); /* Q16 */ st->exc[i] = round (L_temp); move16 (); } /*-------------------------------------------------------* * - Adaptive phase dispersion * *-------------------------------------------------------*/ ph_disp_release(st->ph_disp_st); /* free phase dispersion adaption */ test (); test (); test (); test (); test (); test (); if ( ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0) || (sub(mode, MR59) == 0)) && sub(st->voicedHangover, 3) > 0 && st->inBackgroundNoise != 0 && bfi != 0 ) { ph_disp_lock(st->ph_disp_st); /* Always Use full Phase Disp. */ } /* if error in bg noise */ /* apply phase dispersion to innovation (if enabled) and compute total excitation for synthesis part */ ph_disp(st->ph_disp_st, mode, exc_enhanced, gain_code_mix, gain_pit, code, pitch_fac, tmp_shift); /*-------------------------------------------------------* * - The Excitation control module are active during BFI.* * - Conceal drops in signal energy if in bg noise. * *-------------------------------------------------------*/ L_temp = 0; move32 (); for (i = 0; i < L_SUBFR; i++) { L_temp = L_mac (L_temp, exc_enhanced[i], exc_enhanced[i] ); } L_temp = L_shr (L_temp, 1); /* excEnergy = sqrt(L_temp) in Q0 */ L_temp = sqrt_l_exp(L_temp, &temp); move32 (); /* function result */ L_temp = L_shr(L_temp, add( shr(temp, 1), 15)); L_temp = L_shr(L_temp, 2); /* To cope with 16-bit and */ excEnergy = extract_l(L_temp); /* scaling in ex_ctrl() */ test (); test (); test (); test (); test (); test (); test (); test (); test (); test (); if ( ((sub (mode, MR475) == 0) || (sub (mode, MR515) == 0) || (sub (mode, MR59) == 0)) && sub(st->voicedHangover, 5) > 0 && st->inBackgroundNoise != 0 && sub(st->state, 4) < 0 && ( (pdfi != 0 && st->prev_pdf != 0) || bfi != 0 || st->prev_bf != 0) ) { carefulFlag = 0; move32 (); test (); test (); if ( pdfi != 0 && bfi == 0 ) { carefulFlag = 1; move16 (); } Ex_ctrl(exc_enhanced, excEnergy, st->excEnergyHist, st->voicedHangover, st->prev_bf, carefulFlag); } test (); test (); test (); test (); if ( st->inBackgroundNoise != 0 && ( bfi != 0 || st->prev_bf != 0 ) && sub(st->state, 4) < 0 ) { ; /* do nothing! */ } else { /* Update energy history for all modes */ for (i = 0; i < 8; i++) { st->excEnergyHist[i] = st->excEnergyHist[i+1]; move16 (); } st->excEnergyHist[8] = excEnergy; move16 (); } /*-------------------------------------------------------* * Excitation control module end. * *-------------------------------------------------------*/ fwc (); /* function worst case */ test (); if (sub (pit_sharp, 16384) > 0) { for (i = 0; i < L_SUBFR; i++) { excp[i] = add (excp[i], exc_enhanced[i]); move16 (); } agc2 (exc_enhanced, excp, L_SUBFR); Overflow = 0; move16 (); Syn_filt (Az, excp, &synth[i_subfr], L_SUBFR, st->mem_syn, 0); } else { Overflow = 0; move16 (); Syn_filt (Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->mem_syn, 0); } test (); if (Overflow != 0) /* Test for overflow */ { for (i = 0; i < PIT_MAX + L_INTERPOL + L_SUBFR; i++) { st->old_exc[i] = shr(st->old_exc[i], 2); move16 (); } for (i = 0; i < L_SUBFR; i++) { exc_enhanced[i] = shr(exc_enhanced[i], 2); move16 (); } Syn_filt(Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->mem_syn, 1); } else { Copy(&synth[i_subfr+L_SUBFR-M], st->mem_syn, M); } /*--------------------------------------------------* * Update signal for next frame. * * -> shift to the left by L_SUBFR st->exc[] * *--------------------------------------------------*/ Copy (&st->old_exc[L_SUBFR], &st->old_exc[0], PIT_MAX + L_INTERPOL); fwc (); /* function worst case */ /* interpolated LPC parameters for next subframe */ Az += MP1; move16 (); /* store T0 for next subframe */ st->old_T0 = T0; move16 (); } /*-------------------------------------------------------* * Call the Source Characteristic Detector which updates * * st->inBackgroundNoise and st->voicedHangover. * *-------------------------------------------------------*/ move16 (); /* function result */ st->inBackgroundNoise = Bgn_scd(st->background_state, &(st->ltpGainHistory[0]), &(synth[0]), &(st->voicedHangover) ); dtx_dec_activity_update(st->dtxDecoderState, st->lsfState->past_lsf_q, synth); fwc (); /* function worst case */ /* store bfi for next subframe */ st->prev_bf = bfi; move16 (); st->prev_pdf = pdfi; move16 (); /*--------------------------------------------------* * Calculate the LSF averages on the eight * * previous frames * *--------------------------------------------------*/ lsp_avg(st->lsp_avg_st, st->lsfState->past_lsf_q); fwc (); /* function worst case */ the_end: st->dtxDecoderState->dtxGlobalState = newDTXState; move16(); return 0; }