Commit 034e6403 authored by jm's avatar jm
Browse files

decoder excitation now in 16-bit precision (was 32), which saves quite a bit

of RAM. Also introduced a divide-with-rounding (PDIV) operator


git-svn-id: http://svn.xiph.org/trunk/speex@11407 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent 93fc0708
......@@ -168,8 +168,10 @@ typedef float spx_word64_t;
#define MULT16_16_Q15(a,b) ((a)*(b))
#define MULT16_16_P15(a,b) ((a)*(b))
#define DIV32_16(a,b) ((a)/(b))
#define DIV32(a,b) ((a)/(b))
#define DIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b))
#define PDIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b))
#define DIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))
#define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))
#endif
......
......@@ -603,5 +603,9 @@ SpeexBits *bits,
char *stack
)
{
speex_rand_vec(1, exc, nsf);
int i;
/* FIXME: This is bad, but I don't think the function ever gets called anyway */
spx_int32_t seed = 0;
for (i=0;i<nsf;i++)
exc[i]=SHL32(EXTEND32(speex_rand(1, &seed)),SIG_SHIFT);
}
......@@ -82,7 +82,7 @@ void signal_div(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)
{
spx_word16_t scale_1;
scale = PSHR32(scale, SIG_SHIFT);
scale_1 = EXTRACT16(DIV32_16(SHL32(EXTEND32(SIG_SCALING),7),scale));
scale_1 = EXTRACT16(PDIV32_16(SHL32(EXTEND32(SIG_SCALING),7),scale));
for (i=0;i<len;i++)
{
y[i] = SHR32(MULT16_16(scale_1, EXTRACT16(SHR32(x[i],SIG_SHIFT))),7);
......@@ -160,14 +160,13 @@ spx_word16_t compute_rms(const spx_sig_t *x, int len)
sum = ADD32(sum,SHR32(sum2,6));
}
return EXTRACT16(PSHR32(SHL32(EXTEND32(spx_sqrt(1+DIV32(sum,len))),(sig_shift+3)),SIG_SHIFT));
return EXTRACT16(PSHR32(SHL32(EXTEND32(spx_sqrt(DIV32(sum,len))),(sig_shift+3)),SIG_SHIFT));
}
spx_word16_t compute_rms16(const spx_word16_t *x, int len)
{
int i;
spx_word16_t max_val=10;
int sig_shift;
for (i=0;i<len;i++)
{
......@@ -189,7 +188,7 @@ spx_word16_t compute_rms16(const spx_word16_t *x, int len)
sum2 = MAC16_16(sum2,PSHR16(x[i+3],1),PSHR16(x[i+3],1));
sum = ADD32(sum,SHR32(sum2,6));
}
return SHL16(spx_sqrt(1+DIV32(sum,len)),4);
return SHL16(spx_sqrt(DIV32(sum,len)),4);
} else {
spx_word32_t sum=0;
int sig_shift=0;
......@@ -208,7 +207,7 @@ spx_word16_t compute_rms16(const spx_word16_t *x, int len)
sum2 = MAC16_16(sum2,SHL16(x[i+3],sig_shift),SHL16(x[i+3],sig_shift));
sum = ADD32(sum,SHR32(sum2,6));
}
return SHL16(spx_sqrt(1+DIV32(sum,len)),3-sig_shift);
return SHL16(spx_sqrt(DIV32(sum,len)),3-sig_shift);
}
}
......@@ -728,7 +727,7 @@ int len
}
void multicomb(
spx_sig_t *_exc, /*decoded excitation*/
spx_word16_t *exc, /*decoded excitation*/
spx_word16_t *new_exc, /*enhanced excitation*/
spx_coef_t *ak, /*LPC filter coefs*/
int p, /*LPC order*/
......@@ -744,10 +743,6 @@ char *stack
spx_word16_t old_ener, new_ener;
int corr_pitch;
int nol_pitch[6];
spx_word16_t nol_pitch_coef[6];
spx_word16_t ol_pitch_coef;
spx_word16_t *exc;
spx_word16_t iexc0_mag, iexc1_mag, exc_mag;
spx_word32_t corr0, corr1;
spx_word16_t gain0, gain1;
......@@ -757,21 +752,10 @@ char *stack
spx_word16_t ngain;
spx_word16_t gg1, gg2;
#ifdef FIXED_POINT
VARDECL(spx_word16_t *exc2);
ALLOC(exc2, 12+nsf+(nsf>>1)+2*max_pitch, spx_word16_t);
for (i=0;i<12+nsf+(nsf>>1)+2*max_pitch;i++)
exc2[i] = 0;
exc = exc2+6+2*max_pitch;
for (i=-2*max_pitch-6;i<nsf+(nsf>>1)+6;i++)
exc[i] = PSHR32(_exc[i], SIG_SHIFT);
#else
exc = _exc;
#endif
ALLOC(iexc, 2*nsf, spx_word16_t);
#if 0 /* Set to 1 to enable full pitch search */
int nol_pitch[6];
spx_word16_t nol_pitch_coef[6];
spx_word16_t ol_pitch_coef;
open_loop_nbest_pitch(exc, 20, 120, nsf,
nol_pitch, nol_pitch_coef, 6, stack);
corr_pitch=nol_pitch[0];
......@@ -793,8 +777,11 @@ char *stack
#else
corr_pitch = pitch;
#endif
ALLOC(iexc, 2*nsf, spx_word16_t);
interp_pitch(exc, iexc, corr_pitch, 80);
if (corr_pitch>40)
if (corr_pitch>max_pitch)
interp_pitch(exc, iexc+nsf, 2*corr_pitch, 80);
else
interp_pitch(exc, iexc+nsf, -corr_pitch, 80);
......@@ -821,13 +808,13 @@ char *stack
if (corr0 > MULT16_16(iexc0_mag,exc_mag))
pgain1 = QCONST16(1., 14);
else
pgain1 = DIV32_16(SHL32(DIV32(corr0, exc_mag),14),iexc0_mag);
pgain1 = PDIV32_16(SHL32(PDIV32(corr0, exc_mag),14),iexc0_mag);
if (corr1 > MULT16_16(iexc1_mag,exc_mag))
pgain2 = QCONST16(1., 14);
else
pgain2 = DIV32_16(SHL32(DIV32(corr1, exc_mag),14),iexc1_mag);
gg1 = DIV32_16(SHL32(EXTEND32(exc_mag),8), iexc0_mag);
gg2 = DIV32_16(SHL32(EXTEND32(exc_mag),8), iexc1_mag);
pgain2 = PDIV32_16(SHL32(PDIV32(corr1, exc_mag),14),iexc1_mag);
gg1 = PDIV32_16(SHL32(EXTEND32(exc_mag),8), iexc0_mag);
gg2 = PDIV32_16(SHL32(EXTEND32(exc_mag),8), iexc1_mag);
if (comb_gain>0)
{
#ifdef FIXED_POINT
......@@ -852,9 +839,9 @@ char *stack
g1 = c1;
if (g2<c1)
g2 = c1;
g1 = (spx_word16_t)DIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g1);
g2 = (spx_word16_t)DIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g2);
if (corr_pitch>40)
g1 = (spx_word16_t)PDIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g1);
g2 = (spx_word16_t)PDIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g2);
if (corr_pitch>max_pitch)
{
gain0 = MULT16_16_Q15(QCONST16(.7,15),MULT16_16_Q14(g1,gg1));
gain1 = MULT16_16_Q15(QCONST16(.3,15),MULT16_16_Q14(g2,gg2));
......@@ -874,7 +861,7 @@ char *stack
new_ener = 1;
if (old_ener > new_ener)
old_ener = new_ener;
ngain = DIV32_16(SHL32(EXTEND32(old_ener),14),new_ener);
ngain = PDIV32_16(SHL32(EXTEND32(old_ener),14),new_ener);
for (i=0;i<nsf;i++)
new_exc[i] = MULT16_16_Q14(ngain, new_exc[i]);
......
......@@ -74,7 +74,7 @@ void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, cons
#ifndef OLD_ENHANCER
void multicomb(
spx_sig_t *exc, /*decoded excitation*/
spx_word16_t *exc, /*decoded excitation*/
spx_word16_t *new_exc, /*enhanced excitation*/
spx_coef_t *ak, /*LPC filter coefs*/
int p, /*LPC order*/
......
......@@ -98,6 +98,8 @@
#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15))
#define DIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b))))
#define PDIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word16_t)(b))))
#define DIV32(a,b) (((spx_word32_t)(a))/((spx_word32_t)(b)))
#define PDIV32(a,b) (((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word32_t)(b)))
#endif
......@@ -643,10 +643,11 @@ int plc_tuning
}
void pitch_unquant_3tap(
spx_sig_t exc[], /* Excitation */
spx_word16_t exc[], /* Input excitation */
spx_word32_t exc_out[], /* Output excitation */
int start, /* Smallest pitch value allowed */
int end, /* Largest pitch value allowed */
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
const void *par,
int nsf, /* Number of samples in subframe */
int *pitch_val,
......@@ -719,7 +720,7 @@ int cdbk_offset
gain[1] = SHL16(gain[1],7);
gain[2] = SHL16(gain[2],7);
for (i=0;i<nsf;i++)
exc[i]=0;
exc_out[i]=0;
for (i=0;i<3;i++)
{
int j;
......@@ -729,15 +730,15 @@ int cdbk_offset
if (tmp1>pp)
tmp1=pp;
for (j=0;j<tmp1;j++)
exc[j]=MAC16_32_Q15(exc[j],gain[2-i],exc[j-pp]);
exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]);
tmp3=nsf;
if (tmp3>pp+pitch)
tmp3=pp+pitch;
for (j=tmp1;j<tmp3;j++)
exc[j]=MAC16_32_Q15(exc[j],gain[2-i],exc[j-pp-pitch]);
exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]);
}
for (i=0;i<nsf;i++)
exc[i]=SHL32(exc[i], 2);
/*for (i=0;i<nsf;i++)
exc[i]=PSHR32(exc32[i],13);*/
}
......@@ -765,14 +766,18 @@ int plc_tuning
)
{
int i;
float coef = GAIN_SCALING_1*pitch_coef;
VARDECL(spx_sig_t *res);
ALLOC(res, nsf, spx_sig_t);
if (coef>.99)
coef=.99;
#ifdef FIXED_POINT
if (pitch_coef>63)
pitch_coef=63;
#else
if (pitch_coef>.99)
pitch_coef=.99;
#endif
for (i=0;i<nsf;i++)
{
exc[i]=exc[i-start]*coef;
exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]);
}
syn_percep_zero(exc, ak, awk1, awk2, res, nsf, p, stack);
for (i=0;i<nsf;i++)
......@@ -782,10 +787,11 @@ int plc_tuning
/** Unquantize forced pitch delay and gain */
void forced_pitch_unquant(
spx_sig_t exc[], /* Excitation */
spx_word16_t exc[], /* Input excitation */
spx_word32_t exc_out[], /* Output excitation */
int start, /* Smallest pitch value allowed */
int end, /* Largest pitch value allowed */
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
const void *par,
int nsf, /* Number of samples in subframe */
int *pitch_val,
......@@ -799,12 +805,17 @@ int cdbk_offset
)
{
int i;
float coef = GAIN_SCALING_1*pitch_coef;
if (coef>.99)
coef=.99;
#ifdef FIXED_POINT
if (pitch_coef>63)
pitch_coef=63;
#else
if (pitch_coef>.99)
pitch_coef=.99;
#endif
for (i=0;i<nsf;i++)
{
exc[i]=exc[i-start]*coef;
exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7));
exc[i] = PSHR(exc_out[i],13);
}
*pitch_val = start;
gain_val[0]=gain_val[2]=0;
......
......@@ -79,10 +79,11 @@ int plc_tuning
/*Unquantize adaptive codebook and update pitch contribution*/
void pitch_unquant_3tap(
spx_sig_t exc[], /* Excitation */
spx_word16_t exc[], /* Input excitation */
spx_word32_t exc_out[], /* Output excitation */
int start, /* Smallest pitch value allowed */
int end, /* Largest pitch value allowed */
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
const void *par,
int nsf, /* Number of samples in subframe */
int *pitch_val,
......@@ -120,10 +121,11 @@ int plc_tuning
/** Unquantize forced pitch delay and gain */
void forced_pitch_unquant(
spx_sig_t exc[], /* Excitation */
spx_word16_t exc[], /* Input excitation */
spx_word32_t exc_out[], /* Output excitation */
int start, /* Smallest pitch value allowed */
int end, /* Largest pitch value allowed */
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
const void *par,
int nsf, /* Number of samples in subframe */
int *pitch_val,
......
......@@ -196,12 +196,12 @@ void speex_warning_int(const char *str, int val)
#endif
#ifdef FIXED_POINT
spx_word32_t speex_rand(spx_word16_t std, spx_int32_t *seed)
spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
{
spx_word32_t res;
*seed = 1664525 * *seed + 1013904223;
res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std);
return SUB32(res, SHR(res, 3));
return PSHR32(SUB32(res, SHR(res, 3)),14);
}
#else
spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
......@@ -216,19 +216,6 @@ spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
}
#endif
void speex_rand_vec(float std, spx_sig_t *data, int len)
{
int i;
for (i=0;i<len;i++)
data[i]+=SIG_SCALING*3*std*((((float)rand())/RAND_MAX)-.5);
}
/*float speex_rand(float std)
{
return 3*std*((((float)rand())/RAND_MAX)-.5);
}*/
#ifndef OVERRIDE_SPEEX_PUTC
void _speex_putc(int ch, void *file)
{
......
......@@ -113,11 +113,8 @@ void speex_warning(const char *str);
/** Print warning message with integer argument to stderr */
void speex_warning_int(const char *str, int val);
/** Generate a vector of random numbers */
void speex_rand_vec(float std, spx_sig_t *data, int len);
/** Generate a random number */
spx_word32_t speex_rand(spx_word16_t std, spx_int32_t *seed);
spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed);
/** Speex wrapper for putc */
void _speex_putc(int ch, void *file);
......
......@@ -60,7 +60,7 @@ typedef int (*ltp_quant_func)(spx_sig_t *, spx_word16_t *, spx_coef_t *, spx_coe
int, int, SpeexBits*, char *, spx_sig_t *, spx_word16_t *, int, int, int);
/** Long-term un-quantize */
typedef void (*ltp_unquant_func)(spx_sig_t *, int, int, spx_word16_t, const void *, int, int *,
typedef void (*ltp_unquant_func)(spx_word16_t *, spx_word32_t *, int, int, spx_word16_t, const void *, int, int *,
spx_word16_t *, SpeexBits*, char*, int, int, spx_word16_t, int);
......
......@@ -907,14 +907,14 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
/*FIXME: Should use DIV32_16 and make sure result fits in 16 bits */
#ifdef FIXED_POINT
{
spx_word32_t f = DIV32(ener,PSHR32(ol_gain,SIG_SHIFT));
spx_word32_t f = PDIV32(ener,PSHR32(ol_gain,SIG_SHIFT));
if (f<=32767)
fine_gain = f;
else
fine_gain = 32767;
}
#else
fine_gain = DIV32_16(ener,PSHR32(ol_gain,SIG_SHIFT));
fine_gain = PDIV32_16(ener,PSHR32(ol_gain,SIG_SHIFT));
#endif
/* Calculate gain correction for the sub-frame (if any) */
if (SUBMODE(have_subframe_gain))
......@@ -1073,10 +1073,10 @@ void *nb_decoder_init(const SpeexMode *m)
st->lpc_enh_enabled=1;
#ifdef OLD_ENHANCER
st->excBuf = speex_alloc((st->frameSize + st->max_pitch + 1)*sizeof(spx_sig_t));
st->excBuf = speex_alloc((st->frameSize + st->max_pitch + 1)*sizeof(spx_word16_t));
st->exc = st->excBuf + st->max_pitch + 1;
#else
st->excBuf = speex_alloc((st->frameSize + 2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_sig_t));
st->excBuf = speex_alloc((st->frameSize + 2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t));
st->exc = st->excBuf + 2*st->max_pitch + st->subframeSize + 6;
#endif
for (i=0;i<st->frameSize + st->max_pitch + 1;i++)
......@@ -1084,7 +1084,7 @@ void *nb_decoder_init(const SpeexMode *m)
st->interp_qlpc = speex_alloc(st->lpcSize*sizeof(spx_coef_t));
st->old_qlsp = speex_alloc(st->lpcSize*sizeof(spx_lsp_t));
st->mem_sp = speex_alloc((5*st->lpcSize)*sizeof(spx_mem_t));
st->mem_sp = speex_alloc(st->lpcSize*sizeof(spx_mem_t));
#ifdef OLD_ENHANCER
st->comb_mem = speex_alloc(sizeof(CombFilterMem));
comb_filter_mem_init (st->comb_mem);
......@@ -1176,15 +1176,15 @@ static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)
/* Shift all buffers by one frame */
#ifdef OLD_ENHANCER
speex_move(st->excBuf, st->excBuf+st->frameSize, (st->max_pitch + 1)*sizeof(spx_sig_t));
speex_move(st->excBuf, st->excBuf+st->frameSize, (st->max_pitch + 1)*sizeof(spx_word16_t));
#else
speex_move(st->excBuf, st->excBuf+st->frameSize, (2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_sig_t));
speex_move(st->excBuf, st->excBuf+st->frameSize, (2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t));
#endif
for (sub=0;sub<st->nbSubframes;sub++)
{
int offset;
spx_word16_t *sp;
spx_sig_t *exc;
spx_word16_t *exc;
/* Offset relative to start of frame */
offset = st->subframeSize*sub;
/* Original signal */
......@@ -1199,7 +1199,7 @@ static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)
pitch_gain=.95;*/
/* FIXME: This was rms of innovation (not exc) */
innov_gain = compute_rms(st->exc, st->frameSize);
innov_gain = compute_rms16(st->exc, st->frameSize);
pitch_val = st->last_pitch + SHR32((spx_int32_t)speex_rand(1+st->count_lost, &st->seed),SIG_SHIFT);
if (pitch_val > st->max_pitch)
pitch_val = st->max_pitch;
......@@ -1207,15 +1207,16 @@ static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)
pitch_val = st->min_pitch;
for (i=0;i<st->subframeSize;i++)
{
exc[i]= MULT16_32_Q15(pitch_gain, (exc[i-pitch_val]+VERY_SMALL)) +
MULT16_32_Q15(fact, MULT16_32_Q15(SHL(Q15ONE,15)-SHL(MULT16_16(pitch_gain,pitch_gain),1),speex_rand(innov_gain, &st->seed)));
/* FIXME: Second term need to be 16-bit */
exc[i]= MULT16_16_Q15(pitch_gain, (exc[i-pitch_val]+VERY_SMALL)) +
MULT16_16_Q15(fact, MULT16_16_Q15(SHL(Q15ONE,15)-SHL(MULT16_16(pitch_gain,pitch_gain),1),speex_rand(innov_gain, &st->seed)));
}
#ifdef OLD_ENHANCER
for (i=0;i<st->subframeSize;i++)
sp[i]=PSHR32(exc[i],SIG_SHIFT);
sp[i]=exc[i];
#else
for (i=0;i<st->subframeSize;i++)
sp[i]=PSHR32(exc[i-st->subframeSize],SIG_SHIFT);
sp[i]=exc[i-st->subframeSize];
#endif
iir_mem16(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize,
st->mem_sp);
......@@ -1230,6 +1231,7 @@ static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)
st->pitch_gain_buf_idx = 0;
}
int nb_decode(void *state, SpeexBits *bits, void *vout)
{
DecState *st;
......@@ -1245,6 +1247,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
int m;
char *stack;
VARDECL(spx_sig_t *innov);
VARDECL(spx_word32_t *exc32);
VARDECL(spx_coef_t *ak);
VARDECL(spx_lsp_t *qlsp);
spx_word16_t pitch_average=0;
......@@ -1355,9 +1358,9 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
/* Shift all buffers by one frame */
#ifdef OLD_ENHANCER
speex_move(st->excBuf, st->excBuf+st->frameSize, (st->max_pitch + 1)*sizeof(spx_sig_t));
speex_move(st->excBuf, st->excBuf+st->frameSize, (st->max_pitch + 1)*sizeof(spx_word16_t));
#else
speex_move(st->excBuf, st->excBuf+st->frameSize, (2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_sig_t));
speex_move(st->excBuf, st->excBuf+st->frameSize, (2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t));
#endif
/* If null mode (no transmission), just set a couple things to zero*/
......@@ -1372,10 +1375,9 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
if (pgain>.6)
pgain=.6;
/* FIXME: This was innov, not exc */
innov_gain = compute_rms(st->exc, st->frameSize);
innov_gain = compute_rms16(st->exc, st->frameSize);
for (i=0;i<st->frameSize;i++)
st->exc[i]=VERY_SMALL;
speex_rand_vec(innov_gain, st->exc, st->frameSize);
st->exc[i]=speex_rand(innov_gain, &st->seed);
}
......@@ -1407,7 +1409,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
#else
fact = .6*exp(-.2*lsp_dist);
#endif
for (i=0;i<2*st->lpcSize;i++)
for (i=0;i<st->lpcSize;i++)
st->mem_sp[i] = MULT16_32_Q15(fact,st->mem_sp[i]);
}
......@@ -1465,6 +1467,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
ALLOC(ak, st->lpcSize, spx_coef_t);
ALLOC(innov, st->subframeSize, spx_sig_t);
ALLOC(exc32, st->subframeSize, spx_word32_t);
if (st->submodeID==1)
{
......@@ -1483,7 +1486,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
for (sub=0;sub<st->nbSubframes;sub++)
{
int offset;
spx_sig_t *exc;
spx_word16_t *exc;
spx_word16_t *sp;
spx_sig_t *innov_save = NULL;
spx_word16_t tmp;
......@@ -1549,13 +1552,13 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
#ifdef EPIC_48K
if (st->lbr_48k)
{
SUBMODE(ltp_unquant)(exc, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params),
SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params),
st->subframeSize, &pitch, &pitch_gain[0], bits, stack,
st->count_lost, offset, st->last_pitch_gain, ol_pitch_id);
} else {
#endif
SUBMODE(ltp_unquant)(exc, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params),
SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params),
st->subframeSize, &pitch, &pitch_gain[0], bits, stack,
st->count_lost, offset, st->last_pitch_gain, 0);
......@@ -1624,7 +1627,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
while (st->voc_offset<st->subframeSize)
{
if (st->voc_offset>=0)
exc[st->voc_offset]=SIG_SCALING*sqrt(1.0*ol_pitch);
exc[st->voc_offset]=sqrt(1.0*ol_pitch);
st->voc_offset+=ol_pitch;
}
st->voc_offset -= st->subframeSize;
......@@ -1636,8 +1639,9 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
g=1;
for (i=0;i<st->subframeSize;i++)
{
float exci=exc[i];
exc[i]=.8*g*exc[i]*ol_gain/SIG_SCALING + .6*g*st->voc_m1*ol_gain/SIG_SCALING + .5*g*innov[i] - .5*g*st->voc_m2 + (1-g)*innov[i];
spx_word16_t exci=exc[i];
/* FIXME: cleanup the innov[i]/SIG_SCALING */
exc[i]=.8*g*exc[i]*PSHR32(ol_gain,SIG_SHIFT) + .6*g*st->voc_m1*PSHR32(ol_gain,SIG_SHIFT) + (1-.5*g)*PSHR32(innov[i],SIG_SHIFT) - .5*g*PSHR32(st->voc_m2,SIG_SHIFT);
st->voc_m1 = exci;
st->voc_m2=innov[i];
st->voc_mean = .95*st->voc_mean + .05*exc[i];
......@@ -1645,7 +1649,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
}
} else {
for (i=0;i<st->subframeSize;i++)
exc[i]=ADD32(exc[i],innov[i]);
exc[i]=PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT);
/*print_vec(exc, 40, "innov");*/
}
if (innov_save)
......@@ -1664,7 +1668,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, stack);
signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545,15),ener), st->subframeSize);
for (i=0;i<st->subframeSize;i++)
exc[i] = ADD32(exc[i],innov2[i]);
exc[i] = ADD32(exc[i],PSHR32(innov2[i],SIG_SHIFT));
if (innov_save)
{
for (i=0;i<st->subframeSize;i++)
......@@ -1682,7 +1686,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
pitch, pitch_gain, SUBMODE(comb_gain), st->comb_mem);
} else {
for (i=0;i<st->subframeSize;i++)
sp[i]=PSHR32(exc[i],SIG_SHIFT);
sp[i]=exc[i];
}
#endif
......@@ -1693,11 +1697,11 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
#ifndef OLD_ENHANCER
if (st->lpc_enh_enabled && SUBMODE(comb_gain)>0 && !st->count_lost)
{
multicomb(st->exc-st->subframeSize, out, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, st->max_pitch, SUBMODE(comb_gain), stack);
multicomb(st->exc+st->subframeSize, out+2*st->subframeSize, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, st->max_pitch, SUBMODE(comb_gain), stack);
multicomb(st->exc-st->subframeSize, out, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack);
multicomb(st->exc+st->subframeSize, out+2*st->subframeSize, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack);
} else {
for (i=0;i<st->frameSize;i++)
out[i]=PSHR32(st->exc[i-st->subframeSize],SIG_SHIFT);
out[i]=st->exc[i-st->subframeSize];
}
#endif
......@@ -1707,8 +1711,8 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
spx_word16_t exc_ener;
spx_word32_t gain32;
spx_word16_t gain;
exc_ener = compute_rms (st->exc, st->frameSize);
gain32 = DIV32(ol_gain, ADD16(exc_ener,1));
exc_ener = compute_rms16 (st->exc, st->frameSize);
gain32 = PDIV32(ol_gain, ADD16(exc_ener,1));