📄 nb_celp.cpp
字号:
comp_filter_mem_init (st->comb_mem); st->pi_gain = PUSH(st->stack, st->nbSubframes, float); 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->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; return st;}void nb_decoder_destroy(void *state){ DecState *st; st=(DecState*)state; speex_free(state);}#define median3(a, b, c) ((a) < (b) ? ((b) < (c) ? (b) : ((a) < (c) ? (c) : (a))) : ((c) < (b) ? (b) : ((c) < (a) ? (c) : (a))))static void nb_decode_lost(DecState *st, float *out, char *stack){ int i, sub; float *awk1, *awk2, *awk3; float pitch_gain, fact, gain_med; fact = exp(-.04*st->count_lost*st->count_lost); 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; pitch_gain = st->last_pitch_gain; if (pitch_gain>.95) pitch_gain=.95; pitch_gain = pitch_gain*fact + VERY_SMALL; /* Shift all buffers by one frame */ speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); speex_move(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); awk1=PUSH(stack, (st->lpcSize+1), float); awk2=PUSH(stack, (st->lpcSize+1), float); awk3=PUSH(stack, (st->lpcSize+1), float); for (sub=0;sub<st->nbSubframes;sub++) { int offset; float *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) { float r=.9; float k1,k2,k3; if (st->submodes[st->submodeID] != NULL) { k1=SUBMODE(lpc_enh_k1); k2=SUBMODE(lpc_enh_k2); } else { k1=k2=.7; } k3=(1-(1-r*k1)/(1-r*k2))/r; if (!st->lpc_enh_enabled) { k1=k2; 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 */ /* THIS CAN BE IMPROVED */ /*if (pitch_gain>.95) pitch_gain=.95;*/ { float innov_gain=0; for (i=0;i<st->frameSize;i++) innov_gain += st->innov[i]*st->innov[i]; innov_gain=sqrt(innov_gain/st->frameSize); for (i=0;i<st->subframeSize;i++) {#if 0 exc[i] = pitch_gain * exc[i - st->last_pitch] + fact*sqrt(1-pitch_gain)*st->innov[i+offset]; /*Just so it give the same lost packets as with if 0*/ /*rand();*/#else /*exc[i]=pitch_gain*exc[i-st->last_pitch] + fact*st->innov[i+offset];*/ exc[i]=pitch_gain*(exc[i-st->last_pitch]+VERY_SMALL) + fact*sqrt(1-pitch_gain)*speex_rand(innov_gain);#endif } } for (i=0;i<st->subframeSize;i++) sp[i]=exc[i]+VERY_SMALL; /* 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); } } out[0] = st->frame[0] + st->preemph*st->pre_mem; for (i=1;i<st->frameSize;i++) out[i]=st->frame[i] + st->preemph*out[i-1]; st->pre_mem=out[st->frameSize-1]; st->first = 0; st->count_lost++; st->pitch_gain_buf[st->pitch_gain_buf_idx++] = pitch_gain; if (st->pitch_gain_buf_idx > 2) /* rollover */ st->pitch_gain_buf_idx = 0;}int nb_decode(void *state, SpeexBits *bits, float *out){ DecState *st; int i, sub; int pitch; float pitch_gain[3]; float ol_gain=0; int ol_pitch=0; float ol_pitch_coef=0; int best_pitch=40; float best_pitch_gain=0; int wideband; int m; char *stack; float *awk1, *awk2, *awk3; float pitch_average=0; st=(DecState*)state; 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; } /* Search for next narrowband block (handle requests, skip wideband blocks) */ do { 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); 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 to wideband layers found: corrupted stream?"); return -2; } } } /* 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; } /* Shift all buffers by one frame */ speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); speex_move(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); /* If null mode (no transmission), just set a couple things to zero*/ if (st->submodes[st->submodeID] == NULL) { float *lpc; lpc = PUSH(stack,11, float); bw_lpc(.93, st->interp_qlpc, lpc, 10); /*for (i=0;i<st->frameSize;i++) st->exc[i]=0;*/ { float innov_gain=0; float pgain=st->last_pitch_gain; if (pgain>.6) pgain=.6; for (i=0;i<st->frameSize;i++) innov_gain += st->innov[i]*st->innov[i]; innov_gain=sqrt(innov_gain/st->frameSize); for (i=0;i<st->frameSize;i++) st->exc[i]=0; speex_rand_vec(innov_gain, st->exc, st->frameSize); } st->first=1; /* Final signal synthesis from excitation */ iir_mem2(st->exc, lpc, st->frame, st->frameSize, st->lpcSize, st->mem_sp); out[0] = st->frame[0] + st->preemph*st->pre_mem; for (i=1;i<st->frameSize;i++) out[i]=st->frame[i] + st->preemph*out[i-1]; st->pre_mem=out[st->frameSize-1]; st->count_lost=0; return 0; } /* Unquantize LSPs */ SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits); /*Damp memory if a frame was lost and the LSP changed too much*/ if (st->count_lost) { float lsp_dist=0, fact; for (i=0;i<st->lpcSize;i++) lsp_dist += fabs(st->old_qlsp[i] - st->qlsp[i]); fact = .6*exp(-.2*lsp_dist); for (i=0;i<2*st->lpcSize;i++) st->mem_sp[i] *= fact; } /* Handle first frame and lost-packet case */ if (st->first || st->count_lost) { for (i=0;i<st->lpcSize;i++) st->old_qlsp[i] = st->qlsp[i]; } /* 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=0.066667*quant; } /* Get global excitation gain */ { int qe; qe = speex_bits_unpack_unsigned(bits, 5); ol_gain = exp(qe/3.5); } awk1=PUSH(stack, st->lpcSize+1, float); awk2=PUSH(stack, st->lpcSize+1, float); awk3=PUSH(stack, st->lpcSize+1, float); 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; float *sp, *exc, tmp; /* 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*/ /* LSP interpolation (quantized and unquantized) */ tmp = (1.0 + sub)/st->nbSubframes; for (i=0;i<st->lpcSize;i++) st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; /* Make sure the LSP's are stable */ lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .002); /* Compute interpolated LPCs (unquantized) */ for (i=0;i<st->lpcSize;i++) st->interp_qlsp[i] = cos(st->interp_qlsp[i]); lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); /* Compute enhanced synthesis filter */ if (st->lpc_enh_enabled) { float r=.9; float k1,k2,k3; k1=SUBMODE(lpc_enh_k1); k2=SUBMODE(lpc_enh_k2); k3=(1-(1-r*k1)/(1-r*k2))/r; if (!st->lpc_enh_enabled) { k1=k2; 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); } /* Compute analysis filter at w=pi */ tmp=1; st->pi_gain[sub]=0; for (i=0;i<=st->lpcSize;i++) { st->pi_gain[sub] += tmp*st->interp_qlpc[i]; tmp = -tmp; } /* 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -