From: drowe67 Date: Mon, 10 Oct 2016 06:24:45 +0000 (+0000) Subject: Large patch from Danilo to (i) change some #define names to make them codec2-specific... X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=6277d201964b87c6327e8e43a3d54c2edaa7d533;p=freetel-svn-tracking.git Large patch from Danilo to (i) change some #define names to make them codec2-specific (ii) add an abstraction layer for ffts (iii) add ARM-specific FFTs for stm32 that doesn't help CPU laod but helps memory git-svn-id: https://svn.code.sf.net/p/freetel/code@2885 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/CMakeLists.txt b/codec2-dev/CMakeLists.txt index 41d2b001..36bb52da 100644 --- a/codec2-dev/CMakeLists.txt +++ b/codec2-dev/CMakeLists.txt @@ -53,7 +53,7 @@ endif() # Set default C++ flags. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -g -O2") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -g -O2 -std=gnu11") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS}") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS}") diff --git a/codec2-dev/src/CMakeLists.txt b/codec2-dev/src/CMakeLists.txt index df845fed..978f3d62 100644 --- a/codec2-dev/src/CMakeLists.txt +++ b/codec2-dev/src/CMakeLists.txt @@ -137,6 +137,7 @@ set(CODEC2_SRCS postfilter.c sine.c codec2.c + codec2_fft.c cohpsk.c fifo.c fdmdv.c @@ -205,16 +206,16 @@ target_link_libraries(c2dec ${CMAKE_REQUIRED_LIBRARIES} codec2) add_executable(c2sim c2sim.c ampexp.c phaseexp.c) target_link_libraries(c2sim ${CMAKE_REQUIRED_LIBRARIES} codec2) -add_executable(fdmdv_get_test_bits fdmdv_get_test_bits.c fdmdv.c kiss_fft.c) +add_executable(fdmdv_get_test_bits fdmdv_get_test_bits.c fdmdv.c kiss_fft.c codec2_fft.c kiss_fftr.c) target_link_libraries(fdmdv_get_test_bits ${CMAKE_REQUIRED_LIBRARIES}) -add_executable(fdmdv_mod fdmdv_mod.c fdmdv.c kiss_fft.c) +add_executable(fdmdv_mod fdmdv_mod.c fdmdv.c kiss_fft.c codec2_fft.c kiss_fftr.c) target_link_libraries(fdmdv_mod ${CMAKE_REQUIRED_LIBRARIES}) -add_executable(fdmdv_demod fdmdv_demod.c fdmdv.c kiss_fft.c octave.c modem_stats.c) +add_executable(fdmdv_demod fdmdv_demod.c fdmdv.c kiss_fft.c octave.c modem_stats.c codec2_fft.c kiss_fftr.c) target_link_libraries(fdmdv_demod ${CMAKE_REQUIRED_LIBRARIES}) -add_executable(fdmdv_put_test_bits fdmdv_put_test_bits.c fdmdv.c kiss_fft.c) +add_executable(fdmdv_put_test_bits fdmdv_put_test_bits.c fdmdv.c kiss_fft.c codec2_fft.c kiss_fftr.c) target_link_libraries(fdmdv_put_test_bits ${CMAKE_REQUIRED_LIBRARIES}) add_executable(fdmdv_channel fdmdv_channel.c) diff --git a/codec2-dev/src/c2sim.c b/codec2-dev/src/c2sim.c index 6cb5d7d5..5af1c8b5 100644 --- a/codec2-dev/src/c2sim.c +++ b/codec2-dev/src/c2sim.c @@ -68,12 +68,12 @@ int main(int argc, char *argv[]) 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[M_PITCH]; /* float 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_fft_cfg fft_inv_cfg; - float w[M]; /* time domain hamming window */ + codec2_fft_cfg fft_fwd_cfg; + codec2_fft_cfg fft_inv_cfg; + float w[M_PITCH]; /* time domain hamming window */ COMP W[FFT_ENC]; /* DFT of w[] */ MODEL model; float Pn[2*N_SAMP]; /* trapezoidal synthesis window */ @@ -192,7 +192,7 @@ int main(int argc, char *argv[]) int num_opts=sizeof(long_options)/sizeof(struct option); COMP Aw[FFT_ENC]; - for(i=0; i #include "defines.h" +#include "codec2_fft.h" #include "sine.h" #include "nlp.h" #include "dump.h" @@ -117,16 +118,16 @@ struct CODEC2 * codec2_create(int mode) return NULL; c2->mode = mode; - for(i=0; iSn[i] = 1.0; c2->hpf_states[0] = c2->hpf_states[1] = 0.0; 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->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); - c2->fft_inv_cfg = kiss_fft_alloc(FFT_DEC, 1, NULL, NULL); + c2->fftr_inv_cfg = codec2_fftr_alloc(FFT_DEC, 1, NULL, NULL); quantise_init(); c2->prev_Wo_enc = 0.0; c2->bg_est = 0.0; @@ -143,7 +144,7 @@ struct CODEC2 * codec2_create(int mode) } c2->prev_e_dec = 1; - c2->nlp = nlp_create(M); + c2->nlp = nlp_create(M_PITCH); if (c2->nlp == NULL) { free (c2); return NULL; @@ -186,9 +187,9 @@ void codec2_destroy(struct CODEC2 *c2) assert(c2 != NULL); free(c2->bpf_buf); nlp_destroy(c2->nlp); - KISS_FFT_FREE(c2->fft_fwd_cfg); - KISS_FFT_FREE(c2->fftr_fwd_cfg); - KISS_FFT_FREE(c2->fft_inv_cfg); + codec2_fft_free(c2->fft_fwd_cfg); + codec2_fftr_free(c2->fftr_fwd_cfg); + codec2_fftr_free(c2->fftr_inv_cfg); free(c2); } @@ -1855,7 +1856,7 @@ void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, COMP PROFILE_SAMPLE_AND_LOG(synth_start, pf_start, " postfilter"); - synthesise(c2->fft_inv_cfg, c2->Sn_, model, c2->Pn, 1); + synthesise(c2->fftr_inv_cfg, c2->Sn_, model, c2->Pn, 1); PROFILE_SAMPLE_AND_LOG2(synth_start, " synth"); @@ -1886,18 +1887,16 @@ void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, COMP void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]) { COMP Sw[FFT_ENC]; - COMP Sw_[FFT_ENC]; - COMP Ew[FFT_ENC]; float pitch; int i; PROFILE_VAR(dft_start, nlp_start, model_start, two_stage, estamps); /* Read input speech */ - for(i=0; iSn[i] = c2->Sn[i+N_SAMP]; for(i=0; iSn[i+M-N_SAMP] = speech[i]; + c2->Sn[i+M_PITCH-N_SAMP] = speech[i]; PROFILE_SAMPLE(dft_start); dft_speech(c2->fft_fwd_cfg, Sw, c2->Sn, c2->w); @@ -1917,7 +1916,7 @@ void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]) PROFILE_SAMPLE_AND_LOG(two_stage, model_start, " two_stage"); estimate_amplitudes(model, Sw, c2->W, 0); PROFILE_SAMPLE_AND_LOG(estamps, two_stage, " est_amps"); - est_voicing_mbe(model, Sw, c2->W, Sw_, Ew); + est_voicing_mbe(model, Sw, c2->W); c2->prev_Wo_enc = model->Wo; PROFILE_SAMPLE_AND_LOG2(estamps, " est_voicing"); #ifdef DUMP diff --git a/codec2-dev/src/codec2_fft.c b/codec2-dev/src/codec2_fft.c new file mode 100644 index 00000000..3a5eb475 --- /dev/null +++ b/codec2-dev/src/codec2_fft.c @@ -0,0 +1,151 @@ +/* + * codec2_fft.c + * + * Created on: 24.09.2016 + * Author: danilo + */ + +#include "codec2_fft.h" +#ifdef USE_KISS_FFT +#include "_kiss_fft_guts.h" + +#else +#define FFT_INIT_CACHE_SIZE 4 +const arm_cfft_instance_f32* fft_init_cache[FFT_INIT_CACHE_SIZE]; + +static const arm_cfft_instance_f32* arm_fft_instance2ram(const arm_cfft_instance_f32* in) +{ + + arm_cfft_instance_f32* out = malloc(sizeof(arm_cfft_instance_f32)); + + if (out) { + memcpy(out,in,sizeof(arm_cfft_instance_f32)); + out->pBitRevTable = malloc(out->bitRevLength * sizeof(uint16_t)); + out->pTwiddle = malloc(out->fftLen * sizeof(float32_t)); + memcpy((void*)out->pBitRevTable,in->pBitRevTable,out->bitRevLength * sizeof(uint16_t)); + memcpy((void*)out->pTwiddle,in->pTwiddle,out->fftLen * sizeof(float32_t)); + } + return out; +} + + +static const arm_cfft_instance_f32* arm_fft_cache_get(const arm_cfft_instance_f32* romfft) +{ + const arm_cfft_instance_f32* retval = NULL; + static int used = 0; + for (int i = 0; fft_init_cache[i] != NULL && i < used; i++) + { + if (romfft->fftLen == fft_init_cache[i]->fftLen) + { + retval = fft_init_cache[i]; + break; + } + } + if (retval == NULL && used < FFT_INIT_CACHE_SIZE) + { + retval = arm_fft_instance2ram(romfft); + fft_init_cache[used++] = retval; + } + if (retval == NULL) + { + retval = romfft; + } + return retval; +} +#endif + +void codec2_fft_free(codec2_fft_cfg cfg) +{ +#ifdef USE_KISS_FFT + KISS_FFT_FREE(cfg); +#else + free(cfg); +#endif +} + +codec2_fft_cfg codec2_fft_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem) +{ + codec2_fft_cfg retval; +#ifdef USE_KISS_FFT + retval = kiss_fft_alloc(nfft, inverse_fft, mem, lenmem); +#else + retval = malloc(sizeof(codec2_fft_struct)); + retval->inverse = inverse_fft; + switch(nfft) + { + case 128: + retval->instance = &arm_cfft_sR_f32_len128; + break; + case 256: + retval->instance = &arm_cfft_sR_f32_len256; + break; + case 512: + retval->instance = &arm_cfft_sR_f32_len512; + break; +// case 1024: +// retval->instance = &arm_cfft_sR_f32_len1024; +// break; + default: + abort(); + } + // retval->instance = arm_fft_cache_get(retval->instance); +#endif + return retval; +} + +codec2_fftr_cfg codec2_fftr_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem) +{ + codec2_fftr_cfg retval; +#ifdef USE_KISS_FFT + retval = kiss_fftr_alloc(nfft, inverse_fft, mem, lenmem); +#else + retval = malloc(sizeof(codec2_fftr_struct)); + retval->inverse = inverse_fft; + retval->instance = malloc(sizeof(arm_rfft_fast_instance_f32)); + arm_rfft_fast_init_f32(retval->instance,nfft); + // memcpy(&retval->instance->Sint,arm_fft_cache_get(&retval->instance->Sint),sizeof(arm_cfft_instance_f32)); +#endif + return retval; +} +void codec2_fftr_free(codec2_fftr_cfg cfg) +{ +#ifdef USE_KISS_FFT + KISS_FFT_FREE(cfg); +#else + free(cfg->instance); + free(cfg); +#endif +} + +// there is a little overhead for inplace kiss_fft but this is +// on the powerful platforms like the Raspberry or even x86 PC based ones +// not noticeable +// the reduced usage of RAM and increased performance on STM32 platforms +// should be worth it. +void codec2_fft_inplace(codec2_fft_cfg cfg, codec2_fft_cpx* inout) +{ + +#ifdef USE_KISS_FFT + kiss_fft_cpx in[512]; + // decide whether to use the local stack based buffer for in + // or to allow kiss_fft to allocate RAM + // second part is just to play safe since first method + // is much faster and uses less RAM + if (cfg->nfft <= 512) + { + memcpy(in,inout,cfg->nfft*sizeof(kiss_fft_cpx)); + kiss_fft(cfg, in, (kiss_fft_cpx*)inout); + } + else + { + kiss_fft(cfg, (kiss_fft_cpx*)inout, (kiss_fft_cpx*)inout); + } +#else + arm_cfft_f32(cfg->instance,(float*)inout,cfg->inverse,1); + if (cfg->inverse) + { + arm_scale_f32(inout,cfg->instance->fftLen,inout,cfg->instance->fftLen*2); + } + +#endif +} diff --git a/codec2-dev/src/codec2_fft.h b/codec2-dev/src/codec2_fft.h new file mode 100644 index 00000000..d421c474 --- /dev/null +++ b/codec2-dev/src/codec2_fft.h @@ -0,0 +1,110 @@ +/* + * codec2_fft.h + * + * Created on: 17.09.2016 + * Author: danilo + */ + +#ifndef DRIVERS_FREEDV_CODEC2_FFT_H_ +#define DRIVERS_FREEDV_CODEC2_FFT_H_ + +#include +#include +#include +#include +#include + +#ifdef ARM_MATH_CM4 + #include "stm32f4xx.h" + #include "core_cm4.h" + #include "arm_math.h" + #include "arm_const_structs.h" +#endif + +#include "defines.h" +#include "comp.h" + +#ifndef ARM_MATH_CM4 + #define USE_KISS_FFT +#endif +// #define USE_KISS_FFT + + +typedef COMP codec2_fft_cpx; +#include "kiss_fftr.h" + +#ifdef USE_KISS_FFT + #include "kiss_fft.h" + typedef kiss_fftr_cfg codec2_fftr_cfg; + typedef kiss_fft_cfg codec2_fft_cfg; + typedef kiss_fft_scalar codec2_fft_scalar; +#else + typedef float32_t codec2_fft_scalar; + typedef struct { + arm_rfft_fast_instance_f32* instance; + int inverse; + } codec2_fftr_struct; + + typedef codec2_fftr_struct* codec2_fftr_cfg; + + typedef struct { + const arm_cfft_instance_f32* instance; + int inverse; + } codec2_fft_struct; + typedef codec2_fft_struct* codec2_fft_cfg; +#endif + + + +static inline void codec2_fftr(codec2_fftr_cfg cfg, codec2_fft_scalar* in, codec2_fft_cpx* out) +{ + +#ifdef USE_KISS_FFT + kiss_fftr(cfg, in, (kiss_fft_cpx*)out); +#else + arm_rfft_fast_f32(cfg->instance,in,(float*)out,cfg->inverse); + out->imag = 0; // remove out[FFT_ENC/2]->real stored in out[0].imag +#endif +} + +static inline void codec2_fftri(codec2_fftr_cfg cfg, codec2_fft_cpx* in, codec2_fft_scalar* out) +{ +#ifdef USE_KISS_FFT + kiss_fftri(cfg, (kiss_fft_cpx*)in, out); +#else + arm_rfft_fast_f32(cfg->instance,(float*)in,out,cfg->inverse); + // arm_scale_f32(out,cfg->instance->fftLenRFFT,out,cfg->instance->fftLenRFFT); +#endif + +} + +codec2_fft_cfg codec2_fft_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem); +codec2_fftr_cfg codec2_fftr_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem); +void codec2_fft_free(codec2_fft_cfg cfg); +void codec2_fftr_free(codec2_fftr_cfg cfg); + + +static inline void codec2_fft(codec2_fft_cfg cfg, codec2_fft_cpx* in, codec2_fft_cpx* out) +{ + +#ifdef USE_KISS_FFT + kiss_fft(cfg, (kiss_fft_cpx*)in, (kiss_fft_cpx*)out); +#else + memcpy(out,in,cfg->instance->fftLen*2*sizeof(float)); + arm_cfft_f32(cfg->instance,(float*)out,cfg->inverse,0); + // TODO: this is not nice, but for now required to keep changes minimal + // however, since main goal is to reduce the memory usage + // we should convert to an in place interface + // on PC like platforms the overhead of using the "inplace" kiss_fft calls + // is neglectable compared to the gain in memory usage on STM32 platforms + if (cfg->inverse) + { + arm_scale_f32((float*)out,cfg->instance->fftLen,(float*)out,cfg->instance->fftLen*2); + } +#endif +} + +void codec2_fft_inplace(codec2_fft_cfg cfg, codec2_fft_cpx* inout); + + +#endif diff --git a/codec2-dev/src/codec2_internal.h b/codec2-dev/src/codec2_internal.h index 57f27cbc..cb516cc4 100644 --- a/codec2-dev/src/codec2_internal.h +++ b/codec2-dev/src/codec2_internal.h @@ -29,20 +29,22 @@ #ifndef __CODEC2_INTERNAL__ #define __CODEC2_INTERNAL__ +#include "codec2_fft.h" + struct CODEC2 { int mode; - kiss_fft_cfg fft_fwd_cfg; /* forward FFT config */ - kiss_fftr_cfg fftr_fwd_cfg; /* forward real FFT config */ - float w[M]; /* time domain hamming window */ + codec2_fft_cfg fft_fwd_cfg; /* forward FFT config */ + codec2_fftr_cfg fftr_fwd_cfg; /* forward real FFT config */ + float w[M_PITCH]; /* time domain hamming window */ COMP W[FFT_ENC]; /* DFT of w[] */ float Pn[2*N_SAMP]; /* trapezoidal synthesis window */ float *bpf_buf; /* buffer for band pass filter */ - float Sn[M]; /* input speech */ + float Sn[M_PITCH]; /* input speech */ float hpf_states[2]; /* high pass filter states */ void *nlp; /* pitch predictor states */ int gray; /* non-zero for gray encoding */ - kiss_fft_cfg fft_inv_cfg; /* inverse FFT config */ + codec2_fftr_cfg fftr_inv_cfg; /* inverse FFT config */ float Sn_[2*N_SAMP]; /* synthesised output speech */ float ex_phase; /* excitation model phase track */ float bg_est; /* background noise estimate for post filter */ diff --git a/codec2-dev/src/defines.h b/codec2-dev/src/defines.h index 67e65c4b..9ec7235d 100644 --- a/codec2-dev/src/defines.h +++ b/codec2-dev/src/defines.h @@ -55,7 +55,7 @@ /* Pitch estimation defines */ -#define M 320 /* pitch analysis frame size */ +#define M_PITCH 320 /* pitch analysis frame size */ #define P_MIN 20 /* minimum pitch */ #define P_MAX 160 /* maximum pitch */ diff --git a/codec2-dev/src/dump.h b/codec2-dev/src/dump.h index 58c93102..f4339ca2 100644 --- a/codec2-dev/src/dump.h +++ b/codec2-dev/src/dump.h @@ -28,8 +28,7 @@ #include "defines.h" #include "comp.h" -#include "kiss_fft.h" -#include "kiss_fftr.h" +#include "codec2_fft.h" #include "codec2_internal.h" void dump_on(char filename_prefix[]); diff --git a/codec2-dev/src/fdmdv.c b/codec2-dev/src/fdmdv.c index eb2774fd..ee075016 100644 --- a/codec2-dev/src/fdmdv.c +++ b/codec2-dev/src/fdmdv.c @@ -51,7 +51,7 @@ #include "rxdec_coeff.h" #include "test_bits.h" #include "pilot_coeff.h" -#include "kiss_fft.h" +#include "codec2_fft.h" #include "hanning.h" #include "os.h" #include "machdep.h" @@ -159,7 +159,7 @@ struct FDMDV * fdmdv_create(int Nc) /* freq Offset estimation states */ - f->fft_pilot_cfg = kiss_fft_alloc (MPILOTFFT, 0, NULL, NULL); + f->fft_pilot_cfg = codec2_fft_alloc (MPILOTFFT, 0, NULL, NULL); assert(f->fft_pilot_cfg != NULL); for(i=0; ifft_pilot_cfg); + codec2_fft_free(fdmdv->fft_pilot_cfg); free(fdmdv->rx_test_bits_mem); free(fdmdv); } @@ -713,12 +713,11 @@ void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq) \*---------------------------------------------------------------------------*/ void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], - COMP pilot_lpf[], kiss_fft_cfg fft_pilot_cfg, COMP S[], int nin, + COMP pilot_lpf[], codec2_fft_cfg fft_pilot_cfg, COMP S[], int nin, int do_fft) { int i,j,k; int mpilot; - COMP s[MPILOTFFT]; float mag, imax; int ix; float r; @@ -770,16 +769,12 @@ void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], if (do_fft) { /* decimate to improve DFT resolution, window and DFT */ - mpilot = FS/(2*200); /* calc decimation rate given new sample rate is twice LPF freq */ - for(i=0; imem_fir[i] = 0.0; - nlp->fft_cfg = kiss_fft_alloc (PE_FFT_SIZE, 0, NULL, NULL); + nlp->fft_cfg = codec2_fft_alloc (PE_FFT_SIZE, 0, NULL, NULL); assert(nlp->fft_cfg != NULL); return (void*)nlp; @@ -185,7 +185,7 @@ void nlp_destroy(void *nlp_state) assert(nlp_state != NULL); nlp = (NLP*)nlp_state; - KISS_FFT_FREE(nlp->fft_cfg); + codec2_fft_free(nlp->fft_cfg); free(nlp_state); } @@ -233,8 +233,7 @@ float nlp( { NLP *nlp; float notch; /* current notch filter output */ - COMP fw[PE_FFT_SIZE]; /* DFT of squared signal (input) */ - COMP Fw[PE_FFT_SIZE]; /* DFT of squared signal (output) */ + COMP Fw[PE_FFT_SIZE]; /* DFT of squared signal (input/output) */ float gmax; int gmax_bin; int m, i,j; @@ -285,18 +284,20 @@ float nlp( /* Decimate and DFT */ for(i=0; isq[i*DEC]*nlp->w[i]; + Fw[i].real = nlp->sq[i*DEC]*nlp->w[i]; } PROFILE_SAMPLE_AND_LOG(window, filter, " window"); #ifdef DUMP dump_dec(Fw); #endif - kiss_fft(nlp->fft_cfg, (kiss_fft_cpx *)fw, (kiss_fft_cpx *)Fw); + // FIXME: check if this can be converted to a real fft + // since all imag inputs are 0 + codec2_fft_inplace(nlp->fft_cfg, Fw); PROFILE_SAMPLE_AND_LOG(fft, window, " fft"); for(i=0; iL; m++) { am = (int)((m - 0.5)*model->Wo/r + 0.5); bm = (int)((m + 0.5)*model->Wo/r + 0.5); + + // FIXME: With arm_rfft_fast_f32 we have to use this + // otherwise sometimes a to high bm is calculated + // which causes trouble later in the calculation + // chain + // it seems for some reason model->Wo is calculated somewhat too high + if (bm>FFT_ENC/2) + { + bm = FFT_ENC/2; + } Em = 0.0; for(i=am; iA[m]) Am *= 1.4; } - model->A[m] = Am; } *snr = 10.0*log10f(signal/noise); @@ -1274,12 +1283,12 @@ float speech_to_uq_lsps(float lsp[], ) { int i, roots; - float Wn[M]; + float Wn[M_PITCH]; float R[order+1]; float e, E; e = 0.0; - for(i=0; iL/4; l++) { sig += model->A[l]*model->A[l]; } - for(i=0; iWo; error = 1E-4; @@ -442,12 +465,10 @@ float est_voicing_mbe( offset = FFT_ENC/2 - l*Wo*FFT_ENC/TWO_PI + 0.5; for(m=al; mL; 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; - } - Sw_[b].real = model->A[l]*cosf(model->phi[l]); - Sw_[b].imag = model->A[l]*sinf(model->phi[l]); - Sw_[FFT_DEC-b].real = Sw_[b].real; - Sw_[FFT_DEC-b].imag = -Sw_[b].imag; + //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; + } + Sw_[b].real = model->A[l]*cosf(model->phi[l]); + Sw_[b].imag = model->A[l]*sinf(model->phi[l]); } /* Perform inverse DFT */ - kiss_fft(fft_inv_cfg, (kiss_fft_cpx *)Sw_, (kiss_fft_cpx *)sw_); + codec2_fftri(fftr_inv_cfg, Sw_,sw_); #else /* Direct time domain synthesis using the cos() function. Works @@ -613,28 +632,32 @@ void synthesise( 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; iA[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]); + for(i=0,j=-N_SAMP+1; iA[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