#include "bpf.h"
#include "bpfb.h"
-void synth_one_frame(codec2_fftr_cfg fftr_inv_cfg, short buf[], MODEL *model, float Sn_[], float Pn[], int prede, float *de_mem, float gain);
+void synth_one_frame(int n_samp, codec2_fftr_cfg fftr_inv_cfg, short buf[], MODEL *model, float Sn_[], float Pn[], int prede, float *de_mem, float gain);
void print_help(const struct option *long_options, int num_opts, char* argv[]);
+#define N_SAMP n_samp /* quick fix for run time sample rate selection */
/*---------------------------------------------------------------------------*\
int main(int argc, char *argv[])
{
+ C2CONST c2const = c2const_create(8000);
+ int n_samp = c2const.n_samp;
FILE *fout = NULL; /* output speech file */
FILE *fin; /* input speech file */
short buf[N_SAMP]; /* input/output buffer */
#ifdef DUMP
int dump;
#endif
+ #if 0
struct PEXP *pexp = NULL;
struct AEXP *aexp = NULL;
+ #endif
float gain = 1.0;
int bpf_en = 0;
int bpfb_en = 0;
fft_fwd_cfg = codec2_fft_alloc(FFT_ENC, 0, NULL, NULL); /* fwd FFT,used in several places */
fftr_fwd_cfg = codec2_fftr_alloc(FFT_ENC, 0, NULL, NULL); /* fwd FFT,used in several places */
fftr_inv_cfg = codec2_fftr_alloc(FFT_DEC, 1, NULL, NULL); /* inverse FFT, used just for synth */
- make_analysis_window(fft_fwd_cfg, w, W);
- make_synthesis_window(Pn);
+ make_analysis_window(&c2const, fft_fwd_cfg, w, W);
+ make_synthesis_window(&c2const, Pn);
quantise_init();
+
+ /* disabled for now while we convert to runtime n_samp */
+ #if 0
if (phaseexp)
pexp = phase_experiment_create();
if (ampexp)
aexp = amp_experiment_create();
+ #endif
if (bpfb_en)
bpf_en = 1;
dump_Sn(Sn); dump_Sw(Sw); dump_model(&model);
#endif
+ #if 0
if (ampexp)
amp_experiment(aexp, &model, ampexp_arg);
dump_phase_(&model.phi[0], model.L);
#endif
}
+ #endif
if (hi) {
int m;
} else {
sample_phase(&model_dec[i], H, Aw);
}
- phase_synth_zero_order(&model_dec[i], ex_phase, H);
+ phase_synth_zero_order(n_samp, &model_dec[i], ex_phase, H);
}
if (postfilt)
postfilter(&model_dec[i], &bg_est);
- synth_one_frame(fftr_inv_cfg, buf, &model_dec[i], Sn_, Pn, prede, &de_mem, gain);
+ synth_one_frame(n_samp, fftr_inv_cfg, buf, &model_dec[i], Sn_, Pn, prede, &de_mem, gain);
if (fout != NULL) fwrite(buf,sizeof(short),N_SAMP,fout);
}
fprintf(stderr, "lspmelvq std = %3.1f Hz\n", sqrt(lspmelvq_mse/frames));
}
+ #if 0
if (phaseexp)
phase_experiment_destroy(pexp);
if (ampexp)
amp_experiment_destroy(aexp);
+ #endif
#ifdef DUMP
if (dump)
dump_off();
return 0;
}
-void synth_one_frame(codec2_fftr_cfg fftr_inv_cfg, short buf[], MODEL *model, float Sn_[],
+void synth_one_frame(int n_samp, codec2_fftr_cfg fftr_inv_cfg, short buf[], MODEL *model, float Sn_[],
float Pn[], int prede, float *de_mem, float gain)
{
int i;
- synthesise(fftr_inv_cfg, Sn_, model, Pn, 1);
+ synthesise(n_samp, fftr_inv_cfg, Sn_, model, Pn, 1);
if (prede)
- de_emp(Sn_, Sn_, de_mem, N_SAMP);
+ de_emp(Sn_, Sn_, de_mem, n_samp);
- for(i=0; i<N_SAMP; i++) {
+ for(i=0; i<n_samp; i++) {
Sn_[i] *= gain;
if (Sn_[i] > 32767.0)
buf[i] = 32767;
{
struct CODEC2 *c2;
int i,l;
+ C2CONST c2const = c2const_create(8000);
+ int n_samp = c2const.n_samp;
if (!((mode >= 0) && (mode <= CODEC2_MODE_700C))) {
return NULL;
return NULL;
c2->mode = mode;
+
+ c2->Fs = c2const.Fs;
+ c2->n_samp = n_samp;
+ c2->Pn = (float*)malloc(2*n_samp*sizeof(float));
+ if (c2->Pn == NULL) {
+ free(c2);
+ return NULL;
+ }
+ c2->Sn_ = (float*)malloc(2*n_samp*sizeof(float));
+ if (c2->Sn_ == NULL) {
+ free(c2->Pn);
+ free(c2);
+ return NULL;
+ }
+
for(i=0; i<M_PITCH; i++)
c2->Sn[i] = 1.0;
c2->hpf_states[0] = c2->hpf_states[1] = 0.0;
- for(i=0; i<2*N_SAMP; i++)
+ for(i=0; i<2*n_samp; i++)
c2->Sn_[i] = 0;
c2->fft_fwd_cfg = codec2_fft_alloc(FFT_ENC, 0, NULL, NULL);
c2->fftr_fwd_cfg = codec2_fftr_alloc(FFT_ENC, 0, NULL, NULL);
- make_analysis_window(c2->fft_fwd_cfg, c2->w,c2->W);
- make_synthesis_window(c2->Pn);
+ make_analysis_window(&c2const, c2->fft_fwd_cfg, c2->w,c2->W);
+ make_synthesis_window(&c2const, c2->Pn);
c2->fftr_inv_cfg = codec2_fftr_alloc(FFT_DEC, 1, NULL, NULL);
quantise_init();
c2->prev_Wo_enc = 0.0;
c2->nlp = nlp_create(M_PITCH);
if (c2->nlp == NULL) {
+ free(c2->Sn_);
+ free(c2->Pn);
free (c2);
return NULL;
}
c2->smoothing = 0;
- c2->bpf_buf = (float*)malloc(sizeof(float)*(BPF_N+4*N_SAMP));
+ c2->bpf_buf = (float*)malloc(sizeof(float)*(BPF_N+4*c2->n_samp));
assert(c2->bpf_buf != NULL);
- for(i=0; i<BPF_N+4*N_SAMP; i++)
+ for(i=0; i<BPF_N+4*c2->n_samp; i++)
c2->bpf_buf[i] = 0.0;
c2->softdec = NULL;
/* second 10ms analysis frame */
- analyse_one_frame(c2, &model, &speech[N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
Wo_index = encode_Wo(model.Wo, WO_BITS);
pack(bits, &nbit, Wo_index, WO_BITS);
aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
apply_lpc_correction(&model[i]);
- synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
}
/* update memories for next frame ----------------------------*/
/* second 10ms analysis frame */
- analyse_one_frame(c2, &model, &speech[N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
apply_lpc_correction(&model[i]);
- synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
}
/* update memories for next frame ----------------------------*/
/* frame 2: - voicing, scalar Wo & E -------------------------------*/
- analyse_one_frame(c2, &model, &speech[N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
Wo_index = encode_Wo(model.Wo, WO_BITS);
/* frame 3: - voicing ---------------------------------------------*/
- analyse_one_frame(c2, &model, &speech[2*N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[2*c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
/* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/
- analyse_one_frame(c2, &model, &speech[3*N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[3*c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
Wo_index = encode_Wo(model.Wo, WO_BITS);
aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
apply_lpc_correction(&model[i]);
- synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
}
/* update memories for next frame ----------------------------*/
/* frame 2: - voicing, joint Wo & E -------------------------------*/
- analyse_one_frame(c2, &model, &speech[N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
/* need to run this just to get LPC energy */
/* frame 3: - voicing ---------------------------------------------*/
- analyse_one_frame(c2, &model, &speech[2*N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[2*c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
/* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/
- analyse_one_frame(c2, &model, &speech[3*N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[3*c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
apply_lpc_correction(&model[i]);
- synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
}
/* update memories for next frame ----------------------------*/
/* frame 2: - voicing ---------------------------------------------*/
- analyse_one_frame(c2, &model, &speech[N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[c2->n_samp]);
pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray);
/* frame 3: - voicing ---------------------------------------------*/
- analyse_one_frame(c2, &model, &speech[2*N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[2*c2->n_samp]);
pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray);
/* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/
- analyse_one_frame(c2, &model, &speech[3*N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[3*c2->n_samp]);
pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray);
Wo_index = encode_Wo(model.Wo, WO_BITS);
aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
apply_lpc_correction(&model[i]);
- synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
}
/*
for(i=0; i<4; i++) {
/* frame 2: - voicing, joint Wo & E -------------------------------*/
- analyse_one_frame(c2, &model, &speech[N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
/* need to run this just to get LPC energy */
/* frame 3: - voicing ---------------------------------------------*/
- analyse_one_frame(c2, &model, &speech[2*N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[2*c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
/* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/
- analyse_one_frame(c2, &model, &speech[3*N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[3*c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
apply_lpc_correction(&model[i]);
- synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
}
/* update memories for next frame ----------------------------*/
int indexes[LPC_ORD_LOW];
int Wo_index, e_index, i;
unsigned int nbit = 0;
- float bpf_out[4*N_SAMP];
- short bpf_speech[4*N_SAMP];
+ float bpf_out[4*c2->n_samp];
+ short bpf_speech[4*c2->n_samp];
int spare = 0;
assert(c2 != NULL);
/* band pass filter */
for(i=0; i<BPF_N; i++)
- c2->bpf_buf[i] = c2->bpf_buf[4*N_SAMP+i];
- for(i=0; i<4*N_SAMP; i++)
+ c2->bpf_buf[i] = c2->bpf_buf[4*c2->n_samp+i];
+ for(i=0; i<4*c2->n_samp; i++)
c2->bpf_buf[BPF_N+i] = speech[i];
- inverse_filter(&c2->bpf_buf[BPF_N], bpf, 4*N_SAMP, bpf_out, BPF_N-1);
- for(i=0; i<4*N_SAMP; i++)
+ inverse_filter(&c2->bpf_buf[BPF_N], bpf, 4*c2->n_samp, bpf_out, BPF_N-1);
+ for(i=0; i<4*c2->n_samp; i++)
bpf_speech[i] = bpf_out[i];
/* frame 1 --------------------------------------------------------*/
/* frame 2 --------------------------------------------------------*/
- analyse_one_frame(c2, &model, &bpf_speech[N_SAMP]);
+ analyse_one_frame(c2, &model, &bpf_speech[c2->n_samp]);
/* frame 3 --------------------------------------------------------*/
- analyse_one_frame(c2, &model, &bpf_speech[2*N_SAMP]);
+ analyse_one_frame(c2, &model, &bpf_speech[2*c2->n_samp]);
/* frame 4: - voicing, scalar Wo & E, scalar LSPs -----------------*/
- analyse_one_frame(c2, &model, &bpf_speech[3*N_SAMP]);
+ analyse_one_frame(c2, &model, &bpf_speech[3*c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
Wo_index = encode_log_Wo(model.Wo, 5);
pack_natural_or_gray(bits, &nbit, Wo_index, 5, c2->gray);
aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD_LOW, &model[i], e[i], &snr, 0, 0,
c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
apply_lpc_correction(&model[i]);
- synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
}
#ifdef DUMP
int indexes[3];
int Wo_index, e_index, i;
unsigned int nbit = 0;
- float bpf_out[4*N_SAMP];
- short bpf_speech[4*N_SAMP];
+ float bpf_out[4*c2->n_samp];
+ short bpf_speech[4*c2->n_samp];
int spare = 0;
assert(c2 != NULL);
/* band pass filter */
for(i=0; i<BPF_N; i++)
- c2->bpf_buf[i] = c2->bpf_buf[4*N_SAMP+i];
- for(i=0; i<4*N_SAMP; i++)
+ c2->bpf_buf[i] = c2->bpf_buf[4*c2->n_samp+i];
+ for(i=0; i<4*c2->n_samp; i++)
c2->bpf_buf[BPF_N+i] = speech[i];
- inverse_filter(&c2->bpf_buf[BPF_N], bpfb, 4*N_SAMP, bpf_out, BPF_N-1);
- for(i=0; i<4*N_SAMP; i++)
+ inverse_filter(&c2->bpf_buf[BPF_N], bpfb, 4*c2->n_samp, bpf_out, BPF_N-1);
+ for(i=0; i<4*c2->n_samp; i++)
bpf_speech[i] = bpf_out[i];
/* frame 1 --------------------------------------------------------*/
/* frame 2 --------------------------------------------------------*/
- analyse_one_frame(c2, &model, &bpf_speech[N_SAMP]);
+ analyse_one_frame(c2, &model, &bpf_speech[c2->n_samp]);
/* frame 3 --------------------------------------------------------*/
- analyse_one_frame(c2, &model, &bpf_speech[2*N_SAMP]);
+ analyse_one_frame(c2, &model, &bpf_speech[2*c2->n_samp]);
/* frame 4: - voicing, scalar Wo & E, VQ mel LSPs -----------------*/
- analyse_one_frame(c2, &model, &bpf_speech[3*N_SAMP]);
+ analyse_one_frame(c2, &model, &bpf_speech[3*c2->n_samp]);
pack(bits, &nbit, model.voiced, 1);
Wo_index = encode_log_Wo(model.Wo, 5);
pack_natural_or_gray(bits, &nbit, Wo_index, 5, c2->gray);
aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD_LOW, &model[i], e[i], &snr, 0, 0,
c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
apply_lpc_correction(&model[i]);
- synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
}
#ifdef DUMP
memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8));
for(i=0; i<M; i++) {
- analyse_one_frame(c2, &model, &speech[i*N_SAMP]);
+ analyse_one_frame(c2, &model, &speech[i*c2->n_samp]);
}
int K = 20;
for(i=0; i<M; i++) {
- synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], &HH[i][0]);
+ synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], &HH[i][0]);
}
}
if (c2->mode == CODEC2_MODE_700C) {
/* newamp1, we've already worked out rate L phase */
COMP *H = Aw;
- phase_synth_zero_order(model, &c2->ex_phase, H);
+ phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H);
} else {
/* LPC based phase synthesis */
COMP H[MAX_AMP+1];
sample_phase(model, H, Aw);
- phase_synth_zero_order(model, &c2->ex_phase, H);
+ phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H);
}
PROFILE_SAMPLE_AND_LOG(pf_start, phase_start, " phase_synth");
PROFILE_SAMPLE_AND_LOG(synth_start, pf_start, " postfilter");
- synthesise(c2->fftr_inv_cfg, c2->Sn_, model, c2->Pn, 1);
+ synthesise(c2->n_samp, c2->fftr_inv_cfg, c2->Sn_, model, c2->Pn, 1);
PROFILE_SAMPLE_AND_LOG2(synth_start, " synth");
- ear_protection(c2->Sn_, N_SAMP);
+ ear_protection(c2->Sn_, c2->n_samp);
- for(i=0; i<N_SAMP; i++) {
+ for(i=0; i<c2->n_samp; i++) {
if (c2->Sn_[i] > 32767.0)
speech[i] = 32767;
else if (c2->Sn_[i] < -32767.0)
/* Read input speech */
- for(i=0; i<M_PITCH-N_SAMP; i++)
- c2->Sn[i] = c2->Sn[i+N_SAMP];
- for(i=0; i<N_SAMP; i++)
- c2->Sn[i+M_PITCH-N_SAMP] = speech[i];
+ for(i=0; i<M_PITCH-c2->n_samp; i++)
+ c2->Sn[i] = c2->Sn[i+c2->n_samp];
+ for(i=0; i<c2->n_samp; i++)
+ c2->Sn[i+M_PITCH-c2->n_samp] = speech[i];
PROFILE_SAMPLE(dft_start);
dft_speech(c2->fft_fwd_cfg, Sw, c2->Sn, c2->w);
/* Estimate pitch */
- nlp(c2->nlp,c2->Sn,N_SAMP,P_MIN,P_MAX,&pitch,Sw, c2->W, &c2->prev_Wo_enc);
+ nlp(c2->nlp,c2->Sn,c2->n_samp,P_MIN,P_MAX,&pitch,Sw, c2->W, &c2->prev_Wo_enc);
PROFILE_SAMPLE_AND_LOG(model_start, nlp_start, " nlp");
model->Wo = TWO_PI/pitch;
\*---------------------------------------------------------------------------*/
+C2CONST c2const_create(int Fs) {
+ C2CONST c2const;
+
+ assert((Fs == 8000) || (Fs = 16000));
+ c2const.Fs = Fs;
+ c2const.n_samp = Fs*0.01;
+ return c2const;
+}
+
/*---------------------------------------------------------------------------*\
FUNCTION....: make_analysis_window
\*---------------------------------------------------------------------------*/
-void make_analysis_window(codec2_fft_cfg fft_fwd_cfg, float w[], COMP W[])
+void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], COMP W[])
{
float m;
COMP wshift[FFT_ENC];
\*---------------------------------------------------------------------------*/
-void make_synthesis_window(float Pn[])
+void make_synthesis_window(C2CONST *c2const, float Pn[])
{
int i;
float win;
+ int n_samp = c2const->n_samp;
/* Generate Parzen window in time domain */
win = 0.0;
- for(i=0; i<N_SAMP/2-TW; i++)
+ for(i=0; i<n_samp/2-TW; i++)
Pn[i] = 0.0;
win = 0.0;
- for(i=N_SAMP/2-TW; i<N_SAMP/2+TW; win+=1.0/(2*TW), i++ )
+ for(i=n_samp/2-TW; i<n_samp/2+TW; win+=1.0/(2*TW), i++ )
Pn[i] = win;
- for(i=N_SAMP/2+TW; i<3*N_SAMP/2-TW; i++)
+ for(i=n_samp/2+TW; i<3*n_samp/2-TW; i++)
Pn[i] = 1.0;
win = 1.0;
- for(i=3*N_SAMP/2-TW; i<3*N_SAMP/2+TW; win-=1.0/(2*TW), i++)
+ for(i=3*n_samp/2-TW; i<3*n_samp/2+TW; win-=1.0/(2*TW), i++)
Pn[i] = win;
- for(i=3*N_SAMP/2+TW; i<2*N_SAMP; i++)
+ for(i=3*n_samp/2+TW; i<2*n_samp; i++)
Pn[i] = 0.0;
}
\*---------------------------------------------------------------------------*/
void synthesise(
+ int n_samp,
codec2_fftr_cfg fftr_inv_cfg,
float Sn_[], /* time domain synthesised signal */
MODEL *model, /* ptr to model parameters for this frame */
int shift /* flag used to handle transition frames */
)
{
- int i,l,j,b; /* loop variables */
+ int i,l,j,b; /* loop variables */
COMP Sw_[FFT_DEC/2+1]; /* DFT of synthesised signal */
- float sw_[FFT_DEC]; /* synthesised signal */
+ float sw_[FFT_DEC]; /* synthesised signal */
if (shift) {
/* Update memories */
- for(i=0; i<N_SAMP-1; i++) {
- Sn_[i] = Sn_[i+N_SAMP];
+ for(i=0; i<n_samp-1; i++) {
+ Sn_[i] = Sn_[i+n_samp];
}
- Sn_[N_SAMP-1] = 0.0;
+ Sn_[n_samp-1] = 0.0;
}
for(i=0; i<FFT_DEC/2+1; i++) {
Sw_[i].imag = 0.0;
}
- /*
- Nov 2010 - found that synthesis using time domain cos() functions
- gives better results for synthesis frames greater than 10ms. Inverse
- FFT synthesis using a 512 pt FFT works well for 10ms window. I think
- (but am not sure) that the problem is related to the quantisation of
- the harmonic frequencies to the FFT bin size, e.g. there is a
- 8000/512 Hz step between FFT bins. For some reason this makes
- the speech from longer frame > 10ms sound poor. The effect can also
- be seen when synthesising test signals like single sine waves, some
- sort of amplitude modulation at the frame rate.
-
- Another possibility is using a larger FFT size (1024 or 2048).
- */
-
-#define FFT_SYNTHESIS
-#ifdef FFT_SYNTHESIS
/* Now set up frequency domain synthesised speech */
+
for(l=1; l<=model->L; l++) {
- //for(l=model->L/2; l<=model->L; l++) {
- //for(l=1; l<=model->L/4; l++) {
b = (int)(l*model->Wo*FFT_DEC/TWO_PI + 0.5);
if (b > ((FFT_DEC/2)-1)) {
b = (FFT_DEC/2)-1;
/* Perform inverse DFT */
codec2_fftri(fftr_inv_cfg, Sw_,sw_);
-#else
- /*
- Direct time domain synthesis using the cos() function. Works
- well at 10ms and 20ms frames rates. Note synthesis window is
- still used to handle overlap-add between adjacent frames. This
- could be simplified as we don't need to synthesise where Pn[]
- is zero.
- */
- for(l=1; l<=model->L; l++) {
- for(i=0,j=-N_SAMP+1; i<N_SAMP-1; i++,j++) {
- Sw_[FFT_DEC-N_SAMP+1+i].real += 2.0*model->A[l]*cosf(j*model->Wo*l + model->phi[l]);
- }
- for(i=N_SAMP-1,j=0; i<2*N_SAMP; i++,j++)
- Sw_[j].real += 2.0*model->A[l]*cosf(j*model->Wo*l + model->phi[l]);
- }
-#endif
/* Overlap add to previous samples */
-#ifdef USE_KISS_FFT
-#define FFTI_FACTOR ((float)1.0)
-#else
-#define FFTI_FACTOR ((float32_t)FFT_DEC)
-#endif
- for(i=0; i<N_SAMP-1; i++) {
- Sn_[i] += sw_[FFT_DEC-N_SAMP+1+i]*Pn[i] * FFTI_FACTOR;
+
+ #ifdef USE_KISS_FFT
+ #define FFTI_FACTOR ((float)1.0)
+ #else
+ #define FFTI_FACTOR ((float32_t)FFT_DEC)
+ #endif
+
+ for(i=0; i<n_samp-1; i++) {
+ Sn_[i] += sw_[FFT_DEC-n_samp+1+i]*Pn[i] * FFTI_FACTOR;
}
if (shift)
- for(i=N_SAMP-1,j=0; i<2*N_SAMP; i++,j++)
+ for(i=n_samp-1,j=0; i<2*n_samp; i++,j++)
Sn_[i] = sw_[j]*Pn[i] * FFTI_FACTOR;
else
- for(i=N_SAMP-1,j=0; i<2*N_SAMP; i++,j++)
+ for(i=n_samp-1,j=0; i<2*n_samp; i++,j++)
Sn_[i] += sw_[j]*Pn[i] * FFTI_FACTOR;
}
+/* todo: this should probably be in some states rather than a static */
static unsigned long next = 1;
int codec2_rand(void) {