📄 sb_celp.c
字号:
speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);
speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc);
speex_decoder_ctl(st->st_low, SPEEX_GET_INNOV, low_innov);
SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits);
if (st->first)
{
for (i=0;i<st->lpcSize;i++)
st->old_qlsp[i] = st->qlsp[i];
}
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++)
{
float *exc, *sp, tmp, filter_ratio, el=0;
int offset;
float rl=0,rh=0;
offset = st->subframeSize*sub;
sp=st->high+offset;
exc=st->exc+offset;
/* LSP interpolation */
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];
/* LSPs to x-domain */
for (i=0;i<st->lpcSize;i++)
st->interp_qlsp[i] = cos(st->interp_qlsp[i]);
lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .002);
/* LSP to LPC */
lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack);
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;
k3=k1-k2;
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);
/*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/
}
/* Calculate reponse ratio between the low and high filter in the middle
of the band (4000 Hz) */
tmp=1;
st->pi_gain[sub]=0;
for (i=0;i<=st->lpcSize;i++)
{
rh += tmp*st->interp_qlpc[i];
tmp = -tmp;
st->pi_gain[sub]+=st->interp_qlpc[i];
}
rl = low_pi_gain[sub];
rl=1/(fabs(rl)+.01);
rh=1/(fabs(rh)+.01);
filter_ratio=fabs(.01+rh)/(.01+fabs(rl));
for (i=0;i<st->subframeSize;i++)
exc[i]=0;
if (!SUBMODE(innovation_unquant))
{
float g;
int quant;
for (i=0;i<st->subframeSize;i++)
el+=sqr(low_innov[offset+i]);
quant = speex_bits_unpack_unsigned(bits, 5);
g= exp(((float)quant-10)/8.0);
/*printf ("unquant folding gain: %f\n", g);*/
g /= filter_ratio;
/* High-band excitation using the low-band excitation and a gain */
for (i=0;i<st->subframeSize;i++)
exc[i]=mode->folding_gain*g*low_innov[offset+i];
/*speex_rand_vec(mode->folding_gain*g*sqrt(el/st->subframeSize), exc, st->subframeSize);*/
} else {
float gc, scale;
int qgc = speex_bits_unpack_unsigned(bits, 4);
for (i=0;i<st->subframeSize;i++)
el+=sqr(low_exc[offset+i]);
gc = exp((1/3.7)*qgc-2);
scale = gc*sqrt(1+el)/filter_ratio;
SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize,
bits, stack);
for (i=0;i<st->subframeSize;i++)
exc[i]*=scale;
if (SUBMODE(double_codebook)) {
char *tmp_stack=stack;
float *innov2 = PUSH(tmp_stack, st->subframeSize, float);
for (i=0;i<st->subframeSize;i++)
innov2[i]=0;
SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize,
bits, tmp_stack);
for (i=0;i<st->subframeSize;i++)
innov2[i]*=scale*(1/2.5);
for (i=0;i<st->subframeSize;i++)
exc[i] += innov2[i];
}
}
for (i=0;i<st->subframeSize;i++)
sp[i]=exc[i];
if (st->lpc_enh_enabled)
{
/* Use enhanced LPC filter */
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 {
/* Use regular filter */
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);
}
/*iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);*/
}
fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
for (i=0;i<st->full_frame_size;i++)
out[i]=2*(st->y0[i]-st->y1[i]);
for (i=0;i<st->lpcSize;i++)
st->old_qlsp[i] = st->qlsp[i];
st->first=0;
return 0;
}
int sb_encoder_ctl(void *state, int request, void *ptr)
{
SBEncState *st;
st=(SBEncState*)state;
switch(request)
{
case SPEEX_GET_FRAME_SIZE:
(*(int*)ptr) = st->full_frame_size;
break;
case SPEEX_SET_HIGH_MODE:
st->submodeSelect = st->submodeID = (*(int*)ptr);
break;
case SPEEX_SET_LOW_MODE:
speex_encoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);
break;
case SPEEX_SET_DTX:
speex_encoder_ctl(st->st_low, SPEEX_SET_DTX, ptr);
break;
case SPEEX_GET_DTX:
speex_encoder_ctl(st->st_low, SPEEX_GET_DTX, ptr);
break;
case SPEEX_GET_LOW_MODE:
speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);
break;
case SPEEX_SET_MODE:
speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr);
break;
case SPEEX_SET_VBR:
st->vbr_enabled = (*(int*)ptr);
speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr);
break;
case SPEEX_GET_VBR:
(*(int*)ptr) = st->vbr_enabled;
break;
case SPEEX_SET_VAD:
st->vad_enabled = (*(int*)ptr);
speex_encoder_ctl(st->st_low, SPEEX_SET_VAD, ptr);
break;
case SPEEX_GET_VAD:
(*(int*)ptr) = st->vad_enabled;
break;
case SPEEX_SET_VBR_QUALITY:
{
int q;
float qual = (*(float*)ptr)+.6;
st->vbr_quality = (*(float*)ptr);
if (qual>10)
qual=10;
q=(int)floor(.5+*(float*)ptr);
if (q>10)
q=10;
speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_QUALITY, &qual);
speex_encoder_ctl(state, SPEEX_SET_QUALITY, &q);
break;
}
case SPEEX_SET_ABR:
st->abr_enabled = (*(int*)ptr);
st->vbr_enabled = 1;
speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, &st->vbr_enabled);
{
int i=10, rate, target;
float vbr_qual;
target = (*(int*)ptr);
while (i>=0)
{
speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
if (rate <= target)
break;
i--;
}
vbr_qual=i;
if (vbr_qual<0)
vbr_qual=0;
speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);
st->abr_count=0;
st->abr_drift=0;
st->abr_drift2=0;
}
break;
case SPEEX_GET_ABR:
(*(int*)ptr) = st->abr_enabled;
break;
case SPEEX_SET_QUALITY:
{
int nb_qual;
int quality = (*(int*)ptr);
if (quality < 0)
quality = 0;
if (quality > 10)
quality = 10;
st->submodeSelect = st->submodeID = ((SpeexSBMode*)(st->mode->mode))->quality_map[quality];
nb_qual = ((SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];
speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);
}
break;
case SPEEX_SET_COMPLEXITY:
speex_encoder_ctl(st->st_low, SPEEX_SET_COMPLEXITY, ptr);
st->complexity = (*(int*)ptr);
if (st->complexity<1)
st->complexity=1;
break;
case SPEEX_GET_COMPLEXITY:
(*(int*)ptr) = st->complexity;
break;
case SPEEX_SET_BITRATE:
{
int i=10, rate, target;
target = (*(int*)ptr);
while (i>=0)
{
speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
if (rate <= target)
break;
i--;
}
}
break;
case SPEEX_GET_BITRATE:
speex_encoder_ctl(st->st_low, request, ptr);
/*fprintf (stderr, "before: %d\n", (*(int*)ptr));*/
if (st->submodes[st->submodeID])
(*(int*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;
else
(*(int*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;
/*fprintf (stderr, "after: %d\n", (*(int*)ptr));*/
break;
case SPEEX_SET_SAMPLING_RATE:
{
int tmp=(*(int*)ptr);
st->sampling_rate = tmp;
tmp>>=1;
speex_encoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);
}
break;
case SPEEX_GET_SAMPLING_RATE:
(*(int*)ptr)=st->sampling_rate;
break;
case SPEEX_RESET_STATE:
{
int i;
st->first = 1;
for (i=0;i<st->lpcSize;i++)
st->lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1);
for (i=0;i<st->lpcSize;i++)
st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0;
for (i=0;i<st->bufSize;i++)
st->excBuf[i]=0;
for (i=0;i<QMF_ORDER;i++)
st->h0_mem[i]=st->h1_mem[i]=st->g0_mem[i]=st->g1_mem[i]=0;
}
break;
case SPEEX_GET_PI_GAIN:
{
int i;
float *g = (float*)ptr;
for (i=0;i<st->nbSubframes;i++)
g[i]=st->pi_gain[i];
}
break;
case SPEEX_GET_EXC:
{
int i;
float *e = (float*)ptr;
for (i=0;i<st->full_frame_size;i++)
e[i]=0;
for (i=0;i<st->frame_size;i++)
e[2*i]=2*st->exc[i];
}
break;
case SPEEX_GET_INNOV:
{
int i;
float *e = (float*)ptr;
for (i=0;i<st->full_frame_size;i++)
e[i]=0;
for (i=0;i<st->frame_size;i++)
e[2*i]=2*st->exc[i];
}
break;
case SPEEX_GET_RELATIVE_QUALITY:
(*(float*)ptr)=st->relative_quality;
break;
default:
speex_warning_int("Unknown nb_ctl request: ", request);
return -1;
}
return 0;
}
int sb_decoder_ctl(void *state, int request, void *ptr)
{
SBDecState *st;
st=(SBDecState*)state;
switch(request)
{
case SPEEX_GET_LOW_MODE:
speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);
break;
case SPEEX_GET_FRAME_SIZE:
(*(int*)ptr) = st->full_frame_size;
break;
case SPEEX_SET_ENH:
speex_decoder_ctl(st->st_low, request, ptr);
st->lpc_enh_enabled = *((int*)ptr);
break;
case SPEEX_GET_BITRATE:
speex_decoder_ctl(st->st_low, request, ptr);
if (st->submodes[st->submodeID])
(*(int*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;
else
(*(int*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;
break;
case SPEEX_SET_SAMPLING_RATE:
{
int tmp=(*(int*)ptr);
st->sampling_rate = tmp;
tmp>>=1;
speex_decoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);
}
break;
case SPEEX_GET_SAMPLING_RATE:
(*(int*)ptr)=st->sampling_rate;
break;
case SPEEX_SET_HANDLER:
speex_decoder_ctl(st->st_low, SPEEX_SET_HANDLER, ptr);
break;
case SPEEX_SET_USER_HANDLER:
speex_decoder_ctl(st->st_low, SPEEX_SET_USER_HANDLER, ptr);
break;
case SPEEX_RESET_STATE:
{
int i;
for (i=0;i<2*st->lpcSize;i++)
st->mem_sp[i]=0;
for (i=0;i<QMF_ORDER;i++)
st->h0_mem[i]=st->h1_mem[i]=st->g0_mem[i]=st->g1_mem[i]=0;
}
break;
case SPEEX_GET_PI_GAIN:
{
int i;
float *g = (float*)ptr;
for (i=0;i<st->nbSubframes;i++)
g[i]=st->pi_gain[i];
}
break;
case SPEEX_GET_EXC:
{
int i;
float *e = (float*)ptr;
for (i=0;i<st->full_frame_size;i++)
e[i]=0;
for (i=0;i<st->frame_size;i++)
e[2*i]=2*st->exc[i];
}
break;
case SPEEX_GET_INNOV:
{
int i;
float *e = (float*)ptr;
for (i=0;i<st->full_frame_size;i++)
e[i]=0;
for (i=0;i<st->frame_size;i++)
e[2*i]=2*st->exc[i];
}
break;
case SPEEX_GET_DTX_STATUS:
speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, ptr);
break;
default:
speex_warning_int("Unknown nb_ctl request: ", request);
return -1;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -