nb_celp.c
来自「基于sip协议的网络电话源码」· C语言 代码 · 共 2,058 行 · 第 1/5 页
C
2,058 行
stack=st->stack; /* Check if we're in DTX mode*/ if (!bits && st->dtx_enabled) { st->submodeID=0; } else { /* If bits is NULL, consider the packet to be lost (what could we do anyway) */ if (!bits) { nb_decode_lost(st, out, stack); return 0; } if (st->encode_submode) {#ifdef EPIC_48K if (!st->lbr_48k) {#endif /* Search for next narrowband block (handle requests, skip wideband blocks) */ do { if (speex_bits_remaining(bits)<5) return -1; wideband = speex_bits_unpack_unsigned(bits, 1); if (wideband) /* Skip wideband block (for compatibility) */ { int submode; int advance; advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance); if (advance < 0) { speex_warning ("Invalid wideband mode encountered. Corrupted stream?"); return -2; } advance -= (SB_SUBMODE_BITS+1); speex_bits_advance(bits, advance); if (speex_bits_remaining(bits)<5) return -1; wideband = speex_bits_unpack_unsigned(bits, 1); if (wideband) { advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance); if (advance < 0) { speex_warning ("Invalid wideband mode encountered: corrupted stream?"); return -2; } advance -= (SB_SUBMODE_BITS+1); speex_bits_advance(bits, advance); wideband = speex_bits_unpack_unsigned(bits, 1); if (wideband) { speex_warning ("More than two wideband layers found: corrupted stream?"); return -2; } } } if (speex_bits_remaining(bits)<4) return -1; /* FIXME: Check for overflow */ m = speex_bits_unpack_unsigned(bits, 4); if (m==15) /* We found a terminator */ { return -1; } else if (m==14) /* Speex in-band request */ { int ret = speex_inband_handler(bits, st->speex_callbacks, state); if (ret) return ret; } else if (m==13) /* User in-band request */ { int ret = st->user_callback.func(bits, state, st->user_callback.data); if (ret) return ret; } else if (m>8) /* Invalid mode */ { speex_warning("Invalid mode encountered: corrupted stream?"); return -2; } } while (m>8); /* Get the sub-mode that was used */ st->submodeID = m;#ifdef EPIC_48K }#endif } } /* Shift all buffers by one frame */ speex_move(st->excBuf, st->excBuf+st->frameSize, (2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t)); /* If null mode (no transmission), just set a couple things to zero*/ if (st->submodes[st->submodeID] == NULL) { VARDECL(spx_coef_t *lpc); ALLOC(lpc, st->lpcSize, spx_coef_t); bw_lpc(GAMMA_SCALING*.93, st->interp_qlpc, lpc, st->lpcSize); { float innov_gain=0; float pgain=GAIN_SCALING_1*st->last_pitch_gain; if (pgain>.6) pgain=.6; /* FIXME: This was innov, not exc */ innov_gain = compute_rms16(st->exc, st->frameSize); for (i=0;i<st->frameSize;i++) st->exc[i]=speex_rand(innov_gain, &st->seed); } st->first=1; for (i=0;i<st->frameSize;i++) out[i] = st->exc[i]; /* Final signal synthesis from excitation */ iir_mem16(out, lpc, out, st->frameSize, st->lpcSize, st->mem_sp, stack); st->count_lost=0; return 0; } ALLOC(qlsp, st->lpcSize, spx_lsp_t); /* Unquantize LSPs */ SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits); /*Damp memory if a frame was lost and the LSP changed too much*/ if (st->count_lost) { spx_word16_t fact; spx_word32_t lsp_dist=0; for (i=0;i<st->lpcSize;i++) lsp_dist = ADD32(lsp_dist, EXTEND32(ABS(st->old_qlsp[i] - qlsp[i])));#ifdef FIXED_POINT fact = SHR16(19661,SHR32(lsp_dist,LSP_SHIFT+2)); #else fact = .6*exp(-.2*lsp_dist);#endif for (i=0;i<st->lpcSize;i++) st->mem_sp[i] = MULT16_32_Q15(fact,st->mem_sp[i]); } /* Handle first frame and lost-packet case */ if (st->first || st->count_lost) { for (i=0;i<st->lpcSize;i++) st->old_qlsp[i] = qlsp[i]; }#ifdef EPIC_48K if (st->lbr_48k) { pitch_half[0] = st->min_pitch+speex_bits_unpack_unsigned(bits, 7); pitch_half[1] = pitch_half[0]+speex_bits_unpack_unsigned(bits, 2)-1; ol_pitch_id = speex_bits_unpack_unsigned(bits, 3); ol_pitch_coef=GAIN_SCALING*0.13514*ol_pitch_id; { int qe; qe = speex_bits_unpack_unsigned(bits, 4); ol_gain = SIG_SCALING*exp((qe+2)/2.1),SIG_SHIFT; } } else {#endif /* Get open-loop pitch estimation for low bit-rate pitch coding */ if (SUBMODE(lbr_pitch)!=-1) { ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7); } if (SUBMODE(forced_pitch_gain)) { int quant; quant = speex_bits_unpack_unsigned(bits, 4); ol_pitch_coef=GAIN_SCALING*0.066667*quant; } /* Get global excitation gain */ { int qe; qe = speex_bits_unpack_unsigned(bits, 5);#ifdef FIXED_POINT /* FIXME: Perhaps we could slightly lower the gain here when the output is going to saturate? */ ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]);#else ol_gain = SIG_SCALING*exp(qe/3.5);#endif }#ifdef EPIC_48K }#endif ALLOC(ak, st->lpcSize, spx_coef_t); ALLOC(innov, st->subframeSize, spx_sig_t); ALLOC(exc32, st->subframeSize, spx_word32_t); if (st->submodeID==1) { int extra; extra = speex_bits_unpack_unsigned(bits, 4); if (extra==15) st->dtx_enabled=1; else st->dtx_enabled=0; } if (st->submodeID>1) st->dtx_enabled=0; /*Loop on subframes */ for (sub=0;sub<st->nbSubframes;sub++) { int offset; spx_word16_t *exc; spx_word16_t *sp; spx_sig_t *innov_save = NULL; spx_word16_t tmp;#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; /* Excitation */ exc=st->exc+offset; /* Original signal */ sp=out+offset; if (st->innov_save) innov_save = st->innov_save+offset; /* Reset excitation */ for (i=0;i<st->subframeSize;i++) exc[i]=0; /*Adaptive codebook contribution*/ if (SUBMODE(ltp_unquant)) { int pit_min, pit_max; /* Handle pitch constraints if any */ if (SUBMODE(lbr_pitch) != -1) { int margin; margin = SUBMODE(lbr_pitch); if (margin) {/* GT - need optimization? 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;*/ pit_min = ol_pitch-margin+1; if (pit_min < st->min_pitch) pit_min = st->min_pitch; pit_max = ol_pitch+margin; if (pit_max > st->max_pitch) pit_max = st->max_pitch; } else { pit_min = pit_max = ol_pitch; } } else { pit_min = st->min_pitch; pit_max = st->max_pitch; }#ifdef EPIC_48K if (st->lbr_48k) { SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params), st->subframeSize, &pitch, &pitch_gain[0], bits, stack, st->count_lost, offset, st->last_pitch_gain, ol_pitch_id); } else {#endif SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params), st->subframeSize, &pitch, &pitch_gain[0], bits, stack, st->count_lost, offset, st->last_pitch_gain, 0);#ifdef EPIC_48K }#endif tmp = gain_3tap_to_1tap(pitch_gain); pitch_average += tmp; if ((tmp>best_pitch_gain&&ABS(2*best_pitch-pitch)>=3&&ABS(3*best_pitch-pitch)>=4&&ABS(4*best_pitch-pitch)>=5) || (tmp>MULT16_16_Q15(QCONST16(.6,15),best_pitch_gain)&&(ABS(best_pitch-2*pitch)<3||ABS(best_pitch-3*pitch)<4||ABS(best_pitch-4*pitch)<5)) || (MULT16_16_Q15(QCONST16(.67,15),tmp)>best_pitch_gain&&(ABS(2*best_pitch-pitch)<3||ABS(3*best_pitch-pitch)<4||ABS(4*best_pitch-pitch)<5)) ) { best_pitch = pitch; if (tmp > best_pitch_gain) best_pitch_gain = tmp; } } else { speex_error("No pitch prediction, what's wrong"); } /* Unquantize the innovation */ { int q_energy; spx_word32_t ener; for (i=0;i<st->subframeSize;i++) innov[i]=0; /* Decode sub-frame gain correction */ if (SUBMODE(have_subframe_gain)==3) { q_energy = speex_bits_unpack_unsigned(bits, 3); ener = MULT16_32_Q14(exc_gain_quant_scal3[q_energy],ol_gain); } else if (SUBMODE(have_subframe_gain)==1) { q_energy = speex_bits_unpack_unsigned(bits, 1); ener = MULT16_32_Q14(exc_gain_quant_scal1[q_energy],ol_gain); } else { ener = ol_gain; } if (SUBMODE(innovation_unquant)) { /*Fixed codebook contribution*/ SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed); } else { speex_error("No fixed codebook"); } /* De-normalize innovation and update excitation */#ifdef FIXED_POINT signal_mul(innov, innov, ener, st->subframeSize);#else signal_mul(innov, innov, ener, st->subframeSize);#endif /*Vocoder mode*/ if (st->submodeID==1) { float g=ol_pitch_coef*GAIN_SCALING_1; for (i=0;i<st->subframeSize;i++) exc[i]=0; while (st->voc_offset<st->subframeSize) { if (st->voc_offset>=0) exc[st->voc_offset]=sqrt(1.0*ol_pitch); st->voc_offset+=ol_pitch; } st->voc_offset -= st->subframeSize; g=.5+2*(g-.6); if (g<0) g=0; if (g>1) g=1; for (i=0;i<st->subframeSize;i++) { spx_word16_t exci=exc[i]; /* FIXME: cleanup the innov[i]/SIG_SCALING */ exc[i]=.8*g*exc[i]*PSHR32(ol_gain,SIG_SHIFT) + .6*g*st->voc_m1*PSHR32(ol_gain,SIG_SHIFT) + (1-.5*g)*PSHR32(innov[i],SIG_SHIFT) - .5*g*PSHR32(st->voc_m2,SIG_SHIFT); st->voc_m1 = exci; st->voc_m2=innov[i]; st->voc_mean = .95*st->voc_mean + .05*exc[i]; exc[i]-=st->voc_mean; } } else { for (i=0;i<st->subframeSize;i++) exc[i]=EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767)); /*print_vec(exc, 40, "innov");*/ } if (innov_save) { for (i=0;i<st->subframeSize;i++) innov_save[i] = innov[i]; } /* Decode second codebook (only for some modes) */ 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; SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed); signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545,15),ener), st->subframeSize); for (i=0;i<st->subframeSize;i++) exc[i] = EXTRACT16(SATURATE32(ADD32(EXTEND32(exc[i]),PSHR32(innov2[i],SIG_SHIFT)),32767)); if (innov_save) { for (i=0;i<st->subframeSize;i++) innov_save[i] = ADD32(innov_save[i],innov2[i]); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?