📄 nb_celp.c
字号:
} else { st->relative_quality = -1; } if (st->encode_submode) {#ifdef EPIC_48K if (!st->lbr_48k) {#endif /* First, transmit a zero for narrowband */ speex_bits_pack(bits, 0, 1); /* Transmit the sub-mode we use for this frame */ speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS);#ifdef EPIC_48K }#endif } /* If null mode (no transmission), just set a couple things to zero*/ if (st->submodes[st->submodeID] == NULL) { for (i=0;i<st->frameSize;i++) st->exc[i]=st->exc2[i]=st->sw[i]=VERY_SMALL; for (i=0;i<st->lpcSize;i++) st->mem_sw[i]=0; st->first=1; st->bounded_pitch = 1; /* Final signal synthesis from excitation */ iir_mem2(st->exc, st->interp_qlpc, st->frame, st->frameSize, st->lpcSize, st->mem_sp); for (i=0;i<st->frameSize;i++) in[i]=st->frame[i]; return 0; } /* LSP Quantization */ if (st->first) { for (i=0;i<st->lpcSize;i++) st->old_lsp[i] = st->lsp[i]; } /*Quantize LSPs*/#if 1 /*0 for unquantized*/ SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits);#else for (i=0;i<st->lpcSize;i++) st->qlsp[i]=st->lsp[i];#endif#ifdef EPIC_48K if (st->lbr_48k) { speex_bits_pack(bits, pitch_half[0]-st->min_pitch, 7); speex_bits_pack(bits, pitch_half[1]-pitch_half[0]+1, 2); { int quant = (int)floor(.5+7.4*GAIN_SCALING_1*ol_pitch_coef); if (quant>7) quant=7; if (quant<0) quant=0; ol_pitch_id=quant; speex_bits_pack(bits, quant, 3); ol_pitch_coef=GAIN_SCALING*0.13514*quant; } { int qe = (int)(floor(.5+2.1*log(ol_gain*1.0/SIG_SCALING)))-2; if (qe<0) qe=0; if (qe>15) qe=15; ol_gain = exp((qe+2)/2.1)*SIG_SCALING; speex_bits_pack(bits, qe, 4); } } else {#endif /*If we use low bit-rate pitch mode, transmit open-loop pitch*/ if (SUBMODE(lbr_pitch)!=-1) { speex_bits_pack(bits, ol_pitch-st->min_pitch, 7); } if (SUBMODE(forced_pitch_gain)) { int quant; quant = (int)floor(.5+15*ol_pitch_coef*GAIN_SCALING_1); if (quant>15) quant=15; if (quant<0) quant=0; speex_bits_pack(bits, quant, 4); ol_pitch_coef=GAIN_SCALING*0.066667*quant; } /*Quantize and transmit open-loop excitation gain*/#ifdef FIXED_POINT { int qe = scal_quant32(ol_gain, ol_gain_table, 32); /*ol_gain = exp(qe/3.5)*SIG_SCALING;*/ ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]); speex_bits_pack(bits, qe, 5); }#else { int qe = (int)(floor(.5+3.5*log(ol_gain*1.0/SIG_SCALING))); if (qe<0) qe=0; if (qe>31) qe=31; ol_gain = exp(qe/3.5)*SIG_SCALING; speex_bits_pack(bits, qe, 5); }#endif#ifdef EPIC_48K }#endif /* Special case for first frame */ if (st->first) { for (i=0;i<st->lpcSize;i++) st->old_qlsp[i] = st->qlsp[i]; } /* Filter response */ res = PUSH(stack, st->subframeSize, spx_sig_t); /* Target signal */ target = PUSH(stack, st->subframeSize, spx_sig_t); syn_resp = PUSH(stack, st->subframeSize, spx_sig_t); mem = PUSH(stack, st->lpcSize, spx_mem_t); orig = PUSH(stack, st->frameSize, spx_sig_t); for (i=0;i<st->frameSize;i++) orig[i]=st->frame[i]; /* Loop on sub-frames */ for (sub=0;sub<st->nbSubframes;sub++) { int offset; spx_sig_t *sp, *sw, *exc, *exc2; int pitch;#ifdef EPIC_48K if (st->lbr_48k) { if (sub*2 < st->nbSubframes) ol_pitch = pitch_half[0]; else ol_pitch = pitch_half[1]; }#endif /* Offset relative to start of frame */ offset = st->subframeSize*sub; /* Original signal */ sp=st->frame+offset; /* Excitation */ exc=st->exc+offset; /* Weighted signal */ sw=st->sw+offset; exc2=st->exc2+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); /* Make sure the filters are stable */ lsp_enforce_margin(st->interp_lsp, st->lpcSize, LSP_MARGIN); lsp_enforce_margin(st->interp_qlsp, st->lpcSize, LSP_MARGIN); /* Compute interpolated LPCs (quantized and unquantized) */ lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack); lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); /* Compute analysis filter gain at w=pi (for use in SB-CELP) */ { spx_word32_t pi_g=st->interp_qlpc[0]; for (i=1;i<=st->lpcSize;i+=2) { pi_g += -st->interp_qlpc[i] + st->interp_qlpc[i+1]; } st->pi_gain[sub] = pi_g; } /* Compute bandwidth-expanded (unquantized) LPCs for perceptual weighting */ bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); if (st->gamma2>=0) bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize); else { st->bw_lpc2[0]=1; for (i=1;i<=st->lpcSize;i++) st->bw_lpc2[i]=0; } /* Compute impulse response of A(z/g1) / ( A(z)*A(z/g2) )*/ for (i=0;i<st->subframeSize;i++) exc[i]=VERY_SMALL; exc[0]=SIG_SCALING; syn_percep_zero(exc, 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; for (i=0;i<st->subframeSize;i++) exc2[i]=VERY_SMALL; /* Compute zero response of A(z/g1) / ( A(z/g2) * A(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]=exc2[i]=0; /* If we have a long-term predictor (otherwise, something's wrong) */ if (SUBMODE(ltp_quant)) { int pit_min, pit_max; /* Long-term prediction */ if (SUBMODE(lbr_pitch) != -1) { /* Low bit-rate pitch handling */ int margin; margin = SUBMODE(lbr_pitch); if (margin) { if (ol_pitch < st->min_pitch+margin-1) ol_pitch=st->min_pitch+margin-1; if (ol_pitch > st->max_pitch-margin) ol_pitch=st->max_pitch-margin; pit_min = ol_pitch-margin+1; pit_max = ol_pitch+margin; } else { pit_min=pit_max=ol_pitch; } } else { pit_min = st->min_pitch; pit_max = st->max_pitch; } /* Force pitch to use only the current frame if needed */ if (st->bounded_pitch && pit_max>offset) pit_max=offset;#ifdef EPIC_48K if (st->lbr_48k) { pitch = SUBMODE(ltp_quant)(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, exc, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef, st->lpcSize, st->subframeSize, bits, stack, exc2, syn_resp, st->complexity, ol_pitch_id); } else {#endif /* Perform pitch search */ pitch = SUBMODE(ltp_quant)(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, exc, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef, st->lpcSize, st->subframeSize, bits, stack, exc2, syn_resp, st->complexity, 0);#ifdef EPIC_48K }#endif st->pitch[sub]=pitch; } else { speex_error ("No pitch prediction, what's wrong"); } /* Update target for adaptive codebook contribution */ syn_percep_zero(exc, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, stack); for (i=0;i<st->subframeSize;i++) target[i]=SATURATE(SUB32(target[i],res[i]),805306368); /* Quantization of innovation */ { spx_sig_t *innov; spx_word32_t ener=0; spx_word16_t fine_gain; innov = st->innov+sub*st->subframeSize; for (i=0;i<st->subframeSize;i++) innov[i]=0; residue_percep_zero(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, st->buf2, st->subframeSize, st->lpcSize, stack); ener = SHL(compute_rms(st->buf2, st->subframeSize),SIG_SHIFT); /*for (i=0;i<st->subframeSize;i++) printf ("%f\n", st->buf2[i]/ener); */ /*FIXME: Should use DIV32_16 and make sure result fits in 16 bits */#ifdef FIXED_POINT { spx_word32_t f = DIV32(ener,PSHR(ol_gain,SIG_SHIFT)); if (f<32768) fine_gain = f; else fine_gain = 32767; }#else fine_gain = DIV32_16(ener,PSHR(ol_gain,SIG_SHIFT));#endif /* Calculate gain correction for the sub-frame (if any) */ if (SUBMODE(have_subframe_gain)) { int qe; if (SUBMODE(have_subframe_gain)==3) { qe = scal_quant(fine_gain, exc_gain_quant_scal3_bound, 8); speex_bits_pack(bits, qe, 3); ener=MULT16_32_Q14(exc_gain_quant_scal3[qe],ol_gain); } else { qe = scal_quant(fine_gain, exc_gain_quant_scal1_bound, 2); speex_bits_pack(bits, qe, 1); ener=MULT16_32_Q14(exc_gain_quant_scal1[qe],ol_gain); } } else { ener=ol_gain; } /*printf ("%f %f\n", ener, ol_gain);*/ /* Normalize innovation */ signal_div(target, target, ener, st->subframeSize); /* Quantize innovation */ if (SUBMODE(innovation_quant)) { /* Codebook search */ 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); /* De-normalize innovation and update excitation */ signal_mul(innov, innov, ener, st->subframeSize); for (i=0;i<st->subframeSize;i++) exc[i] += innov[i]; } else { speex_error("No fixed codebook"); } /* In some (rare) modes, we do a second search (more bits) to reduce noise even more */ if (SUBMODE(double_codebook)) { char *tmp_stack=stack; spx_sig_t *innov2 = PUSH(tmp_stack, 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.2; SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, SUBMODE(innovation_params), st->lpcSize, st->subframeSize, innov2, syn_resp, bits, tmp_stack, st->complexity); signal_mul(innov2, innov2, ener*(1/2.2), st->subframeSize); for (i=0;i<st->subframeSize;i++) exc[i] += innov2[i]; } signal_mul(target, target, ener, 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_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); for (i=0;i<st->subframeSize;i++) exc2[i]=exc[i]; } /* Store the LSPs for interpolation in the next frame */ if (st->submodeID>=1) { 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]; } if (st->submodeID==1) { if (st->dtx_count) speex_bits_pack(bits, 15, 4); else speex_bits_pack(bits, 0, 4); } /* The next frame will not be the first (Duh!) */ st->first = 0; if (0) { float ener=0, err=0; float snr; for (i=0;i<st->frameSize;i++) { ener+=st->frame[i]*st->frame[i]; err += (st->frame[i]-orig[i])*(st->frame[i]-orig[i]); } snr = 10*log10((ener+1)/(err+1)); /*printf ("%f %f %f\n", snr, ener, err);*/ } /* Replace input by synthesized speech */ for (i=0;i<st->frameSize;i++) { spx_word32_t sig = PSHR(st->frame[i],SIG_SHIFT); if (sig>32767) sig = 32767; if (sig<-32767) sig = -32767; in[i]=sig; } if (SUBMODE(innovation_quant) == noise_codebook_quant || st->submodeID==0) st->bounded_pitch = 1; else st->bounded_pitch = 0; return 1;}void *nb_decoder_init(const SpeexMode *m){ DecState *st; const SpeexNBMode *mode; int i; mode=(SpeexNBMode*)m->mode; st = (DecState *)speex_alloc(sizeof(DecState)+4000*sizeof(spx_sig_t)); st->mode=m; st->stack = ((char*)st) + sizeof(DecState); st->encode_submode = 1;#ifdef EPIC_48K st->lbr_48k=mode->lbr48k;#endif st->first=1; /* Codec parameters, should eventually have several "modes"*/ st->frameSize = mode->frameSize; st->windowSize = st->frameSize*3/2; st->nbSubframes=mode->frameSize/mode->subframeSize; st->subframeSize=mode->subframeSize; st->lpcSize = mode->lpcSize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -