git-svn-id: http://webrtc.googlecode.com/svn/trunk@4 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
217
modules/audio_coding/codecs/iSAC/main/source/lattice.c
Normal file
217
modules/audio_coding/codecs/iSAC/main/source/lattice.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* lattice.c
|
||||
*
|
||||
* contains the normalized lattice filter routines (MA and AR) for iSAC codec
|
||||
*
|
||||
*/
|
||||
#include "settings.h"
|
||||
#include "codec.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
#ifdef ANDROID
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/* filter the signal using normalized lattice filter */
|
||||
/* MA filter */
|
||||
void WebRtcIsac_NormLatticeFilterMa(int orderCoef,
|
||||
float *stateF,
|
||||
float *stateG,
|
||||
float *lat_in,
|
||||
double *filtcoeflo,
|
||||
double *lat_out)
|
||||
{
|
||||
int n,k,i,u,temp1;
|
||||
int ord_1 = orderCoef+1;
|
||||
float sth[MAX_AR_MODEL_ORDER];
|
||||
float cth[MAX_AR_MODEL_ORDER];
|
||||
float inv_cth[MAX_AR_MODEL_ORDER];
|
||||
double a[MAX_AR_MODEL_ORDER+1];
|
||||
float f[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN], g[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN];
|
||||
float gain1;
|
||||
|
||||
for (u=0;u<SUBFRAMES;u++)
|
||||
{
|
||||
/* set the Direct Form coefficients */
|
||||
temp1 = u*ord_1;
|
||||
a[0] = 1;
|
||||
memcpy(a+1, filtcoeflo+temp1+1, sizeof(double) * (ord_1-1));
|
||||
|
||||
/* compute lattice filter coefficients */
|
||||
WebRtcIsac_Dir2Lat(a,orderCoef,sth,cth);
|
||||
|
||||
/* compute the gain */
|
||||
gain1 = (float)filtcoeflo[temp1];
|
||||
for (k=0;k<orderCoef;k++)
|
||||
{
|
||||
gain1 *= cth[k];
|
||||
inv_cth[k] = 1/cth[k];
|
||||
}
|
||||
|
||||
/* normalized lattice filter */
|
||||
/*****************************/
|
||||
|
||||
/* initial conditions */
|
||||
for (i=0;i<HALF_SUBFRAMELEN;i++)
|
||||
{
|
||||
f[0][i] = lat_in[i + u * HALF_SUBFRAMELEN];
|
||||
g[0][i] = lat_in[i + u * HALF_SUBFRAMELEN];
|
||||
}
|
||||
|
||||
/* get the state of f&g for the first input, for all orders */
|
||||
for (i=1;i<ord_1;i++)
|
||||
{
|
||||
f[i][0] = inv_cth[i-1]*(f[i-1][0] + sth[i-1]*stateG[i-1]);
|
||||
g[i][0] = cth[i-1]*stateG[i-1] + sth[i-1]* f[i][0];
|
||||
}
|
||||
|
||||
/* filtering */
|
||||
for(k=0;k<orderCoef;k++)
|
||||
{
|
||||
for(n=0;n<(HALF_SUBFRAMELEN-1);n++)
|
||||
{
|
||||
f[k+1][n+1] = inv_cth[k]*(f[k][n+1] + sth[k]*g[k][n]);
|
||||
g[k+1][n+1] = cth[k]*g[k][n] + sth[k]* f[k+1][n+1];
|
||||
}
|
||||
}
|
||||
|
||||
for(n=0;n<HALF_SUBFRAMELEN;n++)
|
||||
{
|
||||
lat_out[n + u * HALF_SUBFRAMELEN] = gain1 * f[orderCoef][n];
|
||||
}
|
||||
|
||||
/* save the states */
|
||||
for (i=0;i<ord_1;i++)
|
||||
{
|
||||
stateF[i] = f[i][HALF_SUBFRAMELEN-1];
|
||||
stateG[i] = g[i][HALF_SUBFRAMELEN-1];
|
||||
}
|
||||
/* process next frame */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*///////////////////AR filter ///////////////////////////////*/
|
||||
/* filter the signal using normalized lattice filter */
|
||||
void WebRtcIsac_NormLatticeFilterAr(int orderCoef,
|
||||
float *stateF,
|
||||
float *stateG,
|
||||
double *lat_in,
|
||||
double *lo_filt_coef,
|
||||
float *lat_out)
|
||||
{
|
||||
int n,k,i,u,temp1;
|
||||
int ord_1 = orderCoef+1;
|
||||
float sth[MAX_AR_MODEL_ORDER];
|
||||
float cth[MAX_AR_MODEL_ORDER];
|
||||
double a[MAX_AR_MODEL_ORDER+1];
|
||||
float ARf[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN], ARg[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN];
|
||||
float gain1,inv_gain1;
|
||||
|
||||
for (u=0;u<SUBFRAMES;u++)
|
||||
{
|
||||
/* set the denominator and numerator of the Direct Form */
|
||||
temp1 = u*ord_1;
|
||||
a[0] = 1;
|
||||
|
||||
memcpy(a+1, lo_filt_coef+temp1+1, sizeof(double) * (ord_1-1));
|
||||
|
||||
WebRtcIsac_Dir2Lat(a,orderCoef,sth,cth);
|
||||
|
||||
gain1 = (float)lo_filt_coef[temp1];
|
||||
for (k=0;k<orderCoef;k++)
|
||||
{
|
||||
gain1 = cth[k]*gain1;
|
||||
}
|
||||
|
||||
/* initial conditions */
|
||||
inv_gain1 = 1/gain1;
|
||||
for (i=0;i<HALF_SUBFRAMELEN;i++)
|
||||
{
|
||||
ARf[orderCoef][i] = (float)lat_in[i + u * HALF_SUBFRAMELEN]*inv_gain1;
|
||||
}
|
||||
|
||||
|
||||
for (i=orderCoef-1;i>=0;i--) //get the state of f&g for the first input, for all orders
|
||||
{
|
||||
ARf[i][0] = cth[i]*ARf[i+1][0] - sth[i]*stateG[i];
|
||||
ARg[i+1][0] = sth[i]*ARf[i+1][0] + cth[i]* stateG[i];
|
||||
}
|
||||
ARg[0][0] = ARf[0][0];
|
||||
|
||||
for(n=0;n<(HALF_SUBFRAMELEN-1);n++)
|
||||
{
|
||||
for(k=orderCoef-1;k>=0;k--)
|
||||
{
|
||||
ARf[k][n+1] = cth[k]*ARf[k+1][n+1] - sth[k]*ARg[k][n];
|
||||
ARg[k+1][n+1] = sth[k]*ARf[k+1][n+1] + cth[k]* ARg[k][n];
|
||||
}
|
||||
ARg[0][n+1] = ARf[0][n+1];
|
||||
}
|
||||
|
||||
memcpy(lat_out+u * HALF_SUBFRAMELEN, &(ARf[0][0]), sizeof(float) * HALF_SUBFRAMELEN);
|
||||
|
||||
/* cannot use memcpy in the following */
|
||||
for (i=0;i<ord_1;i++)
|
||||
{
|
||||
stateF[i] = ARf[i][HALF_SUBFRAMELEN-1];
|
||||
stateG[i] = ARg[i][HALF_SUBFRAMELEN-1];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* compute the reflection coefficients using the step-down procedure*/
|
||||
/* converts the direct form parameters to lattice form.*/
|
||||
/* a and b are vectors which contain the direct form coefficients,
|
||||
according to
|
||||
A(z) = a(1) + a(2)*z + a(3)*z^2 + ... + a(M+1)*z^M
|
||||
B(z) = b(1) + b(2)*z + b(3)*z^2 + ... + b(M+1)*z^M
|
||||
*/
|
||||
|
||||
void WebRtcIsac_Dir2Lat(double *a,
|
||||
int orderCoef,
|
||||
float *sth,
|
||||
float *cth)
|
||||
{
|
||||
int m, k;
|
||||
float tmp[MAX_AR_MODEL_ORDER];
|
||||
float tmp_inv, cth2;
|
||||
|
||||
sth[orderCoef-1] = (float)a[orderCoef];
|
||||
cth2 = 1.0f - sth[orderCoef-1] * sth[orderCoef-1];
|
||||
cth[orderCoef-1] = (float)sqrt(cth2);
|
||||
for (m=orderCoef-1; m>0; m--)
|
||||
{
|
||||
tmp_inv = 1.0f / cth2;
|
||||
for (k=1; k<=m; k++)
|
||||
{
|
||||
tmp[k] = ((float)a[k] - sth[m] * (float)a[m-k+1]) * tmp_inv;
|
||||
}
|
||||
|
||||
for (k=1; k<m; k++)
|
||||
{
|
||||
a[k] = tmp[k];
|
||||
}
|
||||
|
||||
sth[m-1] = tmp[m];
|
||||
cth2 = 1 - sth[m-1] * sth[m-1];
|
||||
cth[m-1] = (float)sqrt(cth2);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user