From 9022d768021bbe15c7815cc6f8b64218b46f0e10 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Thu, 15 Oct 2020 16:27:49 +0200 Subject: Bump to upstream version 0.9.2 --- codec2.c | 43 ++++++++----- codec2.h | 5 +- codec2_internal.h | 4 +- newamp1.c | 27 +++++--- newamp1.h | 4 +- nlp.c | 183 +----------------------------------------------------- nlp.h | 2 +- sine.c | 49 ++++++--------- sine.h | 6 +- stripdown.sh | 4 +- version.h | 4 +- 11 files changed, 85 insertions(+), 246 deletions(-) diff --git a/codec2.c b/codec2.c index 840fe21..2697356 100644 --- a/codec2.c +++ b/codec2.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -114,12 +115,25 @@ struct CODEC2 * codec2_create(int mode) struct CODEC2 *c2; int i,l; -#ifndef CORTEX_M4 - if (( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, mode)) || - ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, mode)) ) { + // ALL POSSIBLE MODES MUST BE CHECKED HERE! + // we test if the desired mode is enabled at compile time + // and return NULL if not + + if (false == ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, mode) + || CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, mode) + || CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, mode) + || CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, mode) + || CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, mode) + || CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, mode) + || CODEC2_MODE_ACTIVE(CODEC2_MODE_700, mode) + || CODEC2_MODE_ACTIVE(CODEC2_MODE_700B, mode) + || CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, mode) + || CODEC2_MODE_ACTIVE(CODEC2_MODE_450, mode) + || CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, mode) + ) ) + { return NULL; } -#endif c2 = (struct CODEC2*)MALLOC(sizeof(struct CODEC2)); if (c2 == NULL) @@ -221,14 +235,15 @@ struct CODEC2 * codec2_create(int mode) int k; for(k=0; kprev_rate_K_vec_[k] = 0.0; + c2->eq[k] = 0.0; } + c2->eq_en = 0; c2->Wo_left = 0.0; c2->voicing_left = 0;; c2->phase_fft_fwd_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 0, NULL, NULL); c2->phase_fft_inv_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 1, NULL, NULL); } -#ifndef CORTEX_M4 /* newamp2 initialisation */ if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) { @@ -255,7 +270,6 @@ struct CODEC2 * codec2_create(int mode) c2->phase_fft_fwd_cfg = codec2_fft_alloc(NEWAMP2_PHASE_NFFT, 0, NULL, NULL); c2->phase_fft_inv_cfg = codec2_fft_alloc(NEWAMP2_PHASE_NFFT, 1, NULL, NULL); } -#endif c2->fmlfeat = NULL; @@ -302,7 +316,6 @@ struct CODEC2 * codec2_create(int mode) c2->decode = codec2_decode_1200; } -#ifndef CORTEX_M4 if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700, c2->mode)) { c2->encode = codec2_encode_700; @@ -314,13 +327,13 @@ struct CODEC2 * codec2_create(int mode) c2->encode = codec2_encode_700b; c2->decode = codec2_decode_700b; } -#endif + if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { c2->encode = codec2_encode_700c; c2->decode = codec2_decode_700c; } -#ifndef CORTEX_M4 + if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) { c2->encode = codec2_encode_450; @@ -334,7 +347,6 @@ struct CODEC2 * codec2_create(int mode) c2->decode = codec2_decode_450pwb; } -#endif return c2; } @@ -1518,7 +1530,6 @@ void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * } -#ifndef CORTEX_M4 /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_encode_700 @@ -1926,7 +1937,6 @@ void codec2_decode_700b(struct CODEC2 *c2, short speech[], const unsigned char * for(i=0; iprev_lsps_dec[i] = lsps[3][i]; } -#endif /*---------------------------------------------------------------------------*\ @@ -1987,7 +1997,7 @@ void codec2_encode_700c(struct CODEC2 *c2, unsigned char * bits, short speech[]) K, &mean, rate_K_vec_no_mean, - rate_K_vec_no_mean_, &c2->se); + rate_K_vec_no_mean_, &c2->se, c2->eq, c2->eq_en); c2->nse += K; #ifndef CORTEX_M4 @@ -2092,7 +2102,6 @@ float codec2_energy_700c(struct CODEC2 *c2, const unsigned char * bits) return POW10F(mean/10.0); } -#ifndef CORTEX_M4 float codec2_energy_450(struct CODEC2 *c2, const unsigned char * bits) { int indexes[4]; @@ -2418,7 +2427,6 @@ void codec2_decode_450pwb(struct CODEC2 *c2, short speech[], const unsigned char } } -#endif /*---------------------------------------------------------------------------* \ @@ -2719,3 +2727,8 @@ float *codec2_enable_user_ratek(struct CODEC2 *codec2_state, int *K) { void codec2_700c_post_filter(struct CODEC2 *codec2_state, int en) { codec2_state->post_filter_en = en; } + +void codec2_700c_eq(struct CODEC2 *codec2_state, int en) { + codec2_state->eq_en = en; + codec2_state->se = 0.0; codec2_state->nse = 0; +} diff --git a/codec2.h b/codec2.h index 60532ca..709b462 100644 --- a/codec2.h +++ b/codec2.h @@ -111,13 +111,16 @@ int codec2_rebuild_spare_bit(struct CODEC2 *codec2_state, int unpacked_bits[]); void codec2_set_natural_or_gray(struct CODEC2 *codec2_state, int gray); void codec2_set_softdec(struct CODEC2 *c2, float *softdec); float codec2_get_energy(struct CODEC2 *codec2_state, const unsigned char *bits); - + // support for ML and VQ experiments void codec2_open_mlfeat(struct CODEC2 *codec2_state, char *filename); void codec2_load_codebook(struct CODEC2 *codec2_state, int num, char *filename); float codec2_get_var(struct CODEC2 *codec2_state); float *codec2_enable_user_ratek(struct CODEC2 *codec2_state, int *K); + +// 700C post filter and equaliser void codec2_700c_post_filter(struct CODEC2 *codec2_state, int en); +void codec2_700c_eq(struct CODEC2 *codec2_state, int en); #endif diff --git a/codec2_internal.h b/codec2_internal.h index 498a6c4..b46e358 100644 --- a/codec2_internal.h +++ b/codec2_internal.h @@ -42,7 +42,7 @@ struct CODEC2 { 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 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_pitch] input speech */ @@ -82,6 +82,8 @@ struct CODEC2 { unsigned int nse; /* number of terms in sum */ float *user_rate_K_vec_no_mean_; /* optional, user supplied vector for quantisation experiments */ int post_filter_en; + float eq[NEWAMP1_K]; /* optional equaliser */ + int eq_en; /*newamp2 states (also uses newamp1 states )*/ float energy_prev; diff --git a/newamp1.c b/newamp1.c index 575620a..8980ac6 100644 --- a/newamp1.c +++ b/newamp1.c @@ -415,23 +415,38 @@ void newamp1_model_to_indexes(C2CONST *c2const, float *mean, float rate_K_vec_no_mean[], float rate_K_vec_no_mean_[], - float *se + float *se, + float *eq, + int eq_en ) { int k; /* convert variable rate L to fixed rate K */ - resample_const_rate_f(c2const, model, rate_K_vec, rate_K_sample_freqs_kHz, K); - /* remove mean and two stage VQ */ - + /* remove mean */ float sum = 0.0; for(k=0; kvoiced) { int index = encode_log_Wo(c2const, model->Wo, 6); if (index == 0) { diff --git a/newamp1.h b/newamp1.h index 7783abc..8c18813 100644 --- a/newamp1.h +++ b/newamp1.h @@ -55,7 +55,9 @@ void newamp1_model_to_indexes(C2CONST *c2const, float *mean, float rate_K_vec_no_mean[], float rate_K_vec_no_mean_[], - float *se); + float *se, + float *eq, + int eq_en); void newamp1_indexes_to_rate_K_vec(float rate_K_vec_[], float rate_K_vec_no_mean_[], float rate_K_sample_freqs_kHz[], diff --git a/nlp.c b/nlp.c index 8c8d5f1..036f6be 100644 --- a/nlp.c +++ b/nlp.c @@ -53,7 +53,6 @@ #define F0_MAX 500 #define CNLP 0.3 /* post processor constant */ #define NLP_NTAP 48 /* Decimation LPF order */ -#undef POST_PROCESS_MBE /* choose post processor */ /* 8 to 16 kHz sample rate conversion */ @@ -132,10 +131,6 @@ typedef struct { FILE *f; } NLP; -#ifdef POST_PROCESS_MBE -float test_candidate_mbe(COMP Sw[], COMP W[], float f0); -float post_process_mbe(COMP Fw[], int pmin, int pmax, float gmax, COMP Sw[], COMP W[], float *prev_Wo); -#endif float post_process_sub_multiples(COMP Fw[], int pmin, int pmax, float gmax, int gmax_bin, float *prev_f0); @@ -258,7 +253,7 @@ float nlp( int n, /* frames shift (no. new samples in Sn[]) */ float *pitch, /* estimated pitch period in samples at current Fs */ COMP Sw[], /* Freq domain version of Sn[] */ - COMP W[], /* Freq domain window */ + float W[], /* Freq domain window */ float *prev_f0 /* previous pitch f0 in Hz, memory for pitch tracking */ ) { @@ -389,11 +384,7 @@ float nlp( PROFILE_SAMPLE_AND_LOG(peakpick, magsq, " peak pick"); - #ifdef POST_PROCESS_MBE - best_f0 = post_process_mbe(Fw, pmin, pmax, gmax, Sw, W, prev_f0); - #else best_f0 = post_process_sub_multiples(Fw, pmin, pmax, gmax, gmax_bin, prev_f0); - #endif PROFILE_SAMPLE_AND_LOG(shiftmem, peakpick, " post process"); @@ -491,178 +482,6 @@ float post_process_sub_multiples(COMP Fw[], return best_f0; } -#ifdef POST_PROCESS_MBE - -/*---------------------------------------------------------------------------*\ - - post_process_mbe() - - Use the MBE pitch estimation algorithm to evaluate pitch candidates. This - works OK but the accuracy at low F0 is affected by NW, the analysis window - size used for the DFT of the input speech Sw[]. Also favours high F0 in - the presence of background noise which causes periodic artifacts in the - synthesised speech. - -\*---------------------------------------------------------------------------*/ - -float post_process_mbe(COMP Fw[], int pmin, int pmax, float gmax, COMP Sw[], COMP W[], float *prev_Wo) -{ - float candidate_f0; - float f0,best_f0; /* fundamental frequency */ - float e,e_min; /* MBE cost function */ - int i; - #ifdef DUMP - float e_hz[F0_MAX]; - #endif - #if !defined(NDEBUG) || defined(DUMP) - int bin; - #endif - float f0_min, f0_max; - float f0_start, f0_end; - - f0_min = (float)SAMPLE_RATE/pmax; - f0_max = (float)SAMPLE_RATE/pmin; - - /* Now look for local maxima. Each local maxima is a candidate - that we test using the MBE pitch estimation algotithm */ - - #ifdef DUMP - for(i=0; i Fw[i-1].real) && (Fw[i].real > Fw[i+1].real)) { - - /* local maxima found, lets test if it's big enough */ - - if (Fw[i].real > T*gmax) { - - /* OK, sample MBE cost function over +/- 10Hz range in 2.5Hz steps */ - - candidate_f0 = (float)i*SAMPLE_RATE/(PE_FFT_SIZE*DEC); - f0_start = candidate_f0-20; - f0_end = candidate_f0+20; - if (f0_start < f0_min) f0_start = f0_min; - if (f0_end > f0_max) f0_end = f0_max; - - for(f0=f0_start; f0<=f0_end; f0+= 2.5) { - e = test_candidate_mbe(Sw, W, f0); - #if !defined(NDEBUG) || defined(DUMP) - bin = floorf(f0); assert((bin > 0) && (bin < F0_MAX)); - #endif - #ifdef DUMP - e_hz[bin] = e; - #endif - if (e < e_min) { - e_min = e; - best_f0 = f0; - } - } - - } - } - } - - /* finally sample MBE cost function around previous pitch estimate - (form of pitch tracking) */ - - candidate_f0 = *prev_Wo * SAMPLE_RATE/TWO_PI; - f0_start = candidate_f0-20; - f0_end = candidate_f0+20; - if (f0_start < f0_min) f0_start = f0_min; - if (f0_end > f0_max) f0_end = f0_max; - - for(f0=f0_start; f0<=f0_end; f0+= 2.5) { - e = test_candidate_mbe(Sw, W, f0); - #if !defined(NDEBUG) || defined(DUMP) - bin = floorf(f0); assert((bin > 0) && (bin < F0_MAX)); - #endif - #ifdef DUMP - e_hz[bin] = e; - #endif - if (e < e_min) { - e_min = e; - best_f0 = f0; - } - } - - #ifdef DUMP - dump_e(e_hz); - #endif - - return best_f0; -} - -/*---------------------------------------------------------------------------*\ - - test_candidate_mbe() - - Returns the error of the MBE cost function for the input f0. - - Note: I think a lot of the operations below can be simplified as - W[].imag = 0 and has been normalised such that den always equals 1. - -\*---------------------------------------------------------------------------*/ - -float test_candidate_mbe( - COMP Sw[], - COMP W[], - float f0 -) -{ - COMP Sw_[FFT_ENC]; /* DFT of all voiced synthesised signal */ - int l,al,bl,m; /* loop variables */ - COMP Am; /* amplitude sample for this band */ - int offset; /* centers Hw[] about current harmonic */ - float den; /* denominator of Am expression */ - float error; /* accumulated error between originl and synthesised */ - float Wo; /* current "test" fundamental freq. */ - int L; - - L = floorf((SAMPLE_RATE/2.0)/f0); - Wo = f0*(2*PI/SAMPLE_RATE); - - error = 0.0; - - /* Just test across the harmonics in the first 1000 Hz (L/4) */ - - for(l=1; lm_pitch; int nw = c2const->nw; @@ -156,6 +155,8 @@ void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[ nw/2 nw/2 */ + COMP temp[FFT_ENC]; + for(i=0; iL; m++) { + /* Estimate ampltude of harmonic */ + den = 0.0; am = (int)((m - 0.5)*model->Wo*one_on_r + 0.5); bm = (int)((m + 0.5)*model->Wo*one_on_r + 0.5); - b = (int)(m*model->Wo/r + 0.5); - - /* Estimate ampltude of harmonic */ - den = 0.0; - Am.real = Am.imag = 0.0; - offset = FFT_ENC/2 - (int)(m*model->Wo*one_on_r + 0.5); for(i=am; iA[m] = sqrtf(den); if (est_phase) { + int b = (int)(m*model->Wo/r + 0.5); /* DFT bin of centre of current harmonic */ /* Estimate phase of harmonic, this is expensive in CPU for embedded devicesso we make it an option */ @@ -459,7 +447,7 @@ float est_voicing_mbe( C2CONST *c2const, MODEL *model, COMP Sw[], - COMP W[] + float W[] ) { int l,al,bl,m; /* loop variables */ @@ -497,9 +485,9 @@ float est_voicing_mbe( offset = FFT_ENC/2 - l*Wo*FFT_ENC/TWO_PI + 0.5; for(m=al; m "${DESTDIR}"/codec2.h +sed s:\:\"version.h\": src/codec2.h > "${DESTDIR}"/codec2.h cat > "${DESTDIR}"/debug_alloc.h <<'EOF' #define FREE free @@ -51,7 +51,7 @@ cd .. rm -r "${BUILDDIR}" cat > "${DESTDIR}"/Makefile <<'EOF' -CFLAGS = -Wall -Wno-strict-overflow -std=gnu11 -fPIC -g -O2 -I. +CFLAGS = -Wall -Wno-strict-overflow -std=gnu11 -fPIC -g -O2 -I. -lm CFLAGS += -DHORUS_L2_RX -DINTERLEAVER -DRUN_TIME_TABLES -DSCRAMBLER -Dcodec2_EXPORTS CFLAGS += -Wno-incompatible-pointer-types-discards-qualifiers diff --git a/version.h b/version.h index fc9891d..bae2151 100644 --- a/version.h +++ b/version.h @@ -31,7 +31,7 @@ #define CODEC2_VERSION_MAJOR 0 #define CODEC2_VERSION_MINOR 9 -/* #undef CODEC2_VERSION_PATCH */ -#define CODEC2_VERSION "0.9" +#define CODEC2_VERSION_PATCH 2 +#define CODEC2_VERSION "0.9.2" #endif //CODEC2_HAVE_VERSION -- cgit v1.2.3