/*==================================================================================== EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0 ====================================================================================*/ #include #include "options.h" #include "cnst.h" #include "rom_com.h" #include "prot.h" /*-------------------------------------------------------------------------- * window_ola() * * Windowing, Overlap and Add *--------------------------------------------------------------------------*/ void window_ola( const float *ImdctOut, /* i : input */ float *auOut, /* o : output audio */ float *OldauOut, /* i/o: audio from previous frame */ const short L, /* i : length */ const short right_mode, const short left_mode, /* window overlap of current frame (0: full, 2: none, or 3: half) */ const short use_bfi_win, /* i : use BFI windowing */ const short oldHqVoicing, /* i : previous HqVoicing */ float *oldgapsynth /* i : previous gapsynth */ ) { short i, decimate, decay; short n ,n16, windecay48, windecay16; float win_right[R2_48]; float win_int_left[R1_16]; float win_left[R1_48]; float win_int_right[R2_16]; float SS2[L_FRAME48k-NS2SA(48000, N_ZERO_MDCT_NS)]; float wret2[L_FRAME48k-NS2SA(48000, N_ZERO_MDCT_NS)]; float *paout; n = (short)((float)L*N_ZERO_MDCT_NS/FRAME_SIZE_NS); n16 = (short)((float)L_FRAME16k*N_ZERO_MDCT_NS/FRAME_SIZE_NS); windecay48 = (short)(2*((float)L_FRAME48k*N_ZERO_MDCT_NS/FRAME_SIZE_NS))+R1_48; windecay16 = (short)(2*((float)L_FRAME16k*N_ZERO_MDCT_NS/FRAME_SIZE_NS))+R1_16; decimate = 1; decay = 0; tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L); if ( L == L_FRAME32k || L == L_FRAME16k ) { decimate = 3; decay = 1; } else if ( L == L_FRAME8k ) { decimate = 6; decay = 2; } else if (L == 512) { windecay48 = (short)(2*((float)512*N_ZERO_MDCT_NS/FRAME_SIZE_NS))+R1_25; decimate = 1; decay = 0; } else if (L== 256) { windecay48 = (short)(2*((float)512*N_ZERO_MDCT_NS/FRAME_SIZE_NS))+R1_25; decimate = 2; decay = 0; } paout=auOut-n; if( use_bfi_win ) { if ( L == L_FRAME32k ) { for (i = 0; i < L/2; i+=2) { wret2[L/2-n + i +1] = win_left[(L_FRAME16k/2-i/2-1)*decimate+decay]; wret2[L/2-n + i] = win_int_left[(L_FRAME16k/2-i/2-1)]; } for (i = n; i < L/2; i+=2) { wret2[ i -n] = win_left[(L_FRAME16k-i/2)*decimate-decay-1]; wret2[ i +1-n] = win_int_left[L_FRAME16k-(i/2)-1]; } } else { for (i = 0; i < L/2; i++) { wret2[i+L/2-n] = win_left[(L/2-i-1)*decimate+decay]; } for (i =n; i < L/2; i++) { wret2[i-n] = win_left[(L-i)*decimate-decay-1]; } } sinq(EVS_PI/(2*(L-n)), EVS_PI/(4*(L-n)), L-n, SS2); for (i = n; i < L/2; i++) { paout[i] = ImdctOut[L/2 + i]; } for (i = 0; i < L/2; i++) { paout[L/2 + i] = -ImdctOut[L - 1 - i]; } if( oldHqVoicing ) { for (i=0 ; i < L-n; i++) { auOut[i] = auOut[i]*SS2[i]+ oldgapsynth[i+n]*(SS2[L-n-i-1]); } } else { for (i=0 ; i < L-n; i++) { auOut[i] =auOut[i]*SS2[i]+ OldauOut[i+n]*(SS2[L-n-i-1])/(wret2[i]+0.01f); } } } if ( L == L_FRAME32k ) { if (use_bfi_win==0) { for (i = n; i < L/2; i+=2) { paout[i] = ImdctOut[L/2 + i] * win_right[(2*L_FRAME16k-(n16+(i-n)/2))*decimate-1-decay-windecay48]+OldauOut[i]; paout[i+1] = ImdctOut[L/2 + i +1] * win_int_right[2*L_FRAME16k-(n16+(i-n)/2)-1-windecay16]+OldauOut[i+1]; } for (i = 0; i < L/2-n; i+=2) { paout[L/2 + i +1] = -ImdctOut[L - 1 - (i+1)] * win_right[(3*L_FRAME16k/2-1-i/2)*decimate+decay-windecay48]+OldauOut[i+L/2+1]; paout[L/2 + i ] = -ImdctOut[L - 1 - i] * win_int_right[(3*L_FRAME16k/2-1-i/2)-windecay16]+OldauOut[i+L/2]; } for (i = L/2-n; i < L/2; i+=2) { paout[L/2 + i +1] = -ImdctOut[L - 1 - (i+1)]+OldauOut[i+L/2+1] ; paout[L/2 + i ] = -ImdctOut[L - 1 - i]+OldauOut[i+L/2]; } } for (i = 0; i < L/2; i+=2) { OldauOut[L/2 + i +1] = -ImdctOut[i+1] * win_left[(L_FRAME16k/2-i/2-1)*decimate+decay]; OldauOut[L/2 + i] = -ImdctOut[i] * win_int_left[(L_FRAME16k/2-i/2-1)]; } for (i = n; i < L/2; i+=2) { OldauOut[ i] = -ImdctOut[L/2 - 1 - i] *win_left[(L_FRAME16k-i/2)*decimate-decay-1]; OldauOut[ i +1] = -ImdctOut[L/2 - 1 - (i +1)] * win_int_left[L_FRAME16k-(i/2)-1]; } } else { if (use_bfi_win==0) { for (i = n; i < L/2; i++) { paout[i] = ImdctOut[L/2 + i] * win_right[(2*L-i)*decimate-1-decay-windecay48]+OldauOut[i]; } for (i = 0; i < L/2-n; i++) { paout[L/2 + i] = -ImdctOut[L - 1 - i] * win_right[(3*L/2-1-i)*decimate+decay-windecay48]+OldauOut[i+L/2]; } for (i = L/2-n; i < L/2; i++) { paout[L/2 + i] = -ImdctOut[L - 1 - i] + OldauOut[i+L/2]; } } for (i = 0; i < L/2; i++) { OldauOut[L/2 + i] = -ImdctOut[i] * win_left[(L/2-i-1)*decimate+decay]; } for (i = n; i < L/2; i++) { OldauOut[ i] = -ImdctOut[L/2 - 1 - i] * win_left[(L-i)*decimate-decay-1]; } } for (i = 0; i < n; i++) { OldauOut[i] = -ImdctOut[L/2 - 1 - i]; } for (i = 0; i < n; i++) { paout[L + i] = OldauOut[i]; } return; } /*---------------------------------------------------------------------* * core_switching_OLA() * * modify window after HQ core decoding * Overlap ACELP and HQ *---------------------------------------------------------------------*/ void core_switching_OLA( const float *mem_over_hp, /* i : upsampling filter memory */ const short last_L_frame, /* i : last L_frame lengthture */ const int output_Fs, /* i : output sampling rate */ float *synth, /* i/o: synthesized signal from HQ core */ const float *synth_subfr_out, /* i : synthesized signal from ACELP core */ float *synth_subfr_bwe, /* i : synthesized BWE from ACELP core */ const short output_frame, /* i : output frame length */ const short bwidth /* i : output bandwidth */ ) { short i, L, Loverlapp, out_filt_length, filt_delay, decimate, decay; float tmp_buf_switch[SWITCH_MAX_GAP], tmp_buf_switch2[HQ_DELAY_COMP*HQ_DELTA_MAX+2]; float delta; const float *win, *win_int; win = window_48kHz; win_int = window_8_16_32kHz; decimate = 1; decay = 0; if( output_frame == L_FRAME32k || output_frame == L_FRAME16k ) { decimate = 3; decay = 1; } else if( output_frame == L_FRAME8k ) { decimate = 6; decay = 2; } /* set multiplication factor according to the sampling rate */ delta = 1; if( output_frame == L_FRAME16k ) { delta = 2; } else if( output_frame == L_FRAME32k ) { delta = 4; } else if( output_frame == L_FRAME48k ) { delta = 6; } set_f( tmp_buf_switch, 0, SWITCH_MAX_GAP ); set_f( tmp_buf_switch2, 0, HQ_DELAY_COMP*HQ_DELTA_MAX+2); Loverlapp = (short)(delta*SWITCH_OVERLAP_8k); mvr2r( synth_subfr_out,tmp_buf_switch, NS2SA(output_Fs, SWITCH_GAP_LENGTH_NS)); /* copy 6.25 ms subframe */ /* conversion from 12.8kHz to output_Fs */ if( last_L_frame == L_FRAME) { /* resample filter memory */ if( output_frame == L_FRAME8k ) { mvr2r( synth_subfr_out + NS2SA(output_Fs, SWITCH_GAP_LENGTH_NS), tmp_buf_switch+NS2SA(output_Fs,SWITCH_GAP_LENGTH_NS),NS2SA(output_Fs, DELAY_CLDFB_NS)); /* copy subframe to tmp buffer */ } else { out_filt_length = modify_Fs_intcub3m_sup( mem_over_hp+2, NS2SA(12800,DELAY_CLDFB_NS), 12800, tmp_buf_switch2, output_Fs , &filt_delay ); for( i=0; i=16000) || (bwidth > NB && output_Fs>16000) ) { /* mix cubic and CLDFB resampled buffers in case of resampling to higher frequency rates */ for(i=0; i=16000) || (bwidth > NB && output_Fs>16000) ) { /* mix cubic and CLDFB resampled buffers in case of resampling to higher frequency rates */ for(i=0; i 0.0001f) { A = (x[2]+x[0])/x[1]; } else { A = 0; } for (i=3; i