package org.mobicents.media.server.impl.dsp.audio.g729;
public class CodLD8K {
/*-----------------------------------------------------------------------*
* Initialize pointers to speech vector. *
* *
* *
* |--------------------|-------------|-------------|------------| *
* previous speech sf1 sf2 L_NEXT *
* *
* <---------------- Total speech vector (L_TOTAL) -----------> *
* | <------------ LPC analysis window (L_WINDOW) -----------> *
* | | <-- present frame (L_FRAME) --> *
* old_speech | <-- new speech (L_FRAME) --> *
* p_wind | | *
* speech | *
* new_speech *
*-----------------------------------------------------------------------*/
/* Speech vector */
float[] old_speech_array = new float[LD8KConstants.L_TOTAL];
int old_speech;
int speech;
int p_window;
int new_speech;
/* Weighted speech vector */
float[] old_wsp_array = new float[LD8KConstants.L_FRAME+LD8KConstants.PIT_MAX];
int old_wsp;
int wsp;
/* Excitation vector */
float[] old_exc_array = new float[LD8KConstants.L_FRAME+LD8KConstants.PIT_MAX+LD8KConstants.L_INTERPOL];
int old_exc;
int exc;
/* Zero vector */
float[] ai_zero_array = new float[LD8KConstants.L_SUBFR+LD8KConstants.MP1];
int ai_zero;
int zero;
/* Lsp (Line spectral pairs) */
float[] lsp_old =
{ (float)0.9595, (float)0.8413, (float)0.6549, (float)0.4154, (float)0.1423,
(float)-0.1423, (float)-0.4154, (float)-0.6549, (float)-0.8413, (float)-0.9595};
float[] lsp_old_q = new float[LD8KConstants.M];
/* Filter's memory */
float[] mem_syn = new float[LD8KConstants.M];
float[] mem_w0 = new float[LD8KConstants.M];
float[] mem_w = new float[LD8KConstants.M];
float[] mem_err_array = new float[LD8KConstants.M+LD8KConstants.L_SUBFR];
int mem_err;
int error;
float sharp;
Lpc lpc = new Lpc();
QuaLsp quaLsp = new QuaLsp();
Pwf pwf = new Pwf();
Taming tamingFunc = new Taming();
CelpCo acelp = new CelpCo();
QuaGain quaGain = new QuaGain();
/*----------------------------------------------------------------------------
* init_coder_ld8k - initialization of variables for the encoder
*----------------------------------------------------------------------------
*/
public void init_coder_ld8k()
{
/*-----------------------------------------------------------------------*
* Initialize pointers to speech vector. *
* *
* *
* |--------------------|-------------|-------------|------------| *
* previous speech sf1 sf2 L_NEXT *
* *
* <---------------- Total speech vector (L_TOTAL) -----------> *
* | <------------ LPC analysis window (L_WINDOW) -----------> *
* | | <-- present frame (L_FRAME) --> *
* old_speech | <-- new speech (L_FRAME) --> *
* p_wind | | *
* speech | *
* new_speech *
*-----------------------------------------------------------------------*/
new_speech = old_speech + LD8KConstants.L_TOTAL - LD8KConstants.L_FRAME; /* New speech */
speech = new_speech - LD8KConstants.L_NEXT; /* Present frame */
p_window = old_speech + LD8KConstants.L_TOTAL - LD8KConstants.L_WINDOW; /* For LPC window */
/* Initialize static pointers */
wsp = old_wsp + LD8KConstants.PIT_MAX;
exc = old_exc + LD8KConstants.PIT_MAX + LD8KConstants.L_INTERPOL;
zero = ai_zero + LD8KConstants.MP1;
error = mem_err + LD8KConstants.M;
/* Static vectors to zero */
/*
set_zero(old_speech, LD8KConstants.L_TOTAL);
set_zero(old_exc, PIT_MAX+L_INTERPOL);
set_zero(old_wsp, PIT_MAX);
set_zero(mem_syn, M);
set_zero(mem_w, M);
set_zero(mem_w0, M);
set_zero(mem_err, M);
set_zero(zero, L_SUBFR);
sharp = SHARPMIN;
*/
sharp = LD8KConstants.SHARPMIN;
/* Initialize lsp_old_q[] */
System.arraycopy(lsp_old, 0, lsp_old_q, 0, LD8KConstants.M);
quaLsp.lsp_encw_reset();
tamingFunc.init_exc_err();
return;
}
public void loadSpeech(float[] newSpeech) {
int i=239;
for(int q=79; q>=0; q--) {
old_speech_array[i--] = newSpeech[q];
}
}
/*----------------------------------------------------------------------------
* coder_ld8k - encoder routine ( speech data should be in new_speech )
*----------------------------------------------------------------------------
*/
public void coder_ld8k(
int[] ana_array, int ana /* output: analysis parameters */
)
{
/* LPC coefficients */
float[] r = new float[LD8KConstants.MP1]; /* Autocorrelations low and hi */
float[] A_t = new float[(LD8KConstants.MP1)*2]; /* A(z) unquantized for the 2 subframes */
float[] Aq_t = new float[(LD8KConstants.MP1)*2]; /* A(z) quantized for the 2 subframes */
float[] Ap1 = new float[LD8KConstants.MP1]; /* A(z) with spectral expansion */
float[] Ap2 = new float[LD8KConstants.MP1]; /* A(z) with spectral expansion */
int A, Aq; /* Pointer on A_t and Aq_t */
/* LSP coefficients */
float[] lsp_new = new float[LD8KConstants.M];
float[] lsp_new_q = new float[LD8KConstants.M]; /* LSPs at 2th subframe */
float[] lsf_int = new float[LD8KConstants.M]; /* Interpolated LSF 1st subframe. */
float[] lsf_new = new float[LD8KConstants.M];
/* Variable added for adaptive gamma1 and gamma2 of the PWF */
float[] rc = new float[LD8KConstants.M]; /* Reflection coefficients */
float[] gamma1 = new float[2]; /* Gamma1 for 1st and 2nd subframes */
float[] gamma2 = new float[2]; /* Gamma2 for 1st and 2nd subframes */
/* Other vectors */
float[] synth = new float[LD8KConstants.L_FRAME]; /* Buffer for synthesis speech */
float[] h1 = new float[LD8KConstants.L_SUBFR]; /* Impulse response h1[] */
float[] xn = new float[LD8KConstants.L_SUBFR]; /* Target vector for pitch search */
float[] xn2 = new float[LD8KConstants.L_SUBFR]; /* Target vector for codebook search */
float[] code = new float[LD8KConstants.L_SUBFR]; /* Fixed codebook excitation */
float[] y1 = new float[LD8KConstants.L_SUBFR]; /* Filtered adaptive excitation */
float[] y2 = new float[LD8KConstants.L_SUBFR]; /* Filtered fixed codebook excitation */
float[] g_coeff = new float[5]; /* Correlations between xn, y1, & y2:
<y1,y1>, <xn,y1>, <y2,y2>, <xn,y2>,<y1,y2>*/
/* Scalars */
int i, j, i_gamma, i_subfr;
int T_op, t0;
IntegerPointer t0_frac = new IntegerPointer();
IntegerPointer t0_min = new IntegerPointer();
IntegerPointer t0_max = new IntegerPointer();
int index, taming;
float gain_pit, gain_code=0;
/*------------------------------------------------------------------------*
* - 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 the 2 *
* subframes (both quantized and unquantized) *
*------------------------------------------------------------------------*/
/* LP analysis */
lpc.autocorr(ArrayUtils.subArray(old_speech_array, p_window), LD8KConstants.M, r); /* Autocorrelations */
lpc.lag_window(LD8KConstants.M, r); /* Lag windowing */
float[] tmp = ArrayUtils.subArray(A_t, LD8KConstants.MP1);
lpc.levinson(r, tmp, rc); /* Levinson Durbin */
ArrayUtils.replace(A_t, LD8KConstants.MP1, tmp);
lpc.az_lsp(tmp, lsp_new, lsp_old); /* From A(z) to lsp */
ArrayUtils.replace(A_t, LD8KConstants.MP1, tmp);
/* LSP quantization */
quaLsp.qua_lsp(lsp_new, lsp_new_q, ana_array);
ana += 2; /* Advance analysis parameters pointer */
/*--------------------------------------------------------------------*
* Find interpolated LPC parameters in all subframes (both quantized *
* and unquantized). *
* The interpolated parameters are in array A_t[] of size (M+1)*4 *
* and the quantized interpolated parameters are in array Aq_t[] *
*--------------------------------------------------------------------*/
LpcFunc.int_lpc(lsp_old, lsp_new, lsf_int, lsf_new, A_t);
LpcFunc.int_qlpc(lsp_old_q, lsp_new_q, Aq_t);
/* update the LSPs for the next frame */
for(i=0; i<LD8KConstants.M; i++)
{
lsp_old[i] = lsp_new[i];
lsp_old_q[i] = lsp_new_q[i];
}
/*----------------------------------------------------------------------*
* - Find the weighting factors *
*----------------------------------------------------------------------*/
pwf.perc_var(gamma1, gamma2, lsf_int, lsf_new, rc);
/*----------------------------------------------------------------------*
* - Find the weighted input speech w_sp[] for the whole speech frame *
* - Find the open-loop pitch delay for the whole speech frame *
* - Set the range for searching closed-loop pitch in 1st subframe *
*----------------------------------------------------------------------*/
LpcFunc.weight_az(A_t, 0, gamma1[0], LD8KConstants.M, Ap1, 0);
LpcFunc.weight_az(A_t, 0, gamma2[0], LD8KConstants.M, Ap2, 0);
Filter.residu(Ap1, 0, old_speech_array, speech, old_wsp_array, wsp, LD8KConstants.L_SUBFR);
Filter.syn_filt(Ap2, 0, old_wsp_array, wsp, old_wsp_array, wsp, LD8KConstants.L_SUBFR, mem_w, 0, 1);
LpcFunc.weight_az(A_t, LD8KConstants.MP1, gamma1[1], LD8KConstants.M, Ap1, 0);
LpcFunc.weight_az(A_t, LD8KConstants.MP1, gamma2[1], LD8KConstants.M, Ap2, 0);
Filter.residu(Ap1, 0, old_speech_array, speech + LD8KConstants.L_SUBFR, old_wsp_array, wsp + LD8KConstants.L_SUBFR, LD8KConstants.L_SUBFR);
Filter.syn_filt(Ap2, 0, old_wsp_array, wsp + LD8KConstants.L_SUBFR, old_wsp_array, wsp + LD8KConstants.L_SUBFR, LD8KConstants.L_SUBFR, mem_w, 0, 1);
/* Find open loop pitch lag for whole speech frame */
T_op = Pitch.pitch_ol(old_wsp_array, wsp, LD8KConstants.PIT_MIN, LD8KConstants.PIT_MAX, LD8KConstants.L_FRAME);
/* range for closed loop pitch search in 1st subframe */
t0_min.value = T_op - 3;
if (t0_min.value < LD8KConstants.PIT_MIN) t0_min.value = (int)LD8KConstants.PIT_MIN;
t0_max.value = t0_min.value + 6;
if (t0_max.value > LD8KConstants.PIT_MAX)
{
t0_max.value = (int)LD8KConstants.PIT_MAX;
t0_min.value = t0_max.value - 6;
}
/*------------------------------------------------------------------------*
* 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 *
* - compute the target signal for pitch search *
* - compute impulse response of weighted synthesis filter (h1[]) *
* - find the closed-loop pitch parameters *
* - encode the pitch delay *
* - 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 = 0;//A_t; /* pointer to interpolated LPC parameters */
Aq = 0;//Aq_t; /* pointer to interpolated quantized LPC parameters */
i_gamma = 0;
for (i_subfr = 0; i_subfr < LD8KConstants.L_FRAME; i_subfr += LD8KConstants.L_SUBFR)
{
/*---------------------------------------------------------------*
* Find the weighted LPC coefficients for the weighting filter. *
*---------------------------------------------------------------*/
LpcFunc.weight_az(A_t, A, gamma1[i_gamma], LD8KConstants.M, Ap1, 0);
LpcFunc.weight_az(A_t, A, gamma2[i_gamma], LD8KConstants.M, Ap2, 0);
i_gamma++;
/*---------------------------------------------------------------*
* Compute impulse response, h1[], of weighted synthesis filter *
*---------------------------------------------------------------*/
for (i = 0; i <= LD8KConstants.M; i++) ai_zero_array[ai_zero+i] = Ap1[i];
Filter.syn_filt(Aq_t, Aq, ai_zero_array, ai_zero, h1, 0, LD8KConstants.L_SUBFR, ai_zero_array, zero, 0);
Filter.syn_filt(Ap2, 0, h1, 0, h1, 0, LD8KConstants.L_SUBFR, ai_zero_array, zero, 0);
/*------------------------------------------------------------------------*
* *
* Find the target vector for pitch search: *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* *
* |------| res[n] *
* speech[n]---| A(z) |-------- *
* |------| | |--------| error[n] |------| *
* zero -- (-)--| 1/A(z) |-----------| W(z) |-- target *
* exc |--------| |------| *
* *
* Instead of subtracting the zero-input response of filters from *
* the weighted input speech, the above configuration is used to *
* compute the target vector. This configuration gives better performance *
* with fixed-point implementation. The memory of 1/A(z) is updated by *
* filtering (res[n]-exc[n]) through 1/A(z), or simply by subtracting *
* the synthesis speech from the input speech: *
* error[n] = speech[n] - syn[n]. *
* The memory of W(z) is updated by filtering error[n] through W(z), *
* or more simply by subtracting the filtered adaptive and fixed *
* codebook excitations from the target: *
* target[n] - gain_pit*y1[n] - gain_code*y2[n] *
* as these signals are already available. *
* *
*------------------------------------------------------------------------*/
Filter.residu(Aq_t, Aq, old_speech_array, speech + i_subfr, old_exc_array, exc + i_subfr, LD8KConstants.L_SUBFR); /* LPC residual */
Filter.syn_filt(Aq_t, Aq, old_exc_array, exc+i_subfr, mem_err_array, error, LD8KConstants.L_SUBFR, mem_err_array, mem_err, 0);
Filter.residu(Ap1, 0, mem_err_array, error, xn, 0, LD8KConstants.L_SUBFR);
Filter.syn_filt(Ap2, 0, xn, 0, xn, 0, LD8KConstants.L_SUBFR, mem_w0, 0, 0); /* target signal xn[]*/
/*----------------------------------------------------------------------*
* Closed-loop fractional pitch search *
*----------------------------------------------------------------------*/
t0 = Pitch.pitch_fr3(old_exc_array,exc+i_subfr, xn, 0, h1, 0, LD8KConstants.L_SUBFR, t0_min.value, t0_max.value,
i_subfr, t0_frac);
index = Pitch.enc_lag3(t0, t0_frac.value, t0_min, t0_max,LD8KConstants.PIT_MIN,LD8KConstants.PIT_MAX,i_subfr);
ana_array[ana++] = index;
if (i_subfr == 0)
ana_array[ana++] = PParity.parity_pitch(index);
/*-----------------------------------------------------------------*
* - find unity gain pitch excitation (adaptive codebook entry) *
* with fractional interpolation. *
* - find filtered pitch exc. y1[]=exc[] convolve with h1[]) *
* - compute pitch gain and limit between 0 and 1.2 *
* - update target vector for codebook search *
* - find LTP residual. *
*-----------------------------------------------------------------*/
PredLt.pred_lt_3(old_exc_array,exc + i_subfr, t0, t0_frac.value, LD8KConstants.L_SUBFR);
Filter.convolve(old_exc_array,exc+i_subfr, h1, 0, y1, 0, LD8KConstants.L_SUBFR);
gain_pit = Pitch.g_pitch(xn, 0, y1, 0, g_coeff, 0, LD8KConstants.L_SUBFR);
/* clip pitch gain if taming is necessary */
taming = tamingFunc.test_err(t0, t0_frac.value);
if( taming == 1){
if ( gain_pit> LD8KConstants.GPCLIP) {
gain_pit = LD8KConstants.GPCLIP;
}
}
for (i = 0; i < LD8KConstants.L_SUBFR; i++)
xn2[i] = xn[i] - y1[i]*gain_pit;
/*-----------------------------------------------------*
* - Innovative codebook search. *
*-----------------------------------------------------*/
IntegerPointer tmpi = new IntegerPointer(i);
index = acelp.ACELP_codebook(xn2, h1, t0, sharp, i_subfr, code, y2, tmpi);
i = tmpi.value;
ana_array[ana++] = index; /* Positions index */
ana_array[ana++] = i; /* Signs index */
/*-----------------------------------------------------*
* - Quantization of gains. *
*-----------------------------------------------------*/
CorFunc.corr_xy2(xn, y1, y2, g_coeff);
FloatPointer tmpgain_pit = new FloatPointer(gain_pit), tmpgain_code = new FloatPointer(gain_code);
ana_array[ana++] = quaGain.qua_gain(code, g_coeff, LD8KConstants.L_SUBFR, tmpgain_pit, tmpgain_code, taming );
gain_pit = tmpgain_pit.value; gain_code = tmpgain_code.value;
/*------------------------------------------------------------*
* - Update pitch sharpening "sharp" with quantized gain_pit *
*------------------------------------------------------------*/
sharp = gain_pit;
if (sharp > LD8KConstants.SHARPMAX) sharp = LD8KConstants.SHARPMAX;
if (sharp < LD8KConstants.SHARPMIN) sharp = LD8KConstants.SHARPMIN;
/*------------------------------------------------------*
* - Find the total excitation *
* - find synthesis speech corresponding to exc[] *
* - update filters' memories for finding the target *
* vector in the next subframe *
* (update error[-m..-1] and mem_w0[]) *
* update error function for taming process *
*------------------------------------------------------*/
for (i = 0; i < LD8KConstants.L_SUBFR; i++)
old_exc_array[exc+i+i_subfr] = gain_pit*old_exc_array[exc+i+i_subfr] + gain_code*code[i];
tamingFunc.update_exc_err(gain_pit, t0);
Filter.syn_filt(Aq_t, Aq, old_exc_array, exc+i_subfr, synth, i_subfr, LD8KConstants.L_SUBFR, mem_syn, 0, 1);
for (i = LD8KConstants.L_SUBFR-LD8KConstants.M, j = 0; i < LD8KConstants.L_SUBFR; i++, j++)
{
mem_err_array[mem_err+j] = old_speech_array[speech+i_subfr+i] - synth[i_subfr+i];
mem_w0[j] = xn[i] - gain_pit*y1[i] - gain_code*y2[i];
}
A += LD8KConstants.MP1; /* interpolated LPC parameters for next subframe */
Aq += LD8KConstants.MP1;
}
/*--------------------------------------------------*
* Update signal for next frame. *
* -> shift to the left by L_FRAME: *
* speech[], wsp[] and exc[] *
*--------------------------------------------------*/
Util.copy(old_speech_array,old_speech+LD8KConstants.L_FRAME, old_speech_array, old_speech, LD8KConstants.L_TOTAL-LD8KConstants.L_FRAME);
Util.copy(old_wsp_array, old_wsp+LD8KConstants.L_FRAME, old_wsp_array, old_wsp, LD8KConstants.PIT_MAX);
Util.copy(old_exc_array, old_exc+LD8KConstants.L_FRAME, old_exc_array, old_exc, LD8KConstants.PIT_MAX+LD8KConstants.L_INTERPOL);
return;
}
}