📄 sb_celp.c
字号:
ALLOC(interp_lpc, st->lpcSize, spx_coef_t); ALLOC(bw_lpc1, st->lpcSize, spx_coef_t); ALLOC(bw_lpc2, st->lpcSize, spx_coef_t); ALLOC(lsp, st->lpcSize, spx_lsp_t); ALLOC(qlsp, st->lpcSize, spx_lsp_t); ALLOC(interp_lsp, st->lpcSize, spx_lsp_t); ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t); { VARDECL(spx_word16_t *autocorr); VARDECL(spx_word16_t *w_sig); ALLOC(autocorr, st->lpcSize+1, spx_word16_t); ALLOC(w_sig, st->windowSize, spx_word16_t); /* Window for analysis */ /* FIXME: This is a kludge */ if (st->subframeSize==80) { for (i=0;i<st->windowSize;i++) w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i>>1]),SIG_SHIFT)); } else { for (i=0;i<st->windowSize;i++) w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i]),SIG_SHIFT)); } /* Compute auto-correlation */ _spx_autocorr(w_sig, autocorr, st->lpcSize+1, st->windowSize); autocorr[0] = ADD16(autocorr[0],MULT16_16_Q15(autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */ /* Lag windowing: equivalent to filtering in the power-spectrum domain */ for (i=0;i<st->lpcSize+1;i++) autocorr[i] = MULT16_16_Q14(autocorr[i],st->lagWindow[i]); /* Levinson-Durbin */ _spx_lpc(lpc, autocorr, st->lpcSize); } /* LPC to LSPs (x-domain) transform */ roots=lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA1, stack); if (roots!=st->lpcSize) { roots = lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA2, stack); if (roots!=st->lpcSize) { /*If we can't find all LSP's, do some damage control and use a flat filter*/ for (i=0;i<st->lpcSize;i++) { lsp[i]=st->old_lsp[i]; } } }#ifndef DISABLE_VBR /* VBR code */ if ((st->vbr_enabled || st->vad_enabled) && !dtx) { float ratio; if (st->abr_enabled) { float qual_change=0; if (st->abr_drift2 * st->abr_drift > 0) { /* Only adapt if long-term and short-term drift are the same sign */ qual_change = -.00001*st->abr_drift/(1+st->abr_count); if (qual_change>.1) qual_change=.1; if (qual_change<-.1) qual_change=-.1; } st->vbr_quality += qual_change; if (st->vbr_quality>10) st->vbr_quality=10; if (st->vbr_quality<0) st->vbr_quality=0; } ratio = 2*log((1.f+e_high)/(1.f+e_low)); speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &st->relative_quality); if (ratio<-4) ratio=-4; if (ratio>2) ratio=2; /*if (ratio>-2)*/ if (st->vbr_enabled) { spx_int32_t modeid; modeid = mode->nb_modes-1; st->relative_quality+=1.0*(ratio+2); if (st->relative_quality<-1) st->relative_quality=-1; while (modeid) { int v1; float thresh; v1=(int)floor(st->vbr_quality); if (v1==10) thresh = mode->vbr_thresh[modeid][v1]; else thresh = (st->vbr_quality-v1) * mode->vbr_thresh[modeid][v1+1] + (1+v1-st->vbr_quality) * mode->vbr_thresh[modeid][v1]; if (st->relative_quality >= thresh && st->sampling_rate*st->submodes[modeid]->bits_per_frame/st->full_frame_size <= st->vbr_max_high) break; modeid--; } speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid); if (st->abr_enabled) { spx_int32_t bitrate; speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate); st->abr_drift+=(bitrate-st->abr_enabled); st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled); st->abr_count += 1.0; } } else { /* VAD only */ int modeid; if (st->relative_quality<2.0) modeid=1; else modeid=st->submodeSelect; /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/ st->submodeID=modeid; } /*fprintf (stderr, "%f %f\n", ratio, low_qual);*/ }#endif /* #ifndef DISABLE_VBR */ if (st->encode_submode) { speex_bits_pack(bits, 1, 1); if (dtx) speex_bits_pack(bits, 0, SB_SUBMODE_BITS); else speex_bits_pack(bits, st->submodeID, SB_SUBMODE_BITS); } /* If null mode (no transmission), just set a couple things to zero*/ if (dtx || st->submodes[st->submodeID] == NULL) { for (i=0;i<st->frame_size;i++) high[i]=VERY_SMALL; for (i=0;i<st->lpcSize;i++) st->mem_sw[i]=0; st->first=1; /* Final signal synthesis from excitation */ iir_mem16(high, st->interp_qlpc, high, st->frame_size, st->lpcSize, st->mem_sp, stack); if (dtx) return 0; else return 1; } /* LSP quantization */ SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits); if (st->first) { for (i=0;i<st->lpcSize;i++) st->old_lsp[i] = lsp[i]; for (i=0;i<st->lpcSize;i++) st->old_qlsp[i] = qlsp[i]; } ALLOC(mem, st->lpcSize, spx_mem_t); ALLOC(syn_resp, st->subframeSize, spx_word16_t); ALLOC(innov, st->subframeSize, spx_sig_t); ALLOC(target, st->subframeSize, spx_word16_t); for (sub=0;sub<st->nbSubframes;sub++) { VARDECL(spx_word16_t *exc); VARDECL(spx_word16_t *res); VARDECL(spx_word16_t *sw); spx_word16_t *sp; spx_word16_t filter_ratio; /*Q7*/ int offset; spx_word32_t rl, rh; /*Q13*/ spx_word16_t eh=0; offset = st->subframeSize*sub; sp=high+offset; ALLOC(exc, st->subframeSize, spx_word16_t); ALLOC(res, st->subframeSize, spx_word16_t); ALLOC(sw, st->subframeSize, spx_word16_t); /* LSP interpolation (quantized and unquantized) */ lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes); lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes); lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN); lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN); lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack); lsp_to_lpc(interp_qlsp, st->interp_qlpc, st->lpcSize, stack); bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize); bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize); /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band filters */ 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=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767));#else filter_ratio=(rl+.01)/(rh+.01);#endif /* Compute "real excitation" */ fir_mem16(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2, stack); /* Compute energy of low-band and high-band excitation */ eh = compute_rms16(exc, st->subframeSize); if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */ spx_word32_t g; /*Q7*/ spx_word16_t el; /*Q0*/ el = low_innov_rms[sub]; /* Gain to use if we want to use the low-band excitation for high-band */ g=PDIV32(MULT16_16(filter_ratio,eh),EXTEND32(ADD16(1,el))); #if 0 { char *tmp_stack=stack; float *tmp_sig; float g2; ALLOC(tmp_sig, st->subframeSize, spx_sig_t); for (i=0;i<st->lpcSize;i++) mem[i]=st->mem_sp[i]; iir_mem2(st->low_innov+offset, st->interp_qlpc, tmp_sig, st->subframeSize, st->lpcSize, mem); g2 = compute_rms(sp, st->subframeSize)/(.01+compute_rms(tmp_sig, st->subframeSize)); /*fprintf (stderr, "gains: %f %f\n", g, g2);*/ g = g2; stack = tmp_stack; }#endif /*print_vec(&g, 1, "gain factor");*/ /* Gain quantization */ { int quant = scal_quant(g, fold_quant_bound, 32); /*speex_warning_int("tata", quant);*/ if (quant<0) quant=0; if (quant>31) quant=31; speex_bits_pack(bits, quant, 5); } if (st->innov_rms_save) { st->innov_rms_save[sub] = eh; } st->exc_rms[sub] = eh; } else { spx_word16_t gc; /*Q7*/ spx_word32_t scale; /*Q14*/ spx_word16_t el; /*Q0*/ el = low_exc_rms[sub]; /*Q0*/ gc = PDIV32_16(MULT16_16(filter_ratio,1+eh),1+el); /* This is a kludge that cleans up a historical bug */ if (st->subframeSize==80) gc = MULT16_16_P15(QCONST16(0.70711f,15),gc); /*printf ("%f %f %f %f\n", el, eh, filter_ratio, gc);*/ { int qgc = scal_quant(gc, gc_quant_bound, 16); speex_bits_pack(bits, qgc, 4); gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]); } if (st->subframeSize==80) gc = MULT16_16_P14(QCONST16(1.4142f,14), gc); scale = SHL32(MULT16_16(PDIV32_16(SHL32(EXTEND32(gc),SIG_SHIFT-6),filter_ratio),(1+el)),6); compute_impulse_response(st->interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack); /* Reset excitation */ for (i=0;i<st->subframeSize;i++) res[i]=VERY_SMALL; /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */ for (i=0;i<st->lpcSize;i++) mem[i]=st->mem_sp[i]; iir_mem16(res, st->interp_qlpc, res, st->subframeSize, st->lpcSize, mem, stack); for (i=0;i<st->lpcSize;i++) mem[i]=st->mem_sw[i]; filter_mem16(res, bw_lpc1, bw_lpc2, res, st->subframeSize, st->lpcSize, mem, stack); /* Compute weighted signal */ for (i=0;i<st->lpcSize;i++) mem[i]=st->mem_sw[i]; filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, mem, stack); /* Compute target signal */ for (i=0;i<st->subframeSize;i++) target[i]=SUB16(sw[i],res[i]); signal_div(target, target, scale, st->subframeSize); /* Reset excitation */ SPEEX_MEMSET(innov, 0, st->subframeSize); /*print_vec(target, st->subframeSize, "\ntarget");*/ SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2, SUBMODE(innovation_params), st->lpcSize, st->subframeSize, innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook)); /*print_vec(target, st->subframeSize, "after");*/ signal_mul(innov, innov, scale, st->subframeSize); if (SUBMODE(double_codebook)) { char *tmp_stack=stack; VARDECL(spx_sig_t *innov2); ALLOC(innov2, st->subframeSize, spx_sig_t); SPEEX_MEMSET(innov2, 0, st->subframeSize); for (i=0;i<st->subframeSize;i++) target[i]=MULT16_16_P13(QCONST16(2.5f,13), target[i]); SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2, SUBMODE(innovation_params), st->lpcSize, st->subframeSize, innov2, syn_resp, bits, stack, st->complexity, 0); signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize); for (i=0;i<st->subframeSize;i++) innov[i] = ADD32(innov[i],innov2[i]); stack = tmp_stack; } for (i=0;i<st->subframeSize;i++) exc[i] = PSHR32(innov[i],SIG_SHIFT); if (st->innov_rms_save) { st->innov_rms_save[sub] = MULT16_16_Q15(QCONST16(.70711f, 15), compute_rms(innov, st->subframeSize)); } st->exc_rms[sub] = compute_rms16(exc, st->subframeSize); } /*Keep the previous memory*/ for (i=0;i<st->lpcSize;i++) mem[i]=st->mem_sp[i]; /* Final signal synthesis from excitation */ iir_mem16(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp, stack); /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */ filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw, stack); } for (i=0;i<st->lpcSize;i++) st->old_lsp[i] = lsp[i]; for (i=0;i<st->lpcSize;i++) st->old_qlsp[i] = qlsp[i]; st->first=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -