Skip to content

Commit d7d8ebe

Browse files
authored
Merge pull request #83 from drowe67/ss-wreal
Change W[] vector to float as imag always 0.0
2 parents 670cf64 + 29d003d commit d7d8ebe

File tree

10 files changed

+31
-225
lines changed

10 files changed

+31
-225
lines changed

misc/tnlp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ int main(int argc, char *argv[])
9191
kiss_fft_cfg fft_fwd_cfg;
9292
COMP Sw[FFT_ENC]; /* DFT of Sn[] */
9393
float w[m]; /* time domain hamming window */
94-
COMP W[FFT_ENC]; /* DFT of w[] */
94+
float W[FFT_ENC]; /* DFT of w[] */
9595
float pitch_samples;
9696
int i;
9797
float f0, prev_f0;

src/c2sim.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ int main(int argc, char *argv[])
404404
codec2_fftr_cfg fftr_fwd_cfg;
405405
codec2_fftr_cfg fftr_inv_cfg;
406406
float w[m_pitch]; /* time domain hamming window */
407-
COMP W[FFT_ENC]; /* DFT of w[] */
407+
float W[FFT_ENC]; /* DFT of w[] */
408408
MODEL model;
409409
float Pn[2*N_SAMP]; /* trapezoidal synthesis window */
410410
float Sn_[2*N_SAMP]; /* synthesised speech */

src/codec2_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ struct CODEC2 {
4242
codec2_fft_cfg fft_fwd_cfg; /* forward FFT config */
4343
codec2_fftr_cfg fftr_fwd_cfg; /* forward real FFT config */
4444
float *w; /* [m_pitch] time domain hamming window */
45-
COMP W[FFT_ENC]; /* DFT of w[] */
45+
float W[FFT_ENC]; /* DFT of w[] */
4646
float *Pn; /* [2*n_samp] trapezoidal synthesis window */
4747
float *bpf_buf; /* buffer for band pass filter */
4848
float *Sn; /* [m_pitch] input speech */

src/nlp.c

Lines changed: 1 addition & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
#define F0_MAX 500
5454
#define CNLP 0.3 /* post processor constant */
5555
#define NLP_NTAP 48 /* Decimation LPF order */
56-
#undef POST_PROCESS_MBE /* choose post processor */
5756

5857
/* 8 to 16 kHz sample rate conversion */
5958

@@ -132,10 +131,6 @@ typedef struct {
132131
FILE *f;
133132
} NLP;
134133

135-
#ifdef POST_PROCESS_MBE
136-
float test_candidate_mbe(COMP Sw[], COMP W[], float f0);
137-
float post_process_mbe(COMP Fw[], int pmin, int pmax, float gmax, COMP Sw[], COMP W[], float *prev_Wo);
138-
#endif
139134
float post_process_sub_multiples(COMP Fw[],
140135
int pmin, int pmax, float gmax, int gmax_bin,
141136
float *prev_f0);
@@ -258,7 +253,7 @@ float nlp(
258253
int n, /* frames shift (no. new samples in Sn[]) */
259254
float *pitch, /* estimated pitch period in samples at current Fs */
260255
COMP Sw[], /* Freq domain version of Sn[] */
261-
COMP W[], /* Freq domain window */
256+
float W[], /* Freq domain window */
262257
float *prev_f0 /* previous pitch f0 in Hz, memory for pitch tracking */
263258
)
264259
{
@@ -389,11 +384,7 @@ float nlp(
389384

390385
PROFILE_SAMPLE_AND_LOG(peakpick, magsq, " peak pick");
391386

392-
#ifdef POST_PROCESS_MBE
393-
best_f0 = post_process_mbe(Fw, pmin, pmax, gmax, Sw, W, prev_f0);
394-
#else
395387
best_f0 = post_process_sub_multiples(Fw, pmin, pmax, gmax, gmax_bin, prev_f0);
396-
#endif
397388

398389
PROFILE_SAMPLE_AND_LOG(shiftmem, peakpick, " post process");
399390

@@ -491,178 +482,6 @@ float post_process_sub_multiples(COMP Fw[],
491482
return best_f0;
492483
}
493484

494-
#ifdef POST_PROCESS_MBE
495-
496-
/*---------------------------------------------------------------------------*\
497-
498-
post_process_mbe()
499-
500-
Use the MBE pitch estimation algorithm to evaluate pitch candidates. This
501-
works OK but the accuracy at low F0 is affected by NW, the analysis window
502-
size used for the DFT of the input speech Sw[]. Also favours high F0 in
503-
the presence of background noise which causes periodic artifacts in the
504-
synthesised speech.
505-
506-
\*---------------------------------------------------------------------------*/
507-
508-
float post_process_mbe(COMP Fw[], int pmin, int pmax, float gmax, COMP Sw[], COMP W[], float *prev_Wo)
509-
{
510-
float candidate_f0;
511-
float f0,best_f0; /* fundamental frequency */
512-
float e,e_min; /* MBE cost function */
513-
int i;
514-
#ifdef DUMP
515-
float e_hz[F0_MAX];
516-
#endif
517-
#if !defined(NDEBUG) || defined(DUMP)
518-
int bin;
519-
#endif
520-
float f0_min, f0_max;
521-
float f0_start, f0_end;
522-
523-
f0_min = (float)SAMPLE_RATE/pmax;
524-
f0_max = (float)SAMPLE_RATE/pmin;
525-
526-
/* Now look for local maxima. Each local maxima is a candidate
527-
that we test using the MBE pitch estimation algotithm */
528-
529-
#ifdef DUMP
530-
for(i=0; i<F0_MAX; i++)
531-
e_hz[i] = -1;
532-
#endif
533-
e_min = 1E32;
534-
best_f0 = 50;
535-
for(i=PE_FFT_SIZE*DEC/pmax; i<=PE_FFT_SIZE*DEC/pmin; i++) {
536-
if ((Fw[i].real > Fw[i-1].real) && (Fw[i].real > Fw[i+1].real)) {
537-
538-
/* local maxima found, lets test if it's big enough */
539-
540-
if (Fw[i].real > T*gmax) {
541-
542-
/* OK, sample MBE cost function over +/- 10Hz range in 2.5Hz steps */
543-
544-
candidate_f0 = (float)i*SAMPLE_RATE/(PE_FFT_SIZE*DEC);
545-
f0_start = candidate_f0-20;
546-
f0_end = candidate_f0+20;
547-
if (f0_start < f0_min) f0_start = f0_min;
548-
if (f0_end > f0_max) f0_end = f0_max;
549-
550-
for(f0=f0_start; f0<=f0_end; f0+= 2.5) {
551-
e = test_candidate_mbe(Sw, W, f0);
552-
#if !defined(NDEBUG) || defined(DUMP)
553-
bin = floorf(f0); assert((bin > 0) && (bin < F0_MAX));
554-
#endif
555-
#ifdef DUMP
556-
e_hz[bin] = e;
557-
#endif
558-
if (e < e_min) {
559-
e_min = e;
560-
best_f0 = f0;
561-
}
562-
}
563-
564-
}
565-
}
566-
}
567-
568-
/* finally sample MBE cost function around previous pitch estimate
569-
(form of pitch tracking) */
570-
571-
candidate_f0 = *prev_Wo * SAMPLE_RATE/TWO_PI;
572-
f0_start = candidate_f0-20;
573-
f0_end = candidate_f0+20;
574-
if (f0_start < f0_min) f0_start = f0_min;
575-
if (f0_end > f0_max) f0_end = f0_max;
576-
577-
for(f0=f0_start; f0<=f0_end; f0+= 2.5) {
578-
e = test_candidate_mbe(Sw, W, f0);
579-
#if !defined(NDEBUG) || defined(DUMP)
580-
bin = floorf(f0); assert((bin > 0) && (bin < F0_MAX));
581-
#endif
582-
#ifdef DUMP
583-
e_hz[bin] = e;
584-
#endif
585-
if (e < e_min) {
586-
e_min = e;
587-
best_f0 = f0;
588-
}
589-
}
590-
591-
#ifdef DUMP
592-
dump_e(e_hz);
593-
#endif
594-
595-
return best_f0;
596-
}
597-
598-
/*---------------------------------------------------------------------------*\
599-
600-
test_candidate_mbe()
601-
602-
Returns the error of the MBE cost function for the input f0.
603-
604-
Note: I think a lot of the operations below can be simplified as
605-
W[].imag = 0 and has been normalised such that den always equals 1.
606-
607-
\*---------------------------------------------------------------------------*/
608-
609-
float test_candidate_mbe(
610-
COMP Sw[],
611-
COMP W[],
612-
float f0
613-
)
614-
{
615-
COMP Sw_[FFT_ENC]; /* DFT of all voiced synthesised signal */
616-
int l,al,bl,m; /* loop variables */
617-
COMP Am; /* amplitude sample for this band */
618-
int offset; /* centers Hw[] about current harmonic */
619-
float den; /* denominator of Am expression */
620-
float error; /* accumulated error between originl and synthesised */
621-
float Wo; /* current "test" fundamental freq. */
622-
int L;
623-
624-
L = floorf((SAMPLE_RATE/2.0)/f0);
625-
Wo = f0*(2*PI/SAMPLE_RATE);
626-
627-
error = 0.0;
628-
629-
/* Just test across the harmonics in the first 1000 Hz (L/4) */
630-
631-
for(l=1; l<L/4; l++) {
632-
Am.real = 0.0;
633-
Am.imag = 0.0;
634-
den = 0.0;
635-
al = ceilf((l - 0.5)*Wo*FFT_ENC/TWO_PI);
636-
bl = ceilf((l + 0.5)*Wo*FFT_ENC/TWO_PI);
637-
638-
/* Estimate amplitude of harmonic assuming harmonic is totally voiced */
639-
640-
for(m=al; m<bl; m++) {
641-
offset = FFT_ENC/2 + m - l*Wo*FFT_ENC/TWO_PI + 0.5;
642-
Am.real += Sw[m].real*W[offset].real + Sw[m].imag*W[offset].imag;
643-
Am.imag += Sw[m].imag*W[offset].real - Sw[m].real*W[offset].imag;
644-
den += W[offset].real*W[offset].real + W[offset].imag*W[offset].imag;
645-
}
646-
647-
Am.real = Am.real/den;
648-
Am.imag = Am.imag/den;
649-
650-
/* Determine error between estimated harmonic and original */
651-
652-
for(m=al; m<bl; m++) {
653-
offset = FFT_ENC/2 + m - l*Wo*FFT_ENC/TWO_PI + 0.5;
654-
Sw_[m].real = Am.real*W[offset].real - Am.imag*W[offset].imag;
655-
Sw_[m].imag = Am.real*W[offset].imag + Am.imag*W[offset].real;
656-
error += (Sw[m].real - Sw_[m].real)*(Sw[m].real - Sw_[m].real);
657-
error += (Sw[m].imag - Sw_[m].imag)*(Sw[m].imag - Sw_[m].imag);
658-
}
659-
}
660-
661-
return error;
662-
}
663-
664-
#endif
665-
666485
/*---------------------------------------------------------------------------*\
667486
668487
FUNCTION....: fdmdv_16_to_8()

src/nlp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@
3333
void *nlp_create(C2CONST *c2const);
3434
void nlp_destroy(void *nlp_state);
3535
float nlp(void *nlp_state, float Sn[], int n,
36-
float *pitch_samples, COMP Sw[], COMP W[], float *prev_f0);
36+
float *pitch_samples, COMP Sw[], float W[], float *prev_f0);
3737

3838
#endif

src/sine.c

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,10 @@ C2CONST c2const_create(int Fs, float framelength_s) {
9797
9898
\*---------------------------------------------------------------------------*/
9999

100-
void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], COMP W[])
100+
void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], float W[])
101101
{
102102
float m;
103103
COMP wshift[FFT_ENC];
104-
COMP temp;
105104
int i,j;
106105
int m_pitch = c2const->m_pitch;
107106
int nw = c2const->nw;
@@ -156,6 +155,8 @@ void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[
156155
nw/2 nw/2
157156
*/
158157

158+
COMP temp[FFT_ENC];
159+
159160
for(i=0; i<FFT_ENC; i++) {
160161
wshift[i].real = 0.0;
161162
wshift[i].imag = 0.0;
@@ -165,7 +166,7 @@ void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[
165166
for(i=FFT_ENC-nw/2,j=m_pitch/2-nw/2; i<FFT_ENC; i++,j++)
166167
wshift[i].real = w[j];
167168

168-
codec2_fft(fft_fwd_cfg, wshift, W);
169+
codec2_fft(fft_fwd_cfg, wshift, temp);
169170

170171
/*
171172
Re-arrange W[] to be symmetrical about FFT_ENC/2. Makes later
@@ -192,12 +193,8 @@ void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[
192193

193194

194195
for(i=0; i<FFT_ENC/2; i++) {
195-
temp.real = W[i].real;
196-
temp.imag = W[i].imag;
197-
W[i].real = W[i+FFT_ENC/2].real;
198-
W[i].imag = W[i+FFT_ENC/2].imag;
199-
W[i+FFT_ENC/2].real = temp.real;
200-
W[i+FFT_ENC/2].imag = temp.imag;
196+
W[i] = temp[i + FFT_ENC / 2].real;
197+
W[i + FFT_ENC / 2] = temp[i].real;
201198
}
202199

203200
}
@@ -402,39 +399,30 @@ void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float
402399
403400
\*---------------------------------------------------------------------------*/
404401

405-
void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[], int est_phase)
402+
void estimate_amplitudes(MODEL *model, COMP Sw[], float W[], int est_phase)
406403
{
407404
int i,m; /* loop variables */
408405
int am,bm; /* bounds of current harmonic */
409-
int b; /* DFT bin of centre of current harmonic */
410406
float den; /* denominator of amplitude expression */
411-
float r, one_on_r; /* number of rads/bin */
412-
int offset;
413-
COMP Am;
414407

415-
r = TWO_PI/FFT_ENC;
416-
one_on_r = 1.0/r;
408+
float r = TWO_PI/FFT_ENC;
409+
float one_on_r = 1.0/r;
417410

418411
for(m=1; m<=model->L; m++) {
412+
/* Estimate ampltude of harmonic */
413+
419414
den = 0.0;
420415
am = (int)((m - 0.5)*model->Wo*one_on_r + 0.5);
421416
bm = (int)((m + 0.5)*model->Wo*one_on_r + 0.5);
422-
b = (int)(m*model->Wo/r + 0.5);
423-
424-
/* Estimate ampltude of harmonic */
425417

426-
den = 0.0;
427-
Am.real = Am.imag = 0.0;
428-
offset = FFT_ENC/2 - (int)(m*model->Wo*one_on_r + 0.5);
429418
for(i=am; i<bm; i++) {
430419
den += Sw[i].real*Sw[i].real + Sw[i].imag*Sw[i].imag;
431-
Am.real += Sw[i].real*W[i + offset].real;
432-
Am.imag += Sw[i].imag*W[i + offset].real;
433420
}
434421

435422
model->A[m] = sqrtf(den);
436423

437424
if (est_phase) {
425+
int b = (int)(m*model->Wo/r + 0.5); /* DFT bin of centre of current harmonic */
438426

439427
/* Estimate phase of harmonic, this is expensive in CPU for
440428
embedded devicesso we make it an option */
@@ -459,7 +447,7 @@ float est_voicing_mbe(
459447
C2CONST *c2const,
460448
MODEL *model,
461449
COMP Sw[],
462-
COMP W[]
450+
float W[]
463451
)
464452
{
465453
int l,al,bl,m; /* loop variables */
@@ -497,20 +485,19 @@ float est_voicing_mbe(
497485

498486
offset = FFT_ENC/2 - l*Wo*FFT_ENC/TWO_PI + 0.5;
499487
for(m=al; m<bl; m++) {
500-
Am.real += Sw[m].real*W[offset+m].real;
501-
Am.imag += Sw[m].imag*W[offset+m].real;
502-
den += W[offset+m].real*W[offset+m].real;
488+
Am.real += Sw[m].real*W[offset+m];
489+
Am.imag += Sw[m].imag*W[offset+m];
490+
den += W[offset+m]*W[offset+m];
503491
}
504492

505493
Am.real = Am.real/den;
506494
Am.imag = Am.imag/den;
507495

508496
/* Determine error between estimated harmonic and original */
509497

510-
// Redundant! offset = FFT_ENC/2 - l*Wo*FFT_ENC/TWO_PI + 0.5;
511498
for(m=al; m<bl; m++) {
512-
Ew.real = Sw[m].real - Am.real*W[offset+m].real;
513-
Ew.imag = Sw[m].imag - Am.imag*W[offset+m].real;
499+
Ew.real = Sw[m].real - Am.real*W[offset+m];
500+
Ew.imag = Sw[m].imag - Am.imag*W[offset+m];
514501
error += Ew.real*Ew.real;
515502
error += Ew.imag*Ew.imag;
516503
}

src/sine.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@
3434

3535
C2CONST c2const_create(int Fs, float framelength_ms);
3636

37-
void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], COMP W[]);
37+
void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], float W[]);
3838
float hpf(float x, float states[]);
3939
void dft_speech(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, COMP Sw[], float Sn[], float w[]);
4040
void two_stage_pitch_refinement(C2CONST *c2const, MODEL *model, COMP Sw[]);
41-
void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[], int est_phase);
42-
float est_voicing_mbe(C2CONST *c2const, MODEL *model, COMP Sw[], COMP W[]);
41+
void estimate_amplitudes(MODEL *model, COMP Sw[], float W[], int est_phase);
42+
float est_voicing_mbe(C2CONST *c2const, MODEL *model, COMP Sw[], float W[]);
4343
void make_synthesis_window(C2CONST *c2const, float Pn[]);
4444
void synthesise(int n_samp, codec2_fftr_cfg fftr_inv_cfg, float Sn_[], MODEL *model, float Pn[], int shift);
4545

0 commit comments

Comments
 (0)