MODEL prev_model, interp_model;
int decimate;
+ float lsps[LPC_ORD];
+ float prev_lsps[LPC_ORD];
+ float e, prev_e;
+ int lpc_correction;
+ float ak_interp[LPC_MAX];
void *nlp_states;
for(i=1; i<=MAX_AMP; i++) {
ex_phase[i] = 0.0;
}
+ for(i=0; i<LPC_ORD; i++) {
+ prev_lsps[i] = i*PI/(LPC_ORD+1);
+ }
+ prev_e = 1;
nlp_states = nlp_create();
fscanf(fvoicing,"%d\n",&model.voiced);
}
}
-
+
/* optional LPC model amplitudes */
if (lpc_model) {
- int lpc_correction;
- float e;
- float lsps[LPC_ORD];
int lsp_indexes[LPC_ORD];
e = speech_to_uq_lsps(lsps, ak, Sn, w, order);
printf("needs --phase0 to resample phase for interpolated Wo\n");
exit(0);
}
+ if (!lpc_model) {
+ printf("needs --lpc 10 to resample amplitudes\n");
+ exit(0);
+ }
/* odd frame - interpolate */
if (frames%2) {
- #ifdef TEST
- model.voiced = 1;
- prev_model.voiced = 1;
- if (fabs(prev_model.Wo - model.Wo) < 0.1*model.Wo) {
- interp_model.voiced = 1;
- interpolate(&interp_model, &prev_model, &model);
- for(i=0; i<=interp_model.L; i++) {
- interp_model.phi[i] = phi1[i];
- }
- printf("interp\n");
- }
- else
- interp_model = tmp_model;
- #endif
-
interp_model.voiced = voiced1;
+
+ #ifdef LOG_LIN_INTERP
interpolate(&interp_model, &prev_model, &model);
+ #else
+ interpolate_lsp(&interp_model, &prev_model, &model,
+ prev_lsps, prev_e, lsps, e, ak_interp);
+ apply_lpc_correction(&interp_model, lpc_correction);
+ #endif
if (phase0)
- phase_synth_zero_order(&interp_model, ak, ex_phase);
+ phase_synth_zero_order(&interp_model, ak_interp, ex_phase);
if (postfilt)
postfilter(&interp_model, &bg_est);
synth_one_frame(buf, &interp_model, Sn_, Pn);
if (fout != NULL) fwrite(buf,sizeof(short),N,fout);
prev_model = model;
+ for(i=0; i<LPC_ORD; i++)
+ prev_lsps[i] = lsps[i];
+ prev_e = e;
}
else {
voiced1 = model.voiced;
#include "defines.h"
#include "interp.h"
+#include "lsp.h"
+#include "quantise.h"
float sample_log_amp(MODEL *model, float w);
This version can interpolate the amplitudes between two frames of
different Wo and L.
+
+ This version works by log linear interpolation, but listening tests
+ showed it creates problems in background noise, e.g. hts2a and mmt1.
+ When this function is used (--dec mode) bg noise appears to be
+ amplitude modulated, and gets louder. The interp_lsp() function
+ below seems to do a better job.
\*---------------------------------------------------------------------------*/
return log_amp;
}
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: interp_lsp()
+ AUTHOR......: David Rowe
+ DATE CREATED: 10 Nov 2010
+
+ Given two frames decribed by model parameters 20ms apart, determines
+ the model parameters of the 10ms frame between them. Assumes
+ voicing is available for middle (interpolated) frame. Outputs are
+ amplitudes and Wo for the interpolated frame.
+
+ This version uses interpolation of LSPs, seems to do a better job
+ with bg noise.
+
+\*---------------------------------------------------------------------------*/
+
+void interpolate_lsp(
+ MODEL *interp, /* interpolated model params */
+ MODEL *prev, /* previous frames model params */
+ MODEL *next, /* next frames model params */
+ float *prev_lsps, /* previous frames LSPs */
+ float prev_e, /* previous frames LPC energy */
+ float *next_lsps, /* next frames LSPs */
+ float next_e, /* next frames LPC energy */
+ float *ak_interp /* interpolated aks for this frame */
+ )
+{
+ int l,i;
+ float lsps[LPC_ORD],e;
+ float snr;
+
+ /* Wo depends on voicing of this and adjacent frames */
+
+ if (interp->voiced) {
+ if (prev->voiced && next->voiced)
+ interp->Wo = (prev->Wo + next->Wo)/2.0;
+ if (!prev->voiced && next->voiced)
+ interp->Wo = next->Wo;
+ if (prev->voiced && !next->voiced)
+ interp->Wo = prev->Wo;
+ }
+ else {
+ interp->Wo = TWO_PI/P_MAX;
+ }
+ interp->L = PI/interp->Wo;
+
+ /* interpolate LSPs */
+
+ for(i=0; i<LPC_ORD; i++) {
+ lsps[i] = (prev_lsps[i] + next_lsps[i])/2.0;
+ }
+
+ /* Interpolate LPC energy in log domain */
+
+ e = pow(10.0, (log10(prev_e) + log10(next_e))/2.0);
+
+ /* convert back to amplitudes */
+
+ lsp_to_lpc(lsps, ak_interp, LPC_ORD);
+ aks_to_M2(ak_interp, LPC_ORD, interp, e, &snr, 0);
+}
#define __INTERP__
void interpolate(MODEL *interp, MODEL *prev, MODEL *next);
+void interpolate_lsp(MODEL *interp, MODEL *prev, MODEL *next,
+ float *prev_lsps, float prev_e,
+ float *next_lsps, float next_e,
+ float *ak_interp);
#endif