{
FILE *fout = NULL; /* output speech file */
FILE *fin; /* input speech file */
- short buf[N]; /* input/output buffer */
- float buf_float[N];
- float buf_float_bpf[N];
+ short buf[N_SAMP]; /* input/output buffer */
+ float buf_float[N_SAMP];
+ float buf_float_bpf[N_SAMP];
float Sn[M]; /* float input speech samples */
- float Sn_pre[N]; /* pre-emphasised input speech samples */
+ float Sn_pre[N_SAMP]; /* pre-emphasised input speech samples */
COMP Sw[FFT_ENC]; /* DFT of Sn[] */
kiss_fft_cfg fft_fwd_cfg;
- kiss_fftr_cfg fftr_fwd_cfg;
kiss_fft_cfg fft_inv_cfg;
float w[M]; /* time domain hamming window */
COMP W[FFT_ENC]; /* DFT of w[] */
MODEL model;
- float Pn[2*N]; /* trapezoidal synthesis window */
- float Sn_[2*N]; /* synthesised speech */
+ float Pn[2*N_SAMP]; /* trapezoidal synthesis window */
+ float Sn_[2*N_SAMP]; /* synthesised speech */
int i,m; /* loop variable */
int frames;
float prev_Wo, prev__Wo, prev_uq_Wo;
float gain = 1.0;
int bpf_en = 0;
int bpfb_en = 0;
- float bpf_buf[BPF_N+N];
+ float bpf_buf[BPF_N+N_SAMP];
float lspmelvq_mse = 0.0;
int amread, Woread;
FILE *fam, *fWo;
Sn[i] = 1.0;
Sn_pre[i] = 1.0;
}
- for(i=0; i<2*N; i++)
+ for(i=0; i<2*N_SAMP; i++)
Sn_[i] = 0;
prev_uq_Wo = prev_Wo = prev__Wo = TWO_PI/P_MAX;
/* Initialise ------------------------------------------------------------*/
fft_fwd_cfg = kiss_fft_alloc(FFT_ENC, 0, NULL, NULL); /* fwd FFT,used in several places */
- fftr_fwd_cfg = kiss_fftr_alloc(FFT_ENC, 0, NULL, NULL); /* fwd FFT,used in several places */
fft_inv_cfg = kiss_fft_alloc(FFT_DEC, 1, NULL, NULL); /* inverse FFT, used just for synth */
make_analysis_window(fft_fwd_cfg, w, W);
make_synthesis_window(Pn);
frames = 0;
sum_snr = 0;
- while(fread(buf,sizeof(short),N,fin)) {
+ while(fread(buf,sizeof(short),N_SAMP,fin)) {
frames++;
- for(i=0; i<N; i++)
+ for(i=0; i<N_SAMP; i++)
buf_float[i] = buf[i];
/* optionally filter input speech */
if (prede) {
- pre_emp(Sn_pre, buf_float, &pre_mem, N);
- for(i=0; i<N; i++)
+ pre_emp(Sn_pre, buf_float, &pre_mem, N_SAMP);
+ for(i=0; i<N_SAMP; i++)
buf_float[i] = Sn_pre[i];
}
/* BPF speech */
for(i=0; i<BPF_N; i++)
- bpf_buf[i] = bpf_buf[N+i];
- for(i=0; i<N; i++)
+ bpf_buf[i] = bpf_buf[N_SAMP+i];
+ for(i=0; i<N_SAMP; i++)
bpf_buf[BPF_N+i] = buf_float[i];
if (bpfb_en)
- inverse_filter(&bpf_buf[BPF_N], bpfb, N, buf_float, BPF_N);
+ inverse_filter(&bpf_buf[BPF_N], bpfb, N_SAMP, buf_float, BPF_N);
else
- inverse_filter(&bpf_buf[BPF_N], bpf, N, buf_float, BPF_N);
+ inverse_filter(&bpf_buf[BPF_N], bpf, N_SAMP, buf_float, BPF_N);
}
/* shift buffer of input samples, and insert new samples */
- for(i=0; i<M-N; i++) {
- Sn[i] = Sn[i+N];
+ for(i=0; i<M-N_SAMP; i++) {
+ Sn[i] = Sn[i+N_SAMP];
}
- for(i=0; i<N; i++) {
- Sn[i+M-N] = buf_float[i];
+ for(i=0; i<N_SAMP; i++) {
+ Sn[i+M-N_SAMP] = buf_float[i];
}
/*------------------------------------------------------------*\
\*------------------------------------------------------------*/
- nlp(nlp_states,Sn,N,P_MIN,P_MAX,&pitch,Sw,W,&prev_uq_Wo);
+ nlp(nlp_states,Sn,N_SAMP,P_MIN,P_MAX,&pitch,Sw,W,&prev_uq_Wo);
model.Wo = TWO_PI/pitch;
dft_speech(fft_fwd_cfg, Sw, Sn, w);
for(i=0; i<decimate; i++) {
if (lpc_model) {
lsp_to_lpc(&lsps_dec[i][0], &ak_dec[i][0], order);
- aks_to_M2(fftr_fwd_cfg, &ak_dec[i][0], order, &model_dec[i], e_dec[i],
+ aks_to_M2(fft_fwd_cfg, &ak_dec[i][0], order, &model_dec[i], e_dec[i],
&snr, 0, simlpcpf, lpcpf, 1, LPCPF_BETA, LPCPF_GAMMA, Aw);
apply_lpc_correction(&model_dec[i]);
sum_snr += snr;
if (postfilt)
postfilter(&model_dec[i], &bg_est);
synth_one_frame(fft_inv_cfg, buf, &model_dec[i], Sn_, Pn, prede, &de_mem, gain);
- if (fout != NULL) fwrite(buf,sizeof(short),N,fout);
+ if (fout != NULL) fwrite(buf,sizeof(short),N_SAMP,fout);
}
/* update memories for next frame ----------------------------*/
synthesise(fft_inv_cfg, Sn_, model, Pn, 1);
if (prede)
- de_emp(Sn_, Sn_, de_mem, N);
+ de_emp(Sn_, Sn_, de_mem, N_SAMP);
- for(i=0; i<N; i++) {
+ for(i=0; i<N_SAMP; i++) {
Sn_[i] *= gain;
if (Sn_[i] > 32767.0)
buf[i] = 32767;
for(i=0; i<M; i++)
c2->Sn[i] = 1.0;
c2->hpf_states[0] = c2->hpf_states[1] = 0.0;
- for(i=0; i<2*N; i++)
+ for(i=0; i<2*N_SAMP; i++)
c2->Sn_[i] = 0;
c2->fft_fwd_cfg = kiss_fft_alloc(FFT_ENC, 0, NULL, NULL);
c2->fftr_fwd_cfg = kiss_fftr_alloc(FFT_ENC, 0, NULL, NULL);
c2->smoothing = 0;
- c2->bpf_buf = (float*)malloc(sizeof(float)*(BPF_N+4*N));
+ c2->bpf_buf = (float*)malloc(sizeof(float)*(BPF_N+4*N_SAMP));
assert(c2->bpf_buf != NULL);
- for(i=0; i<BPF_N+4*N; i++)
+ for(i=0; i<BPF_N+4*N_SAMP; i++)
c2->bpf_buf[i] = 0.0;
c2->softdec = NULL;
/* second 10ms analysis frame */
- analyse_one_frame(c2, &model, &speech[N]);
+ analyse_one_frame(c2, &model, &speech[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*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
}
/* update memories for next frame ----------------------------*/
/* second 10ms analysis frame */
- analyse_one_frame(c2, &model, &speech[N]);
+ analyse_one_frame(c2, &model, &speech[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*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
}
/* update memories for next frame ----------------------------*/
/* frame 2: - voicing, scalar Wo & E -------------------------------*/
- analyse_one_frame(c2, &model, &speech[N]);
+ analyse_one_frame(c2, &model, &speech[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]);
+ analyse_one_frame(c2, &model, &speech[2*N_SAMP]);
pack(bits, &nbit, model.voiced, 1);
/* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/
- analyse_one_frame(c2, &model, &speech[3*N]);
+ analyse_one_frame(c2, &model, &speech[3*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*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
}
/* update memories for next frame ----------------------------*/
/* frame 2: - voicing, joint Wo & E -------------------------------*/
- analyse_one_frame(c2, &model, &speech[N]);
+ analyse_one_frame(c2, &model, &speech[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]);
+ analyse_one_frame(c2, &model, &speech[2*N_SAMP]);
pack(bits, &nbit, model.voiced, 1);
/* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/
- analyse_one_frame(c2, &model, &speech[3*N]);
+ analyse_one_frame(c2, &model, &speech[3*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*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
}
/* update memories for next frame ----------------------------*/
/* frame 2: - voicing ---------------------------------------------*/
- analyse_one_frame(c2, &model, &speech[N]);
+ analyse_one_frame(c2, &model, &speech[N_SAMP]);
pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray);
/* frame 3: - voicing ---------------------------------------------*/
- analyse_one_frame(c2, &model, &speech[2*N]);
+ analyse_one_frame(c2, &model, &speech[2*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]);
+ analyse_one_frame(c2, &model, &speech[3*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*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[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]);
+ analyse_one_frame(c2, &model, &speech[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]);
+ analyse_one_frame(c2, &model, &speech[2*N_SAMP]);
pack(bits, &nbit, model.voiced, 1);
/* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/
- analyse_one_frame(c2, &model, &speech[3*N]);
+ analyse_one_frame(c2, &model, &speech[3*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*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[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];
- short bpf_speech[4*N];
+ float bpf_out[4*N_SAMP];
+ short bpf_speech[4*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+i];
- for(i=0; i<4*N; i++)
+ c2->bpf_buf[i] = c2->bpf_buf[4*N_SAMP+i];
+ for(i=0; i<4*N_SAMP; i++)
c2->bpf_buf[BPF_N+i] = speech[i];
- inverse_filter(&c2->bpf_buf[BPF_N], bpf, 4*N, bpf_out, BPF_N-1);
- for(i=0; i<4*N; 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++)
bpf_speech[i] = bpf_out[i];
/* frame 1 --------------------------------------------------------*/
/* frame 2 --------------------------------------------------------*/
- analyse_one_frame(c2, &model, &bpf_speech[N]);
+ analyse_one_frame(c2, &model, &bpf_speech[N_SAMP]);
/* frame 3 --------------------------------------------------------*/
- analyse_one_frame(c2, &model, &bpf_speech[2*N]);
+ analyse_one_frame(c2, &model, &bpf_speech[2*N_SAMP]);
/* frame 4: - voicing, scalar Wo & E, scalar LSPs -----------------*/
- analyse_one_frame(c2, &model, &bpf_speech[3*N]);
+ analyse_one_frame(c2, &model, &bpf_speech[3*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*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[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];
- short bpf_speech[4*N];
+ float bpf_out[4*N_SAMP];
+ short bpf_speech[4*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+i];
- for(i=0; i<4*N; i++)
+ c2->bpf_buf[i] = c2->bpf_buf[4*N_SAMP+i];
+ for(i=0; i<4*N_SAMP; i++)
c2->bpf_buf[BPF_N+i] = speech[i];
- inverse_filter(&c2->bpf_buf[BPF_N], bpfb, 4*N, bpf_out, BPF_N-1);
- for(i=0; i<4*N; 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++)
bpf_speech[i] = bpf_out[i];
/* frame 1 --------------------------------------------------------*/
/* frame 2 --------------------------------------------------------*/
- analyse_one_frame(c2, &model, &bpf_speech[N]);
+ analyse_one_frame(c2, &model, &bpf_speech[N_SAMP]);
/* frame 3 --------------------------------------------------------*/
- analyse_one_frame(c2, &model, &bpf_speech[2*N]);
+ analyse_one_frame(c2, &model, &bpf_speech[2*N_SAMP]);
/* frame 4: - voicing, scalar Wo & E, VQ mel LSPs -----------------*/
- analyse_one_frame(c2, &model, &bpf_speech[3*N]);
+ analyse_one_frame(c2, &model, &bpf_speech[3*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*i], &model[i], Aw);
+ synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw);
}
#ifdef DUMP
PROFILE_SAMPLE_AND_LOG2(synth_start, " synth");
- ear_protection(c2->Sn_, N);
+ ear_protection(c2->Sn_, N_SAMP);
- for(i=0; i<N; i++) {
+ for(i=0; i<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-N; i++)
- c2->Sn[i] = c2->Sn[i+N];
- for(i=0; i<N; i++)
- c2->Sn[i+M-N] = speech[i];
+ for(i=0; i<M-N_SAMP; i++)
+ c2->Sn[i] = c2->Sn[i+N_SAMP];
+ for(i=0; i<N_SAMP; i++)
+ c2->Sn[i+M-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,P_MIN,P_MAX,&pitch,Sw, c2->W, &c2->prev_Wo_enc);
+ nlp(c2->nlp,c2->Sn,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;
kiss_fftr_cfg fftr_fwd_cfg; /* forward real FFT config */
float w[M]; /* time domain hamming window */
COMP W[FFT_ENC]; /* DFT of w[] */
- float Pn[2*N]; /* trapezoidal synthesis window */
+ float Pn[2*N_SAMP]; /* trapezoidal synthesis window */
float *bpf_buf; /* buffer for band pass filter */
float Sn[M]; /* input speech */
float hpf_states[2]; /* high pass filter states */
int gray; /* non-zero for gray encoding */
kiss_fft_cfg fft_inv_cfg; /* inverse FFT config */
- float Sn_[2*N]; /* synthesised output speech */
+ float Sn_[2*N_SAMP]; /* synthesised output speech */
float ex_phase; /* excitation model phase track */
float bg_est; /* background noise estimate for post filter */
float prev_Wo_enc; /* previous frame's pitch estimate */
/* General defines */
-#define N 80 /* number of samples per frame */
+#define N_SAMP 80 /* number of samples per frame */
#define MAX_AMP 80 /* maximum number of harmonics */
+#ifndef PI
#define PI 3.141592654 /* mathematical constant */
+#endif
#define TWO_PI 6.283185307 /* mathematical constant */
#define FS 8000 /* sample rate in Hz */
#define MAX_STR 256 /* maximum string size */
assert(NC == FDMDV_NC_MAX); /* check public and private #defines match */
assert(Nc <= NC);
- assert(FDMDV_NOM_SAMPLES_PER_FRAME == M);
- assert(FDMDV_MAX_SAMPLES_PER_FRAME == (M+M/P));
+ assert(FDMDV_NOM_SAMPLES_PER_FRAME == M_FAC);
+ assert(FDMDV_MAX_SAMPLES_PER_FRAME == (M_FAC+M_FAC/P));
f = (struct FDMDV*)malloc(sizeof(struct FDMDV));
if (f == NULL)
f->pilot_baseband1[i].imag = f->pilot_baseband2[i].imag = 0.0;
}
f->pilot_lut_index = 0;
- f->prev_pilot_lut_index = 3*M;
+ f->prev_pilot_lut_index = 3*M_FAC;
- for(i=0; i<NRXDEC-1+M; i++) {
+ for(i=0; i<NRXDEC-1+M_FAC; i++) {
f->rxdec_lpf_mem[i].real = 0.0;
f->rxdec_lpf_mem[i].imag = 0.0;
}
f->foff_phase_rect.real = 1.0;
f->foff_phase_rect.imag = 0.0;
- for(i=0; i<NFILTER+M; i++) {
+ for(i=0; i<NFILTER+M_FAC; i++) {
f->rx_fdm_mem[i].real = 0.0;
f->rx_fdm_mem[i].imag = 0.0;
}
AUTHOR......: David Rowe
DATE CREATED: 17/4/2012
- Given Nc*NB bits construct M samples (1 symbol) of Nc+1 filtered
+ Given Nc*NB bits construct M_FAC samples (1 symbol) of Nc+1 filtered
symbols streams.
\*---------------------------------------------------------------------------*/
-void tx_filter(COMP tx_baseband[NC+1][M], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM])
+void tx_filter(COMP tx_baseband[NC+1][M_FAC], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM])
{
int c;
int i,j,k;
tx_filter_memory[c][NSYM-1] = cmult(tx_symbols[c], gain);
/*
- tx filter each symbol, generate M filtered output samples for each symbol.
+ tx filter each symbol, generate M_FAC filtered output samples for each symbol.
Efficient polyphase filter techniques used as tx_filter_memory is sparse
*/
- for(i=0; i<M; i++) {
+ for(i=0; i<M_FAC; i++) {
for(c=0; c<Nc+1; c++) {
/* filter real sample of symbol for carrier c */
acc = 0.0;
- for(j=0,k=M-i-1; j<NSYM; j++,k+=M)
- acc += M * tx_filter_memory[c][j].real * gt_alpha5_root[k];
+ for(j=0,k=M_FAC-i-1; j<NSYM; j++,k+=M_FAC)
+ acc += M_FAC * tx_filter_memory[c][j].real * gt_alpha5_root[k];
tx_baseband[c][i].real = acc;
/* filter imag sample of symbol for carrier c */
acc = 0.0;
- for(j=0,k=M-i-1; j<NSYM; j++,k+=M)
- acc += M * tx_filter_memory[c][j].imag * gt_alpha5_root[k];
+ for(j=0,k=M_FAC-i-1; j<NSYM; j++,k+=M_FAC)
+ acc += M_FAC * tx_filter_memory[c][j].imag * gt_alpha5_root[k];
tx_baseband[c][i].imag = acc;
}
AUTHOR......: David Rowe
DATE CREATED: 13 August 2014
- Given Nc symbols construct M samples (1 symbol) of Nc+1 filtered
+ Given Nc symbols construct M_FAC samples (1 symbol) of Nc+1 filtered
and upconverted symbols.
\*---------------------------------------------------------------------------*/
gain.real = sqrtf(2.0)/2.0;
gain.imag = 0.0;
- for(i=0; i<M; i++) {
+ for(i=0; i<M_FAC; i++) {
tx_fdm[i].real = 0.0;
tx_fdm[i].imag = 0.0;
}
tx_filter_memory[c][NSYM-1] = cmult(tx_symbols[c], gain);
/*
- tx filter each symbol, generate M filtered output samples for
+ tx filter each symbol, generate M_FAC filtered output samples for
each symbol, which we then freq shift and sum with other
carriers. Efficient polyphase filter techniques used as
tx_filter_memory is sparse
*/
for(c=0; c<Nc+1; c++) {
- for(i=0; i<M; i++) {
+ for(i=0; i<M_FAC; i++) {
/* filter real sample of symbol for carrier c */
acc = 0.0;
- for(j=0,k=M-i-1; j<NSYM; j++,k+=M)
- acc += M * tx_filter_memory[c][j].real * gt_alpha5_root[k];
+ for(j=0,k=M_FAC-i-1; j<NSYM; j++,k+=M_FAC)
+ acc += M_FAC * tx_filter_memory[c][j].real * gt_alpha5_root[k];
tx_baseband.real = acc;
/* filter imag sample of symbol for carrier c */
acc = 0.0;
- for(j=0,k=M-i-1; j<NSYM; j++,k+=M)
- acc += M * tx_filter_memory[c][j].imag * gt_alpha5_root[k];
+ for(j=0,k=M_FAC-i-1; j<NSYM; j++,k+=M_FAC)
+ acc += M_FAC * tx_filter_memory[c][j].imag * gt_alpha5_root[k];
tx_baseband.imag = acc;
/* freq shift and sum */
/* shift whole thing up to carrier freq */
- for (i=0; i<M; i++) {
+ for (i=0; i<M_FAC; i++) {
*fbb_phase = cmult(*fbb_phase, fbb_rect);
tx_fdm[i] = cmult(tx_fdm[i], *fbb_phase);
}
shifting for the purpose of testing easier
*/
- for (i=0; i<M; i++)
+ for (i=0; i<M_FAC; i++)
tx_fdm[i] = cmult(two, tx_fdm[i]);
/* normalise digital oscillators as the magnitude can drift over time */
\*---------------------------------------------------------------------------*/
-void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq[],
+void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M_FAC], COMP phase_tx[], COMP freq[],
COMP *fbb_phase, COMP fbb_rect)
{
int i,c;
COMP two = {2.0, 0.0};
float mag;
- for(i=0; i<M; i++) {
+ for(i=0; i<M_FAC; i++) {
tx_fdm[i].real = 0.0;
tx_fdm[i].imag = 0.0;
}
for (c=0; c<=Nc; c++)
- for (i=0; i<M; i++) {
+ for (i=0; i<M_FAC; i++) {
phase_tx[c] = cmult(phase_tx[c], freq[c]);
tx_fdm[i] = cadd(tx_fdm[i], cmult(tx_baseband[c][i], phase_tx[c]));
}
/* shift whole thing up to carrier freq */
- for (i=0; i<M; i++) {
+ for (i=0; i<M_FAC; i++) {
*fbb_phase = cmult(*fbb_phase, fbb_rect);
tx_fdm[i] = cmult(tx_fdm[i], *fbb_phase);
}
shifting for the purpose of testing easier
*/
- for (i=0; i<M; i++)
+ for (i=0; i<M_FAC; i++)
tx_fdm[i] = cmult(two, tx_fdm[i]);
/* normalise digital oscilators as the magnitude can drift over time */
AUTHOR......: David Rowe
DATE CREATED: 19/4/2012
- Generate M samples of DBPSK pilot signal for Freq offset estimation.
+ Generate M_FAC samples of DBPSK pilot signal for Freq offset estimation.
\*---------------------------------------------------------------------------*/
float *filter_mem, COMP *phase, COMP *freq)
{
int i,j,k;
- float tx_baseband[M];
+ float tx_baseband[M_FAC];
/* +1 -1 +1 -1 DBPSK sync carrier, once filtered becomes (roughly)
two spectral lines at +/- RS/2 */
else
*bit = 1;
- /* filter DPSK symbol to create M baseband samples */
+ /* filter DPSK symbol to create M_FAC baseband samples */
filter_mem[NFILTER-1] = (sqrtf(2)/2) * *symbol;
- for(i=0; i<M; i++) {
+ for(i=0; i<M_FAC; i++) {
tx_baseband[i] = 0.0;
- for(j=M-1,k=M-i-1; j<NFILTER; j+=M,k+=M)
- tx_baseband[i] += M * filter_mem[j] * gt_alpha5_root[k];
+ for(j=M_FAC-1,k=M_FAC-i-1; j<NFILTER; j+=M_FAC,k+=M_FAC)
+ tx_baseband[i] += M_FAC * filter_mem[j] * gt_alpha5_root[k];
}
/* shift memory, inserting zeros at end */
- for(i=0; i<NFILTER-M; i++)
- filter_mem[i] = filter_mem[i+M];
+ for(i=0; i<NFILTER-M_FAC; i++)
+ filter_mem[i] = filter_mem[i+M_FAC];
- for(i=NFILTER-M; i<NFILTER; i++)
+ for(i=NFILTER-M_FAC; i<NFILTER; i++)
filter_mem[i] = 0.0;
/* upconvert */
- for(i=0; i<M; i++) {
+ for(i=0; i<M_FAC; i++) {
*phase = cmult(*phase, *freq);
pilot_fdm[i].real = sqrtf(2)*2*tx_baseband[i] * phase->real;
pilot_fdm[i].imag = sqrtf(2)*2*tx_baseband[i] * phase->imag;
float pilot_symbol = sqrtf(2.0);
COMP pilot_phase = {1.0, 0.0};
float pilot_filter_mem[NFILTER];
- COMP pilot[M];
+ COMP pilot[M_FAC];
int i,f;
for(i=0; i<NFILTER; i++)
for(f=0; f<8; f++) {
generate_pilot_fdm(pilot, &pilot_rx_bit, &pilot_symbol, pilot_filter_mem, &pilot_phase, pilot_freq);
if (f >= 4)
- memcpy(&pilot_lut[M*(f-4)], pilot, M*sizeof(COMP));
+ memcpy(&pilot_lut[M_FAC*(f-4)], pilot, M_FAC*sizeof(COMP));
}
// create complex conjugate since we need this and only this later on
- for (f=0;f<4*M;f++)
+ for (f=0;f<4*M_FAC;f++)
{
pilot_lut[f] = cconj(pilot_lut[f]);
}
#ifndef ARM_MATH_CM4
int j;
#endif
- COMP pilot[M+M/P];
- COMP prev_pilot[M+M/P];
+ COMP pilot[M_FAC+M_FAC/P];
+ COMP prev_pilot[M_FAC+M_FAC/P];
float foff, foff1, foff2;
float max1, max2;
- assert(nin <= M+M/P);
+ assert(nin <= M_FAC+M_FAC/P);
/* get pilot samples used for correlation/down conversion of rx signal */
for (i=0; i<nin; i++) {
pilot[i] = f->pilot_lut[f->pilot_lut_index];
f->pilot_lut_index++;
- if (f->pilot_lut_index >= 4*M)
+ if (f->pilot_lut_index >= 4*M_FAC)
f->pilot_lut_index = 0;
prev_pilot[i] = f->pilot_lut[f->prev_pilot_lut_index];
f->prev_pilot_lut_index++;
- if (f->prev_pilot_lut_index >= 4*M)
+ if (f->prev_pilot_lut_index >= 4*M_FAC)
f->prev_pilot_lut_index = 0;
}
/*
- Down convert latest M samples of pilot by multiplying by ideal
+ Down convert latest M_FAC samples of pilot by multiplying by ideal
BPSK pilot signal we have generated locally. The peak of the
resulting signal is sensitive to the time shift between the
received and local version of the pilot, so we do it twice at
\*---------------------------------------------------------------------------*/
-void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin)
+void fdm_downconvert(COMP rx_baseband[NC+1][M_FAC+M_FAC/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin)
{
int i,c;
float mag;
/* maximum number of input samples to demod */
- assert(nin <= (M+M/P));
+ assert(nin <= (M_FAC+M_FAC/P));
/* downconvert */
DATE CREATED: 22/4/2012
Receive filter each baseband signal at oversample rate P. Filtering at
- rate P lowers CPU compared to rate M.
+ rate P lowers CPU compared to rate M_FAC.
Depending on the number of input samples to the demod nin, we
produce P-1, P (usually), or P+1 filtered samples at rate P. nin is
\*---------------------------------------------------------------------------*/
-void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M+M/P], COMP rx_filter_memory[NC+1][NFILTER], int nin)
+void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M_FAC+M_FAC/P], COMP rx_filter_memory[NC+1][NFILTER], int nin)
{
int c, i,j,k,l;
- int n=M/P;
+ int n=M_FAC/P;
/* rx filter each symbol, generate P filtered output samples for
- each symbol. Note we keep filter memory at rate M, it's just
+ each symbol. Note we keep filter memory at rate M_FAC, it's just
the filter output at rate P */
for(i=0, j=0; i<nin; i+=n,j++) {
void rxdec_filter(COMP rx_fdm_filter[], COMP rx_fdm[], COMP rxdec_lpf_mem[], int nin) {
int i,j,k;
- for(i=0; i<NRXDEC-1+M-nin; i++)
+ for(i=0; i<NRXDEC-1+M_FAC-nin; i++)
rxdec_lpf_mem[i] = rxdec_lpf_mem[i+nin];
- for(i=0, j=NRXDEC-1+M-nin; i<nin; i++,j++)
+ for(i=0, j=NRXDEC-1+M_FAC-nin; i<nin; i++,j++)
rxdec_lpf_mem[j] = rx_fdm[i];
for(i=0; i<nin; i++) {
COMP rx_fdm_mem[], COMP phase_rx[], COMP freq[],
float freq_pol[], int nin, int dec_rate)
{
- int i,k,c,st,N;
+ int i,k,c,st,Nval;
float windback_phase, mag;
COMP windback_phase_rect;
- COMP rx_baseband[NFILTER+M];
+ COMP rx_baseband[NFILTER+M_FAC];
COMP f_rect;
//PROFILE_VAR(windback_start, downconvert_start, filter_start);
/* update memory of rx_fdm */
#if 0
- for(i=0; i<NFILTER+M-nin; i++)
+ for(i=0; i<NFILTER+M_FAC-nin; i++)
rx_fdm_mem[i] = rx_fdm_mem[i+nin];
- for(i=NFILTER+M-nin, k=0; i<NFILTER+M; i++, k++)
+ for(i=NFILTER+M_FAC-nin, k=0; i<NFILTER+M_FAC; i++, k++)
rx_fdm_mem[i] = rx_fdm[k];
#else
// this gives only 40uS gain on STM32 but now that we have, we keep it
- memmove(&rx_fdm_mem[0],&rx_fdm_mem[nin],(NFILTER+M-nin)*sizeof(COMP));
- memcpy(&rx_fdm_mem[NFILTER+M-nin],&rx_fdm[0],nin*sizeof(COMP));
+ memmove(&rx_fdm_mem[0],&rx_fdm_mem[nin],(NFILTER+M_FAC-nin)*sizeof(COMP));
+ memcpy(&rx_fdm_mem[NFILTER+M_FAC-nin],&rx_fdm[0],nin*sizeof(COMP));
#endif
for(c=0; c<Nc+1; c++) {
/* down convert all samples in buffer */
- st = NFILTER+M-1; /* end of buffer */
+ st = NFILTER+M_FAC-1; /* end of buffer */
st -= nin-1; /* first new sample */
st -= NFILTER; /* first sample used in filtering */
for(i=0; i<dec_rate-1; i++)
f_rect = cmult(f_rect,freq[c]);
- for(i=st; i<NFILTER+M; i+=dec_rate) {
+ for(i=st; i<NFILTER+M_FAC; i+=dec_rate) {
phase_rx[c] = cmult(phase_rx[c], f_rect);
rx_baseband[i] = cmult(rx_fdm_mem[i],cconj(phase_rx[c]));
}
/* now we can filter this carrier's P symbols */
- N=M/P;
- for(i=0, k=0; i<nin; i+=N, k++) {
+ Nval=M_FAC/P;
+ for(i=0, k=0; i<nin; i+=Nval, k++) {
#ifdef ORIG
rx_filt[c][k].real = 0.0; rx_filt[c][k].imag = 0.0;
The input signal is complex to support single sided frequency shifting
before the demod input (e.g. fdmdv2 click to tune feature).
- The number of input samples nin will normally be M ==
+ The number of input samples nin will normally be M_FAC ==
FDMDV_SAMPLES_PER_FRAME. However to adjust for differences in
- transmit and receive sample clocks nin will occasionally be M-M/P,
- or M+M/P.
+ transmit and receive sample clocks nin will occasionally be M_FAC-M_FAC/P,
+ or M_FAC+M_FAC/P.
\*---------------------------------------------------------------------------*/
int *reliable_sync_bit, COMP rx_fdm[], int *nin)
{
float foff_coarse, foff_fine;
- COMP rx_fdm_fcorr[M+M/P];
- COMP rx_fdm_filter[M+M/P];
- COMP rx_fdm_bb[M+M/P];
+ COMP rx_fdm_fcorr[M_FAC+M_FAC/P];
+ COMP rx_fdm_filter[M_FAC+M_FAC/P];
+ COMP rx_fdm_bb[M_FAC+M_FAC/P];
COMP rx_filt[NC+1][P+1];
COMP rx_symbols[NC+1];
float env[NT*P];
rxdec_filter(rx_fdm_filter, rx_fdm_fcorr, fdmdv->rxdec_lpf_mem, *nin);
down_convert_and_rx_filter(rx_filt, fdmdv->Nc, rx_fdm_filter, fdmdv->rx_fdm_mem, fdmdv->phase_rx, fdmdv->freq,
- fdmdv->freq_pol, *nin, M/Q);
+ fdmdv->freq_pol, *nin, M_FAC/Q);
PROFILE_SAMPLE_AND_LOG(rx_est_timing_start, down_convert_and_rx_filter_start, " down_convert_and_rx_filter");
- fdmdv->rx_timing = rx_est_timing(rx_symbols, fdmdv->Nc, rx_filt, fdmdv->rx_filter_mem_timing, env, *nin, M);
+ fdmdv->rx_timing = rx_est_timing(rx_symbols, fdmdv->Nc, rx_filt, fdmdv->rx_filter_mem_timing, env, *nin, M_FAC);
PROFILE_SAMPLE_AND_LOG(qpsk_to_bits_start, rx_est_timing_start, " rx_est_timing");
/* Adjust number of input samples to keep timing within bounds */
- *nin = M;
+ *nin = M_FAC;
- if (fdmdv->rx_timing > 2*M/P)
- *nin += M/P;
+ if (fdmdv->rx_timing > 2*M_FAC/P)
+ *nin += M_FAC/P;
if (fdmdv->rx_timing < 0)
- *nin -= M/P;
+ *nin -= M_FAC/P;
foff_fine = qpsk_to_bits(rx_bits, &sync_bit, fdmdv->Nc, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols,
fdmdv->old_qpsk_mapping);
#define NC 20 /* max number of data carriers (plus one pilot in the centre) */
#define NB 2 /* Bits/symbol for QPSK modulation */
#define RB (NC*RS*NB) /* bit rate */
-#define M (FS/RS) /* oversampling factor */
+#define M_FAC (FS/RS) /* oversampling factor */
#define NSYM 6 /* number of symbols to filter over */
-#define NFILTER (NSYM*M) /* size of tx/rx filters at sample rate M */
+#define NFILTER (NSYM*M_FAC) /* size of tx/rx filters at sample rate M */
#define FSEP 75 /* Default separation between carriers (Hz) */
#define NT 5 /* number of symbols we estimate timing over */
#define P 4 /* oversample factor used for initial rx symbol filtering output */
-#define Q (M/4) /* oversample factor used for initial rx symbol filtering input */
+#define Q (M_FAC/4) /* oversample factor used for initial rx symbol filtering input */
#define NRXDEC 31 /* number of taps in the rx decimation filter */
-#define NPILOT_LUT (4*M) /* number of pilot look up table samples */
+#define NPILOT_LUT (4*M_FAC) /* number of pilot look up table samples */
#define NPILOTCOEFF 30 /* number of FIR filter coeffs in LP filter */
-#define NPILOTBASEBAND (NPILOTCOEFF+M+M/P) /* number of pilot baseband samples reqd for pilot LPF */
-#define NPILOTLPF (4*M) /* number of samples we DFT pilot over, pilot est window */
+#define NPILOTBASEBAND (NPILOTCOEFF+M_FAC+M_FAC/P) /* number of pilot baseband samples reqd for pilot LPF */
+#define NPILOTLPF (4*M_FAC) /* number of samples we DFT pilot over, pilot est window */
#define MPILOTFFT 256
#define NSYNC_MEM 6
/* Demodulator */
- COMP rxdec_lpf_mem[NRXDEC-1+M];
- COMP rx_fdm_mem[NFILTER+M];
+ COMP rxdec_lpf_mem[NRXDEC-1+M_FAC];
+ COMP rx_fdm_mem[NFILTER+M_FAC];
COMP phase_rx[NC+1];
COMP rx_filter_mem_timing[NC+1][NT*P];
float rx_timing;
\*---------------------------------------------------------------------------*/
void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit, int old_qpsk_mapping);
-void tx_filter(COMP tx_baseband[NC+1][M], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM]);
-void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq_tx[],
+void tx_filter(COMP tx_baseband[NC+1][M_FAC], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM]);
+void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M_FAC], COMP phase_tx[], COMP freq_tx[],
COMP *fbb_phase, COMP fbb_rect);
void tx_filter_and_upconvert(COMP tx_fdm[], int Nc, COMP tx_symbols[],
COMP tx_filter_memory[NC+1][NSYM],
void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq);
float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin, int do_fft);
void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], kiss_fft_cfg fft_pilot_cfg, COMP S[], int nin, int do_fft);
-void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin);
+void fdm_downconvert(COMP rx_baseband[NC+1][M_FAC+M_FAC/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin);
void rxdec_filter(COMP rx_fdm_filter[], COMP rx_fdm[], COMP rxdec_lpf_mem[], int nin);
-void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M+M/P], COMP rx_filter_memory[NC+1][NFILTER], int nin);
+void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M_FAC+M_FAC/P], COMP rx_filter_memory[NC+1][NFILTER], int nin);
void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[],
COMP rx_fdm_mem[], COMP phase_rx[], COMP freq[],
float freq_pol[], int nin, int dec_rate);
As we don't transmit the pulse position for this model, we need to
synthesise it. Now the excitation pulses occur at a rate of Wo.
- This means the phase of the first harmonic advances by N samples
- over a synthesis frame of N samples. For example if Wo is pi/20
- (200 Hz), then over a 10ms frame (N=80 samples), the phase of the
+ This means the phase of the first harmonic advances by N_SAMP samples
+ over a synthesis frame of N_SAMP samples. For example if Wo is pi/20
+ (200 Hz), then over a 10ms frame (N_SAMP=80 samples), the phase of the
first harmonic would advance (pi/20)*80 = 4*pi or two complete
cycles.
We generate the excitation phase of the fundamental (first
harmonic):
- arg[E[1]] = Wo*N;
+ arg[E[1]] = Wo*N_SAMP;
We then relate the phase of the m-th excitation harmonic to the
phase of the fundamental as:
I found that using just this frame's Wo improved quality for UV
sounds compared to interpolating two frames Wo like this:
- ex_phase[0] += (*prev_Wo+model->Wo)*N/2;
+ ex_phase[0] += (*prev_Wo+model->Wo)*N_SAMP/2;
*/
- ex_phase[0] += (model->Wo)*N;
+ ex_phase[0] += (model->Wo)*N_SAMP;
ex_phase[0] -= TWO_PI*floorf(ex_phase[0]/TWO_PI + 0.5);
for(m=1; m<=model->L; m++) {
if (mag > mag_thresh) {
for(i=start; i<=end; i++) {
- float pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0;
+ float pred = pexp->phi_prev[i] + N_SAMP*i*(model->Wo + pexp->Wo_prev)/2.0;
float err = pred - model->phi[i];
err = atan2(sin(err),cos(err));
printf("%f\n",err);
int i;
for(i=start; i<=end; i++) {
- model->phi[i] = pexp->phi_prev[i] + N*i*model->Wo;
+ model->phi[i] = pexp->phi_prev[i] + N_SAMP*i*model->Wo;
}
}
}
else
for(i=start; i<=end; i++) {
- model->phi[i] = pexp->phi_prev[i] + N*i*best_Wo;
+ model->phi[i] = pexp->phi_prev[i] + N_SAMP*i*best_Wo;
}
printf("state %d\n", pexp->state);
}
float pred, str, diff;
for(i=start; i<=end; i++) {
- pred = pexp->phi_prev[i] + N*i*model->Wo;
+ pred = pexp->phi_prev[i] + N_SAMP*i*model->Wo;
str = pexp->phi1*i;
diff = str - pred;
diff = atan2(sin(diff), cos(diff));
if (!top) {
model->phi[i] = 0.0; /* make sure */
if (pred) {
- //model->phi[i] = pexp->phi_prev[i] + i*N*(model->Wo + pexp->Wo_prev)/2.0;
+ //model->phi[i] = pexp->phi_prev[i] + i*N_SAMP*(model->Wo + pexp->Wo_prev)/2.0;
model->phi[i] = i*model->phi[1];
}
else
float pred, pred_error, error;
for(i=start; i<=end; i++) {
- pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0;
+ pred = pexp->phi_prev[i] + N_SAMP*i*(model->Wo + pexp->Wo_prev)/2.0;
pred_error = pred - model->phi[i];
pred_error -= TWO_PI*floor((pred_error+PI)/TWO_PI);
quant_phase(&pred_error, -limit, limit, 2);
float pred, pred_error;
for(i=start; i<=end; i++) {
- pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0;
+ pred = pexp->phi_prev[i] + N_SAMP*i*(model->Wo + pexp->Wo_prev)/2.0;
pred_error = pred - model->phi[i];
pred_error -= TWO_PI*floor((pred_error+PI)/TWO_PI);
}
for(i=start; i<=end; i++) {
- pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0;
+ pred = pexp->phi_prev[i] + N_SAMP*i*(model->Wo + pexp->Wo_prev)/2.0;
error = pred - model->phi[i];
error = atan2(sin(error),cos(error));
var = 0.0;
for(i=start; i<=end; i++) {
- pred = pexp->phi_prev[i] + N*i*Wo;
+ pred = pexp->phi_prev[i] + N_SAMP*i*Wo;
error = pred - model->phi[i];
error = atan2(sin(error),cos(error));
var += error*error;
//printf("\n");
for(i=1; i<=model->L; i++) {
- pred = pexp->phi_prev[i] + N*i*best_Wo;
+ pred = pexp->phi_prev[i] + N_SAMP*i*best_Wo;
error = pred - model->phi[i];
index = MAX_AMP*i*model->Wo/PI;
/* transform quantised phases back */
for(i=1; i<=model->L; i++) {
- pred = pexp->phi_prev[i] + N*i*best_Wo;
+ pred = pexp->phi_prev[i] + N_SAMP*i*best_Wo;
index = MAX_AMP*i*model->Wo/PI;
assert(index < MAX_AMP);
best_Wo = refine_Wo(pexp, model, 1, model->L);
for(i=start; i<=end; i++) {
- model->phi[i] = pexp->phi_prev[i] + N*i*best_Wo;
+ model->phi[i] = pexp->phi_prev[i] + N_SAMP*i*best_Wo;
}
}
/* set up sparse array */
for(m=1; m<=model->L; m++) {
- pred = pexp->phi_prev[m] + N*m*best_Wo;
+ pred = pexp->phi_prev[m] + N_SAMP*m*best_Wo;
err = model->phi[m] - pred;
err = atan2(sin(err),cos(err));
for(m=1; m<=model->L; m++) {
index = MAX_AMP*m*model->Wo/PI;
assert(index < MAX_AMP);
- pred = pexp->phi_prev[m] + N*m*best_Wo;
+ pred = pexp->phi_prev[m] + N_SAMP*m*best_Wo;
err = atan2(sparse_pe_out[index].imag, sparse_pe_out[index].real);
model->phi[m] = pred + err;
}
c = s = 0.0;
if (h>1) {
for(i=a; i<b; i++) {
- pred = pexp->phi_prev[i] + N*i*best_Wo;
+ pred = pexp->phi_prev[i] + N_SAMP*i*best_Wo;
err = model->phi[i] - pred;
c += cos(err); s += sin(err);
}
phi1_ = atan2(s,c);
for(i=a; i<b; i++) {
- pred = pexp->phi_prev[i] + N*i*best_Wo;
+ pred = pexp->phi_prev[i] + N_SAMP*i*best_Wo;
printf("%d: %4.3f -> ", i, model->phi[i]);
model->phi[i] = pred + phi1_;
model->phi[i] = atan2(sin(model->phi[i]),cos(model->phi[i]));
/* est predicted phase from average */
- pred = pexp->phi_prev[m] + N*m*best_Wo;
+ pred = pexp->phi_prev[m] + N_SAMP*m*best_Wo;
err = model->phi[m] - pred;
av[b].real += cos(err); av[b].imag += sin(err);
}
printf("L %d m %d f %4.f b %d\n", model->L, m, f, b);
- pred = pexp->phi_prev[m] + N*m*best_Wo;
+ pred = pexp->phi_prev[m] + N_SAMP*m*best_Wo;
err = atan2(av[b].imag, av[b].real);
printf(" %d: %4.3f -> ", m, model->phi[m]);
model->phi[m] = pred + err;
assert(b < MAX_BINS);
if (m != max_ind[b])
- model->phi[m] = pexp->phi_prev[m] + N*m*best_Wo;
+ model->phi[m] = pexp->phi_prev[m] + N_SAMP*m*best_Wo;
}
}
}
st = 2*model->L/4;
step = 3;
- model->phi[1] = pexp->phi_prev[1] + (pexp->Wo_prev+model->Wo)*N/2.0;
+ model->phi[1] = pexp->phi_prev[1] + (pexp->Wo_prev+model->Wo)*N_SAMP/2.0;
printf("L=%d ", model->L);
for(m=st; m<st+step*2; m+=step) {
for(i=a; i<b; i++) {
//model->phi[i] = i*phi1_;
//model->phi[i] = i*model->phi[1];
- //model->phi[i] = m*(pexp->Wo_prev+model->Wo)*N/2.0;
+ //model->phi[i] = m*(pexp->Wo_prev+model->Wo)*N_SAMP/2.0;
model->A[m] = A[m];
printf("%d ", i);
}
*model = pexp->prev_model;
for(m=1; m<=model->L; m++)
- model->phi[m] += N*m*model->Wo;
+ model->phi[m] += N_SAMP*m*model->Wo;
}
/* update states */
//best_Wo = refine_Wo(pexp, model, model->L/2, model->L);
- pexp->phi1 += N*model->Wo;
+ pexp->phi1 += N_SAMP*model->Wo;
for(m=1; m<=model->L; m++)
pexp->phi_prev[m] = model->phi[m];
/* Generate Parzen window in time domain */
win = 0.0;
- for(i=0; i<N/2-TW; i++)
+ for(i=0; i<N_SAMP/2-TW; i++)
Pn[i] = 0.0;
win = 0.0;
- for(i=N/2-TW; i<N/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/2+TW; i<3*N/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/2-TW; i<3*N/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/2+TW; i<2*N; i++)
+ for(i=3*N_SAMP/2+TW; i<2*N_SAMP; i++)
Pn[i] = 0.0;
}
if (shift) {
/* Update memories */
- for(i=0; i<N-1; i++) {
- Sn_[i] = Sn_[i+N];
+ for(i=0; i<N_SAMP-1; i++) {
+ Sn_[i] = Sn_[i+N_SAMP];
}
- Sn_[N-1] = 0.0;
+ Sn_[N_SAMP-1] = 0.0;
}
for(i=0; i<FFT_DEC; i++) {
is zero.
*/
for(l=1; l<=model->L; l++) {
- for(i=0,j=-N+1; i<N-1; i++,j++) {
- Sw_[FFT_DEC-N+1+i].real += 2.0*model->A[l]*cosf(j*model->Wo*l + model->phi[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-1,j=0; i<2*N; i++,j++)
+ 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 */
- for(i=0; i<N-1; i++) {
- Sn_[i] += sw_[FFT_DEC-N+1+i].real*Pn[i];
+ for(i=0; i<N_SAMP-1; i++) {
+ Sn_[i] += sw_[FFT_DEC-N_SAMP+1+i].real*Pn[i];
}
if (shift)
- for(i=N-1,j=0; i<2*N; i++,j++)
+ for(i=N_SAMP-1,j=0; i<2*N_SAMP; i++,j++)
Sn_[i] = sw_[j].real*Pn[i];
else
- for(i=N-1,j=0; i<2*N; i++,j++)
+ for(i=N_SAMP-1,j=0; i<2*N_SAMP; i++,j++)
Sn_[i] += sw_[j].real*Pn[i];
}
#include "octave.h"
#define FRAMES 35
-#define CHANNEL_BUF_SIZE (10*M)
+#define CHANNEL_BUF_SIZE (10*M_FAC)
extern float pilot_coeff[];
struct FDMDV *fdmdv;
int tx_bits[FDMDV_BITS_PER_FRAME];
COMP tx_symbols[FDMDV_NC+1];
- COMP tx_fdm[M];
+ COMP tx_fdm[M_FAC];
float channel[CHANNEL_BUF_SIZE];
int channel_count;
- COMP rx_fdm[M+M/P];
+ COMP rx_fdm[M_FAC+M_FAC/P];
float foff_coarse;
int nin, next_nin;
- COMP rx_fdm_fcorr[M+M/P];
- COMP rx_fdm_filter[M+M/P];
+ COMP rx_fdm_fcorr[M_FAC+M_FAC/P];
+ COMP rx_fdm_filter[M_FAC+M_FAC/P];
COMP rx_filt[NC+1][P+1];
float rx_timing;
float env[NT*P];
int tx_bits_log[FDMDV_BITS_PER_FRAME*FRAMES];
COMP tx_symbols_log[(FDMDV_NC+1)*FRAMES];
- COMP tx_fdm_log[M*FRAMES];
+ COMP tx_fdm_log[M_FAC*FRAMES];
COMP pilot_baseband1_log[NPILOTBASEBAND*FRAMES];
COMP pilot_baseband2_log[NPILOTBASEBAND*FRAMES];
COMP pilot_lpf1_log[NPILOTLPF*FRAMES];
COMP S2_log[MPILOTFFT*FRAMES];
float foff_coarse_log[FRAMES];
float foff_log[FRAMES];
- COMP rx_fdm_filter_log[(M+M/P)*FRAMES];
+ COMP rx_fdm_filter_log[(M_FAC+M_FAC/P)*FRAMES];
int rx_fdm_filter_log_index;
COMP rx_filt_log[NC+1][(P+1)*FRAMES];
int rx_filt_log_col_index;
int f,c,i,j;
fdmdv = fdmdv_create(FDMDV_NC);
- next_nin = M;
+ next_nin = M_FAC;
channel_count = 0;
rx_fdm_filter_log_index = 0;
nin = next_nin;
- // nin = M; // when debugging good idea to uncomment this to "open loop"
+ // nin = M_FAC; // when debugging good idea to uncomment this to "open loop"
- /* add M tx samples to end of buffer */
+ /* add M_FAC tx samples to end of buffer */
- assert((channel_count + M) < CHANNEL_BUF_SIZE);
- for(i=0; i<M; i++)
+ assert((channel_count + M_FAC) < CHANNEL_BUF_SIZE);
+ for(i=0; i<M_FAC; i++)
channel[channel_count+i] = tx_fdm[i].real;
- channel_count += M;
+ channel_count += M_FAC;
/* take nin samples from start of buffer */
rxdec_filter(rx_fdm_filter, rx_fdm_fcorr, fdmdv->rxdec_lpf_mem, nin);
down_convert_and_rx_filter(rx_filt, fdmdv->Nc, rx_fdm_filter, fdmdv->rx_fdm_mem, fdmdv->phase_rx, fdmdv->freq,
- fdmdv->freq_pol, nin, M/Q);
- rx_timing = rx_est_timing(rx_symbols, FDMDV_NC, rx_filt, fdmdv->rx_filter_mem_timing, env, nin, M);
+ fdmdv->freq_pol, nin, M_FAC/Q);
+ rx_timing = rx_est_timing(rx_symbols, FDMDV_NC, rx_filt, fdmdv->rx_filter_mem_timing, env, nin, M_FAC);
foff_fine = qpsk_to_bits(rx_bits, &sync_bit, FDMDV_NC, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols, 0);
//for(i=0; i<FDMDV_NC;i++)
snr_update(fdmdv->sig_est, fdmdv->noise_est, FDMDV_NC, fdmdv->phase_difference);
memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(FDMDV_NC+1));
- next_nin = M;
+ next_nin = M_FAC;
- if (rx_timing > 2*M/P)
- next_nin += M/P;
+ if (rx_timing > 2*M_FAC/P)
+ next_nin += M_FAC/P;
if (rx_timing < 0)
- next_nin -= M/P;
+ next_nin -= M_FAC/P;
fdmdv->sync = freq_state(&reliable_sync_bit, sync_bit, &fdmdv->fest_state, &fdmdv->timer, fdmdv->sync_mem);
fdmdv->foff -= TRACK_COEFF*foff_fine;
memcpy(&tx_bits_log[FDMDV_BITS_PER_FRAME*f], tx_bits, sizeof(int)*FDMDV_BITS_PER_FRAME);
memcpy(&tx_symbols_log[(FDMDV_NC+1)*f], tx_symbols, sizeof(COMP)*(FDMDV_NC+1));
- memcpy(&tx_fdm_log[M*f], tx_fdm, sizeof(COMP)*M);
+ memcpy(&tx_fdm_log[M_FAC*f], tx_fdm, sizeof(COMP)*M_FAC);
memcpy(&pilot_baseband1_log[f*NPILOTBASEBAND], fdmdv->pilot_baseband1, sizeof(COMP)*NPILOTBASEBAND);
memcpy(&pilot_baseband2_log[f*NPILOTBASEBAND], fdmdv->pilot_baseband2, sizeof(COMP)*NPILOTBASEBAND);
rx_fdm_filter_log_index += nin;
for(c=0; c<NC+1; c++) {
- for(i=0; i<(P*nin)/M; i++)
+ for(i=0; i<(P*nin)/M_FAC; i++)
rx_filt_log[c][rx_filt_log_col_index + i] = rx_filt[c][i];
}
- rx_filt_log_col_index += (P*nin)/M;
+ rx_filt_log_col_index += (P*nin)/M_FAC;
/* timing estimation */
fprintf(fout, "# Created by tfdmdv.c\n");
octave_save_int(fout, "tx_bits_log_c", tx_bits_log, 1, FDMDV_BITS_PER_FRAME*FRAMES);
octave_save_complex(fout, "tx_symbols_log_c", tx_symbols_log, 1, (FDMDV_NC+1)*FRAMES, (FDMDV_NC+1)*FRAMES);
- octave_save_complex(fout, "tx_fdm_log_c", (COMP*)tx_fdm_log, 1, M*FRAMES, M*FRAMES);
+ octave_save_complex(fout, "tx_fdm_log_c", (COMP*)tx_fdm_log, 1, M_FAC*FRAMES, M_FAC*FRAMES);
octave_save_complex(fout, "pilot_lut_c", (COMP*)fdmdv->pilot_lut, 1, NPILOT_LUT, NPILOT_LUT);
octave_save_complex(fout, "pilot_baseband1_log_c", pilot_baseband1_log, 1, NPILOTBASEBAND*FRAMES, NPILOTBASEBAND*FRAMES);
octave_save_complex(fout, "pilot_baseband2_log_c", pilot_baseband2_log, 1, NPILOTBASEBAND*FRAMES, NPILOTBASEBAND*FRAMES);
float run_a_test(char raw_file_name[], int bit_to_corrupt)
{
FILE *fin;
- short buf[N];
+ short buf[N_SAMP];
struct CODEC2 *c2;
kiss_fft_cfg fft_fwd_cfg;
MODEL model;
snr_sum = 0.0;
frames = 0;
- while(fread(buf, sizeof(short), N, fin) == N) {
+ while(fread(buf, sizeof(short), N_SAMP, fin) == N_SAMP) {
analyse_one_frame(c2, &model, buf);
e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);