www.pudn.com > AVS_M_ver10.rar > cod_new_stereo.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2007 Audio Video Coding Standard, Part ¢ú * * This software module was developed by AVS Audio sub-group * * DISCLAIMER OF WARRANTY * * These software programs are available to the users without any * license fee or royalty on an "as is" basis. The AVS disclaims * any and all warranties, whether express, implied, or statutory, * including any implied warranties of merchantability or of fitness * for a particular purpose. In no event shall the contributors or * the AVS be liable for any incidental, punitive, or consequential * damages of any kind whatsoever arising from the use of this program. * * This disclaimer of warranty extends to the user of this program * and user's customers, employees, agents, transferees, successors, * and assigns. * * The AVS does not represent or warrant that the program furnished * hereunder are free of infringement of any third-party patents. * Commercial implementations of AVS, including shareware, may be * subject to royalty fees to patent holders. Information regarding * the AVS patent policy is available from the AVS Web site at * http://www.avs.org.cn * * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. ************************************************************************ */ #include#include #include #include #include "../include/amr_plus.h" #include "../include/s_util.h" /* NEW_STEREO */ /* TO BOTTOM OF THIS FILE */ #define EPS 0.001f // initial stereo struction and parameter void init_new_stereo_encoder(NEW_STEREO_DATA *newStereo, //(i/o): Encoder states float bitrate) //(i): encoding bitrate { int i; set_zero(newStereo->old_speech_side, L_OLD_SPEECH_ST+NEW_STEREO_DELAY); set_zero(newStereo->old_speech_mono, L_OLD_SPEECH_ST+NEW_STEREO_DELAY); set_zero(newStereo->mem_side_error, 4); set_zero(newStereo->mem_mono_error, 4); set_zero(newStereo->old_AqLF, 5*(M+1)); for (i = 0;i < 5;i++) { newStereo->old_AqLF[i*(M+1)]=1.0f; } set_zero(newStereo->pre_left_gain, MF_GAIN_NUM); set_zero(newStereo->pre_right_gain, MF_GAIN_NUM); newStereo->mem_ovlp_size_enc = 0; newStereo->signalType.is_transient = 0; newStereo->signalType.min_energy = 10.0f; newStereo->signalType.attack_threshold = 8.0f; newStereo->signalType.prev_frame_energy = 0.0f; newStereo->bitrate = bitrate; if (bitrate <= 32.0f) { newStereo->lowfreq_end_num_l = 128; newStereo->lowfreq_end_num_s = newStereo->lowfreq_end_num_l / 4; } else { newStereo->lowfreq_end_num_l = 192; newStereo->lowfreq_end_num_s = newStereo->lowfreq_end_num_l / 4; } // side exc estimation set_zero(newStereo->wiener_filter, HI_FILT_ORDER*4); set_zero(newStereo->old_mono_exc, HI_FILT_ORDER); newStereo->filt_energy_threshold = 0.0f; set_zero(newStereo->old_wh_q, HI_FILT_ORDER); } static void MakeSignalTypeAnalysis(NEW_STEREO_DATA *newStereo, SIGNAL_TYPE* signalType, const float *side_exc) { int i, b; float block_energy[BLOCK_NUM+1]; int block_len = L_FRAME_PLUS/BLOCK_NUM; float attack_threshold = signalType->attack_threshold; float min_attack = signalType->min_energy; block_energy[0] = signalType->prev_frame_energy; for (b = 0; b < BLOCK_NUM; b++) { block_energy[b+1] = 0.0f; for (i = b*block_len; i < (b+1)*block_len; i++) { block_energy[b+1] += side_exc[i] * side_exc[i]; } } signalType->prev_frame_energy = block_energy[BLOCK_NUM]; signalType->is_transient = 0; for (b = 1; b < BLOCK_NUM+1; b++) { if ((block_energy[b] > attack_threshold * block_energy[b-1]) && (block_energy[b] > min_attack)) { signalType->is_transient = 1; break; } } } static void MakeFFTTransform(NEW_STEREO_DATA *newStereo, SIGNAL_TYPE* signalType, const float *est_side_ch, const float *side_ch, const float *mono_ch, float *side_fft, float *mono_fft, float *left_fft, float *right_fft, float *est_left_fft, float *est_right_fft) { int i, w; int L_frame, lext, lg; float window[256]; int ovlp_size; // memory can be saved by reusing some place float est_xn_side[L_FRAME_PLUS+L_OVLP]; float xn_side[L_FRAME_PLUS+L_OVLP]; float xn_mono[L_FRAME_PLUS+L_OVLP]; float est_side_fft[L_FRAME_PLUS+L_OVLP]; if (!signalType->is_transient) // smooth { mvr2r(est_side_ch, est_xn_side, L_FRAME_PLUS+L_OVLP); mvr2r(side_ch, xn_side, L_FRAME_PLUS+L_OVLP); mvr2r(mono_ch, xn_mono, L_FRAME_PLUS+L_OVLP); lext = L_OVLP; L_frame =L_FRAME_PLUS; ovlp_size = newStereo->mem_ovlp_size_enc; lg = L_frame + lext; // built window for overlaps section cos_window(window, ovlp_size, lext); // est_xn_side[] etc windowing for DFT overlap for (i = 0; i < ovlp_size; i++) { est_xn_side[i] *= window[i]; xn_side[i] *= window[i]; xn_mono[i] *= window[i]; } for (i = 0; i < lext; i++) { est_xn_side[L_frame+i] *= window[ovlp_size+i]; xn_side[L_frame+i] *= window[ovlp_size+i]; xn_mono[L_frame+i] *= window[ovlp_size+i]; } /*-----------------------------------------------------------* * Compute the FFT of xn[]. * * Coefficients (xri[]) order are * * re[0], re[n/2], re[1], re[2], ... re[n/2-1], im[n/2-1] * * Note that last FFT element (re[n/2]) is zeroed. * *-----------------------------------------------------------*/ fft9(est_xn_side, est_side_fft, (short)lg); est_side_fft[1] = 0.0f; // freq bin at 6400 Hz zeroed fft9(xn_side, side_fft, (short)lg); side_fft[1] = 0.0f; // freq bin at 6400 Hz zeroed fft9(xn_mono, mono_fft, (short)lg); mono_fft[1] = 0.0f; // freq bin at 6400 Hz zeroed newStereo->mem_ovlp_size_enc = L_OVLP; } else { lext = L_OVLP/4; L_frame =L_FRAME_PLUS/4; lg = L_frame + lext; for (w = 0; w < 4; w++) { float *cur_est_side_fft = est_side_fft + w * lg; float *cur_side_fft = side_fft + w * lg; float *cur_mono_fft = mono_fft + w * lg; mvr2r(est_side_ch + w * lg, est_xn_side, lg); // it IS lg NOT L_frame, because wiener_estimation ovlp mvr2r(side_ch + w * L_frame, xn_side, lg); mvr2r(mono_ch + w * L_frame, xn_mono, lg); ovlp_size = newStereo->mem_ovlp_size_enc; cos_window(window, ovlp_size, lext); // est_xn_side[] windowing for DFT overlap for (i = 0; i < ovlp_size; i++) { est_xn_side[i] *= window[i]; xn_side[i] *= window[i]; xn_mono[i] *= window[i]; } for (i = 0; i < lext; i++) { est_xn_side[L_frame+i] *= window[ovlp_size+i]; xn_side[L_frame+i] *= window[ovlp_size+i]; xn_mono[L_frame+i] *= window[ovlp_size+i]; } fft9(est_xn_side, cur_est_side_fft, (short)lg); cur_est_side_fft[1] = 0.0f; // freq bin at 6400 Hz zeroed fft9(xn_side, cur_side_fft, (short)lg); cur_side_fft[1] = 0.0f; // freq bin at 6400 Hz zeroed fft9(xn_mono, cur_mono_fft, (short)lg); cur_mono_fft[1] = 0.0f; // freq bin at 6400 Hz zeroed newStereo->mem_ovlp_size_enc = L_OVLP/4; } } // get left & right signal for (i = 0; i < L_FRAME_PLUS+L_OVLP; i++) { left_fft[i] = mono_fft[i] + side_fft[i]; right_fft[i] = mono_fft[i] - side_fft[i]; est_left_fft[i] = mono_fft[i] + est_side_fft[i]; est_right_fft[i] = mono_fft[i] - est_side_fft[i]; } } // find gain (for low freq AVQ) static float get_gain_freq(const float x[], const float y[], int n) { float ener_x = 0.0f, ener_y = 1e-6f; float gain; float x_mag, y_mag; short i; for (i = 0; i < n/2; i++) { x_mag = x[2*i]*x[2*i] + x[2*i+1]*x[2*i+1]; y_mag = y[2*i]*y[2*i] + y[2*i+1]*y[2*i+1]; ener_x += (float)sqrt(x_mag*y_mag); ener_y += (float)sqrt(y_mag*y_mag); } gain = ener_x / ener_y; return gain; } // quantize gain (for low freq AVQ) static int q_gain_new_tcx( // output: return quantization index float code[], // (i) : quantized vector int lcode, // (i) : frame size float *gain // in/out: quantized gain ) { int i, index; float tmp, gcode0, gcode; /* energy */ tmp = 0.01f; for(i=0; i 127) { index = 127; } gcode = (float)pow(10.0, ((float)index)/25.0) / gcode0; *gain = gcode; return(index); } static void MakeLowFreqCoding(NEW_STEREO_DATA *newStereo, const float *side_fft, int low_freq_num, int used_bits, // (i)number of AVQ bits int *prm) // (o)AVQ bits stream { int i; float fac_ns; float syn_side_fft[NEW_STEREO_LF_MAX_NUM_L]; float syn_side_fft_q[NEW_STEREO_LF_MAX_NUM_L]; float gain; float gh, gg; // wlei [20070604] mvr2r(side_fft, syn_side_fft, low_freq_num); /*-----------------------------------------------------------* * Spectral algebraic quantization * * with adaptive low frequency emphasis/deemphasis. * * Noise factor is the average level of unquantized freq. * *-----------------------------------------------------------*/ #ifdef NEW_TVC adap_pulse_emph(syn_side_fft, 4*low_freq_num); used_bits -= (7); /* gain = 7 bits */ AVQ_gain_allocator(syn_side_fft, low_freq_num, used_bits, &gh, &gg); // wlei [20070604] fac_ns = AVQ_cod(syn_side_fft, prm+1, used_bits, low_freq_num/8, &gh, &gg); #else adap_low_freq_emph(syn_side_fft, 4*low_freq_num); used_bits -= (7); /* gain = 7 bits */ fac_ns = AVQ_cod(syn_side_fft, prm+1, used_bits, low_freq_num/8); #endif for(i=0; i 0) { left_gain[b] = max(0.0f, left_gain[b]+gain_correlation); } if (right_gain[b] > 0) { right_gain[b] = max(0.0f, right_gain[b]+gain_correlation); } } } if (newStereo->signalType.is_transient == 0) { for (b = 0; b < gain_num; b++) { left_error[b] = (left_gain[b]-cb_gain_hi_mean_smooth[0]) - 0.5f*newStereo->pre_left_gain[b]; right_error[b] = (right_gain[b]-cb_gain_hi_mean_smooth[1]) - 0.5f*newStereo->pre_right_gain[b]; tmpGain[0] = left_error[b]; tmpGain[1] = right_error[b]; VQ_gain(tmpGain, dico_gain_side_hf_smooth, HI_GAIN_ORDER, SIZE_GAIN_HI_MSVQ_5A, param+b); quant_left_gain[b] = tmpGain[0] + cb_gain_hi_mean_smooth[0] + 0.5f*newStereo->pre_left_gain[b]; quant_right_gain[b] = tmpGain[1] + cb_gain_hi_mean_smooth[1] + 0.5f*newStereo->pre_right_gain[b]; quant_left_gain[b] = (float)pow(10.0, 0.05*quant_left_gain[b]); quant_right_gain[b] = (float)pow(10.0, 0.05*quant_right_gain[b]); newStereo->pre_left_gain[b] = tmpGain[0] + 0.5f*newStereo->pre_left_gain[b]; newStereo->pre_right_gain[b] = tmpGain[1] + 0.5f*newStereo->pre_right_gain[b]; } } else { for (b = 0; b < gain_num; b++) { left_error[b] = left_gain[b] - cb_gain_hi_mean_quick[0]; right_error[b] = right_gain[b] - cb_gain_hi_mean_quick[1]; tmpGain[0] = left_error[b]; tmpGain[1] = right_error[b]; VQ_gain(tmpGain, dico_gain_side_hf_quick, HI_GAIN_ORDER, SIZE_GAIN_HI_MSVQ_5A, param+b); tmpGain[0] += cb_gain_hi_mean_quick[0]; tmpGain[1] += cb_gain_hi_mean_quick[1]; quant_left_gain[b] = (float)pow(10.0, 0.05*tmpGain[0]); quant_right_gain[b] = (float)pow(10.0, 0.05*tmpGain[1]); } } } static void MakeStereoCoding(NEW_STEREO_DATA *newStereo, SIGNAL_TYPE* signalType, const float *side_fft, const float *left_fft, const float *right_fft, const float *est_left_fft, const float *est_right_fft, int nbits, int *param) { int low_freq_num; int mid_freq_num; int w, lg; int *prm; float *p_left_gain; float *p_right_gain; float *p_quant_left_gain; float *p_quant_right_gain; int gain_num; int lf_bits; int wiener_bits; float gain_corr; int hf_bits = 40; // number of mid-freq gains bits prm = param + 8; // 8 mid-freq's gain if (signalType->is_transient == 0) // smooth frame { low_freq_num = newStereo->lowfreq_end_num_l; mid_freq_num = L_FRAME_PLUS + L_OVLP - low_freq_num; p_left_gain = newStereo->left_gain; p_right_gain = newStereo->right_gain; p_quant_left_gain = newStereo->quant_left_gain; p_quant_right_gain = newStereo->quant_right_gain; gain_num = MF_GAIN_NUM; gain_corr = newStereo->gain_correlation[0]; wiener_bits = 7; lf_bits = nbits - wiener_bits - hf_bits; // mid-freq gain MakeLowFreqCoding(newStereo, side_fft, low_freq_num, lf_bits, prm); MakeMidFreqCoding(newStereo, signalType->is_transient, left_fft+low_freq_num, right_fft+low_freq_num, est_left_fft+low_freq_num, est_right_fft+low_freq_num, mid_freq_num, p_left_gain, p_right_gain, p_quant_left_gain, p_quant_right_gain, 0, gain_num, param, gain_corr); } else { lg = (L_FRAME_PLUS+L_OVLP)/4; low_freq_num = newStereo->lowfreq_end_num_s; mid_freq_num = lg - low_freq_num; gain_num = MF_GAIN_NUM/4; if (newStereo->bitrate < 32.0f) { wiener_bits = 4*4; } else { wiener_bits = 7*4; } lf_bits = nbits - hf_bits - wiener_bits - 3; // 3:unused bits for (w = 0; w < 4; w++) { float *cur_side_fft = side_fft + w * lg; float *cur_left_fft = left_fft + w * lg; float *cur_right_fft = right_fft + w * lg; float *cur_est_left_fft = est_left_fft + w * lg; float *cur_est_right_fft = est_right_fft + w * lg; int *cur_prm = prm + w * (1+low_freq_num+low_freq_num/8); //1 global gain p_left_gain = newStereo->left_gain + w * gain_num; p_right_gain = newStereo->right_gain + w * gain_num; p_quant_left_gain = newStereo->quant_left_gain + w * gain_num; p_quant_right_gain = newStereo->quant_right_gain + w * gain_num; gain_corr = newStereo->gain_correlation[w]; MakeLowFreqCoding(newStereo, cur_side_fft, low_freq_num, lf_bits/4, cur_prm); MakeMidFreqCoding(newStereo, signalType->is_transient, cur_left_fft+low_freq_num, cur_right_fft+low_freq_num, cur_est_left_fft+low_freq_num, cur_est_right_fft+low_freq_num, mid_freq_num, p_left_gain, p_right_gain, p_quant_left_gain, p_quant_right_gain, w, gain_num, param+w*gain_num, gain_corr); } } } /* filter smoother */ static void smooth_ener_filter(float *filter, float *threshold) { float tmp, ener,old_ener; int i; /* compute energy over subframe */ ener = 0.0001f; for (i=0; i 16.0f){ ener= 16.0f; } /* if energy *threshold) { tmp = *threshold; } } else { tmp = tmp/1.414f; if (tmp < *threshold) { tmp = *threshold; } } /* set the threshold for next subframer to the current modified energy */ *threshold = tmp; /* apply correction scale factor to HF signal */ tmp = (float)sqrt(tmp/old_ener); for (i=0; i 1e-10) | (y1 < -1e-10)) ? y1 : 0; mem[1] = ((y2 > 1e-10) | (y2 < -1e-10)) ? y2 : 0; mem[2] = ((x0 > 1e-10) | (x0 < -1e-10)) ? x0 : 0; mem[3] = ((x1 > 1e-10) | (x1 < -1e-10)) ? x1 : 0; } static void GetEstimatedSideExc(NEW_STEREO_DATA *newStereo, int nIsTransient, const float *side_exc, const float *mono_exc, float *est_side_exc, int est_len, int *param) { int k, t, j, i; float tmp_mono_exc[L_FRAME_PLUS+L_OVLP+HI_FILT_ORDER]; float filted_side_exc[L_FRAME_PLUS+L_OVLP]; float filted_mono_exc[L_FRAME_PLUS+L_OVLP]; /* covariance matrix */ float r[HI_FILT_ORDER][HI_FILT_ORDER]; float c[HI_FILT_ORDER]; float *p_h = newStereo->wiener_filter; float *x, *y; int *prm; float energy_right; float energy_left; float energy_mono; #if 1 hp1K_12k8(side_exc, filted_side_exc, newStereo->mem_side_error, est_len); hp1K_12k8(mono_exc, filted_mono_exc, newStereo->mem_mono_error, est_len); #else mvr2r(side_exc, filted_side_exc, est_len); mvr2r(mono_exc, filted_mono_exc, est_len); #endif mvr2r(newStereo->old_mono_exc, tmp_mono_exc, HI_FILT_ORDER); mvr2r(filted_mono_exc, tmp_mono_exc+HI_FILT_ORDER, est_len); mvr2r(filted_mono_exc+L_FRAME_PLUS-HI_FILT_ORDER, newStereo->old_mono_exc, HI_FILT_ORDER); if (nIsTransient == 0) // smooth { newStereo->filt_hi_pmsvq = &filt_hi_pmsvq7; prm = param; /* set signal pointers */ x = tmp_mono_exc+HI_FILT_ORDER; // y = side_exc; y = filted_side_exc; /* compute cross-correlation terms */ for (k = 0; k < HI_FILT_ORDER; k++) { c[k] = 0.0f; for (t = 0; t < est_len; t++) { c[k] += y[t]*x[t-k]; } } /* compute correlation matrix */ for (k = 0; k < HI_FILT_ORDER; k++) { for (j = k; j < HI_FILT_ORDER; j++) { r[k][j] = 0.0f; for (t = 0; t < est_len; t++) { r[k][j] += x[t-k]*x[t-j]; } } } /* compute a solution to the linear system */ if (cholsolc(r, c, p_h, HI_FILT_ORDER)) { /* cholesky failed use panning */ for (k = 1; k < HI_FILT_ORDER; k++) { p_h[k] = 0.0f; } p_h[0] = c[0]/(r[0][0]+1.0f); } energy_left = 0.001f; energy_right = 0.001f; energy_mono = 0.001f; for (t = 0; t < est_len; t++) { /* mono + side */ energy_left += (x[t]+y[t]) * (x[t]+y[t]); /* mono */ energy_mono += x[t] * x[t]; /* mono - side */ energy_right += (x[t]-y[t]) * (x[t]-y[t]); } newStereo->gain_correlation[0] = (4.0f*energy_mono)/(energy_left+energy_right); newStereo->gain_correlation[0] = 10.0f*(float)log10(newStereo->gain_correlation[0]); /* wiener filter energy smoothing */ smooth_ener_filter(p_h, &newStereo->filt_energy_threshold); /* quantize the filters*/ quant_filt(p_h, newStereo->old_wh_q, &prm, newStereo->filt_hi_pmsvq); /* local synthesis */ fir_filt(p_h, HI_FILT_ORDER, x, est_side_exc, est_len); } else // quick signal { int est_len_quick = est_len / 4; if (newStereo->bitrate < 32.0) { newStereo->filt_hi_pmsvq = &filt_hi_pmsvq4; } else { newStereo->filt_hi_pmsvq = &filt_hi_pmsvq7; } for (i = 0; i < 4; i++) { prm = param + i * 2; // maximum: 2 msvq stages (filt) /* set signal pointers */ x = tmp_mono_exc + HI_FILT_ORDER + i*256; // y = side_exc; y = filted_side_exc + i*256; /* compute cross-correlation terms */ for (k = 0; k < HI_FILT_ORDER; k++) { c[k] = 0.0f; for (t = 0; t < est_len_quick; t++) { c[k] += y[t]*x[t-k]; } } /* compute correlation matrix */ for (k = 0; k < HI_FILT_ORDER; k++) { for (j = k; j < HI_FILT_ORDER; j++) { r[k][j] = 0.0f; for (t = 0; t < est_len_quick; t++) { r[k][j] += x[t-k]*x[t-j]; } } } /* compute a solution to the linear system */ if (cholsolc(r, c, p_h, HI_FILT_ORDER)) { /* cholesky failed use panning */ for (k = 1; k < HI_FILT_ORDER; k++) { p_h[k] = 0.0f; } p_h[0] = c[0]/(r[0][0]+1.0f); } energy_left = 0.001f; energy_right = 0.001f; energy_mono = 0.001f; for (t = 0; t < est_len_quick; t++) { /* mono + side */ energy_left += (x[t]+y[t]) * (x[t]+y[t]); /* mono */ energy_mono += x[t] * x[t]; /* mono - side */ energy_right += (x[t]-y[t]) * (x[t]-y[t]); } newStereo->gain_correlation[i] = (4.0f*energy_mono)/(energy_left+energy_right); newStereo->gain_correlation[i] = 10.0f*(float)log10(newStereo->gain_correlation[i]); /* wiener filter energy smoothing */ smooth_ener_filter(p_h, &newStereo->filt_energy_threshold); /* quantize the filters*/ quant_filt(p_h, newStereo->old_wh_q, &prm, newStereo->filt_hi_pmsvq); // est_side_exc has 32-point overlap every other 288-point!!!!! because it is est_len_quick(288), NO 256 fir_filt(p_h, HI_FILT_ORDER, x, est_side_exc+i*est_len_quick, est_len_quick); p_h += HI_FILT_ORDER; } } } void cod_new_stereo_side(const float *sig_left, // (i)mono channel const float *sig_right, // (i)right channel int brMode, float AqLF[], int param_stereo[], // (o)Encoded parameters NEW_STEREO_DATA *newStereo) //(i/o): Encoder states { int i_subfr, k; int nbits; float mono_exc[L_FRAME_PLUS+NEW_STEREO_DELAY];//NEW_STEREO_DELAY >= L_OVLP float side_exc[L_FRAME_PLUS+NEW_STEREO_DELAY]; float est_side_exc[L_FRAME_PLUS+L_OVLP]; float *p_Aq; int *prm = NULL; float old_speech_side[L_TOTAL_ST+NEW_STEREO_DELAY]; float *speech_side, *new_speech_side; float old_speech_mono[L_TOTAL_ST+NEW_STEREO_DELAY]; float *speech_mono, *new_speech_mono; set_zero(old_speech_side, L_TOTAL_ST+NEW_STEREO_DELAY); set_zero(old_speech_mono, L_TOTAL_ST+NEW_STEREO_DELAY); new_speech_side = old_speech_side + L_OLD_SPEECH_ST + NEW_STEREO_DELAY; speech_side = old_speech_side + L_TOTAL_ST - L_FRAME_PLUS - L_A_MAX - L_BSP; new_speech_mono = old_speech_mono + L_OLD_SPEECH_ST + NEW_STEREO_DELAY; speech_mono = old_speech_mono + L_TOTAL_ST - L_FRAME_PLUS - L_A_MAX - L_BSP; mvr2r(newStereo->old_speech_side, old_speech_side, L_OLD_SPEECH_ST+NEW_STEREO_DELAY); mvr2r(newStereo->old_speech_mono, old_speech_mono, L_OLD_SPEECH_ST+NEW_STEREO_DELAY); mix_ch(sig_left, sig_right, new_speech_mono, L_FRAME_PLUS, 1.0f, 1.0f); mvr2r(sig_right, new_speech_side, L_FRAME_PLUS); mvr2r(old_speech_side+L_FRAME_PLUS, newStereo->old_speech_side, L_OLD_SPEECH_ST+NEW_STEREO_DELAY); mvr2r(old_speech_mono+L_FRAME_PLUS, newStereo->old_speech_mono, L_OLD_SPEECH_ST+NEW_STEREO_DELAY); // calc available bits /* number of bits per frame (80 ms) */ // 1 bit: signal type nbits = StereoNbits[brMode]; nbits -= 1; // signal type, // get old mono lf exc p_Aq = newStereo->old_AqLF; residu(p_Aq, M, &speech_mono[0], &mono_exc[0], L_SUBFR/2); residu(p_Aq, M, &speech_side[0], &side_exc[0], L_SUBFR/2); p_Aq += (M+1); for (i_subfr = L_SUBFR/2; i_subfr < 4*L_SUBFR+L_SUBFR/2; i_subfr+=L_SUBFR) { residu(p_Aq, M, &speech_mono[i_subfr], &mono_exc[i_subfr], L_SUBFR); residu(p_Aq, M, &speech_side[i_subfr], &side_exc[i_subfr], L_SUBFR); p_Aq += (M+1); } // get mono lf exc, forced delay 288 in order to synchonize with decoder p_Aq = AqLF; for (i_subfr = L_SUBFR/2+4*L_SUBFR; i_subfr < L_FRAME_PLUS+L_SUBFR/2+4*L_SUBFR; i_subfr+=L_SUBFR) { residu(p_Aq, M, &speech_mono[i_subfr], &mono_exc[i_subfr], L_SUBFR); residu(p_Aq, M, &speech_side[i_subfr], &side_exc[i_subfr], L_SUBFR); p_Aq += (M+1); } mvr2r(&AqLF[11*(M+1)], newStereo->old_AqLF, 5*(M+1)); // get real side for (k = 0; k < L_FRAME_PLUS+L_OVLP; k++) { side_exc[k] = mono_exc[k] - side_exc[k]; } MakeSignalTypeAnalysis(newStereo, &newStereo->signalType, side_exc); param_stereo[0] = newStereo->signalType.is_transient; // wiener estimation prm = param_stereo + 1; GetEstimatedSideExc(newStereo, newStereo->signalType.is_transient, side_exc, mono_exc, est_side_exc, L_FRAME_PLUS+L_OVLP, prm); // time-frequency transform MakeFFTTransform(newStereo, &newStereo->signalType, est_side_exc, side_exc, mono_exc, newStereo->side_fft, newStereo->mono_fft, newStereo->left_fft, newStereo->right_fft, newStereo->est_left_fft, newStereo->est_right_fft); // low-frequency AVQ coding and mid-frequency gain control prm = param_stereo + (1+8); // 1: signal type; 8: wiener VQ MakeStereoCoding(newStereo, &newStereo->signalType, newStereo->side_fft, newStereo->left_fft, newStereo->right_fft, newStereo->est_left_fft, newStereo->est_right_fft, nbits, prm); } static int unpack4bits_d(int nbits, int *prm, short *ptr) { int i; i=0; while (nbits > 4) { int2bin(prm[i], 4, ptr); ptr += 4; nbits -= 4; i++; } int2bin(prm[i], nbits, ptr); i++; return(i); } void enc_prm_new_stereo(int param[], /* (i) : parameters */ short serial[], /* (o) : serial bits stream */ int nbits_pack, /* (i) : number of bits per packet of 20ms*/ int nbits_bwe, /* (i) : number of BWE bits per 20ms */ int brMode, NEW_STEREO_DATA *newStereo ) { int nbits; int k,j; short *ptr = NULL; int *prm = NULL; int mod[NB_DIV],nbits_AVQ[NB_DIV]; int n_pack; int prm_AVQ[(NBITS_MAX/4)+N_PACK_MAX]; int hf_bits = 0; int si_bits = 0; int signal_type; int low_freq_len_l = newStereo->lowfreq_end_num_l; int low_freq_len_s = newStereo->lowfreq_end_num_s; /*----------------------------------------------------------* * Set number of bits used for stereo (per packet of 20 ms) * * When stereo is transmitted, the bit ordering is: * * serial: mode (2bits), core, stereo, 2xBWE(2x16bits) * *----------------------------------------------------------*/ nbits = (StereoNbits[brMode] + (2*nbits_bwe))/4; // exclude sum side's low freq signal_type = param[0]; /*----------------------------------------------------------* * Encode the high band parameters * *----------------------------------------------------------*/ k = 0; if (signal_type == 0) // smooth type { prm = param + 17; // skip to AVQ param n_pack = 4; nbits_AVQ[0] = ((StereoNbits[brMode])/4)-1-4-3-5-5; // nbits_AVQ[1] = ((StereoNbits[brMode])/4)-1-7-5-5; nbits_AVQ[2] = ((StereoNbits[brMode])/4)-5-5; nbits_AVQ[3] = ((StereoNbits[brMode])/4)-5-5; AVQ_encmux(n_pack, prm+1, prm_AVQ, nbits_AVQ, low_freq_len_l/8); /* set pointer to bit stream */ ptr = serial + (k+1)*nbits_pack - nbits; /* encode first 20 ms frame */ int2bin(param[0], 1, ptr); ptr += 1; // signal type int2bin(param[1], 4, ptr); ptr += 4; // 1st FIR coef int2bin(param[2], 3, ptr); ptr += 3; // 2nd FIR coef int2bin(param[9], 5, ptr); ptr += 5; // 1st mid-freq's gain int2bin(param[10], 5, ptr); ptr += 5; // 2nd mid-freq's gain j = unpack4bits_d(nbits_AVQ[0], prm_AVQ, ptr); // AVQ /* set pointer to bit stream */ ptr = serial + (k+2)*nbits_pack - nbits; /* encode second 20 ms frame */ *ptr = 0; ptr += 1; // unused bits int2bin(param[17], 7, ptr); ptr += 7; // global gain int2bin(param[11], 5, ptr); ptr += 5; // 3rd mid-freq's gain int2bin(param[12], 5, ptr); ptr += 5; // 4th mid-freq's gain j += unpack4bits_d(nbits_AVQ[1], prm_AVQ+j, ptr); /* set pointer to bit stream */ ptr = serial + (k+3)*nbits_pack - nbits; /* encode third 20 ms frame */ int2bin(param[13], 5, ptr); ptr += 5; // 5th mid-freq's gain int2bin(param[14], 5, ptr); ptr += 5; // 6th mid-freq's gain j += unpack4bits_d(nbits_AVQ[2], prm_AVQ+j, ptr); /* set pointer to bit stream */ ptr = serial + (k+4)*nbits_pack - nbits; /* encode forth 20 ms frame */ int2bin(param[15], 5, ptr); ptr += 5; // 7th mid-freq's gain int2bin(param[16], 5, ptr); ptr += 5; // 8th mid-freq's gain unpack4bits_d(nbits_AVQ[3], prm_AVQ+j, ptr); } else // quick type { // side information // 1st packet /* set pointer to bit stream */ k = 0; ptr = serial + (k+1)*nbits_pack - nbits; int2bin(param[0], 1, ptr); ptr += 1; // signal type if (newStereo->bitrate < 32.0f) { int2bin(param[1], 4, ptr); ptr += 4; // 1st FIR coef } else { int2bin(param[1], 4, ptr); ptr += 4; // 1st FIR coef int2bin(param[2], 3, ptr); ptr += 3; // 2nd FIR coef } int2bin(param[9], 5, ptr); ptr += 5; // 1st mid-freq's gain int2bin(param[10], 5, ptr); ptr += 5; // 2nd mid-freq's gain k = 1; ptr = serial + (k+1)*nbits_pack - nbits; *ptr = 0; ptr += 1; // reserved bits if (newStereo->bitrate < 32.0f) { int2bin(param[3], 4, ptr); ptr += 4; // 1st FIR coef } else { int2bin(param[3], 4, ptr); ptr += 4; // 1st FIR coef int2bin(param[4], 3, ptr); ptr += 3; // 2nd FIR coef } int2bin(param[11], 5, ptr); ptr += 5; // 3rd mid-freq's gain int2bin(param[12], 5, ptr); ptr += 5; // 4th mid-freq's gain // 3rd packet k = 2; ptr = serial + (k+1)*nbits_pack - nbits; *ptr = 0; ptr += 1; // reserved bits if (newStereo->bitrate < 32.0f) { int2bin(param[5], 4, ptr); ptr += 4; // 1st FIR coef } else { int2bin(param[5], 4, ptr); ptr += 4; // 1st FIR coef int2bin(param[6], 3, ptr); ptr += 3; // 2nd FIR coef } int2bin(param[13], 5, ptr); ptr += 5; // 5th mid-freq's gain int2bin(param[14], 5, ptr); ptr += 5; // 6th mid-freq's gain k = 3; ptr = serial + (k+1)*nbits_pack - nbits; *ptr = 0; ptr += 1; // reserved bits if (newStereo->bitrate < 32.0f) { int2bin(param[7], 4, ptr); ptr += 4; // 1st FIR coef } else { int2bin(param[7], 4, ptr); ptr += 4; // 1st FIR coef int2bin(param[8], 3, ptr); ptr += 3; // 2nd FIR coef } int2bin(param[15], 5, ptr); ptr += 5; // 7th mid-freq's gain int2bin(param[16], 5, ptr); ptr += 5; // 8th mid-freq's gain if (newStereo->bitrate < 32.0f) { si_bits = 15; } else { si_bits = 18; } prm = param + 17; // 17 side info used // core (SplitVQ + global gain) for (k = 0; k < 4; k++) // 4 packets { n_pack = 1; nbits_AVQ[0] = ((StereoNbits[brMode])/4) - si_bits - 7; // 7 global gain AVQ_encmux(n_pack, prm+1, prm_AVQ, nbits_AVQ, low_freq_len_s/8); /* set pointer to bit stream */ ptr = serial + (k+1)*nbits_pack - nbits + si_bits; int2bin(prm[0], 7, ptr); ptr += 7; // global gain unpack4bits_d(nbits_AVQ[0], prm_AVQ, ptr); ptr += nbits_AVQ[0]; prm += (1+(low_freq_len_s+low_freq_len_s/8)); } } return; } /* END_NEW_STEREO */ /* FROM TOP OF THIS FILE */