📄 sb_celp.c
字号:
/*Keep the previous memory*/
for (i=0;i<st->lpcSize;i++)
mem[i]=st->mem_sp[i];
/* Final signal synthesis from excitation */
iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);
/* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */
filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw);
}
#ifdef RESYNTH
/* Reconstruct the original */
fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
for (i=0;i<st->full_frame_size;i++)
in[i]=SHR(st->y0[i]-st->y1[i], SIG_SHIFT-1);
#endif
for (i=0;i<st->lpcSize;i++)
st->old_lsp[i] = st->lsp[i];
for (i=0;i<st->lpcSize;i++)
st->old_qlsp[i] = st->qlsp[i];
st->first=0;
return 1;
}
void *sb_decoder_init(const SpeexMode *m)
{
SBDecState *st;
const SpeexSBMode *mode;
st = (SBDecState*)speex_alloc(sizeof(SBDecState));
if (!st)
return NULL;
#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
st->stack = NULL;
#else
st->stack = (char*)speex_alloc_scratch(SB_DEC_STACK);
#endif
st->mode = m;
mode=(const SpeexSBMode*)m->mode;
st->encode_submode = 1;
st->st_low = speex_decoder_init(mode->nb_mode);
st->full_frame_size = 2*mode->frameSize;
st->frame_size = mode->frameSize;
st->subframeSize = mode->subframeSize;
st->nbSubframes = mode->frameSize/mode->subframeSize;
st->lpcSize=mode->lpcSize;
speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
st->sampling_rate*=2;
st->submodes=mode->submodes;
st->submodeID=mode->defaultSubmode;
st->first=1;
st->x0d=speex_alloc((st->frame_size)*sizeof(spx_sig_t));
st->x1d=speex_alloc((st->frame_size)*sizeof(spx_sig_t));
st->high=speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
st->y0=speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
st->y1=speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
st->g0_mem=speex_alloc((QMF_ORDER)*sizeof(spx_word32_t));
st->g1_mem=speex_alloc((QMF_ORDER)*sizeof(spx_word32_t));
st->exc=speex_alloc((st->frame_size)*sizeof(spx_sig_t));
st->qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
st->old_qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
st->interp_qlsp = speex_alloc(st->lpcSize*sizeof(spx_lsp_t));
st->interp_qlpc = speex_alloc(st->lpcSize*sizeof(spx_coef_t));
st->pi_gain = speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
st->mem_sp = speex_alloc((2*st->lpcSize)*sizeof(spx_mem_t));
st->lpc_enh_enabled=0;
#ifdef ENABLE_VALGRIND
VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
#endif
return st;
}
void sb_decoder_destroy(void *state)
{
SBDecState *st;
st = (SBDecState*)state;
speex_decoder_destroy(st->st_low);
#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
speex_free_scratch(st->stack);
#endif
speex_free(st->x0d);
speex_free(st->x1d);
speex_free(st->high);
speex_free(st->y0);
speex_free(st->y1);
speex_free(st->g0_mem);
speex_free(st->g1_mem);
speex_free(st->exc);
speex_free(st->qlsp);
speex_free(st->old_qlsp);
speex_free(st->interp_qlsp);
speex_free(st->interp_qlpc);
speex_free(st->pi_gain);
speex_free(st->mem_sp);
speex_free(state);
}
static void sb_decode_lost(SBDecState *st, spx_word16_t *out, int dtx, char *stack)
{
int i;
VARDECL(spx_coef_t *awk1);
VARDECL(spx_coef_t *awk2);
VARDECL(spx_coef_t *awk3);
int saved_modeid=0;
if (dtx)
{
saved_modeid=st->submodeID;
st->submodeID=1;
} else {
bw_lpc(GAMMA_SCALING*0.99, st->interp_qlpc, st->interp_qlpc, st->lpcSize);
}
st->first=1;
ALLOC(awk1, st->lpcSize+1, spx_coef_t);
ALLOC(awk2, st->lpcSize+1, spx_coef_t);
ALLOC(awk3, st->lpcSize+1, spx_coef_t);
if (st->lpc_enh_enabled)
{
spx_word16_t k1,k2,k3;
if (st->submodes[st->submodeID] != NULL)
{
k1=SUBMODE(lpc_enh_k1);
k2=SUBMODE(lpc_enh_k2);
k3=SUBMODE(lpc_enh_k3);
} else {
k1=k2=.7*GAMMA_SCALING;
k3 = 0;
}
bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize);
bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize);
bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize);
/*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/
}
/* Final signal synthesis from excitation */
if (!dtx)
{
for (i=0;i<st->frame_size;i++)
st->exc[i] *= .9;
}
for (i=0;i<st->frame_size;i++)
st->high[i]=st->exc[i];
if (st->lpc_enh_enabled)
{
/* Use enhanced LPC filter */
filter_mem2(st->high, awk2, awk1, st->high, st->frame_size, st->lpcSize,
st->mem_sp+st->lpcSize);
filter_mem2(st->high, awk3, st->interp_qlpc, st->high, st->frame_size, st->lpcSize,
st->mem_sp);
} else {
/* Use regular filter */
for (i=0;i<st->lpcSize;i++)
st->mem_sp[st->lpcSize+i] = 0;
iir_mem2(st->high, st->interp_qlpc, st->high, st->frame_size, st->lpcSize,
st->mem_sp);
}
/*iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp);*/
/* Reconstruct the original */
fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
mix_and_saturate(st->y0, st->y1, out, st->full_frame_size);
if (dtx)
{
st->submodeID=saved_modeid;
}
return;
}
int sb_decode(void *state, SpeexBits *bits, void *vout)
{
int i, sub;
SBDecState *st;
int wideband;
int ret;
char *stack;
VARDECL(spx_word32_t *low_pi_gain);
VARDECL(spx_sig_t *low_exc);
VARDECL(spx_sig_t *low_innov);
VARDECL(spx_coef_t *awk1);
VARDECL(spx_coef_t *awk2);
VARDECL(spx_coef_t *awk3);
int dtx;
const SpeexSBMode *mode;
spx_word16_t *out = vout;
st = (SBDecState*)state;
stack=st->stack;
mode = (const SpeexSBMode*)(st->mode->mode);
{
VARDECL(spx_word16_t *low);
ALLOC(low, st->frame_size, spx_word16_t);
/* Decode the low-band */
ret = speex_decode_native(st->st_low, bits, low);
for (i=0;i<st->frame_size;i++)
st->x0d[i] = SHL((spx_sig_t)low[i], SIG_SHIFT);
}
speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, &dtx);
/* If error decoding the narrowband part, propagate error */
if (ret!=0)
{
return ret;
}
if (!bits)
{
sb_decode_lost(st, out, dtx, stack);
return 0;
}
if (st->encode_submode)
{
/*Check "wideband bit"*/
if (speex_bits_remaining(bits)>0)
wideband = speex_bits_peek(bits);
else
wideband = 0;
if (wideband)
{
/*Regular wideband frame, read the submode*/
wideband = speex_bits_unpack_unsigned(bits, 1);
st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
} else
{
/*Was a narrowband frame, set "null submode"*/
st->submodeID = 0;
}
if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL)
{
speex_warning("Invalid mode encountered: corrupted stream?");
return -2;
}
}
/* If null mode (no transmission), just set a couple things to zero*/
if (st->submodes[st->submodeID] == NULL)
{
if (dtx)
{
sb_decode_lost(st, out, 1, stack);
return 0;
}
for (i=0;i<st->frame_size;i++)
st->exc[i]=VERY_SMALL;
st->first=1;
/* Final signal synthesis from excitation */
iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp);
fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
mix_and_saturate(st->y0, st->y1, out, st->full_frame_size);
return 0;
}
for (i=0;i<st->frame_size;i++)
st->exc[i]=0;
ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t);
ALLOC(low_exc, st->frame_size, spx_sig_t);
ALLOC(low_innov, st->frame_size, spx_sig_t);
speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);
speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc);
speex_decoder_ctl(st->st_low, SPEEX_GET_INNOV, low_innov);
SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits);
if (st->first)
{
for (i=0;i<st->lpcSize;i++)
st->old_qlsp[i] = st->qlsp[i];
}
ALLOC(awk1, st->lpcSize+1, spx_coef_t);
ALLOC(awk2, st->lpcSize+1, spx_coef_t);
ALLOC(awk3, st->lpcSize+1, spx_coef_t);
for (sub=0;sub<st->nbSubframes;sub++)
{
spx_sig_t *exc, *sp;
spx_word16_t filter_ratio;
spx_word16_t el=0;
int offset;
spx_word32_t rl=0,rh=0;
offset = st->subframeSize*sub;
sp=st->high+offset;
exc=st->exc+offset;
/* LSP interpolation */
lsp_interpolate(st->old_qlsp, st->qlsp, st->interp_qlsp, st->lpcSize, sub, st->nbSubframes);
lsp_enforce_margin(st->interp_qlsp, st->lpcSize, LSP_MARGIN);
/* LSP to LPC */
lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack);
if (st->lpc_enh_enabled)
{
spx_word16_t k1,k2,k3;
k1=SUBMODE(lpc_enh_k1);
k2=SUBMODE(lpc_enh_k2);
k3=SUBMODE(lpc_enh_k3);
bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize);
bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize);
bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize);
/*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/
}
/* Calculate reponse ratio between the low and high filter in the middle
of the band (4000 Hz) */
st->pi_gain[sub]=LPC_SCALING;
rh = LPC_SCALING;
for (i=0;i<st->lpcSize;i+=2)
{
rh += st->interp_qlpc[i+1] - st->interp_qlpc[i];
st->pi_gain[sub] += st->interp_qlpc[i] + st->interp_qlpc[i+1];
}
rl = low_pi_gain[sub];
#ifdef FIXED_POINT
filter_ratio=DIV32_16(SHL(rl+82,2),SHR(82+rh,5));
#else
filter_ratio=(rl+.01)/(rh+.01);
#endif
for (i=0;i<st->subframeSize;i++)
exc[i]=0;
if (!SUBMODE(innovation_unquant))
{
float g;
int quant;
quant = speex_bits_unpack_unsigned(bits, 5);
g= exp(((float)quant-10)/8.0);
#ifdef FIXED_POINT
g /= filter_ratio/128.;
#else
g /= filter_ratio;
#endif
/* High-band excitation using the low-band excitation and a gain */
for (i=0;i<st->subframeSize;i++)
exc[i]=mode->folding_gain*g*low_innov[offset+i];
/*speex_rand_vec(mode->folding_gain*g*sqrt(el/st->subframeSize), exc, st->subframeSize);*/
} else {
spx_word16_t gc;
spx_word32_t scale;
int qgc = speex_bits_unpack_unsigned(bits, 4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -