📄 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 + -