📄 sb_celp.c
字号:
mode = (const SpeexSBMode*)(st->mode->mode); { VARDECL(spx_word16_t *low); ALLOC(low, st->frame_size, spx_word16_t); /* Compute the two sub-bands by filtering with h0 and h1*/ qmf_decomp(in, h0, st->x0d, st->x1d, st->full_frame_size, QMF_ORDER, st->h0_mem, stack); for (i=0;i<st->frame_size;i++) low[i] = SATURATE(PSHR(st->x0d[i],SIG_SHIFT),32767); /* Encode the narrowband part*/ speex_encode_native(st->st_low, low, bits); for (i=0;i<st->frame_size;i++) st->x0d[i] = SHL(low[i],SIG_SHIFT); } /* High-band buffering / sync with low band */ for (i=0;i<st->windowSize-st->frame_size;i++) st->high[i] = st->high[st->frame_size+i]; for (i=0;i<st->frame_size;i++) st->high[st->windowSize-st->frame_size+i]=SATURATE(st->x1d[i],536854528); speex_move(st->excBuf, st->excBuf+st->frame_size, (st->bufSize-st->frame_size)*sizeof(spx_sig_t)); 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_encoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain); speex_encoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc); speex_encoder_ctl(st->st_low, SPEEX_GET_INNOV, low_innov); speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, &dtx); if (dtx==0) dtx=1; else dtx=0; { VARDECL(spx_word16_t *w_sig); ALLOC(w_sig, st->windowSize, spx_word16_t); /* Window for analysis */ for (i=0;i<st->windowSize;i++) w_sig[i] = SHR(MULT16_16(SHR((spx_word32_t)(st->high[i]),SIG_SHIFT),st->window[i]),SIG_SHIFT); /* Compute auto-correlation */ _spx_autocorr(w_sig, st->autocorr, st->lpcSize+1, st->windowSize); } st->autocorr[0] = (spx_word16_t)(st->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++) st->autocorr[i] = MULT16_16_Q14(st->autocorr[i],st->lagWindow[i]); /* Levinson-Durbin */ _spx_lpc(st->lpc, st->autocorr, st->lpcSize); /* LPC to LSPs (x-domain) transform */ roots=lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 15, LSP_DELTA1, stack); if (roots!=st->lpcSize) { roots = lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 11, 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++) { st->lsp[i]=M_PI*((float)(i+1))/(st->lpcSize+1); } } } /* VBR code */ if ((st->vbr_enabled || st->vad_enabled) && !dtx) { float e_low=0, e_high=0; 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; } /*FIXME: Are the two signals (low, high) in sync? */ e_low = compute_rms(st->x0d, st->frame_size); e_high = compute_rms(st->high, st->frame_size); ratio = 2*log((1+e_high)/(1+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) { int 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) break; modeid--; } speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid); if (st->abr_enabled) { int 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);*/ } 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++) st->exc[i]=st->sw[i]=VERY_SMALL; for (i=0;i<st->lpcSize;i++) st->mem_sw[i]=0; 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);#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 if (dtx) return 0; else return 1; } /* LSP quantization */ SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits); if (st->first) { 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]; } ALLOC(mem, st->lpcSize, spx_mem_t); ALLOC(syn_resp, st->subframeSize, spx_word16_t); ALLOC(innov, st->subframeSize, spx_sig_t); for (sub=0;sub<st->nbSubframes;sub++) { spx_sig_t *exc, *sp, *res, *target, *sw; spx_word16_t filter_ratio; int offset; spx_word32_t rl, rh; spx_word16_t eh=0; offset = st->subframeSize*sub; sp=st->high+offset; exc=st->exc+offset; res=st->res+offset; target=st->target+offset; sw=st->sw+offset; /* LSP interpolation (quantized and unquantized) */ lsp_interpolate(st->old_lsp, st->lsp, st->interp_lsp, st->lpcSize, sub, st->nbSubframes); lsp_interpolate(st->old_qlsp, st->qlsp, st->interp_qlsp, st->lpcSize, sub, st->nbSubframes); lsp_enforce_margin(st->interp_lsp, st->lpcSize, LSP_MARGIN); lsp_enforce_margin(st->interp_qlsp, st->lpcSize, LSP_MARGIN); lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack); lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); bw_lpc(st->gamma2, st->interp_lpc, st->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=DIV32_16(SHL(rl+82,2),SHR(82+rh,5));#else filter_ratio=(rl+.01)/(rh+.01);#endif /* Compute "real excitation" */ fir_mem2(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2); /* Compute energy of low-band and high-band excitation */ eh = compute_rms(exc, st->subframeSize); if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */ float g; spx_word16_t el; el = compute_rms(low_innov+offset, st->subframeSize); /* Gain to use if we want to use the low-band excitation for high-band */ g=eh/(.01+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(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#ifdef FIXED_POINT g *= filter_ratio/128.;#else g *= filter_ratio;#endif /*print_vec(&g, 1, "gain factor");*/ /* Gain quantization */ { int quant = (int) floor(.5 + 10 + 8.0 * log((g+.0001))); /*speex_warning_int("tata", quant);*/ if (quant<0) quant=0; if (quant>31) quant=31; speex_bits_pack(bits, quant, 5); } } else { spx_word16_t gc; spx_word32_t scale; spx_word16_t el; el = compute_rms(low_exc+offset, st->subframeSize); gc = DIV32_16(MULT16_16(filter_ratio,1+eh),1+el); /* This is a kludge that cleans up a historical bug */ if (st->subframeSize==80) gc *= 0.70711; /*printf ("%f %f %f %f\n", el, eh, filter_ratio, gc);*/#ifdef FIXED_POINT { int qgc = scal_quant(gc, gc_quant_bound, 16); speex_bits_pack(bits, qgc, 4); gc = MULT16_32_Q15(28626,gc_quant_bound[qgc]); }#else { int qgc = (int)floor(.5+3.7*(log(gc)+0.15556)); if (qgc<0) qgc=0; if (qgc>15) qgc=15; speex_bits_pack(bits, qgc, 4); gc = exp((1/3.7)*qgc-0.15556); } #endif if (st->subframeSize==80) gc *= 1.4142; scale = SHL(MULT16_16(DIV32_16(SHL(gc,SIG_SHIFT-4),filter_ratio),(1+el)),4); compute_impulse_response(st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack); /* Reset excitation */ for (i=0;i<st->subframeSize;i++) exc[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_mem2(exc, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, mem); for (i=0;i<st->lpcSize;i++) mem[i]=st->mem_sw[i]; filter_mem2(exc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, mem); /* Compute weighted signal */ for (i=0;i<st->lpcSize;i++) mem[i]=st->mem_sw[i]; filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, mem); /* Compute target signal */ for (i=0;i<st->subframeSize;i++) target[i]=sw[i]-res[i]; for (i=0;i<st->subframeSize;i++) exc[i]=0; signal_div(target, target, scale, st->subframeSize); /* Reset excitation */ for (i=0;i<st->subframeSize;i++) innov[i]=0; /*print_vec(target, st->subframeSize, "\ntarget");*/ SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, SUBMODE(innovation_params), st->lpcSize, st->subframeSize, innov, syn_resp, bits, stack, (st->complexity+1)>>1, SUBMODE(double_codebook)); /*print_vec(target, st->subframeSize, "after");*/ signal_mul(innov, innov, scale, st->subframeSize); for (i=0;i<st->subframeSize;i++) exc[i] = ADD32(exc[i], innov[i]); if (SUBMODE(double_codebook)) { char *tmp_stack=stack; VARDECL(spx_sig_t *innov2); ALLOC(innov2, st->subframeSize, spx_sig_t); for (i=0;i<st->subframeSize;i++) innov2[i]=0; for (i=0;i<st->subframeSize;i++) target[i]*=2.5; SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, SUBMODE(innovation_params), st->lpcSize, st->subframeSize, innov2, syn_resp, bits, stack, (st->complexity+1)>>1, 0); for (i=0;i<st->subframeSize;i++) innov2[i]*=scale*(1/2.5)/SIG_SCALING; for (i=0;i<st->subframeSize;i++) exc[i] = ADD32(exc[i],innov2[i]); stack = tmp_stack; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -