}
- aks_to_M2(fft_fwd_cfg, ak, order, &model, e, &snr, 1, simlpcpf, lpcpf);
+ aks_to_M2(fft_fwd_cfg, ak, order, &model, e, &snr, 1, simlpcpf, lpcpf, 1, LPCPF_BETA, LPCPF_GAMMA);
apply_lpc_correction(&model);
#ifdef DUMP
return NULL;
}
+ c2->lpc_pf = 1; c2->bass_boost = 1; c2->beta = LPCPF_BETA; c2->gamma = LPCPF_GAMMA;
+
c2->xq_enc[0] = c2->xq_enc[1] = 0.0;
c2->xq_dec[0] = c2->xq_dec[1] = 0.0;
interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5);
for(i=0; i<2; i++) {
lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
- aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, 1);
+ aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
+ c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma);
apply_lpc_correction(&model[i]);
}
interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5);
for(i=0; i<2; i++) {
lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
- aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, 1);
+ aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
+ c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma);
apply_lpc_correction(&model[i]);
}
}
for(i=0; i<4; i++) {
lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
- aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, 1);
+ aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
+ c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma);
apply_lpc_correction(&model[i]);
}
}
for(i=0; i<4; i++) {
lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
- aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, 1);
+ aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
+ c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma);
apply_lpc_correction(&model[i]);
}
in_out[i] *= gain;
}
}
+
+int CODEC2_WIN32SUPPORT codec2_set_lpc_post_filter(struct CODEC2 *c2, int enable, int bass_boost, float beta, float gamma)
+{
+ assert((beta >= 0.0) && (beta <= 1.0));
+ assert((gamma >= 0.0) && (gamma <= 1.0));
+ c2->lpc_pf = enable;
+ c2->bass_boost = bass_boost;
+ c2->beta = beta;
+ c2->gamma = gamma;
+}
+
void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits);
int CODEC2_WIN32SUPPORT codec2_samples_per_frame(struct CODEC2 *codec2_state);
int CODEC2_WIN32SUPPORT codec2_bits_per_frame(struct CODEC2 *codec2_state);
+int CODEC2_WIN32SUPPORT codec2_set_lpc_post_filter(struct CODEC2 *codec2_state, int enable, int bass_boost, float beta, float gamma);
#endif
MODEL prev_model_dec; /* previous frame's model parameters */
float prev_lsps_dec[LPC_ORD]; /* previous frame's LSPs */
float prev_e_dec; /* previous frame's LPC energy */
+
+ int lpc_pf; /* LPC post filter on */
+ int bass_boost; /* LPC post filter bass boost */
+ float beta; /* LPC post filter parameters */
+ float gamma;
float xq_enc[2]; /* joint pitch and energy VQ states */
float xq_dec[2];
/* convert back to amplitudes */
lsp_to_lpc(lsps_interp, ak_interp, LPC_ORD);
- aks_to_M2(fft_fwd_cfg, ak_interp, LPC_ORD, interp, e, &snr, 0, 0, 1);
+ aks_to_M2(fft_fwd_cfg, ak_interp, LPC_ORD, interp, e, &snr, 0, 0, 1, 1, LPCPF_BETA, LPCPF_GAMMA);
//printf(" interp: ak[1]: %f A[1] %f\n", ak_interp[1], interp->A[1]);
}
\*---------------------------------------------------------------------------*/
-#define LPCPF_GAMMA 0.5
-#define LPCPF_BETA 0.2
-
-void lpc_post_filter(kiss_fft_cfg fft_fwd_cfg, MODEL *model, COMP Pw[], float ak[], int order, int dump)
+void lpc_post_filter(kiss_fft_cfg fft_fwd_cfg, MODEL *model, COMP Pw[], float ak[],
+ int order, int dump, float beta, float gamma, int bass_boost)
{
int i;
COMP x[FFT_ENC]; /* input to FFTs */
}
for(i=0; i<=order; i++)
- x[i].real = ak[i] * pow(LPCPF_GAMMA, (float)i);
+ x[i].real = ak[i] * pow(gamma, (float)i);
kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)x, (kiss_fft_cpx *)Ww);
for(i=0; i<FFT_ENC/2; i++) {
e_after = 1E-4;
for(i=0; i<FFT_ENC/2; i++) {
- Pfw[i] = pow(Rw[i], LPCPF_BETA);
+ Pfw[i] = pow(Rw[i], beta);
Pw[i].real *= Pfw[i] * Pfw[i];
e_after += Pw[i].real;
}
Pw[i].real *= gain;
}
- /* add 3dB to first 1 kHz to account for LP effect of PF */
+ if (bass_boost) {
+ /* add 3dB to first 1 kHz to account for LP effect of PF */
- for(i=0; i<FFT_ENC/8; i++) {
- Pw[i].real *= 1.4*1.4;
+ for(i=0; i<FFT_ENC/8; i++) {
+ Pw[i].real *= 1.4*1.4;
+ }
}
-
-
}
float *snr, /* signal to noise ratio for this frame in dB */
int dump, /* true to dump sample to dump file */
int sim_pf, /* true to simulate a post filter */
- int pf /* true to post filter */
+ int pf, /* true to LPC post filter */
+ int bass_boost, /* enable LPC filter 0-1khz 3dB boost */
+ float beta,
+ float gamma /* LPC post filter parameters */
)
{
COMP pw[FFT_ENC]; /* input to FFT for power spectrum */
Pw[i].real = E/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag);
if (pf)
- lpc_post_filter(fft_fwd_cfg, model, Pw, ak, order, dump);
+ lpc_post_filter(fft_fwd_cfg, model, Pw, ak, order, dump, beta, gamma, bass_boost);
#ifdef DUMP
if (dump)
#define WO_E_BITS 8
+#define LPCPF_GAMMA 0.5
+#define LPCPF_BETA 0.2
+
void quantise_init();
float lpc_model_amplitudes(float Sn[], float w[], MODEL *model, int order,
int lsp,float ak[]);
void aks_to_M2(kiss_fft_cfg fft_fwd_cfg, float ak[], int order, MODEL *model,
- float E, float *snr, int dump, int sim_pf, int pf);
+ float E, float *snr, int dump, int sim_pf,
+ int pf, int bass_boost, float beta, float gamma);
int encode_Wo(float Wo);
float decode_Wo(int index);