📄 nb_celp.c
字号:
} } 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, exc, syn_resp, st->complexity, ol_pitch_id, st->plc_tuning); } 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, exc, syn_resp, st->complexity, 0, st->plc_tuning);#ifdef EPIC_48K }#endif st->pitch[sub]=pitch; } else { speex_error ("No pitch prediction, what's wrong"); } /* 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; for (i=0;i<st->subframeSize;i++) real_exc[i] = SUB32(real_exc[i], exc[i]); ener = SHL32(EXTEND32(compute_rms(real_exc, st->subframeSize)),SIG_SHIFT); /*FIXME: Should use DIV32_16 and make sure result fits in 16 bits */#ifdef FIXED_POINT { spx_word32_t f = DIV32(ener,PSHR32(ol_gain,SIG_SHIFT)); if (f<=32767) fine_gain = f; else fine_gain = 32767; }#else fine_gain = DIV32_16(ener,PSHR32(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, SUBMODE(double_codebook)); /* De-normalize innovation and update excitation */ signal_mul(innov, innov, ener, st->subframeSize); for (i=0;i<st->subframeSize;i++) exc[i] = ADD32(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; 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.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, stack, st->complexity, 0); signal_mul(innov2, innov2, (spx_word32_t) (ener*(1.f/2.2f)), st->subframeSize); for (i=0;i<st->subframeSize;i++) exc[i] = ADD32(exc[i],innov2[i]); stack = tmp_stack; } } /* 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) */ if (st->complexity!=0) filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw); } /* 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]; }#ifdef VORBIS_PSYCHO if (st->submodeID>=1) { for (i=0;i<128;i++) st->old_curve[i] = st->curve[i]; }#endif 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;#ifdef RESYNTH /* Replace input by synthesized speech */ for (i=0;i<st->frameSize;i++) { spx_word32_t sig = PSHR32(st->frame[i],SIG_SHIFT); if (sig>32767) sig = 32767; if (sig<-32767) sig = -32767; in[i]=sig; }#endif 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=(const SpeexNBMode*)m->mode; st = (DecState *)speex_alloc(sizeof(DecState)); if (!st) return NULL;#if defined(VAR_ARRAYS) || defined (USE_ALLOCA) st->stack = NULL;#else st->stack = (char*)speex_alloc_scratch(NB_DEC_STACK);#endif st->mode=m; 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->nbSubframes=mode->frameSize/mode->subframeSize; st->subframeSize=mode->subframeSize; st->lpcSize = mode->lpcSize; st->min_pitch=mode->pitchStart; st->max_pitch=mode->pitchEnd; st->submodes=mode->submodes; st->submodeID=mode->defaultSubmode; st->lpc_enh_enabled=0; st->inBuf = speex_alloc((st->frameSize)*sizeof(spx_sig_t)); st->frame = st->inBuf; st->excBuf = speex_alloc((st->frameSize + st->max_pitch + 1)*sizeof(spx_sig_t)); st->exc = st->excBuf + st->max_pitch + 1; for (i=0;i<st->frameSize;i++) st->inBuf[i]=0; for (i=0;i<st->frameSize + st->max_pitch + 1;i++) st->excBuf[i]=0; st->innov = speex_alloc((st->frameSize)*sizeof(spx_sig_t)); st->interp_qlpc = speex_alloc(st->lpcSize*sizeof(spx_coef_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->mem_sp = speex_alloc((5*st->lpcSize)*sizeof(spx_mem_t)); st->comb_mem = speex_alloc(sizeof(CombFilterMem)); comb_filter_mem_init (st->comb_mem); st->pi_gain = speex_alloc((st->nbSubframes)*sizeof(spx_word32_t)); st->last_pitch = 40; st->count_lost=0; st->pitch_gain_buf[0] = st->pitch_gain_buf[1] = st->pitch_gain_buf[2] = 0; st->pitch_gain_buf_idx = 0; st->seed = 1000; st->sampling_rate=8000; st->last_ol_gain = 0; st->user_callback.func = &speex_default_user_handler; st->user_callback.data = NULL; for (i=0;i<16;i++) st->speex_callbacks[i].func = NULL; st->voc_m1=st->voc_m2=st->voc_mean=0; st->voc_offset=0; st->dtx_enabled=0;#ifdef ENABLE_VALGRIND VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));#endif return st;}void nb_decoder_destroy(void *state){ DecState *st; st=(DecState*)state; #if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA)) speex_free_scratch(st->stack);#endif speex_free (st->inBuf); speex_free (st->excBuf); speex_free (st->innov); speex_free (st->interp_qlpc); speex_free (st->qlsp); speex_free (st->old_qlsp); speex_free (st->interp_qlsp); speex_free (st->mem_sp); speex_free (st->comb_mem); speex_free (st->pi_gain); speex_free(state);}#define median3(a, b, c) ((a) < (b) ? ((b) < (c) ? (b) : ((a) < (c) ? (c) : (a))) : ((c) < (b) ? (b) : ((c) < (a) ? (c) : (a))))#ifdef FIXED_POINTconst spx_word16_t attenuation[10] = {32767, 31483, 27923, 22861, 17278, 12055, 7764, 4616, 2533, 1283};#elseconst spx_word16_t attenuation[10] = {1., 0.961, 0.852, 0.698, 0.527, 0.368, 0.237, 0.141, 0.077, 0.039};#endifstatic void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack){ int i, sub; int pitch_val; VARDECL(spx_coef_t *awk1); VARDECL(spx_coef_t *awk2); VARDECL(spx_coef_t *awk3); spx_word16_t pitch_gain; spx_word16_t fact; spx_word16_t gain_med; spx_word16_t innov_gain; if (st->count_lost<10) fact = attenuation[st->count_lost]; else fact = 0; gain_med = median3(st->pitch_gain_buf[0], st->pitch_gain_buf[1], st->pitch_gain_buf[2]); if (gain_med < st->last_pitch_gain) st->last_pitch_gain = gain_med; #ifdef FIXED_POINT pitch_gain = st->last_pitch_gain; if (pitch_gain>54) pitch_gain = 54; pitch_gain = SHL(pitch_gain, 9);#else pitch_gain = GAIN_SCALING_1*st->last_pitch_gain; if (pitch_gain>.85) pitch_gain=.85;#endif pitch_gain = MULT16_16_Q15(fact,pitch_gain) + VERY_SMALL; /* Shift all buffers by one frame */ /*speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(spx_sig_t));*/ speex_move(st->excBuf, st->excBuf+st->frameSize, (st->max_pitch + 1)*sizeof(spx_sig_t)); 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++) { int offset; spx_sig_t *sp, *exc; /* Offset relative to start of frame */ offset = st->subframeSize*sub; /* Original signal */ sp=st->frame+offset; /* Excitation */ exc=st->exc+offset; /* Excitation after post-filter*/ /* Calculate perceptually enhanced LPC filter */ 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); } /* Make up a plausible excitation */ /* FIXME: THIS CAN BE IMPROVED */ /*if (pitch_gain>.95) pitch_gain=.95;*/ innov_gain = compute_rms(st->innov, st->frameSize); pitch_val = st->last_pitch + SHR32((spx_int32_t)speex_rand(1+st->count_lost, &st->seed),SIG_SHIFT); if (pitch_val > st->max_pitch) pitch_val = st->max_pitch; if (pitch_val < st->min_pitch) pitch_val = st->min_pitch; for (i=0;i<st->subframeSize;i++) { exc[i]= MULT16_32_Q15(pitch_gain, (exc[i-pitch_val]+VERY_SMALL)) + MULT16_32_Q15(fact, MULT16_32_Q15(SHL(Q15ONE,15)-SHL(MULT16_16(pitch_gain,pitch_gain),1),speex_rand(innov_gain, &st->seed))); } for (i=0;i<st->subframeSize;i++) sp[i]=exc[i]; /* Signal synthesis */ if (st->lpc_enh_enabled) { filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, st->mem_sp+st->lpcSize); filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp); } else { for (i=0;i<st->lpcSize;i++) st->mem_sp[st->lpcSize+i] = 0; iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp); } } for (i=0;i<st->frameSize;i++) { spx_word32_t sig = PSHR32(st->frame[i],SIG_SHIFT); if (sig>32767) sig = 32767; if (sig<-32767) sig = -32767; out[i]=sig; } st->first = 0; st->count_lost++; st->pitch_gain_buf[st->pitch_gain_buf_idx++] = PSHR(pitch_gain,9); if (st->pitch_gain_buf_idx > 2) /* rollover */ st->pitch_gain_buf_idx = 0;}int nb_decode(void *state, SpeexBits *bits, void *vout){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -