blob: e8cdac3b8737fc928f7428ecab00c1527b0c48d4 [file] [edit]
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include <stdio.h>
#include <assert.h>
#include "gsm610_priv.h"
/*
* SHORT TERM ANALYSIS FILTERING SECTION
*/
/* 4.2.8 */
static void Decoding_of_the_coded_Log_Area_Ratios (
int16_t * LARc, /* coded log area ratio [0..7] IN */
int16_t * LARpp) /* out: decoded .. */
{
register int16_t temp1 ;
/* This procedure requires for efficient implementation
* two tables.
*
* INVA[1..8] = integer((32768 * 8) / real_A[1..8])
* MIC[1..8] = minimum value of the LARc[1..8]
*/
/* Compute the LARpp[1..8]
*/
/* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) {
*
* temp1 = GSM_ADD (*LARc, *MIC) << 10;
* temp2 = *B << 1;
* temp1 = GSM_SUB(temp1, temp2) ;
*
* assert(*INVA != MIN_WORD) ;
*
* temp1 = GSM_MULT_R (*INVA, temp1) ;
* *LARpp = GSM_ADD (temp1, temp1) ;
* }
*/
#undef STEP
#define STEP(B, MIC, INVA) \
temp1 = arith_shift_left (GSM_ADD (*LARc++, MIC), 10) ; \
temp1 = GSM_SUB (temp1, B * 2) ; \
temp1 = GSM_MULT_R (INVA, temp1) ; \
*LARpp++ = GSM_ADD (temp1, temp1) ;
STEP (0, -32, 13107) ;
STEP (0, -32, 13107) ;
STEP (2048, -16, 13107) ;
STEP (-2560, -16, 13107) ;
STEP (94, -8, 19223) ;
STEP (-1792, -8, 17476) ;
STEP (-341, -4, 31454) ;
STEP (-1144, -4, 29708) ;
/* NOTE: the addition of *MIC is used to restore
* the sign of *LARc.
*/
}
/* 4.2.9 */
/* Computation of the quantized reflection coefficients
*/
/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8]
*/
/*
* Within each frame of 160 analyzed speech samples the short term
* analysis and synthesis filters operate with four different sets of
* coefficients, derived from the previous set of decoded LARs(LARpp(j-1))
* and the actual set of decoded LARs (LARpp(j))
*
* (Initial value: LARpp(j-1)[1..8] = 0.)
*/
static void Coefficients_0_12 (
register int16_t * LARpp_j_1,
register int16_t * LARpp_j,
register int16_t * LARp)
{
register int i ;
for (i = 1 ; i <= 8 ; i++, LARp++, LARpp_j_1++, LARpp_j++)
{ *LARp = GSM_ADD (SASR_W (*LARpp_j_1, 2), SASR_W (*LARpp_j, 2)) ;
*LARp = GSM_ADD (*LARp, SASR_W (*LARpp_j_1, 1)) ;
}
}
static void Coefficients_13_26 (
register int16_t * LARpp_j_1,
register int16_t * LARpp_j,
register int16_t * LARp)
{
register int i ;
for (i = 1 ; i <= 8 ; i++, LARpp_j_1++, LARpp_j++, LARp++)
*LARp = GSM_ADD (SASR_W (*LARpp_j_1, 1), SASR_W (*LARpp_j, 1)) ;
}
static void Coefficients_27_39 (
register int16_t * LARpp_j_1,
register int16_t * LARpp_j,
register int16_t * LARp)
{
register int i ;
for (i = 1 ; i <= 8 ; i++, LARpp_j_1++, LARpp_j++, LARp++)
{ *LARp = GSM_ADD (SASR_W (*LARpp_j_1, 2), SASR_W (*LARpp_j, 2)) ;
*LARp = GSM_ADD (*LARp, SASR_W (*LARpp_j, 1)) ;
}
}
static void Coefficients_40_159 (
register int16_t * LARpp_j,
register int16_t * LARp)
{
register int i ;
for (i = 1 ; i <= 8 ; i++, LARp++, LARpp_j++)
*LARp = *LARpp_j ;
}
/* 4.2.9.2 */
static void LARp_to_rp (
register int16_t * LARp) /* [0..7] IN/OUT */
/*
* The input of this procedure is the interpolated LARp[0..7] array.
* The reflection coefficients, rp[i], are used in the analysis
* filter and in the synthesis filter.
*/
{
register int i ;
register int16_t temp ;
for (i = 1 ; i <= 8 ; i++, LARp++)
{ /* temp = GSM_ABS(*LARp) ;
*
* if (temp < 11059) temp <<= 1;
* else if (temp < 20070) temp += 11059;
* else temp = GSM_ADD (temp >> 2, 26112) ;
*
* *LARp = *LARp < 0 ? -temp : temp;
*/
if (*LARp < 0)
{ temp = *LARp == MIN_WORD ? MAX_WORD : - (*LARp) ;
*LARp = - ((temp < 11059) ? temp << 1
: ((temp < 20070) ? temp + 11059
: GSM_ADD ((int16_t) (temp >> 2), (int16_t) 26112))) ;
}
else
{ temp = *LARp ;
*LARp = (temp < 11059) ? temp << 1
: ((temp < 20070) ? temp + 11059
: GSM_ADD ((int16_t) (temp >> 2), (int16_t) 26112)) ;
}
}
}
/* 4.2.10 */
static void Short_term_analysis_filtering (
struct gsm_state * S,
register int16_t * rp, /* [0..7] IN */
register int k_n, /* k_end - k_start */
register int16_t * s /* [0..n-1] IN/OUT */
)
/*
* This procedure computes the short term residual signal d[..] to be fed
* to the RPE-LTP loop from the s[..] signal and from the local rp[..]
* array (quantized reflection coefficients). As the call of this
* procedure can be done in many ways (see the interpolation of the LAR
* coefficient), it is assumed that the computation begins with index
* k_start (for arrays d[..] and s[..]) and stops with index k_end
* (k_start and k_end are defined in 4.2.9.1). This procedure also
* needs to keep the array u [0..7] in memory for each call.
*/
{
register int16_t * u = S->u ;
register int i ;
register int16_t di, zzz, ui, sav, rpi ;
for ( ; k_n-- ; s++)
{ di = sav = *s ;
for (i = 0 ; i < 8 ; i++)
{ /* YYY */
ui = u [i] ;
rpi = rp [i] ;
u [i] = sav ;
zzz = GSM_MULT_R (rpi, di) ;
sav = GSM_ADD (ui, zzz) ;
zzz = GSM_MULT_R (rpi, ui) ;
di = GSM_ADD (di, zzz) ;
}
*s = di ;
}
}
#if defined (USE_FLOAT_MUL) && defined (FAST)
static void Fast_Short_term_analysis_filtering (
struct gsm_state * S,
register int16_t * rp, /* [0..7] IN */
register int k_n, /* k_end - k_start */
register int16_t * s /* [0..n-1] IN/OUT */
)
{
register int16_t * u = S->u ;
register int i ;
float uf [8], rpf [8] ;
register float scalef = 3.0517578125e-5 ;
register float sav, di, temp ;
for (i = 0 ; i < 8 ; ++i)
{ uf [i] = u [i] ;
rpf [i] = rp [i] * scalef ;
}
for ( ; k_n-- ; s++)
{ sav = di = *s ;
for (i = 0 ; i < 8 ; i++)
{ register float rpfi = rpf [i] ;
register float ufi = uf [i] ;
uf [i] = sav ;
temp = rpfi * di + ufi ;
di += rpfi * ufi ;
sav = temp ;
}
*s = di ;
}
for (i = 0 ; i < 8 ; i++) u [i] = uf [i] ;
}
#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */
static void Short_term_synthesis_filtering (
struct gsm_state * S,
register int16_t * rrp, /* [0..7] IN */
register int k, /* k_end - k_start */
register int16_t * wt, /* [0..k-1] IN */
register int16_t * sr /* [0..k-1] OUT */
)
{
register int16_t * v = S->v ;
register int i ;
register int16_t sri, tmp1, tmp2 ;
while (k--)
{ sri = *wt++ ;
for (i = 8 ; i-- ; )
{ /* sri = GSM_SUB(sri, gsm_mult_r(rrp[i], v [i])) ;
*/
tmp1 = rrp [i] ;
tmp2 = v [i] ;
tmp2 = (tmp1 == MIN_WORD && tmp2 == MIN_WORD
? MAX_WORD
: 0x0FFFF & (((int32_t) tmp1 * (int32_t) tmp2
+ 16384) >> 15)) ;
sri = GSM_SUB (sri, tmp2) ;
/* v [i+1] = GSM_ADD (v [i], gsm_mult_r(rrp[i], sri)) ;
*/
tmp1 = (tmp1 == MIN_WORD && sri == MIN_WORD
? MAX_WORD
: 0x0FFFF & (((int32_t) tmp1 * (int32_t) sri
+ 16384) >> 15)) ;
v [i + 1] = GSM_ADD (v [i], tmp1) ;
}
*sr++ = v [0] = sri ;
}
}
#if defined (FAST) && defined (USE_FLOAT_MUL)
static void Fast_Short_term_synthesis_filtering (
struct gsm_state * S,
register int16_t * rrp, /* [0..7] IN */
register int k, /* k_end - k_start */
register int16_t * wt, /* [0..k-1] IN */
register int16_t * sr /* [0..k-1] OUT */
)
{
register int16_t * v = S->v ;
register int i ;
float va [9], rrpa [8] ;
register float scalef = 3.0517578125e-5, temp ;
for (i = 0 ; i < 8 ; ++i)
{ va [i] = v [i] ;
rrpa [i] = (float) rrp [i] * scalef ;
}
while (k--) {
register float sri = *wt++ ;
for (i = 8 ; i-- ; )
{ sri -= rrpa [i] * va [i] ;
if (sri < -32768.0) sri = -32768.0 ;
else if (sri > 32767.0) sri = 32767.0 ;
temp = va [i] + rrpa [i] * sri ;
if (temp < -32768.0) temp = -32768.0 ;
else if (temp > 32767.0) temp = 32767.0 ;
va [i+1] = temp ;
}
*sr++ = va [0] = sri ;
}
for (i = 0 ; i < 9 ; ++i) v [i] = va [i] ;
}
#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */
void Gsm_Short_Term_Analysis_Filter (
struct gsm_state * S,
int16_t * LARc, /* coded log area ratio [0..7] IN */
int16_t * s /* signal [0..159] IN/OUT */
)
{
int16_t * LARpp_j = S->LARpp [S->j] ;
int16_t * LARpp_j_1 = S->LARpp [S->j ^= 1] ;
int16_t LARp [8] ;
#undef FILTER
#if defined (FAST) && defined (USE_FLOAT_MUL)
# define FILTER (* (S->fast \
? Fast_Short_term_analysis_filtering \
: Short_term_analysis_filtering))
#else
# define FILTER Short_term_analysis_filtering
#endif
Decoding_of_the_coded_Log_Area_Ratios (LARc, LARpp_j) ;
Coefficients_0_12 (LARpp_j_1, LARpp_j, LARp) ;
LARp_to_rp (LARp) ;
FILTER (S, LARp, 13, s) ;
Coefficients_13_26 (LARpp_j_1, LARpp_j, LARp) ;
LARp_to_rp (LARp) ;
FILTER (S, LARp, 14, s + 13) ;
Coefficients_27_39 (LARpp_j_1, LARpp_j, LARp) ;
LARp_to_rp (LARp) ;
FILTER (S, LARp, 13, s + 27) ;
Coefficients_40_159 (LARpp_j, LARp) ;
LARp_to_rp (LARp) ;
FILTER (S, LARp, 120, s + 40) ;
}
void Gsm_Short_Term_Synthesis_Filter (
struct gsm_state * S,
int16_t * LARcr, /* received log area ratios [0..7] IN */
int16_t * wt, /* received d [0..159] IN */
int16_t * s /* signal s [0..159] OUT */
)
{
int16_t * LARpp_j = S->LARpp [S->j] ;
int16_t * LARpp_j_1 = S->LARpp [S->j ^= 1] ;
int16_t LARp [8] ;
#undef FILTER
#if defined (FAST) && defined (USE_FLOAT_MUL)
# define FILTER (* (S->fast \
? Fast_Short_term_synthesis_filtering \
: Short_term_synthesis_filtering))
#else
# define FILTER Short_term_synthesis_filtering
#endif
Decoding_of_the_coded_Log_Area_Ratios (LARcr, LARpp_j) ;
Coefficients_0_12 (LARpp_j_1, LARpp_j, LARp) ;
LARp_to_rp (LARp) ;
FILTER (S, LARp, 13, wt, s) ;
Coefficients_13_26 (LARpp_j_1, LARpp_j, LARp) ;
LARp_to_rp (LARp) ;
FILTER (S, LARp, 14, wt + 13, s + 13) ;
Coefficients_27_39 (LARpp_j_1, LARpp_j, LARp) ;
LARp_to_rp (LARp) ;
FILTER (S, LARp, 13, wt + 27, s + 27) ;
Coefficients_40_159 (LARpp_j, LARp) ;
LARp_to_rp (LARp) ;
FILTER (S, LARp, 120, wt + 40, s + 40) ;
}