📄 nb_celp.c
字号:
ol1 = compute_rms(st->exc, st->frameSize>>1);
ol2 = compute_rms(st->exc+(st->frameSize>>1), st->frameSize>>1);
ol1 *= ol1*(st->frameSize>>1);
ol2 *= ol2*(st->frameSize>>1);
ol_gain2=ol1;
if (ol2>ol1)
ol_gain2=ol2;
ol_gain2 = sqrt(2*ol_gain2*(ol1+ol2))*1.3*(1-.5*GAIN_SCALING_1*GAIN_SCALING_1*ol_pitch_coef*ol_pitch_coef);
ol_gain=SHR(sqrt(1+ol_gain2/st->frameSize),SIG_SHIFT);
} else {
#endif
ol_gain = SHL32(EXTEND32(compute_rms(st->exc, st->frameSize)),SIG_SHIFT);
#ifdef EPIC_48K
}
#endif
}
/*VBR stuff*/
if (st->vbr && (st->vbr_enabled||st->vad_enabled))
{
float lsp_dist=0;
for (i=0;i<st->lpcSize;i++)
lsp_dist += (st->old_lsp[i] - st->lsp[i])*(st->old_lsp[i] - st->lsp[i]);
lsp_dist /= LSP_SCALING*LSP_SCALING;
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>.05)
qual_change=.05;
if (qual_change<-.05)
qual_change=-.05;
}
st->vbr_quality += qual_change;
if (st->vbr_quality>10)
st->vbr_quality=10;
if (st->vbr_quality<0)
st->vbr_quality=0;
}
st->relative_quality = vbr_analysis(st->vbr, in, st->frameSize, ol_pitch, GAIN_SCALING_1*ol_pitch_coef);
/*if (delta_qual<0)*/
/* delta_qual*=.1*(3+st->vbr_quality);*/
if (st->vbr_enabled)
{
int mode;
int choice=0;
float min_diff=100;
mode = 8;
while (mode)
{
int v1;
float thresh;
v1=(int)floor(st->vbr_quality);
if (v1==10)
thresh = vbr_nb_thresh[mode][v1];
else
thresh = (st->vbr_quality-v1)*vbr_nb_thresh[mode][v1+1] + (1+v1-st->vbr_quality)*vbr_nb_thresh[mode][v1];
if (st->relative_quality > thresh &&
st->relative_quality-thresh<min_diff)
{
choice = mode;
min_diff = st->relative_quality-thresh;
}
mode--;
}
mode=choice;
if (mode==0)
{
if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)
{
mode=1;
st->dtx_count=1;
} else {
mode=0;
st->dtx_count++;
}
} else {
st->dtx_count=0;
}
speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);
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 case*/
int mode;
if (st->relative_quality<2)
{
if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)
{
st->dtx_count=1;
mode=1;
} else {
mode=0;
st->dtx_count++;
}
} else {
st->dtx_count = 0;
mode=st->submodeSelect;
}
/*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/
st->submodeID=mode;
}
} 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->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);
#ifdef RESYNTH
for (i=0;i<st->frameSize;i++)
in[i]=st->frame[i];
#endif
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 */
ALLOC(res, st->subframeSize, spx_sig_t);
/* Target signal */
ALLOC(target, st->subframeSize, spx_sig_t);
ALLOC(syn_resp, st->subframeSize, spx_word16_t);
ALLOC(real_exc, st->subframeSize, spx_sig_t);
ALLOC(mem, st->lpcSize, spx_mem_t);
/* Loop on sub-frames */
for (sub=0;sub<st->nbSubframes;sub++)
{
int offset;
spx_sig_t *sp, *sw, *exc;
int pitch;
int response_bound = st->subframeSize;
#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;
/* 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=LPC_SCALING;
for (i=0;i<st->lpcSize;i+=2)
{
/*pi_g += -st->interp_qlpc[i] + st->interp_qlpc[i+1];*/
pi_g = ADD32(pi_g, SUB32(st->interp_qlpc[i+1],st->interp_qlpc[i]));
}
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;
}
for (i=0;i<st->subframeSize;i++)
real_exc[i] = exc[i];
if (st->complexity==0)
response_bound >>= 1;
compute_impulse_response(st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, syn_resp, response_bound, st->lpcSize, stack);
for (i=response_bound;i<st->subframeSize;i++)
syn_resp[i]=VERY_SMALL;
/* Reset excitation */
for (i=0;i<st->subframeSize;i++)
exc[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];
#ifdef SHORTCUTS2
iir_mem2(exc, st->interp_qlpc, exc, response_bound, 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, response_bound, st->lpcSize, mem);
for (i=response_bound;i<st->subframeSize;i++)
res[i]=0;
#else
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);
#endif
/* 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);
if (st->complexity==0)
for (i=0;i<st->lpcSize;i++)
st->mem_sw[i]=mem[i];
/* 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;
/* 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -