/*************************************************************************/ /* */ /* LD-CELP G.728 */ /* */ /* Low-Delay Code Excitation Linear Prediction speech compression. */ /* */ /* Code edited by Michael Concannon. */ /* Based on code written by Alex Zatsman, Analog Devices 1993 */ /* */ /*************************************************************************/ /********************************* Perceptual Weighting Filter **/ #include "common.h" #include "parm.h" #include "fast.h" #include "prototyp.h" /* Filter Memory in reverse order, i.e. firmem[0] is the most recent */ static real firmem[LPCW+IDIM]; static real iirmem[LPCW+IDIM]; void pwfilter2(real QMEM input[], real output[]) { int k; real out; real temp; RSHIFT(firmem, LPCW, IDIM); for(k=0; k=0; j--) statelpc[j+IDIM] = statelpc[j]; { real STATE_MEM * sjpk = statelpc + LPC+IDIM-1; real out = 0.0; for (k=0; k=0; j--) { out -= sj*aj; sj = *sjp--; aj = *ajp--; } output[k] = out - sj*aj; *sjp--= output[k]; sjpk--; } } #else /** This is un-pipelined version of the above. Kept for reference **/ for(j=LPC-1; j>=0; j--) statelpc[j+IDIM] = statelpc[j]; for (k=0; k=1; j--) { out -= sj*aj; sj = statelpc[IDIM-k+j]; aj = sf_coeff[j+1]; } output[k] = out - sj*aj-statelpc[IDIM-k] * sf_coeff[1]; statelpc[IDIM-1-k] = output[k]; } return; #endif } void pwf_zresp(real input[], real output[]) { int j,k; real tmp; #if PIPELINE for (k=0; k=1; j--) { input[k] += zirwfir[j] * pwf_z_coeff[j+1]; zirwfir[j] = zirwfir[j-1]; } input[k] += zirwfir[0] * pwf_z_coeff[1]; zirwfir[0] = tmp; for (j=LPCW-1; j>=1; j--) { input[k] -= zirwiir[j] * pwf_p_coeff[j+1]; zirwiir[j] = zirwiir[j-1]; } output[k] = input[k] - zirwiir[0] * pwf_p_coeff[1]; zirwiir[0] = output[k]; } #else /** Un-pipelined version, kept for reference **/ for (k=0; k=1; j--) { input[k] += zirwfir[j] * pwf_z_coeff[j+1]; zirwfir[j] = zirwfir[j-1]; } input[k] += zirwfir[0] * pwf_z_coeff[1]; zirwfir[0] = tmp; for (j=LPCW-1; j>=1; j--) { input[k] -= zirwiir[j] * pwf_p_coeff[j+1]; zirwiir[j] = zirwiir[j-1]; } output[k] = input[k] - zirwiir[0] * pwf_p_coeff[1]; zirwiir[0] = output[k]; } #endif } void zresp(real output[]) { real temp[IDIM]; sf_zresp(temp); pwf_zresp(temp, output); } void mem_update (real input[], real output[]) { int i,k; real temp[IDIM], a0, a1, a2; real STATE_MEM *t2 = zirwfir; t2[0] = temp[0] = input[0]; for (k=1; k= 1; i--) { t2[i] = t2[i-1]; temp[i] = temp[i-1]; a0 -= sf_coeff[i] * t2[i]; a1 += pwf_z_coeff[i] * t2[i]; a2 -= pwf_p_coeff[i] * temp[i]; } t2[0] = a0; temp[0] = a0+a1+a2; } for (k=0; k Max) statelpc[k] = Max; else if (statelpc[k] < Min) statelpc[k] = Min; zirwiir[k] += temp[k]; } for (i=0; i # define LOG10(X) log10(X) # define EXP10(X) pow(10,X) /*********************************************** The Gain Predictor */ extern real COEFF_MEM gp_coeff[]; static real gain_input[LPCLG]; real log_rms(real input[]) { real etrms=0.0; int k; for(k=0; k 60.0) new_gain = 60.0; new_gain = EXP10(0.05*new_gain); return (new_gain); } void update_gain(real input[], real *lgp) { int i; *lgp = log_rms(input) - GOFF; for (i=0; i