From b86e88413d4c6ec428aaedb147f7675f28882fe4 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Fri, 14 Jul 2023 12:36:50 +0930 Subject: clang-format -i applied to src unittest misc --- src/codec2.c | 2980 ++++++++++++++++++++++++++++------------------------------ 1 file changed, 1439 insertions(+), 1541 deletions(-) (limited to 'src/codec2.c') diff --git a/src/codec2.c b/src/codec2.c index e0726d8..264141c 100644 --- a/src/codec2.c +++ b/src/codec2.c @@ -26,32 +26,32 @@ along with this program; if not, see . */ +#include "codec2.h" + #include +#include +#include #include #include -#include #include -#include -#include "defines.h" +#include "bpf.h" +#include "bpfb.h" #include "codec2_fft.h" -#include "sine.h" -#include "nlp.h" +#include "codec2_internal.h" +#include "debug_alloc.h" +#include "defines.h" #include "dump.h" -#include "lpc.h" -#include "quantise.h" -#include "phase.h" #include "interp.h" -#include "postfilter.h" -#include "codec2.h" +#include "lpc.h" #include "lsp.h" -#include "newamp2.h" -#include "codec2_internal.h" #include "machdep.h" -#include "bpf.h" -#include "bpfb.h" - -#include "debug_alloc.h" +#include "newamp2.h" +#include "nlp.h" +#include "phase.h" +#include "postfilter.h" +#include "quantise.h" +#include "sine.h" /*---------------------------------------------------------------------------* \ @@ -61,28 +61,35 @@ void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]); void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, - COMP Aw[], float gain); -void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[]); -void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * bits); -void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]); -void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * bits); -void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]); -void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char * bits); -void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]); -void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits); -void codec2_encode_1300(struct CODEC2 *c2, unsigned char * bits, short speech[]); -void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits, float ber_est); -void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]); -void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * bits); -void codec2_encode_700c(struct CODEC2 *c2, unsigned char * bits, short speech[]); -void codec2_decode_700c(struct CODEC2 *c2, short speech[], const unsigned char * bits); -void codec2_encode_450(struct CODEC2 *c2, unsigned char * bits, short speech[]); -void codec2_decode_450(struct CODEC2 *c2, short speech[], const unsigned char * bits); -void codec2_decode_450pwb(struct CODEC2 *c2, short speech[], const unsigned char * bits); + COMP Aw[], float gain); +void codec2_encode_3200(struct CODEC2 *c2, unsigned char *bits, short speech[]); +void codec2_decode_3200(struct CODEC2 *c2, short speech[], + const unsigned char *bits); +void codec2_encode_2400(struct CODEC2 *c2, unsigned char *bits, short speech[]); +void codec2_decode_2400(struct CODEC2 *c2, short speech[], + const unsigned char *bits); +void codec2_encode_1600(struct CODEC2 *c2, unsigned char *bits, short speech[]); +void codec2_decode_1600(struct CODEC2 *c2, short speech[], + const unsigned char *bits); +void codec2_encode_1400(struct CODEC2 *c2, unsigned char *bits, short speech[]); +void codec2_decode_1400(struct CODEC2 *c2, short speech[], + const unsigned char *bits); +void codec2_encode_1300(struct CODEC2 *c2, unsigned char *bits, short speech[]); +void codec2_decode_1300(struct CODEC2 *c2, short speech[], + const unsigned char *bits, float ber_est); +void codec2_encode_1200(struct CODEC2 *c2, unsigned char *bits, short speech[]); +void codec2_decode_1200(struct CODEC2 *c2, short speech[], + const unsigned char *bits); +void codec2_encode_700c(struct CODEC2 *c2, unsigned char *bits, short speech[]); +void codec2_decode_700c(struct CODEC2 *c2, short speech[], + const unsigned char *bits); +void codec2_encode_450(struct CODEC2 *c2, unsigned char *bits, short speech[]); +void codec2_decode_450(struct CODEC2 *c2, short speech[], + const unsigned char *bits); +void codec2_decode_450pwb(struct CODEC2 *c2, short speech[], + const unsigned char *bits); static void ear_protection(float in_out[], int n); - - /*---------------------------------------------------------------------------*\ FUNCTIONS @@ -103,228 +110,218 @@ static void ear_protection(float in_out[], int n); \*---------------------------------------------------------------------------*/ - -//Don't create CODEC2_MODE_450PWB for Encoding as it has undefined behavior ! -struct CODEC2 * codec2_create(int mode) -{ - struct CODEC2 *c2; - int i,l; - - // 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_700C, mode) - || CODEC2_MODE_ACTIVE(CODEC2_MODE_450, mode) - || CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, mode) - ) ) - { - return NULL; - } - - c2 = (struct CODEC2*)MALLOC(sizeof(struct CODEC2)); - if (c2 == NULL) - return NULL; - - c2->mode = mode; - - /* store constants in a few places for convenience */ - - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, mode) == 0) { - c2->c2const = c2const_create(8000, N_S); - }else{ - c2->c2const = c2const_create(16000, N_S); - } - c2->Fs = c2->c2const.Fs; - int n_samp = c2->n_samp = c2->c2const.n_samp; - int m_pitch = c2->m_pitch = c2->c2const.m_pitch; - - c2->Pn = (float*)MALLOC(2*n_samp*sizeof(float)); - if (c2->Pn == NULL) { - return NULL; - } - c2->Sn_ = (float*)MALLOC(2*n_samp*sizeof(float)); - if (c2->Sn_ == NULL) { - FREE(c2->Pn); - return NULL; - } - c2->w = (float*)MALLOC(m_pitch*sizeof(float)); - if (c2->w == NULL) { - FREE(c2->Pn); - FREE(c2->Sn_); - return NULL; - } - c2->Sn = (float*)MALLOC(m_pitch*sizeof(float)); - if (c2->Sn == NULL) { - FREE(c2->Pn); - FREE(c2->Sn_); - FREE(c2->w); - return NULL; - } - - 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 = codec2_fft_alloc(FFT_ENC, 0, NULL, NULL); - c2->fftr_fwd_cfg = codec2_fftr_alloc(FFT_ENC, 0, NULL, NULL); - make_analysis_window(&c2->c2const, c2->fft_fwd_cfg, c2->w,c2->W); - make_synthesis_window(&c2->c2const, c2->Pn); - c2->fftr_inv_cfg = codec2_fftr_alloc(FFT_DEC, 1, NULL, NULL); - c2->prev_f0_enc = 1/P_MAX_S; - c2->bg_est = 0.0; - c2->ex_phase = 0.0; - - for(l=1; l<=MAX_AMP; l++) - c2->prev_model_dec.A[l] = 0.0; - c2->prev_model_dec.Wo = TWO_PI/c2->c2const.p_max; - c2->prev_model_dec.L = PI/c2->prev_model_dec.Wo; - c2->prev_model_dec.voiced = 0; - - for(i=0; iprev_lsps_dec[i] = i*PI/(LPC_ORD+1); - } - c2->prev_e_dec = 1; - - c2->nlp = nlp_create(&c2->c2const); - if (c2->nlp == NULL) { - return NULL; - } - - c2->lpc_pf = 1; c2->bass_boost = 1; c2->beta = LPCPF_BETA; c2->gamma = LPCPF_GAMMA; - - c2->xq_enc[0] = c2->xq_enc[1] = 0.0; - c2->xq_dec[0] = c2->xq_dec[1] = 0.0; - - c2->smoothing = 0; - c2->se = 0.0; c2->nse = 0; - c2->user_rate_K_vec_no_mean_ = NULL; - c2->post_filter_en = true; - - c2->bpf_buf = (float*)MALLOC(sizeof(float)*(BPF_N+4*c2->n_samp)); - assert(c2->bpf_buf != NULL); - for(i=0; in_samp; i++) - c2->bpf_buf[i] = 0.0; - - c2->softdec = NULL; - c2->gray = 1; - - /* newamp1 initialisation */ - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { - mel_sample_freqs_kHz(c2->rate_K_sample_freqs_kHz, NEWAMP1_K, ftomel(200.0), ftomel(3700.0) ); - int k; - for(k=0; kprev_rate_K_vec_[k] = 0.0; - c2->eq[k] = 0.0; - } - c2->eq_en = false; - 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); - } - - /* newamp2 initialisation */ - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) { - n2_mel_sample_freqs_kHz(c2->n2_rate_K_sample_freqs_kHz, NEWAMP2_K); - int k; - for(k=0; kn2_prev_rate_K_vec_[k] = 0.0; - } - c2->Wo_left = 0.0; - c2->voicing_left = 0;; - 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); - } - /* newamp2 PWB initialisation */ - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { - n2_mel_sample_freqs_kHz(c2->n2_pwb_rate_K_sample_freqs_kHz, NEWAMP2_16K_K); - int k; - for(k=0; kn2_pwb_prev_rate_K_vec_[k] = 0.0; - } - c2->Wo_left = 0.0; - c2->voicing_left = 0;; - 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); - } - - c2->fmlfeat = NULL; c2->fmlmodel = NULL; - - // make sure that one of the two decode function pointers is empty - // for the encode function pointer this is not required since we always set it - // to a meaningful value - - c2->decode = NULL; - c2->decode_ber = NULL; - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) - { - c2->encode = codec2_encode_3200; - c2->decode = codec2_decode_3200; - } - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) - { - c2->encode = codec2_encode_2400; - c2->decode = codec2_decode_2400; - } - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) - { - c2->encode = codec2_encode_1600; - c2->decode = codec2_decode_1600; - } - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) - { - c2->encode = codec2_encode_1400; - c2->decode = codec2_decode_1400; - } - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) - { - c2->encode = codec2_encode_1300; - c2->decode_ber = codec2_decode_1300; - } - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) - { - c2->encode = codec2_encode_1200; - c2->decode = codec2_decode_1200; - } - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) - { - c2->encode = codec2_encode_700c; - c2->decode = codec2_decode_700c; - } - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) - { - c2->encode = codec2_encode_450; - c2->decode = codec2_decode_450; - } - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) - { - //Encode PWB doesn't make sense - c2->encode = codec2_encode_450; - c2->decode = codec2_decode_450pwb; - } - - - return c2; +// Don't create CODEC2_MODE_450PWB for Encoding as it has undefined behavior ! +struct CODEC2 *codec2_create(int mode) { + struct CODEC2 *c2; + int i, l; + + // 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_700C, mode) || + CODEC2_MODE_ACTIVE(CODEC2_MODE_450, mode) || + CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, mode))) { + return NULL; + } + + c2 = (struct CODEC2 *)MALLOC(sizeof(struct CODEC2)); + if (c2 == NULL) return NULL; + + c2->mode = mode; + + /* store constants in a few places for convenience */ + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, mode) == 0) { + c2->c2const = c2const_create(8000, N_S); + } else { + c2->c2const = c2const_create(16000, N_S); + } + c2->Fs = c2->c2const.Fs; + int n_samp = c2->n_samp = c2->c2const.n_samp; + int m_pitch = c2->m_pitch = c2->c2const.m_pitch; + + c2->Pn = (float *)MALLOC(2 * n_samp * sizeof(float)); + if (c2->Pn == NULL) { + return NULL; + } + c2->Sn_ = (float *)MALLOC(2 * n_samp * sizeof(float)); + if (c2->Sn_ == NULL) { + FREE(c2->Pn); + return NULL; + } + c2->w = (float *)MALLOC(m_pitch * sizeof(float)); + if (c2->w == NULL) { + FREE(c2->Pn); + FREE(c2->Sn_); + return NULL; + } + c2->Sn = (float *)MALLOC(m_pitch * sizeof(float)); + if (c2->Sn == NULL) { + FREE(c2->Pn); + FREE(c2->Sn_); + FREE(c2->w); + return NULL; + } + + for (i = 0; i < m_pitch; i++) c2->Sn[i] = 1.0; + c2->hpf_states[0] = c2->hpf_states[1] = 0.0; + for (i = 0; i < 2 * n_samp; i++) c2->Sn_[i] = 0; + c2->fft_fwd_cfg = codec2_fft_alloc(FFT_ENC, 0, NULL, NULL); + c2->fftr_fwd_cfg = codec2_fftr_alloc(FFT_ENC, 0, NULL, NULL); + make_analysis_window(&c2->c2const, c2->fft_fwd_cfg, c2->w, c2->W); + make_synthesis_window(&c2->c2const, c2->Pn); + c2->fftr_inv_cfg = codec2_fftr_alloc(FFT_DEC, 1, NULL, NULL); + c2->prev_f0_enc = 1 / P_MAX_S; + c2->bg_est = 0.0; + c2->ex_phase = 0.0; + + for (l = 1; l <= MAX_AMP; l++) c2->prev_model_dec.A[l] = 0.0; + c2->prev_model_dec.Wo = TWO_PI / c2->c2const.p_max; + c2->prev_model_dec.L = PI / c2->prev_model_dec.Wo; + c2->prev_model_dec.voiced = 0; + + for (i = 0; i < LPC_ORD; i++) { + c2->prev_lsps_dec[i] = i * PI / (LPC_ORD + 1); + } + c2->prev_e_dec = 1; + + c2->nlp = nlp_create(&c2->c2const); + if (c2->nlp == NULL) { + return NULL; + } + + c2->lpc_pf = 1; + c2->bass_boost = 1; + c2->beta = LPCPF_BETA; + c2->gamma = LPCPF_GAMMA; + + c2->xq_enc[0] = c2->xq_enc[1] = 0.0; + c2->xq_dec[0] = c2->xq_dec[1] = 0.0; + + c2->smoothing = 0; + c2->se = 0.0; + c2->nse = 0; + c2->user_rate_K_vec_no_mean_ = NULL; + c2->post_filter_en = true; + + c2->bpf_buf = (float *)MALLOC(sizeof(float) * (BPF_N + 4 * c2->n_samp)); + assert(c2->bpf_buf != NULL); + for (i = 0; i < BPF_N + 4 * c2->n_samp; i++) c2->bpf_buf[i] = 0.0; + + c2->softdec = NULL; + c2->gray = 1; + + /* newamp1 initialisation */ + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { + mel_sample_freqs_kHz(c2->rate_K_sample_freqs_kHz, NEWAMP1_K, ftomel(200.0), + ftomel(3700.0)); + int k; + for (k = 0; k < NEWAMP1_K; k++) { + c2->prev_rate_K_vec_[k] = 0.0; + c2->eq[k] = 0.0; + } + c2->eq_en = false; + 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); + } + + /* newamp2 initialisation */ + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) { + n2_mel_sample_freqs_kHz(c2->n2_rate_K_sample_freqs_kHz, NEWAMP2_K); + int k; + for (k = 0; k < NEWAMP2_K; k++) { + c2->n2_prev_rate_K_vec_[k] = 0.0; + } + c2->Wo_left = 0.0; + c2->voicing_left = 0; + ; + 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); + } + /* newamp2 PWB initialisation */ + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { + n2_mel_sample_freqs_kHz(c2->n2_pwb_rate_K_sample_freqs_kHz, NEWAMP2_16K_K); + int k; + for (k = 0; k < NEWAMP2_16K_K; k++) { + c2->n2_pwb_prev_rate_K_vec_[k] = 0.0; + } + c2->Wo_left = 0.0; + c2->voicing_left = 0; + ; + 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); + } + + c2->fmlfeat = NULL; + c2->fmlmodel = NULL; + + // make sure that one of the two decode function pointers is empty + // for the encode function pointer this is not required since we always set it + // to a meaningful value + + c2->decode = NULL; + c2->decode_ber = NULL; + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) { + c2->encode = codec2_encode_3200; + c2->decode = codec2_decode_3200; + } + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) { + c2->encode = codec2_encode_2400; + c2->decode = codec2_decode_2400; + } + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) { + c2->encode = codec2_encode_1600; + c2->decode = codec2_decode_1600; + } + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) { + c2->encode = codec2_encode_1400; + c2->decode = codec2_decode_1400; + } + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) { + c2->encode = codec2_encode_1300; + c2->decode_ber = codec2_decode_1300; + } + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) { + c2->encode = codec2_encode_1200; + c2->decode = codec2_decode_1200; + } + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { + c2->encode = codec2_encode_700c; + c2->decode = codec2_decode_700c; + } + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) { + c2->encode = codec2_encode_450; + c2->decode = codec2_decode_450; + } + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { + // Encode PWB doesn't make sense + c2->encode = codec2_encode_450; + c2->decode = codec2_decode_450pwb; + } + + return c2; } /*---------------------------------------------------------------------------*\ @@ -337,31 +334,30 @@ struct CODEC2 * codec2_create(int mode) \*---------------------------------------------------------------------------*/ -void codec2_destroy(struct CODEC2 *c2) -{ - assert(c2 != NULL); - FREE(c2->bpf_buf); - nlp_destroy(c2->nlp); - codec2_fft_free(c2->fft_fwd_cfg); - codec2_fftr_free(c2->fftr_fwd_cfg); - codec2_fftr_free(c2->fftr_inv_cfg); - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { - codec2_fft_free(c2->phase_fft_fwd_cfg); - codec2_fft_free(c2->phase_fft_inv_cfg); - } - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) { - codec2_fft_free(c2->phase_fft_fwd_cfg); - codec2_fft_free(c2->phase_fft_inv_cfg); - } - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { - codec2_fft_free(c2->phase_fft_fwd_cfg); - codec2_fft_free(c2->phase_fft_inv_cfg); - } - FREE(c2->Pn); - FREE(c2->Sn); - FREE(c2->w); - FREE(c2->Sn_); - FREE(c2); +void codec2_destroy(struct CODEC2 *c2) { + assert(c2 != NULL); + FREE(c2->bpf_buf); + nlp_destroy(c2->nlp); + codec2_fft_free(c2->fft_fwd_cfg); + codec2_fftr_free(c2->fftr_fwd_cfg); + codec2_fftr_free(c2->fftr_inv_cfg); + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { + codec2_fft_free(c2->phase_fft_fwd_cfg); + codec2_fft_free(c2->phase_fft_inv_cfg); + } + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) { + codec2_fft_free(c2->phase_fft_fwd_cfg); + codec2_fft_free(c2->phase_fft_inv_cfg); + } + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { + codec2_fft_free(c2->phase_fft_fwd_cfg); + codec2_fft_free(c2->phase_fft_inv_cfg); + } + FREE(c2->Pn); + FREE(c2->Sn); + FREE(c2->w); + FREE(c2->Sn_); + FREE(c2); } /*---------------------------------------------------------------------------*\ @@ -375,29 +371,19 @@ void codec2_destroy(struct CODEC2 *c2) \*---------------------------------------------------------------------------*/ int codec2_bits_per_frame(struct CODEC2 *c2) { - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) - return 64; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) - return 48; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) - return 64; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) - return 56; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) - return 52; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) - return 48; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) - return 28; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) - return 18; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) - return 18; - - return 0; /* shouldn't get here */ + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) return 64; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) return 48; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) return 64; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) return 56; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) return 52; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) return 48; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) return 28; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) return 18; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) return 18; + + return 0; /* shouldn't get here */ } - /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_bytes_per_frame @@ -410,10 +396,9 @@ int codec2_bits_per_frame(struct CODEC2 *c2) { \*---------------------------------------------------------------------------*/ int codec2_bytes_per_frame(struct CODEC2 *c2) { - return (codec2_bits_per_frame(c2)+7)/8; + return (codec2_bits_per_frame(c2) + 7) / 8; } - /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_samples_per_frame @@ -425,28 +410,18 @@ int codec2_bytes_per_frame(struct CODEC2 *c2) { \*---------------------------------------------------------------------------*/ int codec2_samples_per_frame(struct CODEC2 *c2) { - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) - return 160; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) - return 160; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) - return 320; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) - return 320; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) - return 320; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) - return 320; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) - return 320; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) - return 320; - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) - return 640; - return 0; /* shouldn't get here */ + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) return 160; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) return 160; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) return 320; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) return 320; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) return 320; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) return 320; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) return 320; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) return 320; + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) return 640; + return 0; /* shouldn't get here */ } - /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_encode @@ -458,13 +433,11 @@ int codec2_samples_per_frame(struct CODEC2 *c2) { \*---------------------------------------------------------------------------*/ -void codec2_encode(struct CODEC2 *c2, unsigned char *bytes, short speech[]) -{ - assert(c2 != NULL); - assert(c2->encode != NULL); - - c2->encode(c2, bytes, speech); +void codec2_encode(struct CODEC2 *c2, unsigned char *bytes, short speech[]) { + assert(c2 != NULL); + assert(c2->encode != NULL); + c2->encode(c2, bytes, speech); } /*---------------------------------------------------------------------------*\ @@ -478,27 +451,23 @@ void codec2_encode(struct CODEC2 *c2, unsigned char *bytes, short speech[]) \*---------------------------------------------------------------------------*/ -void codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bytes) -{ - codec2_decode_ber(c2, speech, bytes, 0.0); +void codec2_decode(struct CODEC2 *c2, short speech[], + const unsigned char *bytes) { + codec2_decode_ber(c2, speech, bytes, 0.0); } -void codec2_decode_ber(struct CODEC2 *c2, short speech[], const unsigned char *bits, float ber_est) -{ - assert(c2 != NULL); - assert(c2->decode != NULL || c2->decode_ber != NULL); +void codec2_decode_ber(struct CODEC2 *c2, short speech[], + const unsigned char *bits, float ber_est) { + assert(c2 != NULL); + assert(c2->decode != NULL || c2->decode_ber != NULL); - if (c2->decode != NULL) - { - c2->decode(c2, speech, bits); - } - else - { - c2->decode_ber(c2, speech, bits, ber_est); - } + if (c2->decode != NULL) { + c2->decode(c2, speech, bits); + } else { + c2->decode_ber(c2, speech, bits, ber_est); + } } - /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_encode_3200 @@ -526,45 +495,44 @@ void codec2_decode_ber(struct CODEC2 *c2, short speech[], const unsigned char *b \*---------------------------------------------------------------------------*/ -void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[]) -{ - MODEL model; - float ak[LPC_ORD+1]; - float lsps[LPC_ORD]; - float e; - int Wo_index, e_index; - int lspd_indexes[LPC_ORD]; - int i; - unsigned int nbit = 0; +void codec2_encode_3200(struct CODEC2 *c2, unsigned char *bits, + short speech[]) { + MODEL model; + float ak[LPC_ORD + 1]; + float lsps[LPC_ORD]; + float e; + int Wo_index, e_index; + int lspd_indexes[LPC_ORD]; + int i; + unsigned int nbit = 0; - assert(c2 != NULL); + assert(c2 != NULL); - memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); - /* first 10ms analysis frame - we just want voicing */ + /* first 10ms analysis frame - we just want voicing */ - analyse_one_frame(c2, &model, speech); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, speech); + pack(bits, &nbit, model.voiced, 1); - /* second 10ms analysis frame */ + /* second 10ms analysis frame */ - analyse_one_frame(c2, &model, &speech[c2->n_samp]); - pack(bits, &nbit, model.voiced, 1); - Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); - pack(bits, &nbit, Wo_index, WO_BITS); + analyse_one_frame(c2, &model, &speech[c2->n_samp]); + pack(bits, &nbit, model.voiced, 1); + Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); + pack(bits, &nbit, Wo_index, WO_BITS); - e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); - e_index = encode_energy(e, E_BITS); - pack(bits, &nbit, e_index, E_BITS); + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); + e_index = encode_energy(e, E_BITS); + pack(bits, &nbit, e_index, E_BITS); - encode_lspds_scalar(lspd_indexes, lsps, LPC_ORD); - for(i=0; ic2const, Wo_index, WO_BITS); - model[1].L = PI/model[1].Wo; + Wo_index = unpack(bits, &nbit, WO_BITS); + model[1].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); + model[1].L = PI / model[1].Wo; - e_index = unpack(bits, &nbit, E_BITS); - e[1] = decode_energy(e_index, E_BITS); + e_index = unpack(bits, &nbit, E_BITS); + e[1] = decode_energy(e_index, E_BITS); - for(i=0; iprev_model_dec, &model[1], c2->c2const.Wo_min); - e[0] = interp_energy(c2->prev_e_dec, e[1]); + interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); + e[0] = interp_energy(c2->prev_e_dec, e[1]); - /* LSPs are sampled every 20ms so we interpolate the frame in - between, then recover spectral amplitudes */ + /* LSPs are sampled every 20ms so we interpolate the frame in + between, then recover spectral amplitudes */ - interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5, LPC_ORD); + interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5, + LPC_ORD); - for(i=0; i<2; i++) { - lsp_to_lpc(&lsps[i][0], &ak[i][0], 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[c2->n_samp*i], &model[i], Aw, 1.0); - } + for (i = 0; i < 2; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], 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[c2->n_samp * i], &model[i], Aw, 1.0); + } - /* update memories for next frame ----------------------------*/ + /* update memories for next frame ----------------------------*/ - c2->prev_model_dec = model[1]; - c2->prev_e_dec = e[1]; - for(i=0; iprev_lsps_dec[i] = lsps[1][i]; + c2->prev_model_dec = model[1]; + c2->prev_e_dec = e[1]; + for (i = 0; i < LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[1][i]; } - /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_encode_2400 @@ -671,46 +637,45 @@ void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * \*---------------------------------------------------------------------------*/ -void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]) -{ - MODEL model; - float ak[LPC_ORD+1]; - float lsps[LPC_ORD]; - float e; - int WoE_index; - int lsp_indexes[LPC_ORD]; - int i; - int spare = 0; - unsigned int nbit = 0; +void codec2_encode_2400(struct CODEC2 *c2, unsigned char *bits, + short speech[]) { + MODEL model; + float ak[LPC_ORD + 1]; + float lsps[LPC_ORD]; + float e; + int WoE_index; + int lsp_indexes[LPC_ORD]; + int i; + int spare = 0; + unsigned int nbit = 0; - assert(c2 != NULL); + assert(c2 != NULL); - memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); - /* first 10ms analysis frame - we just want voicing */ + /* first 10ms analysis frame - we just want voicing */ - analyse_one_frame(c2, &model, speech); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, speech); + pack(bits, &nbit, model.voiced, 1); - /* second 10ms analysis frame */ + /* second 10ms analysis frame */ - analyse_one_frame(c2, &model, &speech[c2->n_samp]); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, &speech[c2->n_samp]); + pack(bits, &nbit, model.voiced, 1); - e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); - WoE_index = encode_WoE(&model, e, c2->xq_enc); - pack(bits, &nbit, WoE_index, WO_E_BITS); + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); + WoE_index = encode_WoE(&model, e, c2->xq_enc); + pack(bits, &nbit, WoE_index, WO_E_BITS); - encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); - for(i=0; ic2const, &model[1], &e[1], c2->xq_dec, WoE_index); + model[1].voiced = unpack(bits, &nbit, 1); + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&c2->c2const, &model[1], &e[1], c2->xq_dec, WoE_index); - for(i=0; iprev_model_dec, &model[1], c2->c2const.Wo_min); - e[0] = interp_energy(c2->prev_e_dec, e[1]); - - /* LSPs are sampled every 20ms so we interpolate the frame in - between, then recover spectral amplitudes */ - - interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5, LPC_ORD); - for(i=0; i<2; i++) { - lsp_to_lpc(&lsps[i][0], &ak[i][0], 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[c2->n_samp*i], &model[i], Aw, 1.0); - - /* dump parameters for deep learning experiments */ - - if (c2->fmlfeat != NULL) { - /* 10 LSPs - energy - Wo - voicing flag - 10 LPCs */ - fwrite(&lsps[i][0], LPC_ORD, sizeof(float), c2->fmlfeat); - fwrite(&e[i], 1, sizeof(float), c2->fmlfeat); - fwrite(&model[i].Wo, 1, sizeof(float), c2->fmlfeat); - float voiced_float = model[i].voiced; - fwrite(&voiced_float, 1, sizeof(float), c2->fmlfeat); - fwrite(&ak[i][1], LPC_ORD, sizeof(float), c2->fmlfeat); - } + for (i = 0; i < LSP_SCALAR_INDEXES; i++) { + lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); + } + decode_lsps_scalar(&lsps[1][0], lsp_indexes, LPC_ORD); + check_lsp_order(&lsps[1][0], LPC_ORD); + bw_expand_lsps(&lsps[1][0], LPC_ORD, 50.0, 100.0); + + /* interpolate ------------------------------------------------*/ + + /* Wo and energy are sampled every 20ms, so we interpolate just 1 + 10ms frame between 20ms samples */ + + interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); + e[0] = interp_energy(c2->prev_e_dec, e[1]); + + /* LSPs are sampled every 20ms so we interpolate the frame in + between, then recover spectral amplitudes */ + + interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5, + LPC_ORD); + for (i = 0; i < 2; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], 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[c2->n_samp * i], &model[i], Aw, 1.0); + + /* dump parameters for deep learning experiments */ + + if (c2->fmlfeat != NULL) { + /* 10 LSPs - energy - Wo - voicing flag - 10 LPCs */ + fwrite(&lsps[i][0], LPC_ORD, sizeof(float), c2->fmlfeat); + fwrite(&e[i], 1, sizeof(float), c2->fmlfeat); + fwrite(&model[i].Wo, 1, sizeof(float), c2->fmlfeat); + float voiced_float = model[i].voiced; + fwrite(&voiced_float, 1, sizeof(float), c2->fmlfeat); + fwrite(&ak[i][1], LPC_ORD, sizeof(float), c2->fmlfeat); } + } - /* update memories for next frame ----------------------------*/ + /* update memories for next frame ----------------------------*/ - c2->prev_model_dec = model[1]; - c2->prev_e_dec = e[1]; - for(i=0; iprev_lsps_dec[i] = lsps[1][i]; + c2->prev_model_dec = model[1]; + c2->prev_e_dec = e[1]; + for (i = 0; i < LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[1][i]; } - /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_encode_1600 @@ -829,65 +792,64 @@ void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * \*---------------------------------------------------------------------------*/ -void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]) -{ - MODEL model; - float lsps[LPC_ORD]; - float ak[LPC_ORD+1]; - float e; - int lsp_indexes[LPC_ORD]; - int Wo_index, e_index; - int i; - unsigned int nbit = 0; +void codec2_encode_1600(struct CODEC2 *c2, unsigned char *bits, + short speech[]) { + MODEL model; + float lsps[LPC_ORD]; + float ak[LPC_ORD + 1]; + float e; + int lsp_indexes[LPC_ORD]; + int Wo_index, e_index; + int i; + unsigned int nbit = 0; - assert(c2 != NULL); + assert(c2 != NULL); - memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); - /* frame 1: - voicing ---------------------------------------------*/ + /* frame 1: - voicing ---------------------------------------------*/ - analyse_one_frame(c2, &model, speech); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, speech); + pack(bits, &nbit, model.voiced, 1); - /* frame 2: - voicing, scalar Wo & E -------------------------------*/ + /* frame 2: - voicing, scalar Wo & E -------------------------------*/ - analyse_one_frame(c2, &model, &speech[c2->n_samp]); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, &speech[c2->n_samp]); + pack(bits, &nbit, model.voiced, 1); - Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); - pack(bits, &nbit, Wo_index, WO_BITS); + Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); + pack(bits, &nbit, Wo_index, WO_BITS); - /* need to run this just to get LPC energy */ - e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); - e_index = encode_energy(e, E_BITS); - pack(bits, &nbit, e_index, E_BITS); + /* need to run this just to get LPC energy */ + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); + e_index = encode_energy(e, E_BITS); + pack(bits, &nbit, e_index, E_BITS); - /* frame 3: - voicing ---------------------------------------------*/ + /* frame 3: - voicing ---------------------------------------------*/ - analyse_one_frame(c2, &model, &speech[2*c2->n_samp]); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, &speech[2 * c2->n_samp]); + pack(bits, &nbit, model.voiced, 1); - /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ + /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ - analyse_one_frame(c2, &model, &speech[3*c2->n_samp]); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, &speech[3 * c2->n_samp]); + pack(bits, &nbit, model.voiced, 1); - Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); - pack(bits, &nbit, Wo_index, WO_BITS); + Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); + pack(bits, &nbit, Wo_index, WO_BITS); - e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); - e_index = encode_energy(e, E_BITS); - pack(bits, &nbit, e_index, E_BITS); + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); + e_index = encode_energy(e, E_BITS); + pack(bits, &nbit, e_index, E_BITS); - encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); - for(i=0; ic2const, Wo_index, WO_BITS); - model[1].L = PI/model[1].Wo; - - e_index = unpack(bits, &nbit, E_BITS); - e[1] = decode_energy(e_index, E_BITS); - - model[2].voiced = unpack(bits, &nbit, 1); - - model[3].voiced = unpack(bits, &nbit, 1); - Wo_index = unpack(bits, &nbit, WO_BITS); - model[3].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); - model[3].L = PI/model[3].Wo; - - e_index = unpack(bits, &nbit, E_BITS); - e[3] = decode_energy(e_index, E_BITS); - - for(i=0; iprev_model_dec, &model[1], c2->c2const.Wo_min); - e[0] = interp_energy(c2->prev_e_dec, e[1]); - interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min); - e[2] = interp_energy(e[1], e[3]); - - /* LSPs are sampled every 40ms so we interpolate the 3 frames in - between, then recover spectral amplitudes */ - - for(i=0, weight=0.25; i<3; i++, weight += 0.25) { - interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD); - } - for(i=0; i<4; i++) { - lsp_to_lpc(&lsps[i][0], &ak[i][0], 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[c2->n_samp*i], &model[i], Aw, 1.0); - } - - /* update memories for next frame ----------------------------*/ - - c2->prev_model_dec = model[3]; - c2->prev_e_dec = e[3]; - for(i=0; iprev_lsps_dec[i] = lsps[3][i]; - +void codec2_decode_1600(struct CODEC2 *c2, short speech[], + const unsigned char *bits) { + MODEL model[4]; + int lsp_indexes[LPC_ORD]; + float lsps[4][LPC_ORD]; + int Wo_index, e_index; + float e[4]; + float snr; + float ak[4][LPC_ORD + 1]; + int i, j; + unsigned int nbit = 0; + float weight; + COMP Aw[FFT_ENC]; + + assert(c2 != NULL); + + /* only need to zero these out due to (unused) snr calculation */ + + for (i = 0; i < 4; i++) + for (j = 1; j <= MAX_AMP; j++) model[i].A[j] = 0.0; + + /* unpack bits from channel ------------------------------------*/ + + /* this will partially fill the model params for the 4 x 10ms + frames */ + + model[0].voiced = unpack(bits, &nbit, 1); + + model[1].voiced = unpack(bits, &nbit, 1); + Wo_index = unpack(bits, &nbit, WO_BITS); + model[1].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); + model[1].L = PI / model[1].Wo; + + e_index = unpack(bits, &nbit, E_BITS); + e[1] = decode_energy(e_index, E_BITS); + + model[2].voiced = unpack(bits, &nbit, 1); + + model[3].voiced = unpack(bits, &nbit, 1); + Wo_index = unpack(bits, &nbit, WO_BITS); + model[3].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); + model[3].L = PI / model[3].Wo; + + e_index = unpack(bits, &nbit, E_BITS); + e[3] = decode_energy(e_index, E_BITS); + + for (i = 0; i < LSP_SCALAR_INDEXES; i++) { + lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); + } + decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); + check_lsp_order(&lsps[3][0], LPC_ORD); + bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); + + /* interpolate ------------------------------------------------*/ + + /* Wo and energy are sampled every 20ms, so we interpolate just 1 + 10ms frame between 20ms samples */ + + interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); + e[0] = interp_energy(c2->prev_e_dec, e[1]); + interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min); + e[2] = interp_energy(e[1], e[3]); + + /* LSPs are sampled every 40ms so we interpolate the 3 frames in + between, then recover spectral amplitudes */ + + for (i = 0, weight = 0.25; i < 3; i++, weight += 0.25) { + interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, + LPC_ORD); + } + for (i = 0; i < 4; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], 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[c2->n_samp * i], &model[i], Aw, 1.0); + } + + /* update memories for next frame ----------------------------*/ + + c2->prev_model_dec = model[3]; + c2->prev_e_dec = e[3]; + for (i = 0; i < LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[3][i]; } /*---------------------------------------------------------------------------*\ @@ -1012,60 +972,59 @@ void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char * \*---------------------------------------------------------------------------*/ -void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]) -{ - MODEL model; - float lsps[LPC_ORD]; - float ak[LPC_ORD+1]; - float e; - int lsp_indexes[LPC_ORD]; - int WoE_index; - int i; - unsigned int nbit = 0; +void codec2_encode_1400(struct CODEC2 *c2, unsigned char *bits, + short speech[]) { + MODEL model; + float lsps[LPC_ORD]; + float ak[LPC_ORD + 1]; + float e; + int lsp_indexes[LPC_ORD]; + int WoE_index; + int i; + unsigned int nbit = 0; - assert(c2 != NULL); + assert(c2 != NULL); - memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); - /* frame 1: - voicing ---------------------------------------------*/ + /* frame 1: - voicing ---------------------------------------------*/ - analyse_one_frame(c2, &model, speech); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, speech); + pack(bits, &nbit, model.voiced, 1); - /* frame 2: - voicing, joint Wo & E -------------------------------*/ + /* frame 2: - voicing, joint Wo & E -------------------------------*/ - analyse_one_frame(c2, &model, &speech[c2->n_samp]); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, &speech[c2->n_samp]); + pack(bits, &nbit, model.voiced, 1); - /* need to run this just to get LPC energy */ - e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); + /* need to run this just to get LPC energy */ + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); - WoE_index = encode_WoE(&model, e, c2->xq_enc); - pack(bits, &nbit, WoE_index, WO_E_BITS); + WoE_index = encode_WoE(&model, e, c2->xq_enc); + pack(bits, &nbit, WoE_index, WO_E_BITS); - /* frame 3: - voicing ---------------------------------------------*/ + /* frame 3: - voicing ---------------------------------------------*/ - analyse_one_frame(c2, &model, &speech[2*c2->n_samp]); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, &speech[2 * c2->n_samp]); + pack(bits, &nbit, model.voiced, 1); - /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/ + /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/ - analyse_one_frame(c2, &model, &speech[3*c2->n_samp]); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, &speech[3 * c2->n_samp]); + pack(bits, &nbit, model.voiced, 1); - e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); - WoE_index = encode_WoE(&model, e, c2->xq_enc); - pack(bits, &nbit, WoE_index, WO_E_BITS); + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); + WoE_index = encode_WoE(&model, e, c2->xq_enc); + pack(bits, &nbit, WoE_index, WO_E_BITS); - encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); - for(i=0; ic2const, &model[1], &e[1], c2->xq_dec, WoE_index); - - model[2].voiced = unpack(bits, &nbit, 1); - - model[3].voiced = unpack(bits, &nbit, 1); - WoE_index = unpack(bits, &nbit, WO_E_BITS); - decode_WoE(&c2->c2const, &model[3], &e[3], c2->xq_dec, WoE_index); - - for(i=0; iprev_model_dec, &model[1], c2->c2const.Wo_min); - e[0] = interp_energy(c2->prev_e_dec, e[1]); - interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min); - e[2] = interp_energy(e[1], e[3]); - - /* LSPs are sampled every 40ms so we interpolate the 3 frames in - between, then recover spectral amplitudes */ - - for(i=0, weight=0.25; i<3; i++, weight += 0.25) { - interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD); - } - for(i=0; i<4; i++) { - lsp_to_lpc(&lsps[i][0], &ak[i][0], 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[c2->n_samp*i], &model[i], Aw, 1.0); - } - - /* update memories for next frame ----------------------------*/ - - c2->prev_model_dec = model[3]; - c2->prev_e_dec = e[3]; - for(i=0; iprev_lsps_dec[i] = lsps[3][i]; - +void codec2_decode_1400(struct CODEC2 *c2, short speech[], + const unsigned char *bits) { + MODEL model[4]; + int lsp_indexes[LPC_ORD]; + float lsps[4][LPC_ORD]; + int WoE_index; + float e[4]; + float snr; + float ak[4][LPC_ORD + 1]; + int i, j; + unsigned int nbit = 0; + float weight; + COMP Aw[FFT_ENC]; + + assert(c2 != NULL); + + /* only need to zero these out due to (unused) snr calculation */ + + for (i = 0; i < 4; i++) + for (j = 1; j <= MAX_AMP; j++) model[i].A[j] = 0.0; + + /* unpack bits from channel ------------------------------------*/ + + /* this will partially fill the model params for the 4 x 10ms + frames */ + + model[0].voiced = unpack(bits, &nbit, 1); + + model[1].voiced = unpack(bits, &nbit, 1); + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&c2->c2const, &model[1], &e[1], c2->xq_dec, WoE_index); + + model[2].voiced = unpack(bits, &nbit, 1); + + model[3].voiced = unpack(bits, &nbit, 1); + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&c2->c2const, &model[3], &e[3], c2->xq_dec, WoE_index); + + for (i = 0; i < LSP_SCALAR_INDEXES; i++) { + lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); + } + decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); + check_lsp_order(&lsps[3][0], LPC_ORD); + bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); + + /* interpolate ------------------------------------------------*/ + + /* Wo and energy are sampled every 20ms, so we interpolate just 1 + 10ms frame between 20ms samples */ + + interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); + e[0] = interp_energy(c2->prev_e_dec, e[1]); + interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min); + e[2] = interp_energy(e[1], e[3]); + + /* LSPs are sampled every 40ms so we interpolate the 3 frames in + between, then recover spectral amplitudes */ + + for (i = 0, weight = 0.25; i < 3; i++, weight += 0.25) { + interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, + LPC_ORD); + } + for (i = 0; i < 4; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], 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[c2->n_samp * i], &model[i], Aw, 1.0); + } + + /* update memories for next frame ----------------------------*/ + + c2->prev_model_dec = model[3]; + c2->prev_e_dec = e[3]; + for (i = 0; i < LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[3][i]; } /*---------------------------------------------------------------------------*\ @@ -1183,56 +1140,55 @@ void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * \*---------------------------------------------------------------------------*/ -void codec2_encode_1300(struct CODEC2 *c2, unsigned char * bits, short speech[]) -{ - MODEL model; - float lsps[LPC_ORD]; - float ak[LPC_ORD+1]; - float e; - int lsp_indexes[LPC_ORD]; - int Wo_index, e_index; - int i; - unsigned int nbit = 0; - - assert(c2 != NULL); +void codec2_encode_1300(struct CODEC2 *c2, unsigned char *bits, + short speech[]) { + MODEL model; + float lsps[LPC_ORD]; + float ak[LPC_ORD + 1]; + float e; + int lsp_indexes[LPC_ORD]; + int Wo_index, e_index; + int i; + unsigned int nbit = 0; - memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + assert(c2 != NULL); - /* frame 1: - voicing ---------------------------------------------*/ + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); - analyse_one_frame(c2, &model, speech); - pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); + /* frame 1: - voicing ---------------------------------------------*/ - /* frame 2: - voicing ---------------------------------------------*/ + analyse_one_frame(c2, &model, speech); + pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); - analyse_one_frame(c2, &model, &speech[c2->n_samp]); - pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); + /* frame 2: - voicing ---------------------------------------------*/ - /* frame 3: - voicing ---------------------------------------------*/ + analyse_one_frame(c2, &model, &speech[c2->n_samp]); + pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); - analyse_one_frame(c2, &model, &speech[2*c2->n_samp]); - pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); + /* frame 3: - voicing ---------------------------------------------*/ - /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ + analyse_one_frame(c2, &model, &speech[2 * c2->n_samp]); + pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); - analyse_one_frame(c2, &model, &speech[3*c2->n_samp]); - pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); + /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ - Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); - pack_natural_or_gray(bits, &nbit, Wo_index, WO_BITS, c2->gray); + analyse_one_frame(c2, &model, &speech[3 * c2->n_samp]); + pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); - e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); - e_index = encode_energy(e, E_BITS); - pack_natural_or_gray(bits, &nbit, e_index, E_BITS, c2->gray); + Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); + pack_natural_or_gray(bits, &nbit, Wo_index, WO_BITS, c2->gray); - encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); - for(i=0; igray); - } + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); + e_index = encode_energy(e, E_BITS); + pack_natural_or_gray(bits, &nbit, e_index, E_BITS, c2->gray); - assert(nbit == (unsigned)codec2_bits_per_frame(c2)); -} + encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); + for (i = 0; i < LSP_SCALAR_INDEXES; i++) { + pack_natural_or_gray(bits, &nbit, lsp_indexes[i], lsp_bits(i), c2->gray); + } + assert(nbit == (unsigned)codec2_bits_per_frame(c2)); +} /*---------------------------------------------------------------------------*\ @@ -1244,107 +1200,105 @@ void codec2_encode_1300(struct CODEC2 *c2, unsigned char * bits, short speech[]) \*---------------------------------------------------------------------------*/ -void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits, float ber_est) -{ - MODEL model[4]; - int lsp_indexes[LPC_ORD]; - float lsps[4][LPC_ORD]; - int Wo_index, e_index; - float e[4]; - float snr; - float ak[4][LPC_ORD+1]; - int i,j; - unsigned int nbit = 0; - float weight; - COMP Aw[FFT_ENC]; - - assert(c2 != NULL); - - /* only need to zero these out due to (unused) snr calculation */ - - for(i=0; i<4; i++) - for(j=1; j<=MAX_AMP; j++) - model[i].A[j] = 0.0; - - /* unpack bits from channel ------------------------------------*/ - - /* this will partially fill the model params for the 4 x 10ms - frames */ - - model[0].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); - model[1].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); - model[2].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); - model[3].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); - - Wo_index = unpack_natural_or_gray(bits, &nbit, WO_BITS, c2->gray); - model[3].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); - model[3].L = PI/model[3].Wo; - - e_index = unpack_natural_or_gray(bits, &nbit, E_BITS, c2->gray); - e[3] = decode_energy(e_index, E_BITS); - - for(i=0; igray); - } - decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); - check_lsp_order(&lsps[3][0], LPC_ORD); - bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); - - if (ber_est > 0.15) { - model[0].voiced = model[1].voiced = model[2].voiced = model[3].voiced = 0; - e[3] = decode_energy(10, E_BITS); - bw_expand_lsps(&lsps[3][0], LPC_ORD, 200.0, 200.0); - //fprintf(stderr, "soft mute\n"); - } - - /* interpolate ------------------------------------------------*/ +void codec2_decode_1300(struct CODEC2 *c2, short speech[], + const unsigned char *bits, float ber_est) { + MODEL model[4]; + int lsp_indexes[LPC_ORD]; + float lsps[4][LPC_ORD]; + int Wo_index, e_index; + float e[4]; + float snr; + float ak[4][LPC_ORD + 1]; + int i, j; + unsigned int nbit = 0; + float weight; + COMP Aw[FFT_ENC]; + + assert(c2 != NULL); + + /* only need to zero these out due to (unused) snr calculation */ + + for (i = 0; i < 4; i++) + for (j = 1; j <= MAX_AMP; j++) model[i].A[j] = 0.0; + + /* unpack bits from channel ------------------------------------*/ + + /* this will partially fill the model params for the 4 x 10ms + frames */ + + model[0].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); + model[1].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); + model[2].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); + model[3].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); + + Wo_index = unpack_natural_or_gray(bits, &nbit, WO_BITS, c2->gray); + model[3].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); + model[3].L = PI / model[3].Wo; + + e_index = unpack_natural_or_gray(bits, &nbit, E_BITS, c2->gray); + e[3] = decode_energy(e_index, E_BITS); + + for (i = 0; i < LSP_SCALAR_INDEXES; i++) { + lsp_indexes[i] = unpack_natural_or_gray(bits, &nbit, lsp_bits(i), c2->gray); + } + decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); + check_lsp_order(&lsps[3][0], LPC_ORD); + bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); + + if (ber_est > 0.15) { + model[0].voiced = model[1].voiced = model[2].voiced = model[3].voiced = 0; + e[3] = decode_energy(10, E_BITS); + bw_expand_lsps(&lsps[3][0], LPC_ORD, 200.0, 200.0); + // fprintf(stderr, "soft mute\n"); + } + + /* interpolate ------------------------------------------------*/ + + /* Wo, energy, and LSPs are sampled every 40ms so we interpolate + the 3 frames in between */ + + for (i = 0, weight = 0.25; i < 3; i++, weight += 0.25) { + interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, + LPC_ORD); + interp_Wo2(&model[i], &c2->prev_model_dec, &model[3], weight, + c2->c2const.Wo_min); + e[i] = interp_energy2(c2->prev_e_dec, e[3], weight); + } + + /* then recover spectral amplitudes */ + + for (i = 0; i < 4; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], 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[c2->n_samp * i], &model[i], Aw, 1.0); + + /* dump parameters for deep learning experiments */ - /* Wo, energy, and LSPs are sampled every 40ms so we interpolate - the 3 frames in between */ - - for(i=0, weight=0.25; i<3; i++, weight += 0.25) { - interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD); - interp_Wo2(&model[i], &c2->prev_model_dec, &model[3], weight, c2->c2const.Wo_min); - e[i] = interp_energy2(c2->prev_e_dec, e[3],weight); - } - - /* then recover spectral amplitudes */ - - for(i=0; i<4; i++) { - lsp_to_lpc(&lsps[i][0], &ak[i][0], 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[c2->n_samp*i], &model[i], Aw, 1.0); - - /* dump parameters for deep learning experiments */ - - if (c2->fmlfeat != NULL) { - /* 10 LSPs - energy - Wo - voicing flag - 10 LPCs */ - fwrite(&lsps[i][0], LPC_ORD, sizeof(float), c2->fmlfeat); - fwrite(&e[i], 1, sizeof(float), c2->fmlfeat); - fwrite(&model[i].Wo, 1, sizeof(float), c2->fmlfeat); - float voiced_float = model[i].voiced; - fwrite(&voiced_float, 1, sizeof(float), c2->fmlfeat); - fwrite(&ak[i][1], LPC_ORD, sizeof(float), c2->fmlfeat); - } - } - - #ifdef DUMP - dump_lsp_(&lsps[3][0]); - dump_ak_(&ak[3][0], LPC_ORD); - #endif - - /* update memories for next frame ----------------------------*/ + if (c2->fmlfeat != NULL) { + /* 10 LSPs - energy - Wo - voicing flag - 10 LPCs */ + fwrite(&lsps[i][0], LPC_ORD, sizeof(float), c2->fmlfeat); + fwrite(&e[i], 1, sizeof(float), c2->fmlfeat); + fwrite(&model[i].Wo, 1, sizeof(float), c2->fmlfeat); + float voiced_float = model[i].voiced; + fwrite(&voiced_float, 1, sizeof(float), c2->fmlfeat); + fwrite(&ak[i][1], LPC_ORD, sizeof(float), c2->fmlfeat); + } + } + +#ifdef DUMP + dump_lsp_(&lsps[3][0]); + dump_ak_(&ak[3][0], LPC_ORD); +#endif - c2->prev_model_dec = model[3]; - c2->prev_e_dec = e[3]; - for(i=0; iprev_lsps_dec[i] = lsps[3][i]; + /* update memories for next frame ----------------------------*/ + c2->prev_model_dec = model[3]; + c2->prev_e_dec = e[3]; + for (i = 0; i < LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[3][i]; } - /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_encode_1200 @@ -1373,63 +1327,62 @@ void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * \*---------------------------------------------------------------------------*/ -void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]) -{ - MODEL model; - float lsps[LPC_ORD]; - float lsps_[LPC_ORD]; - float ak[LPC_ORD+1]; - float e; - int lsp_indexes[LPC_ORD]; - int WoE_index; - int i; - int spare = 0; - unsigned int nbit = 0; +void codec2_encode_1200(struct CODEC2 *c2, unsigned char *bits, + short speech[]) { + MODEL model; + float lsps[LPC_ORD]; + float lsps_[LPC_ORD]; + float ak[LPC_ORD + 1]; + float e; + int lsp_indexes[LPC_ORD]; + int WoE_index; + int i; + int spare = 0; + unsigned int nbit = 0; - assert(c2 != NULL); + assert(c2 != NULL); - memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); - /* frame 1: - voicing ---------------------------------------------*/ + /* frame 1: - voicing ---------------------------------------------*/ - analyse_one_frame(c2, &model, speech); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, speech); + pack(bits, &nbit, model.voiced, 1); - /* frame 2: - voicing, joint Wo & E -------------------------------*/ + /* frame 2: - voicing, joint Wo & E -------------------------------*/ - analyse_one_frame(c2, &model, &speech[c2->n_samp]); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, &speech[c2->n_samp]); + pack(bits, &nbit, model.voiced, 1); - /* need to run this just to get LPC energy */ - e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); + /* need to run this just to get LPC energy */ + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); - WoE_index = encode_WoE(&model, e, c2->xq_enc); - pack(bits, &nbit, WoE_index, WO_E_BITS); + WoE_index = encode_WoE(&model, e, c2->xq_enc); + pack(bits, &nbit, WoE_index, WO_E_BITS); - /* frame 3: - voicing ---------------------------------------------*/ + /* frame 3: - voicing ---------------------------------------------*/ - analyse_one_frame(c2, &model, &speech[2*c2->n_samp]); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, &speech[2 * c2->n_samp]); + pack(bits, &nbit, model.voiced, 1); - /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/ + /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/ - analyse_one_frame(c2, &model, &speech[3*c2->n_samp]); - pack(bits, &nbit, model.voiced, 1); + analyse_one_frame(c2, &model, &speech[3 * c2->n_samp]); + pack(bits, &nbit, model.voiced, 1); - e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); - WoE_index = encode_WoE(&model, e, c2->xq_enc); - pack(bits, &nbit, WoE_index, WO_E_BITS); + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); + WoE_index = encode_WoE(&model, e, c2->xq_enc); + pack(bits, &nbit, WoE_index, WO_E_BITS); - encode_lsps_vq(lsp_indexes, lsps, lsps_, LPC_ORD); - for(i=0; ic2const, &model[1], &e[1], c2->xq_dec, WoE_index); - - model[2].voiced = unpack(bits, &nbit, 1); - - model[3].voiced = unpack(bits, &nbit, 1); - WoE_index = unpack(bits, &nbit, WO_E_BITS); - decode_WoE(&c2->c2const, &model[3], &e[3], c2->xq_dec, WoE_index); - - for(i=0; iprev_model_dec, &model[1], c2->c2const.Wo_min); - e[0] = interp_energy(c2->prev_e_dec, e[1]); - interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min); - e[2] = interp_energy(e[1], e[3]); - - /* LSPs are sampled every 40ms so we interpolate the 3 frames in - between, then recover spectral amplitudes */ - - for(i=0, weight=0.25; i<3; i++, weight += 0.25) { - interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD); - } - for(i=0; i<4; i++) { - lsp_to_lpc(&lsps[i][0], &ak[i][0], 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[c2->n_samp*i], &model[i], Aw, 1.0); - } - - /* update memories for next frame ----------------------------*/ - - c2->prev_model_dec = model[3]; - c2->prev_e_dec = e[3]; - for(i=0; iprev_lsps_dec[i] = lsps[3][i]; +void codec2_decode_1200(struct CODEC2 *c2, short speech[], + const unsigned char *bits) { + MODEL model[4]; + int lsp_indexes[LPC_ORD]; + float lsps[4][LPC_ORD]; + int WoE_index; + float e[4]; + float snr; + float ak[4][LPC_ORD + 1]; + int i, j; + unsigned int nbit = 0; + float weight; + COMP Aw[FFT_ENC]; + + assert(c2 != NULL); + + /* only need to zero these out due to (unused) snr calculation */ + + for (i = 0; i < 4; i++) + for (j = 1; j <= MAX_AMP; j++) model[i].A[j] = 0.0; + + /* unpack bits from channel ------------------------------------*/ + + /* this will partially fill the model params for the 4 x 10ms + frames */ + + model[0].voiced = unpack(bits, &nbit, 1); + + model[1].voiced = unpack(bits, &nbit, 1); + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&c2->c2const, &model[1], &e[1], c2->xq_dec, WoE_index); + + model[2].voiced = unpack(bits, &nbit, 1); + + model[3].voiced = unpack(bits, &nbit, 1); + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&c2->c2const, &model[3], &e[3], c2->xq_dec, WoE_index); + + for (i = 0; i < LSP_PRED_VQ_INDEXES; i++) { + lsp_indexes[i] = unpack(bits, &nbit, lsp_pred_vq_bits(i)); + } + decode_lsps_vq(lsp_indexes, &lsps[3][0], LPC_ORD, 0); + check_lsp_order(&lsps[3][0], LPC_ORD); + bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); + + /* interpolate ------------------------------------------------*/ + + /* Wo and energy are sampled every 20ms, so we interpolate just 1 + 10ms frame between 20ms samples */ + + interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); + e[0] = interp_energy(c2->prev_e_dec, e[1]); + interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min); + e[2] = interp_energy(e[1], e[3]); + + /* LSPs are sampled every 40ms so we interpolate the 3 frames in + between, then recover spectral amplitudes */ + + for (i = 0, weight = 0.25; i < 3; i++, weight += 0.25) { + interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, + LPC_ORD); + } + for (i = 0; i < 4; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], 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[c2->n_samp * i], &model[i], Aw, 1.0); + } + + /* update memories for next frame ----------------------------*/ + + c2->prev_model_dec = model[3]; + c2->prev_e_dec = e[3]; + for (i = 0; i < LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[3][i]; } - /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_encode_700c @@ -1535,7 +1486,7 @@ void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * frame 0: nothing frame 1: nothing frame 2: nothing - frame 3: 18 bit 2 stage VQ (9 bits/stage), 4 bits energy, + frame 3: 18 bit 2 stage VQ (9 bits/stage), 4 bits energy, 6 bit scalar Wo/voicing. No spare bits. Voicing is encoded using the 0 index of the Wo quantiser. @@ -1551,60 +1502,54 @@ void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * \*---------------------------------------------------------------------------*/ -void codec2_encode_700c(struct CODEC2 *c2, unsigned char * bits, short speech[]) -{ - MODEL model; - int indexes[4], i, M=4; - unsigned int nbit = 0; +void codec2_encode_700c(struct CODEC2 *c2, unsigned char *bits, + short speech[]) { + MODEL model; + int indexes[4], i, M = 4; + unsigned int nbit = 0; - assert(c2 != NULL); + assert(c2 != NULL); - memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); - for(i=0; in_samp]); - } + for (i = 0; i < M; i++) { + analyse_one_frame(c2, &model, &speech[i * c2->n_samp]); + } - int K = 20; - float rate_K_vec[K], mean; - float rate_K_vec_no_mean[K], rate_K_vec_no_mean_[K]; - - newamp1_model_to_indexes(&c2->c2const, - indexes, - &model, - rate_K_vec, - c2->rate_K_sample_freqs_kHz, - K, - &mean, - rate_K_vec_no_mean, - rate_K_vec_no_mean_, &c2->se, c2->eq, c2->eq_en); - c2->nse += K; + int K = 20; + float rate_K_vec[K], mean; + float rate_K_vec_no_mean[K], rate_K_vec_no_mean_[K]; + + newamp1_model_to_indexes(&c2->c2const, indexes, &model, rate_K_vec, + c2->rate_K_sample_freqs_kHz, K, &mean, + rate_K_vec_no_mean, rate_K_vec_no_mean_, &c2->se, + c2->eq, c2->eq_en); + c2->nse += K; #ifndef CORTEX_M4 - /* dump features for deep learning experiments */ - if (c2->fmlfeat != NULL) { - fwrite(&mean, 1, sizeof(float), c2->fmlfeat); - fwrite(rate_K_vec_no_mean, K, sizeof(float), c2->fmlfeat); - fwrite(rate_K_vec_no_mean_, K, sizeof(float), c2->fmlfeat); - MODEL model_; memcpy(&model_, &model, sizeof(model)); - float rate_K_vec_[K]; - for(int k=0; kc2const, &model_, rate_K_vec_, c2->rate_K_sample_freqs_kHz, K); - fwrite(&model_.A, MAX_AMP, sizeof(float), c2->fmlfeat); - } - if (c2->fmlmodel != NULL) - fwrite(&model,sizeof(MODEL),1,c2->fmlmodel); + /* dump features for deep learning experiments */ + if (c2->fmlfeat != NULL) { + fwrite(&mean, 1, sizeof(float), c2->fmlfeat); + fwrite(rate_K_vec_no_mean, K, sizeof(float), c2->fmlfeat); + fwrite(rate_K_vec_no_mean_, K, sizeof(float), c2->fmlfeat); + MODEL model_; + memcpy(&model_, &model, sizeof(model)); + float rate_K_vec_[K]; + for (int k = 0; k < K; k++) rate_K_vec_[k] = rate_K_vec_no_mean_[k] + mean; + resample_rate_L(&c2->c2const, &model_, rate_K_vec_, + c2->rate_K_sample_freqs_kHz, K); + fwrite(&model_.A, MAX_AMP, sizeof(float), c2->fmlfeat); + } + if (c2->fmlmodel != NULL) fwrite(&model, sizeof(MODEL), 1, c2->fmlmodel); #endif - - pack_natural_or_gray(bits, &nbit, indexes[0], 9, 0); - pack_natural_or_gray(bits, &nbit, indexes[1], 9, 0); - pack_natural_or_gray(bits, &nbit, indexes[2], 4, 0); - pack_natural_or_gray(bits, &nbit, indexes[3], 6, 0); - assert(nbit == (unsigned)codec2_bits_per_frame(c2)); -} + pack_natural_or_gray(bits, &nbit, indexes[0], 9, 0); + pack_natural_or_gray(bits, &nbit, indexes[1], 9, 0); + pack_natural_or_gray(bits, &nbit, indexes[2], 4, 0); + pack_natural_or_gray(bits, &nbit, indexes[3], 6, 0); + assert(nbit == (unsigned)codec2_bits_per_frame(c2)); +} /*---------------------------------------------------------------------------*\ @@ -1616,58 +1561,53 @@ void codec2_encode_700c(struct CODEC2 *c2, unsigned char * bits, short speech[]) \*---------------------------------------------------------------------------*/ -void codec2_decode_700c(struct CODEC2 *c2, short speech[], const unsigned char * bits) -{ - MODEL model[4]; - int indexes[4]; - int i; - unsigned int nbit = 0; - - assert(c2 != NULL); - - /* unpack bits from channel ------------------------------------*/ - - indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); - indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); - indexes[2] = unpack_natural_or_gray(bits, &nbit, 4, 0); - indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); - - int M = 4; - COMP HH[M][MAX_AMP+1]; - float interpolated_surface_[M][NEWAMP1_K]; - - newamp1_indexes_to_model(&c2->c2const, - model, - (COMP*)HH, - (float*)interpolated_surface_, - c2->prev_rate_K_vec_, - &c2->Wo_left, - &c2->voicing_left, - c2->rate_K_sample_freqs_kHz, - NEWAMP1_K, - c2->phase_fft_fwd_cfg, - c2->phase_fft_inv_cfg, - indexes, - c2->user_rate_K_vec_no_mean_, - c2->post_filter_en); - - - for(i=0; ifmlfeat != NULL) { - /* We use standard nb_features=55 feature records for compatibility with train_lpcnet.py */ - float features[55] = {0}; - /* just using 18/20 for compatibility with LPCNet, coarse scaling for NN input */ - for(int j=0; j<18; j++) - features[j] = (interpolated_surface_[i][j]-30)/40; - int pitch_index = 21 + 2.0*M_PI/model[i].Wo; - features[36] = 0.02*(pitch_index-100); - features[37] = model[i].voiced; - fwrite(features, 55, sizeof(float), c2->fmlfeat); - } - - /* 700C is a little quieter so lets apply some experimentally derived audio gain */ - synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], &HH[i][0], 1.5); - } +void codec2_decode_700c(struct CODEC2 *c2, short speech[], + const unsigned char *bits) { + MODEL model[4]; + int indexes[4]; + int i; + unsigned int nbit = 0; + + assert(c2 != NULL); + + /* unpack bits from channel ------------------------------------*/ + + indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); + indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); + indexes[2] = unpack_natural_or_gray(bits, &nbit, 4, 0); + indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); + + int M = 4; + COMP HH[M][MAX_AMP + 1]; + float interpolated_surface_[M][NEWAMP1_K]; + + newamp1_indexes_to_model( + &c2->c2const, model, (COMP *)HH, (float *)interpolated_surface_, + c2->prev_rate_K_vec_, &c2->Wo_left, &c2->voicing_left, + c2->rate_K_sample_freqs_kHz, NEWAMP1_K, c2->phase_fft_fwd_cfg, + c2->phase_fft_inv_cfg, indexes, c2->user_rate_K_vec_no_mean_, + c2->post_filter_en); + + for (i = 0; i < M; i++) { + if (c2->fmlfeat != NULL) { + /* We use standard nb_features=55 feature records for compatibility with + * train_lpcnet.py */ + float features[55] = {0}; + /* just using 18/20 for compatibility with LPCNet, coarse scaling for NN + * input */ + for (int j = 0; j < 18; j++) + features[j] = (interpolated_surface_[i][j] - 30) / 40; + int pitch_index = 21 + 2.0 * M_PI / model[i].Wo; + features[36] = 0.02 * (pitch_index - 100); + features[37] = model[i].voiced; + fwrite(features, 55, sizeof(float), c2->fmlfeat); + } + + /* 700C is a little quieter so lets apply some experimentally derived audio + * gain */ + synthesise_one_frame(c2, &speech[c2->n_samp * i], &model[i], &HH[i][0], + 1.5); + } } /*---------------------------------------------------------------------------*\ @@ -1680,48 +1620,44 @@ void codec2_decode_700c(struct CODEC2 *c2, short speech[], const unsigned char * \*---------------------------------------------------------------------------*/ -float codec2_energy_700c(struct CODEC2 *c2, const unsigned char * bits) -{ - int indexes[4]; - unsigned int nbit = 0; +float codec2_energy_700c(struct CODEC2 *c2, const unsigned char *bits) { + int indexes[4]; + unsigned int nbit = 0; - assert(c2 != NULL); + assert(c2 != NULL); - /* unpack bits from channel ------------------------------------*/ + /* unpack bits from channel ------------------------------------*/ - indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); - indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); - indexes[2] = unpack_natural_or_gray(bits, &nbit, 4, 0); - indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); + indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); + indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); + indexes[2] = unpack_natural_or_gray(bits, &nbit, 4, 0); + indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); - float mean = newamp1_energy_cb[0].cb[indexes[2]]; - mean -= 10; - if (indexes[3] == 0) - mean -= 10; + float mean = newamp1_energy_cb[0].cb[indexes[2]]; + mean -= 10; + if (indexes[3] == 0) mean -= 10; - return POW10F(mean/10.0); + return POW10F(mean / 10.0); } -float codec2_energy_450(struct CODEC2 *c2, const unsigned char * bits) -{ - int indexes[4]; - unsigned int nbit = 0; +float codec2_energy_450(struct CODEC2 *c2, const unsigned char *bits) { + int indexes[4]; + unsigned int nbit = 0; - assert(c2 != NULL); + assert(c2 != NULL); - /* unpack bits from channel ------------------------------------*/ + /* unpack bits from channel ------------------------------------*/ - indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); - //indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); - indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0); - indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); - - float mean = newamp2_energy_cb[0].cb[indexes[2]]; - mean -= 10; - if (indexes[3] == 0) - mean -= 10; + indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); + // indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); + indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0); + indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); - return POW10F(mean/10.0); + float mean = newamp2_energy_cb[0].cb[indexes[2]]; + mean -= 10; + if (indexes[3] == 0) mean -= 10; + + return POW10F(mean / 10.0); } /*---------------------------------------------------------------------------*\ @@ -1734,74 +1670,71 @@ float codec2_energy_450(struct CODEC2 *c2, const unsigned char * bits) \*---------------------------------------------------------------------------*/ -float codec2_get_energy(struct CODEC2 *c2, const unsigned char *bits) -{ - assert(c2 != NULL); - assert( - ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) || - ( CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) || - ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) || - ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) || - ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) || - ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) || - ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) || - ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) || - ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) - ); - MODEL model; - float xq_dec[2] = {}; - int e_index, WoE_index; - float e = 0.0f; - unsigned int nbit; - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) { - nbit = 1 + 1 + WO_BITS; - e_index = unpack(bits, &nbit, E_BITS); - e = decode_energy(e_index, E_BITS); - } - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) { - nbit = 1 + 1; - WoE_index = unpack(bits, &nbit, WO_E_BITS); - decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index); - } - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) { - nbit = 1 + 1 + WO_BITS; - e_index = unpack(bits, &nbit, E_BITS); - e = decode_energy(e_index, E_BITS); - } - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) { - nbit = 1 + 1; - WoE_index = unpack(bits, &nbit, WO_E_BITS); - decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index); - } - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) { - nbit = 1 + 1 + 1 + 1 + WO_BITS; - e_index = unpack_natural_or_gray(bits, &nbit, E_BITS, c2->gray); - e = decode_energy(e_index, E_BITS); - } - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) { - nbit = 1 + 1; - WoE_index = unpack(bits, &nbit, WO_E_BITS); - decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index); - } - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { - e = codec2_energy_700c(c2, bits); - } - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode) || CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { - e = codec2_energy_450(c2, bits); - } - - return e; +float codec2_get_energy(struct CODEC2 *c2, const unsigned char *bits) { + assert(c2 != NULL); + assert((CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) || + (CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) || + (CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) || + (CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) || + (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) || + (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) || + (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) || + (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) || + (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode))); + MODEL model; + float xq_dec[2] = {}; + int e_index, WoE_index; + float e = 0.0f; + unsigned int nbit; + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) { + nbit = 1 + 1 + WO_BITS; + e_index = unpack(bits, &nbit, E_BITS); + e = decode_energy(e_index, E_BITS); + } + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) { + nbit = 1 + 1; + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index); + } + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) { + nbit = 1 + 1 + WO_BITS; + e_index = unpack(bits, &nbit, E_BITS); + e = decode_energy(e_index, E_BITS); + } + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) { + nbit = 1 + 1; + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index); + } + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) { + nbit = 1 + 1 + 1 + 1 + WO_BITS; + e_index = unpack_natural_or_gray(bits, &nbit, E_BITS, c2->gray); + e = decode_energy(e_index, E_BITS); + } + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) { + nbit = 1 + 1; + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index); + } + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { + e = codec2_energy_700c(c2, bits); + } + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode) || + CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { + e = codec2_energy_450(c2, bits); + } + + return e; } - /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_encode_450 AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg - DATE CREATED: July 2018 - + INSTITUTE...: Institute for Electronics Engineering, University of +Erlangen-Nuremberg DATE CREATED: July 2018 + 450 bit/s codec that uses newamp2 fixed rate VQ of amplitudes. Encodes 320 speech samples (40ms of speech) into 28 bits. @@ -1812,9 +1745,9 @@ float codec2_get_energy(struct CODEC2 *c2, const unsigned char *bits) frame 0: nothing frame 1: nothing frame 2: nothing - frame 3: 9 bit 1 stage VQ, 3 bits energy, + frame 3: 9 bit 1 stage VQ, 3 bits energy, 6 bit scalar Wo/voicing/plosive. No spare bits. - + If a plosive is detected the frame at the energy-step is encoded. Voicing is encoded using the 000000 index of the Wo quantiser. @@ -1824,7 +1757,7 @@ float codec2_get_energy(struct CODEC2 *c2, const unsigned char *bits) Parameter frames 1-3 frame 4 Total ----------------------------------------------------------- - Harmonic magnitudes (rate k VQ) 0 9 9 + Harmonic magnitudes (rate k VQ) 0 9 9 Energy 0 3 3 log Wo/voicing/plosive 0 6 6 TOTAL 0 18 18 @@ -1832,190 +1765,158 @@ float codec2_get_energy(struct CODEC2 *c2, const unsigned char *bits) \*---------------------------------------------------------------------------*/ -void codec2_encode_450(struct CODEC2 *c2, unsigned char * bits, short speech[]) -{ - MODEL model; - int indexes[4], i,h, M=4; - unsigned int nbit = 0; - int plosiv = 0; - float energydelta[M]; - int spectralCounter; - - assert(c2 != NULL); - - memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); - for(i=0; in_samp]); - energydelta[i] = 0; - spectralCounter = 0; - for(h = 0;h<(model.L);h++){ - //only detect above 300 Hz - if(h*model.Wo*(c2->c2const.Fs/2000.0)/M_PI > 0.3){ - energydelta[i] = (double)energydelta[i] + (double)20.0*log10(model.A[10]+1E-16); - spectralCounter = spectralCounter+1; - } - - } - energydelta[i] = energydelta[i] / spectralCounter ; - } - //Constants for plosive Detection tdB = threshold; minPwr = from below this level plosives have to rise - float tdB = 15; //not fixed can be changed - float minPwr = 15; //not fixed can be changed - if((c2->energy_prev)((c2->energy_prev)+tdB)){ - - plosiv = 1; - } - if(energydelta[0](energydelta[0]+tdB)){ - - plosiv = 2; - } - if(energydelta[1](energydelta[1]+tdB)){ - - plosiv = 3; - } - if(energydelta[2](energydelta[2]+tdB)){ - - plosiv = 4; - } - if(plosiv != 0 && plosiv != 4){ - analyse_one_frame(c2, &model, &speech[(plosiv-1)*c2->n_samp]); - } - - c2->energy_prev = energydelta[3]; - - - int K = 29; - float rate_K_vec[K], mean; - float rate_K_vec_no_mean[K], rate_K_vec_no_mean_[K]; - if(plosiv > 0){ - plosiv = 1; - } - newamp2_model_to_indexes(&c2->c2const, - indexes, - &model, - rate_K_vec, - c2->n2_rate_K_sample_freqs_kHz, - K, - &mean, - rate_K_vec_no_mean, - rate_K_vec_no_mean_, - plosiv); - - - pack_natural_or_gray(bits, &nbit, indexes[0], 9, 0); - //pack_natural_or_gray(bits, &nbit, indexes[1], 9, 0); - pack_natural_or_gray(bits, &nbit, indexes[2], 3, 0); - pack_natural_or_gray(bits, &nbit, indexes[3], 6, 0); - - assert(nbit == (unsigned)codec2_bits_per_frame(c2)); +void codec2_encode_450(struct CODEC2 *c2, unsigned char *bits, short speech[]) { + MODEL model; + int indexes[4], i, h, M = 4; + unsigned int nbit = 0; + int plosiv = 0; + float energydelta[M]; + int spectralCounter; + + assert(c2 != NULL); + + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + for (i = 0; i < M; i++) { + analyse_one_frame(c2, &model, &speech[i * c2->n_samp]); + energydelta[i] = 0; + spectralCounter = 0; + for (h = 0; h < (model.L); h++) { + // only detect above 300 Hz + if (h * model.Wo * (c2->c2const.Fs / 2000.0) / M_PI > 0.3) { + energydelta[i] = + (double)energydelta[i] + (double)20.0 * log10(model.A[10] + 1E-16); + spectralCounter = spectralCounter + 1; + } + } + energydelta[i] = energydelta[i] / spectralCounter; + } + // Constants for plosive Detection tdB = threshold; minPwr = from below this + // level plosives have to rise + float tdB = 15; // not fixed can be changed + float minPwr = 15; // not fixed can be changed + if ((c2->energy_prev) < minPwr && + energydelta[0] > ((c2->energy_prev) + tdB)) { + plosiv = 1; + } + if (energydelta[0] < minPwr && energydelta[1] > (energydelta[0] + tdB)) { + plosiv = 2; + } + if (energydelta[1] < minPwr && energydelta[2] > (energydelta[1] + tdB)) { + plosiv = 3; + } + if (energydelta[2] < minPwr && energydelta[3] > (energydelta[2] + tdB)) { + plosiv = 4; + } + if (plosiv != 0 && plosiv != 4) { + analyse_one_frame(c2, &model, &speech[(plosiv - 1) * c2->n_samp]); + } + + c2->energy_prev = energydelta[3]; + + int K = 29; + float rate_K_vec[K], mean; + float rate_K_vec_no_mean[K], rate_K_vec_no_mean_[K]; + if (plosiv > 0) { + plosiv = 1; + } + newamp2_model_to_indexes(&c2->c2const, indexes, &model, rate_K_vec, + c2->n2_rate_K_sample_freqs_kHz, K, &mean, + rate_K_vec_no_mean, rate_K_vec_no_mean_, plosiv); + + pack_natural_or_gray(bits, &nbit, indexes[0], 9, 0); + // pack_natural_or_gray(bits, &nbit, indexes[1], 9, 0); + pack_natural_or_gray(bits, &nbit, indexes[2], 3, 0); + pack_natural_or_gray(bits, &nbit, indexes[3], 6, 0); + + assert(nbit == (unsigned)codec2_bits_per_frame(c2)); } - /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_decode_450 AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg - DATE CREATED: July 2018 + INSTITUTE...: Institute for Electronics Engineering, University of +Erlangen-Nuremberg DATE CREATED: July 2018 \*---------------------------------------------------------------------------*/ -void codec2_decode_450(struct CODEC2 *c2, short speech[], const unsigned char * bits) -{ - MODEL model[4]; - int indexes[4]; - int i; - unsigned int nbit = 0; - - assert(c2 != NULL); - - /* unpack bits from channel ------------------------------------*/ - - indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); - //indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); - indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0); - indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); - - int M = 4; - COMP HH[M][MAX_AMP+1]; - float interpolated_surface_[M][NEWAMP2_K]; - int pwbFlag = 0; - - newamp2_indexes_to_model(&c2->c2const, - model, - (COMP*)HH, - (float*)interpolated_surface_, - c2->n2_prev_rate_K_vec_, - &c2->Wo_left, - &c2->voicing_left, - c2->n2_rate_K_sample_freqs_kHz, - NEWAMP2_K, - c2->phase_fft_fwd_cfg, - c2->phase_fft_inv_cfg, - indexes, - 1.5, - pwbFlag); - - - for(i=0; in_samp*i], &model[i], &HH[i][0], 1.5); - } +void codec2_decode_450(struct CODEC2 *c2, short speech[], + const unsigned char *bits) { + MODEL model[4]; + int indexes[4]; + int i; + unsigned int nbit = 0; + + assert(c2 != NULL); + + /* unpack bits from channel ------------------------------------*/ + + indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); + // indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); + indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0); + indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); + + int M = 4; + COMP HH[M][MAX_AMP + 1]; + float interpolated_surface_[M][NEWAMP2_K]; + int pwbFlag = 0; + + newamp2_indexes_to_model( + &c2->c2const, model, (COMP *)HH, (float *)interpolated_surface_, + c2->n2_prev_rate_K_vec_, &c2->Wo_left, &c2->voicing_left, + c2->n2_rate_K_sample_freqs_kHz, NEWAMP2_K, c2->phase_fft_fwd_cfg, + c2->phase_fft_inv_cfg, indexes, 1.5, pwbFlag); + + for (i = 0; i < M; i++) { + synthesise_one_frame(c2, &speech[c2->n_samp * i], &model[i], &HH[i][0], + 1.5); + } } /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_decode_450pwb AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg - DATE CREATED: July 2018 - + INSTITUTE...: Institute for Electronics Engineering, University of +Erlangen-Nuremberg DATE CREATED: July 2018 + Decodes the 450 codec data in pseudo wideband at 16kHz samplerate. \*---------------------------------------------------------------------------*/ -void codec2_decode_450pwb(struct CODEC2 *c2, short speech[], const unsigned char * bits) -{ - MODEL model[4]; - int indexes[4]; - int i; - unsigned int nbit = 0; - - assert(c2 != NULL); - - /* unpack bits from channel ------------------------------------*/ - - indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); - //indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); - indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0); - indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); - - int M = 4; - COMP HH[M][MAX_AMP+1]; - float interpolated_surface_[M][NEWAMP2_16K_K]; - int pwbFlag = 1; - - newamp2_indexes_to_model(&c2->c2const, - model, - (COMP*)HH, - (float*)interpolated_surface_, - c2->n2_pwb_prev_rate_K_vec_, - &c2->Wo_left, - &c2->voicing_left, - c2->n2_pwb_rate_K_sample_freqs_kHz, - NEWAMP2_16K_K, - c2->phase_fft_fwd_cfg, - c2->phase_fft_inv_cfg, - indexes, - 1.5, - pwbFlag); - - - for(i=0; in_samp*i], &model[i], &HH[i][0], 1.5); - } +void codec2_decode_450pwb(struct CODEC2 *c2, short speech[], + const unsigned char *bits) { + MODEL model[4]; + int indexes[4]; + int i; + unsigned int nbit = 0; + + assert(c2 != NULL); + + /* unpack bits from channel ------------------------------------*/ + + indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); + // indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); + indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0); + indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); + + int M = 4; + COMP HH[M][MAX_AMP + 1]; + float interpolated_surface_[M][NEWAMP2_16K_K]; + int pwbFlag = 1; + + newamp2_indexes_to_model( + &c2->c2const, model, (COMP *)HH, (float *)interpolated_surface_, + c2->n2_pwb_prev_rate_K_vec_, &c2->Wo_left, &c2->voicing_left, + c2->n2_pwb_rate_K_sample_freqs_kHz, NEWAMP2_16K_K, c2->phase_fft_fwd_cfg, + c2->phase_fft_inv_cfg, indexes, 1.5, pwbFlag); + + for (i = 0; i < M; i++) { + synthesise_one_frame(c2, &speech[c2->n_samp * i], &model[i], &HH[i][0], + 1.5); + } } - /*---------------------------------------------------------------------------* \ FUNCTION....: synthesise_one_frame() @@ -2026,42 +1927,42 @@ void codec2_decode_450pwb(struct CODEC2 *c2, short speech[], const unsigned char \*---------------------------------------------------------------------------*/ -void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, COMP Aw[], float gain) -{ - int i; - - if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode) || CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode) || CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode) ) { - /* newamp1/2, we've already worked out rate L phase */ - COMP *H = Aw; - phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H); - } else { - /* LPC based phase synthesis */ - COMP H[MAX_AMP+1]; - sample_phase(model, H, Aw); - phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H); - } - - postfilter(model, &c2->bg_est); - synthesise(c2->n_samp, c2->fftr_inv_cfg, c2->Sn_, model, c2->Pn, 1); - - for(i=0; in_samp; i++) { - c2->Sn_[i] *= gain; - } - - ear_protection(c2->Sn_, c2->n_samp); - - for(i=0; in_samp; i++) { - if (c2->Sn_[i] > 32767.0) - speech[i] = 32767; - else if (c2->Sn_[i] < -32767.0) - speech[i] = -32767; - else - speech[i] = c2->Sn_[i]; - } - +void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, + COMP Aw[], float gain) { + int i; + + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode) || + CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode) || + CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { + /* newamp1/2, we've already worked out rate L phase */ + COMP *H = Aw; + phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H); + } else { + /* LPC based phase synthesis */ + COMP H[MAX_AMP + 1]; + sample_phase(model, H, Aw); + phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H); + } + + postfilter(model, &c2->bg_est); + synthesise(c2->n_samp, c2->fftr_inv_cfg, c2->Sn_, model, c2->Pn, 1); + + for (i = 0; i < c2->n_samp; i++) { + c2->Sn_[i] *= gain; + } + + ear_protection(c2->Sn_, c2->n_samp); + + for (i = 0; i < c2->n_samp; i++) { + if (c2->Sn_[i] > 32767.0) + speech[i] = 32767; + else if (c2->Sn_[i] < -32767.0) + speech[i] = -32767; + else + speech[i] = c2->Sn_[i]; + } } - /*---------------------------------------------------------------------------* \ FUNCTION....: analyse_one_frame() @@ -2073,43 +1974,39 @@ 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]; - float pitch; - int i; - int n_samp = c2->n_samp; - int m_pitch = c2->m_pitch; +void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]) { + COMP Sw[FFT_ENC]; + float pitch; + int i; + int n_samp = c2->n_samp; + int m_pitch = c2->m_pitch; - /* Read input speech */ + /* Read input speech */ - for(i=0; iSn[i] = c2->Sn[i+n_samp]; - for(i=0; iSn[i+m_pitch-n_samp] = speech[i]; + for (i = 0; i < m_pitch - n_samp; i++) c2->Sn[i] = c2->Sn[i + n_samp]; + for (i = 0; i < n_samp; i++) c2->Sn[i + m_pitch - n_samp] = speech[i]; - dft_speech(&c2->c2const, c2->fft_fwd_cfg, Sw, c2->Sn, c2->w); + dft_speech(&c2->c2const, c2->fft_fwd_cfg, Sw, c2->Sn, c2->w); - /* Estimate pitch */ - nlp(c2->nlp, c2->Sn, n_samp, &pitch, Sw, c2->W, &c2->prev_f0_enc); - model->Wo = TWO_PI/pitch; - model->L = PI/model->Wo; + /* Estimate pitch */ + nlp(c2->nlp, c2->Sn, n_samp, &pitch, Sw, c2->W, &c2->prev_f0_enc); + model->Wo = TWO_PI / pitch; + model->L = PI / model->Wo; - /* estimate model parameters */ - two_stage_pitch_refinement(&c2->c2const, model, Sw); + /* estimate model parameters */ + two_stage_pitch_refinement(&c2->c2const, model, Sw); - /* estimate phases when doing ML experiments */ - if (c2->fmlfeat != NULL) - estimate_amplitudes(model, Sw, c2->W, 1); - else - estimate_amplitudes(model, Sw, c2->W, 0); - est_voicing_mbe(&c2->c2const, model, Sw, c2->W); - #ifdef DUMP - dump_model(model); - #endif + /* estimate phases when doing ML experiments */ + if (c2->fmlfeat != NULL) + estimate_amplitudes(model, Sw, c2->W, 1); + else + estimate_amplitudes(model, Sw, c2->W, 0); + est_voicing_mbe(&c2->c2const, model, Sw, c2->W); +#ifdef DUMP + dump_model(model); +#endif } - /*---------------------------------------------------------------------------* \ FUNCTION....: ear_protection() @@ -2123,66 +2020,61 @@ void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]) \*---------------------------------------------------------------------------*/ static void ear_protection(float in_out[], int n) { - float max_sample, over, gain; - int i; + float max_sample, over, gain; + int i; - /* find maximum sample in frame */ + /* find maximum sample in frame */ - max_sample = 0.0; - for(i=0; i max_sample) - max_sample = in_out[i]; + max_sample = 0.0; + for (i = 0; i < n; i++) + if (in_out[i] > max_sample) max_sample = in_out[i]; - /* determine how far above set point */ + /* determine how far above set point */ - over = max_sample/30000.0; + over = max_sample / 30000.0; - /* If we are x dB over set point we reduce level by 2x dB, this - attenuates major excursions in amplitude (likely to be caused - by bit errors) more than smaller ones */ + /* If we are x dB over set point we reduce level by 2x dB, this + attenuates major excursions in amplitude (likely to be caused + by bit errors) more than smaller ones */ - if (over > 1.0) { - gain = 1.0/(over*over); - for(i=0; i 1.0) { + gain = 1.0 / (over * over); + for (i = 0; i < n; i++) in_out[i] *= gain; + } } - -void codec2_set_lpc_post_filter(struct CODEC2 *c2, int enable, int bass_boost, float beta, float gamma) -{ - assert((beta >= 0.0) && (beta <= 1.0)); - assert((gamma >= 0.0) && (gamma <= 1.0)); - c2->lpc_pf = enable; - c2->bass_boost = bass_boost; - c2->beta = beta; - c2->gamma = gamma; +void codec2_set_lpc_post_filter(struct CODEC2 *c2, int enable, int bass_boost, + float beta, float gamma) { + assert((beta >= 0.0) && (beta <= 1.0)); + assert((gamma >= 0.0) && (gamma <= 1.0)); + c2->lpc_pf = enable; + c2->bass_boost = bass_boost; + c2->beta = beta; + c2->gamma = gamma; } - /* Allows optional stealing of one of the voicing bits for use as a spare bit, only 1300 & 1400 & 1600 bit/s supported for now. Experimental method of sending voice/data frames for FreeDV. */ -int codec2_get_spare_bit_index(struct CODEC2 *c2) -{ - assert(c2 != NULL); +int codec2_get_spare_bit_index(struct CODEC2 *c2) { + assert(c2 != NULL); - switch(c2->mode) { + switch (c2->mode) { case CODEC2_MODE_1300: - return 2; // bit 2 (3th bit) is v2 (third voicing bit) - break; + return 2; // bit 2 (3th bit) is v2 (third voicing bit) + break; case CODEC2_MODE_1400: - return 10; // bit 10 (11th bit) is v2 (third voicing bit) - break; + return 10; // bit 10 (11th bit) is v2 (third voicing bit) + break; case CODEC2_MODE_1600: - return 15; // bit 15 (16th bit) is v2 (third voicing bit) - break; - } + return 15; // bit 15 (16th bit) is v2 (third voicing bit) + break; + } - return -1; + return -1; } /* @@ -2190,117 +2082,123 @@ int codec2_get_spare_bit_index(struct CODEC2 *c2) for convenience. */ -int codec2_rebuild_spare_bit(struct CODEC2 *c2, char unpacked_bits[]) -{ - int v1,v3; +int codec2_rebuild_spare_bit(struct CODEC2 *c2, char unpacked_bits[]) { + int v1, v3; - assert(c2 != NULL); + assert(c2 != NULL); - v1 = unpacked_bits[1]; + v1 = unpacked_bits[1]; - switch(c2->mode) { + switch (c2->mode) { case CODEC2_MODE_1300: - v3 = unpacked_bits[1+1+1]; + v3 = unpacked_bits[1 + 1 + 1]; - /* if either adjacent frame is voiced, make this one voiced */ + /* if either adjacent frame is voiced, make this one voiced */ - unpacked_bits[2] = (v1 || v3); + unpacked_bits[2] = (v1 || v3); - return 0; + return 0; - break; + break; case CODEC2_MODE_1400: - v3 = unpacked_bits[1+1+8+1]; + v3 = unpacked_bits[1 + 1 + 8 + 1]; - /* if either adjacent frame is voiced, make this one voiced */ + /* if either adjacent frame is voiced, make this one voiced */ - unpacked_bits[10] = (v1 || v3); + unpacked_bits[10] = (v1 || v3); - return 0; + return 0; - break; + break; case CODEC2_MODE_1600: - v3 = unpacked_bits[1+1+8+5+1]; + v3 = unpacked_bits[1 + 1 + 8 + 5 + 1]; - /* if either adjacent frame is voiced, make this one voiced */ + /* if either adjacent frame is voiced, make this one voiced */ - unpacked_bits[15] = (v1 || v3); + unpacked_bits[15] = (v1 || v3); - return 0; + return 0; - break; - } + break; + } - return -1; + return -1; } -void codec2_set_natural_or_gray(struct CODEC2 *c2, int gray) -{ - assert(c2 != NULL); - c2->gray = gray; +void codec2_set_natural_or_gray(struct CODEC2 *c2, int gray) { + assert(c2 != NULL); + c2->gray = gray; } -void codec2_set_softdec(struct CODEC2 *c2, float *softdec) -{ - assert(c2 != NULL); - c2->softdec = softdec; +void codec2_set_softdec(struct CODEC2 *c2, float *softdec) { + assert(c2 != NULL); + c2->softdec = softdec; } -void codec2_open_mlfeat(struct CODEC2 *codec2_state, char *feat_fn, char *model_fn) { - if ((codec2_state->fmlfeat = fopen(feat_fn, "wb")) == NULL) { - fprintf(stderr, "error opening machine learning feature file: %s\n", feat_fn); - exit(1); - } - if (model_fn) { - if ((codec2_state->fmlmodel = fopen(model_fn, "wb")) == NULL) { - fprintf(stderr, "error opening machine learning Codec 2 model file: %s\n", feat_fn); - exit(1); - } - } +void codec2_open_mlfeat(struct CODEC2 *codec2_state, char *feat_fn, + char *model_fn) { + if ((codec2_state->fmlfeat = fopen(feat_fn, "wb")) == NULL) { + fprintf(stderr, "error opening machine learning feature file: %s\n", + feat_fn); + exit(1); + } + if (model_fn) { + if ((codec2_state->fmlmodel = fopen(model_fn, "wb")) == NULL) { + fprintf(stderr, "error opening machine learning Codec 2 model file: %s\n", + feat_fn); + exit(1); + } + } } #ifndef __EMBEDDED__ -void codec2_load_codebook(struct CODEC2 *codec2_state, int num, char *filename) { - FILE *f; - - if ((f = fopen(filename, "rb")) == NULL) { - fprintf(stderr, "error opening codebook file: %s\n", filename); - exit(1); - } - //fprintf(stderr, "reading newamp1vq_cb[%d] k=%d m=%d\n", num, newamp1vq_cb[num].k, newamp1vq_cb[num].m); - float tmp[newamp1vq_cb[num].k*newamp1vq_cb[num].m]; - int nread = fread(tmp, sizeof(float), newamp1vq_cb[num].k*newamp1vq_cb[num].m, f); - float *p = (float*)newamp1vq_cb[num].cb; - for(int i=0; inse) - return codec2_state->se/codec2_state->nse; - else - return 0; + if (codec2_state->nse) + return codec2_state->se / codec2_state->nse; + else + return 0; } float *codec2_enable_user_ratek(struct CODEC2 *codec2_state, int *K) { - codec2_state->user_rate_K_vec_no_mean_ = (float*)malloc(sizeof(float)*NEWAMP1_K); - *K = NEWAMP1_K; - return codec2_state->user_rate_K_vec_no_mean_; + codec2_state->user_rate_K_vec_no_mean_ = + (float *)malloc(sizeof(float) * NEWAMP1_K); + *K = NEWAMP1_K; + return codec2_state->user_rate_K_vec_no_mean_; } void codec2_700c_post_filter(struct CODEC2 *codec2_state, bool en) { - codec2_state->post_filter_en = en; + codec2_state->post_filter_en = en; } void codec2_700c_eq(struct CODEC2 *codec2_state, bool en) { - codec2_state->eq_en = en; - codec2_state->se = 0.0; codec2_state->nse = 0; + codec2_state->eq_en = en; + codec2_state->se = 0.0; + codec2_state->nse = 0; } -- cgit v1.2.3 From 6549fa1d6f0b6c195dd597752cf3053ccc7fb8c0 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Sun, 16 Jul 2023 10:14:55 +0930 Subject: rm-ed 450 & 450WB --- CMakeLists.txt | 8 - src/CMakeLists.txt | 1 - src/c2dec.c | 8 +- src/c2enc.c | 8 +- src/codec2.c | 292 +---------------------------- src/codec2.h | 8 - src/newamp2.c | 536 ----------------------------------------------------- 7 files changed, 9 insertions(+), 852 deletions(-) delete mode 100644 src/newamp2.c (limited to 'src/codec2.c') diff --git a/CMakeLists.txt b/CMakeLists.txt index 86d5599..d296efe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1146,14 +1146,6 @@ endif(NOT APPLE) COMMAND sh -c "./c2enc 700C ${CMAKE_CURRENT_SOURCE_DIR}/raw/hts1a.raw - | ./c2dec 700C - - | sox -t .s16 -r 8000 - hts1a_700C.wav" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src ) - add_test(NAME test_codec2_mode_450 - COMMAND sh -c "./c2enc 450 ${CMAKE_CURRENT_SOURCE_DIR}/raw/hts1a.raw - | ./c2dec 450 - - | sox -t .s16 -r 8000 - hts1a_450.wav" - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src - ) - add_test(NAME test_codec2_mode_450PWB - COMMAND sh -c "./c2enc 450PWB ${CMAKE_CURRENT_SOURCE_DIR}/raw/hts1a.raw - | ./c2dec 450PWB - - | sox -t .s16 -r 16000 - hts1a_450PWB.wav" - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src - ) add_test(NAME test_vq_mbest COMMAND sh -c "./tvq_mbest; \ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 25081a0..fb10d28 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -169,7 +169,6 @@ set(CODEC2_SRCS lsp.c mbest.c newamp1.c - newamp2.c ofdm.c ofdm_mode.c phase.c diff --git a/src/c2dec.c b/src/c2dec.c index 5cd5383..b852078 100644 --- a/src/c2dec.c +++ b/src/c2dec.c @@ -139,14 +139,10 @@ int main(int argc, char *argv[]) { mode = CODEC2_MODE_1200; else if (strcmp(argv[1], "700C") == 0) mode = CODEC2_MODE_700C; - else if (strcmp(argv[1], "450") == 0) - mode = CODEC2_MODE_450; - else if (strcmp(argv[1], "450PWB") == 0) - mode = CODEC2_MODE_450PWB; else { fprintf(stderr, "Error in mode: %s. Must be 3200, 2400, 1600, 1400, 1300, 1200, " - "700C, 450, or 450PWB\n", + "700C\n", argv[1]); exit(1); } @@ -396,7 +392,7 @@ void print_help(const struct option *long_options, int num_opts, char *argv[]) { char *option_parameters; fprintf(stderr, "\nc2dec - Codec 2 decoder and bit error simulation program\n" - "usage: %s 3200|2400|1600|1400|1300|1200|700C|450|450PWB InputFile " + "usage: %s 3200|2400|1600|1400|1300|1200|700C InputFile " "OutputRawFile [OPTIONS]\n\n" "Options:\n", argv[0]); diff --git a/src/c2enc.c b/src/c2enc.c index fe37acd..5511d9d 100644 --- a/src/c2enc.c +++ b/src/c2enc.c @@ -51,7 +51,7 @@ int main(int argc, char *argv[]) { if (argc < 4) { printf( - "usage: c2enc 3200|2400|1600|1400|1300|1200|700C|450|450PWB " + "usage: c2enc 3200|2400|1600|1400|1300|1200|700C " "InputRawspeechFile OutputBitFile [--natural] [--softdec] " "[--bitperchar] [--mlfeat f32File modelFile] [--loadcb stageNum " "Filename] [--var] [--eq]\n"); @@ -76,14 +76,10 @@ int main(int argc, char *argv[]) { mode = CODEC2_MODE_1200; else if (strcmp(argv[1], "700C") == 0) mode = CODEC2_MODE_700C; - else if (strcmp(argv[1], "450") == 0) - mode = CODEC2_MODE_450; - else if (strcmp(argv[1], "450PWB") == 0) - mode = CODEC2_MODE_450; else { fprintf(stderr, "Error in mode: %s. Must be 3200, 2400, 1600, 1400, 1300, 1200, " - "700C, 450, 450PWB or WB\n", + "700C\n", argv[1]); exit(1); } diff --git a/src/codec2.c b/src/codec2.c index 264141c..52602e3 100644 --- a/src/codec2.c +++ b/src/codec2.c @@ -83,11 +83,6 @@ void codec2_decode_1200(struct CODEC2 *c2, short speech[], void codec2_encode_700c(struct CODEC2 *c2, unsigned char *bits, short speech[]); void codec2_decode_700c(struct CODEC2 *c2, short speech[], const unsigned char *bits); -void codec2_encode_450(struct CODEC2 *c2, unsigned char *bits, short speech[]); -void codec2_decode_450(struct CODEC2 *c2, short speech[], - const unsigned char *bits); -void codec2_decode_450pwb(struct CODEC2 *c2, short speech[], - const unsigned char *bits); static void ear_protection(float in_out[], int n); /*---------------------------------------------------------------------------*\ @@ -110,7 +105,6 @@ static void ear_protection(float in_out[], int n); \*---------------------------------------------------------------------------*/ -// Don't create CODEC2_MODE_450PWB for Encoding as it has undefined behavior ! struct CODEC2 *codec2_create(int mode) { struct CODEC2 *c2; int i, l; @@ -125,9 +119,7 @@ struct CODEC2 *codec2_create(int 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_700C, mode) || - CODEC2_MODE_ACTIVE(CODEC2_MODE_450, mode) || - CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, mode))) { + CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, mode))) { return NULL; } @@ -138,11 +130,7 @@ struct CODEC2 *codec2_create(int mode) { /* store constants in a few places for convenience */ - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, mode) == 0) { - c2->c2const = c2const_create(8000, N_S); - } else { - c2->c2const = c2const_create(16000, N_S); - } + c2->c2const = c2const_create(8000, N_S); c2->Fs = c2->c2const.Fs; int n_samp = c2->n_samp = c2->c2const.n_samp; int m_pitch = c2->m_pitch = c2->c2const.m_pitch; @@ -231,40 +219,10 @@ struct CODEC2 *codec2_create(int mode) { c2->eq_en = false; 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); } - /* newamp2 initialisation */ - - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) { - n2_mel_sample_freqs_kHz(c2->n2_rate_K_sample_freqs_kHz, NEWAMP2_K); - int k; - for (k = 0; k < NEWAMP2_K; k++) { - c2->n2_prev_rate_K_vec_[k] = 0.0; - } - c2->Wo_left = 0.0; - c2->voicing_left = 0; - ; - 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); - } - /* newamp2 PWB initialisation */ - - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { - n2_mel_sample_freqs_kHz(c2->n2_pwb_rate_K_sample_freqs_kHz, NEWAMP2_16K_K); - int k; - for (k = 0; k < NEWAMP2_16K_K; k++) { - c2->n2_pwb_prev_rate_K_vec_[k] = 0.0; - } - c2->Wo_left = 0.0; - c2->voicing_left = 0; - ; - 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); - } - c2->fmlfeat = NULL; c2->fmlmodel = NULL; @@ -310,17 +268,6 @@ struct CODEC2 *codec2_create(int mode) { c2->decode = codec2_decode_700c; } - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) { - c2->encode = codec2_encode_450; - c2->decode = codec2_decode_450; - } - - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { - // Encode PWB doesn't make sense - c2->encode = codec2_encode_450; - c2->decode = codec2_decode_450pwb; - } - return c2; } @@ -345,14 +292,6 @@ void codec2_destroy(struct CODEC2 *c2) { codec2_fft_free(c2->phase_fft_fwd_cfg); codec2_fft_free(c2->phase_fft_inv_cfg); } - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) { - codec2_fft_free(c2->phase_fft_fwd_cfg); - codec2_fft_free(c2->phase_fft_inv_cfg); - } - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { - codec2_fft_free(c2->phase_fft_fwd_cfg); - codec2_fft_free(c2->phase_fft_inv_cfg); - } FREE(c2->Pn); FREE(c2->Sn); FREE(c2->w); @@ -378,8 +317,6 @@ int codec2_bits_per_frame(struct CODEC2 *c2) { if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) return 52; if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) return 48; if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) return 28; - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) return 18; - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) return 18; return 0; /* shouldn't get here */ } @@ -417,8 +354,6 @@ int codec2_samples_per_frame(struct CODEC2 *c2) { if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) return 320; if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) return 320; if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) return 320; - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) return 320; - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) return 640; return 0; /* shouldn't get here */ } @@ -1640,26 +1575,6 @@ float codec2_energy_700c(struct CODEC2 *c2, const unsigned char *bits) { return POW10F(mean / 10.0); } -float codec2_energy_450(struct CODEC2 *c2, const unsigned char *bits) { - int indexes[4]; - unsigned int nbit = 0; - - assert(c2 != NULL); - - /* unpack bits from channel ------------------------------------*/ - - indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); - // indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); - indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0); - indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); - - float mean = newamp2_energy_cb[0].cb[indexes[2]]; - mean -= 10; - if (indexes[3] == 0) mean -= 10; - - return POW10F(mean / 10.0); -} - /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_get_energy() @@ -1678,9 +1593,7 @@ float codec2_get_energy(struct CODEC2 *c2, const unsigned char *bits) { (CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) || (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) || (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) || - (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) || - (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) || - (CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode))); + (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode))); MODEL model; float xq_dec[2] = {}; int e_index, WoE_index; @@ -1720,203 +1633,10 @@ float codec2_get_energy(struct CODEC2 *c2, const unsigned char *bits) { if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { e = codec2_energy_700c(c2, bits); } - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode) || - CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { - e = codec2_energy_450(c2, bits); - } return e; } -/*---------------------------------------------------------------------------*\ - - FUNCTION....: codec2_encode_450 - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - - 450 bit/s codec that uses newamp2 fixed rate VQ of amplitudes. - - Encodes 320 speech samples (40ms of speech) into 28 bits. - - The codec2 algorithm actually operates internally on 10ms (80 - sample) frames, so we run the encoding algorithm four times: - - frame 0: nothing - frame 1: nothing - frame 2: nothing - frame 3: 9 bit 1 stage VQ, 3 bits energy, - 6 bit scalar Wo/voicing/plosive. No spare bits. - - If a plosive is detected the frame at the energy-step is encoded. - - Voicing is encoded using the 000000 index of the Wo quantiser. - Plosive is encoded using the 111111 index of the Wo quantiser. - - The bit allocation is: - - Parameter frames 1-3 frame 4 Total - ----------------------------------------------------------- - Harmonic magnitudes (rate k VQ) 0 9 9 - Energy 0 3 3 - log Wo/voicing/plosive 0 6 6 - TOTAL 0 18 18 - - -\*---------------------------------------------------------------------------*/ - -void codec2_encode_450(struct CODEC2 *c2, unsigned char *bits, short speech[]) { - MODEL model; - int indexes[4], i, h, M = 4; - unsigned int nbit = 0; - int plosiv = 0; - float energydelta[M]; - int spectralCounter; - - assert(c2 != NULL); - - memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); - for (i = 0; i < M; i++) { - analyse_one_frame(c2, &model, &speech[i * c2->n_samp]); - energydelta[i] = 0; - spectralCounter = 0; - for (h = 0; h < (model.L); h++) { - // only detect above 300 Hz - if (h * model.Wo * (c2->c2const.Fs / 2000.0) / M_PI > 0.3) { - energydelta[i] = - (double)energydelta[i] + (double)20.0 * log10(model.A[10] + 1E-16); - spectralCounter = spectralCounter + 1; - } - } - energydelta[i] = energydelta[i] / spectralCounter; - } - // Constants for plosive Detection tdB = threshold; minPwr = from below this - // level plosives have to rise - float tdB = 15; // not fixed can be changed - float minPwr = 15; // not fixed can be changed - if ((c2->energy_prev) < minPwr && - energydelta[0] > ((c2->energy_prev) + tdB)) { - plosiv = 1; - } - if (energydelta[0] < minPwr && energydelta[1] > (energydelta[0] + tdB)) { - plosiv = 2; - } - if (energydelta[1] < minPwr && energydelta[2] > (energydelta[1] + tdB)) { - plosiv = 3; - } - if (energydelta[2] < minPwr && energydelta[3] > (energydelta[2] + tdB)) { - plosiv = 4; - } - if (plosiv != 0 && plosiv != 4) { - analyse_one_frame(c2, &model, &speech[(plosiv - 1) * c2->n_samp]); - } - - c2->energy_prev = energydelta[3]; - - int K = 29; - float rate_K_vec[K], mean; - float rate_K_vec_no_mean[K], rate_K_vec_no_mean_[K]; - if (plosiv > 0) { - plosiv = 1; - } - newamp2_model_to_indexes(&c2->c2const, indexes, &model, rate_K_vec, - c2->n2_rate_K_sample_freqs_kHz, K, &mean, - rate_K_vec_no_mean, rate_K_vec_no_mean_, plosiv); - - pack_natural_or_gray(bits, &nbit, indexes[0], 9, 0); - // pack_natural_or_gray(bits, &nbit, indexes[1], 9, 0); - pack_natural_or_gray(bits, &nbit, indexes[2], 3, 0); - pack_natural_or_gray(bits, &nbit, indexes[3], 6, 0); - - assert(nbit == (unsigned)codec2_bits_per_frame(c2)); -} - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: codec2_decode_450 - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - -\*---------------------------------------------------------------------------*/ - -void codec2_decode_450(struct CODEC2 *c2, short speech[], - const unsigned char *bits) { - MODEL model[4]; - int indexes[4]; - int i; - unsigned int nbit = 0; - - assert(c2 != NULL); - - /* unpack bits from channel ------------------------------------*/ - - indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); - // indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); - indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0); - indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); - - int M = 4; - COMP HH[M][MAX_AMP + 1]; - float interpolated_surface_[M][NEWAMP2_K]; - int pwbFlag = 0; - - newamp2_indexes_to_model( - &c2->c2const, model, (COMP *)HH, (float *)interpolated_surface_, - c2->n2_prev_rate_K_vec_, &c2->Wo_left, &c2->voicing_left, - c2->n2_rate_K_sample_freqs_kHz, NEWAMP2_K, c2->phase_fft_fwd_cfg, - c2->phase_fft_inv_cfg, indexes, 1.5, pwbFlag); - - for (i = 0; i < M; i++) { - synthesise_one_frame(c2, &speech[c2->n_samp * i], &model[i], &HH[i][0], - 1.5); - } -} - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: codec2_decode_450pwb - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - - Decodes the 450 codec data in pseudo wideband at 16kHz samplerate. - -\*---------------------------------------------------------------------------*/ - -void codec2_decode_450pwb(struct CODEC2 *c2, short speech[], - const unsigned char *bits) { - MODEL model[4]; - int indexes[4]; - int i; - unsigned int nbit = 0; - - assert(c2 != NULL); - - /* unpack bits from channel ------------------------------------*/ - - indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); - // indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); - indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0); - indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); - - int M = 4; - COMP HH[M][MAX_AMP + 1]; - float interpolated_surface_[M][NEWAMP2_16K_K]; - int pwbFlag = 1; - - newamp2_indexes_to_model( - &c2->c2const, model, (COMP *)HH, (float *)interpolated_surface_, - c2->n2_pwb_prev_rate_K_vec_, &c2->Wo_left, &c2->voicing_left, - c2->n2_pwb_rate_K_sample_freqs_kHz, NEWAMP2_16K_K, c2->phase_fft_fwd_cfg, - c2->phase_fft_inv_cfg, indexes, 1.5, pwbFlag); - - for (i = 0; i < M; i++) { - synthesise_one_frame(c2, &speech[c2->n_samp * i], &model[i], &HH[i][0], - 1.5); - } -} - /*---------------------------------------------------------------------------* \ FUNCTION....: synthesise_one_frame() @@ -1931,10 +1651,8 @@ void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, COMP Aw[], float gain) { int i; - if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode) || - CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode) || - CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { - /* newamp1/2, we've already worked out rate L phase */ + if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { + /* newamp1, we've already worked out rate L phase */ COMP *H = Aw; phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H); } else { diff --git a/src/codec2.h b/src/codec2.h index 892a0da..9f88264 100644 --- a/src/codec2.h +++ b/src/codec2.h @@ -42,8 +42,6 @@ extern "C" { #define CODEC2_MODE_1300 4 #define CODEC2_MODE_1200 5 #define CODEC2_MODE_700C 8 -#define CODEC2_MODE_450 10 -#define CODEC2_MODE_450PWB 11 #ifndef CODEC2_MODE_EN_DEFAULT #define CODEC2_MODE_EN_DEFAULT 1 @@ -78,12 +76,6 @@ extern "C" { #if !defined(CODEC2_MODE_700C_EN) #define CODEC2_MODE_700C_EN CODEC2_MODE_EN_DEFAULT #endif -#if !defined(CODEC2_MODE_450_EN) -#define CODEC2_MODE_450_EN CODEC2_MODE_EN_DEFAULT -#endif -#if !defined(CODEC2_MODE_450PWB_EN) -#define CODEC2_MODE_450PWB_EN CODEC2_MODE_EN_DEFAULT -#endif #define CODEC2_MODE_ACTIVE(mode_name, var) \ ((mode_name##_EN) == 0 ? 0 : (var) == mode_name) diff --git a/src/newamp2.c b/src/newamp2.c deleted file mode 100644 index 0b5f032..0000000 --- a/src/newamp2.c +++ /dev/null @@ -1,536 +0,0 @@ -/*---------------------------------------------------------------------------*\ - - FILE........: newamp2.c - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - BASED ON....: "newamp1" by David Rowe - - Quantisation functions for the sinusoidal coder, using "newamp1" - algorithm that resamples variable rate L [Am} to a fixed rate K then - VQs. - -\*---------------------------------------------------------------------------*/ - -/* - Copyright David Rowe 2017 - - All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1, as - published by the Free Software Foundation. This program is - distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, see . - -*/ - -#include "newamp2.h" - -#include -#include -#include -#include -#include - -#include "defines.h" -#include "mbest.h" -#include "newamp1.h" -#include "phase.h" -#include "quantise.h" - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: n2_mel_sample_freqs_kHz() - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - - Outputs fixed frequencies for the K-Vectors to be able to work with both 8k -and 16k mode. - -\*---------------------------------------------------------------------------*/ - -void n2_mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K) { - float freq[] = {0.199816, 0.252849, 0.309008, 0.368476, 0.431449, 0.498134, - 0.568749, 0.643526, 0.722710, 0.806561, 0.895354, 0.989380, - 1.088948, 1.194384, 1.306034, 1.424264, 1.549463, 1.682041, - 1.822432, 1.971098, 2.128525, 2.295232, 2.471763, 2.658699, - 2.856652, 3.066272, 3.288246, 3.523303, 3.772214, 4.035795, - 4.314912, 4.610478, 4.923465, 5.254899, 5.605865, 5.977518, - 6.371075, 6.787827, 7.229141, 7.696465}; - int k; - // printf("\n\n"); - for (k = 0; k < K; k++) { - rate_K_sample_freqs_kHz[k] = freq[k]; - // printf("%f ",mel); - // printf("%f \n",rate_K_sample_freqs_kHz[k]); - } -} - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: n2_resample_const_rate_f() still equal to -resample_const_rate_f() AUTHOR......: David Rowe DATE CREATED: Jan 2017 - - Resample Am from time-varying rate L=floor(pi/Wo) to fixed rate K. - -\*---------------------------------------------------------------------------*/ - -void n2_resample_const_rate_f(C2CONST *c2const, MODEL *model, - float rate_K_vec[], - float rate_K_sample_freqs_kHz[], int K) { - int m; - float AmdB[MAX_AMP + 1], rate_L_sample_freqs_kHz[MAX_AMP + 1], AmdB_peak; - - /* convert rate L=pi/Wo amplitude samples to fixed rate K */ - - AmdB_peak = -100.0; - for (m = 1; m <= model->L; m++) { - AmdB[m] = 20.0 * log10(model->A[m] + 1E-16); - if (AmdB[m] > AmdB_peak) { - AmdB_peak = AmdB[m]; - } - rate_L_sample_freqs_kHz[m] = m * model->Wo * (c2const->Fs / 2000.0) / M_PI; - // printf("m: %d AmdB: %f AmdB_peak: %f sf: %f\n", m, AmdB[m], AmdB_peak, - // rate_L_sample_freqs_kHz[m]); - } - - /* clip between peak and peak -50dB, to reduce dynamic range */ - - for (m = 1; m <= model->L; m++) { - if (AmdB[m] < (AmdB_peak - 50.0)) { - AmdB[m] = AmdB_peak - 50.0; - } - } - - interp_para(rate_K_vec, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, - rate_K_sample_freqs_kHz, K); -} - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: n2_rate_K_mbest_encode - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - - One stage rate K newamp2 VQ quantiser using mbest search. - -\*---------------------------------------------------------------------------*/ - -void n2_rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim) { - int i, n1; - const float *codebook1 = newamp2vq_cb[0].cb; - struct MBEST *mbest_stage1; - float w[ndim]; - int index[1]; - - /* codebook is compiled for a fixed K */ - - // assert(ndim == newamp2vq_cb[0].k); - - /* equal weights, could be argued mel freq axis gives freq dep weighting */ - - for (i = 0; i < ndim; i++) w[i] = 1.0; - - mbest_stage1 = mbest_create(1); - - index[0] = 0; - - /* Stage 1 */ - - mbest_search450(codebook1, x, w, ndim, NEWAMP2_K, newamp2vq_cb[0].m, - mbest_stage1, index); - n1 = mbest_stage1->list[0].index[0]; - - mbest_destroy(mbest_stage1); - - // indexes[1]: legacy from newamp1 - indexes[0] = n1; - indexes[1] = n1; -} - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: n2_resample_rate_L - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - - Decoder side conversion of rate K vector back to rate L. - Plosives are set to zero for the first 2 of 4 frames. - -\*---------------------------------------------------------------------------*/ - -void n2_resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], - float rate_K_sample_freqs_kHz[], int K, - int plosive_flag) { - float rate_K_vec_term[K + 2], rate_K_sample_freqs_kHz_term[K + 2]; - float AmdB[MAX_AMP + 1], rate_L_sample_freqs_kHz[MAX_AMP + 1]; - int m, k; - - /* terminate either end of the rate K vecs with 0dB points */ - - rate_K_vec_term[0] = rate_K_vec_term[K + 1] = 0.0; - rate_K_sample_freqs_kHz_term[0] = 0.0; - rate_K_sample_freqs_kHz_term[K + 1] = 4.0; - - for (k = 0; k < K; k++) { - rate_K_vec_term[k + 1] = rate_K_vec[k]; - rate_K_sample_freqs_kHz_term[k + 1] = rate_K_sample_freqs_kHz[k]; - - // printf("k: %d f: %f rate_K: %f\n", k, rate_K_sample_freqs_kHz[k], - // rate_K_vec[k]); - } - - for (m = 1; m <= model->L; m++) { - rate_L_sample_freqs_kHz[m] = m * model->Wo * (c2const->Fs / 2000.0) / M_PI; - } - - interp_para(&AmdB[1], rate_K_sample_freqs_kHz_term, rate_K_vec_term, K + 2, - &rate_L_sample_freqs_kHz[1], model->L); - for (m = 1; m <= model->L; m++) { - if (plosive_flag == 0) { - model->A[m] = pow(10.0, AmdB[m] / 20.0); - } else { - model->A[m] = 0.1; - } - // printf("m: %d f: %f AdB: %f A: %f\n", m, rate_L_sample_freqs_kHz[m], - // AmdB[m], model->A[m]); - } -} - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: n2_post_filter_newamp2 - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - - Postfilter for the pseudo wideband mode. Still has to be adapted! - -\*---------------------------------------------------------------------------*/ - -void n2_post_filter_newamp2(float vec[], float sample_freq_kHz[], int K, - float pf_gain) { - int k; - - /* - vec is rate K vector describing spectrum of current frame lets - pre-emp before applying PF. 20dB/dec over 300Hz. Postfilter - affects energy of frame so we measure energy before and after - and normalise. Plenty of room for experiment here as well. - */ - - float pre[K]; - float e_before = 0.0; - float e_after = 0.0; - for (k = 0; k < K; k++) { - pre[k] = 20.0 * log10f(sample_freq_kHz[k] / 0.3); - vec[k] += pre[k]; - e_before += POW10F(vec[k] / 10.0); - vec[k] *= pf_gain; - e_after += POW10F(vec[k] / 10.0); - } - - float gain = e_after / e_before; - float gaindB = 10 * log10f(gain); - - for (k = 0; k < K; k++) { - vec[k] -= gaindB; - vec[k] -= pre[k]; - } -} - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: newamp2_model_to_indexes - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - - newamp2 encoder: Encodes the 8k sampled samples using mbest search (one stage) - -\*---------------------------------------------------------------------------*/ - -void newamp2_model_to_indexes(C2CONST *c2const, int indexes[], MODEL *model, - float rate_K_vec[], - float rate_K_sample_freqs_kHz[], int K, - float *mean, float rate_K_vec_no_mean[], - float rate_K_vec_no_mean_[], int plosive) { - 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 */ - - float sum = 0.0; - for (k = 0; k < K; k++) sum += rate_K_vec[k]; - *mean = sum / K; - for (k = 0; k < K; k++) { - rate_K_vec_no_mean[k] = rate_K_vec[k] - *mean; - } - // NEWAMP2_16K_K+1 because the last vector is not a vector for VQ (and not - // included in the constant) but a calculated medium mean value - n2_rate_K_mbest_encode(indexes, rate_K_vec_no_mean, rate_K_vec_no_mean_, - NEWAMP2_16K_K + 1); - - /* scalar quantise mean (effectively the frame energy) */ - - float w[1] = {1.0}; - float se; - indexes[2] = quantise(newamp2_energy_cb[0].cb, mean, w, - newamp2_energy_cb[0].k, newamp2_energy_cb[0].m, &se); - - /* scalar quantise Wo. We steal the smallest Wo index to signal - an unvoiced frame */ - - if (model->voiced) { - int index = encode_log_Wo(c2const, model->Wo, 6); - if (index == 0) { - index = 1; - } - if (index == 63) { - index = 62; - } - indexes[3] = index; - } else { - indexes[3] = 0; - } - if (plosive != 0) { - indexes[3] = 63; - } -} - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: newamp2_indexes_to_rate_K_vec - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - - newamp2 decoder for amplitudes {Am}. Given the rate K VQ and energy - indexes, outputs rate K vector. Equal to newamp1 but using only one stage VQ. - -\*---------------------------------------------------------------------------*/ - -void newamp2_indexes_to_rate_K_vec(float rate_K_vec_[], - float rate_K_vec_no_mean_[], - float rate_K_sample_freqs_kHz[], int K, - float *mean_, int indexes[], float pf_gain) { - int k; - const float *codebook1 = newamp2vq_cb[0].cb; - int n1 = indexes[0]; - - for (k = 0; k < K; k++) { - rate_K_vec_no_mean_[k] = codebook1[(NEWAMP2_16K_K + 1) * n1 + k]; - } - - post_filter_newamp1(rate_K_vec_no_mean_, rate_K_sample_freqs_kHz, K, pf_gain); - - *mean_ = newamp2_energy_cb[0].cb[indexes[2]]; - - for (k = 0; k < K; k++) { - rate_K_vec_[k] = rate_K_vec_no_mean_[k] + *mean_; - } -} - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: newamp2_16k_indexes_to_rate_K_vec - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - - newamp2 decoder for amplitudes {Am}. Given the rate K VQ and energy - indexes, outputs rate K vector. Extends the sample rate by looking up the -corresponding higher frequency values with their energy difference to the base -energy (=>mean2) - -\*---------------------------------------------------------------------------*/ - -void newamp2_16k_indexes_to_rate_K_vec(float rate_K_vec_[], - float rate_K_vec_no_mean_[], - float rate_K_sample_freqs_kHz[], int K, - float *mean_, int indexes[], - float pf_gain) { - int k; - const float *codebook1 = newamp2vq_cb[0].cb; - float mean2 = 0; - int n1 = indexes[0]; - - for (k = 0; k < K; k++) { - rate_K_vec_no_mean_[k] = codebook1[(K + 1) * n1 + k]; - } - - n2_post_filter_newamp2(rate_K_vec_no_mean_, rate_K_sample_freqs_kHz, K, - pf_gain); - - *mean_ = newamp2_energy_cb[0].cb[indexes[2]]; - mean2 = *mean_ + codebook1[(K + 1) * n1 + K] - 10; - - // HF ear Protection - if (mean2 > 50) { - mean2 = 50; - } - - for (k = 0; k < K; k++) { - if (k < NEWAMP2_K) { - rate_K_vec_[k] = rate_K_vec_no_mean_[k] + *mean_; - } else { - // Amplify or Reduce ?? - rate_K_vec_[k] = rate_K_vec_no_mean_[k] + mean2; - } - } -} -/*---------------------------------------------------------------------------*\ - - FUNCTION....: newamp2_interpolate - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - - Interpolates to the 4 10ms Frames and leaves the first 2 empty for plosives - -\*---------------------------------------------------------------------------*/ - -void newamp2_interpolate(float interpolated_surface_[], float left_vec[], - float right_vec[], int K, int plosive_flag) { - int i, k; - int M = 4; - float c; - - /* (linearly) interpolate 25Hz amplitude vectors back to 100Hz */ - - if (plosive_flag == 0) { - for (i = 0, c = 1.0; i < M; i++, c -= 1.0 / M) { - for (k = 0; k < K; k++) { - interpolated_surface_[i * K + k] = - left_vec[k] * c + right_vec[k] * (1.0 - c); - } - } - } else { - for (i = 0, c = 1.0; i < M; i++, c -= 1.0 / M) { - for (k = 0; k < K; k++) { - if (i < 2) { - interpolated_surface_[i * K + k] = 0; - } else { - // perhaps add some dB ? - interpolated_surface_[i * K + k] = right_vec[k]; - } - } - } - } -} - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: newamp2_indexes_to_model - AUTHOR......: Thomas Kurin and Stefan Erhardt - INSTITUTE...: Institute for Electronics Engineering, University of -Erlangen-Nuremberg DATE CREATED: July 2018 - - newamp2 decoder. Chooses whether to decode to 16k mode or to 8k mode - -\*---------------------------------------------------------------------------*/ - -void newamp2_indexes_to_model(C2CONST *c2const, MODEL model_[], COMP H[], - float *interpolated_surface_, - float prev_rate_K_vec_[], float *Wo_left, - int *voicing_left, - float rate_K_sample_freqs_kHz[], int K, - codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg, - int indexes[], float pf_gain, int flag16k) { - float rate_K_vec_[K], rate_K_vec_no_mean_[K], mean_, Wo_right; - int voicing_right, k; - int M = 4; - - /* extract latest rate K vector */ - - if (flag16k == 0) { - newamp2_indexes_to_rate_K_vec(rate_K_vec_, rate_K_vec_no_mean_, - rate_K_sample_freqs_kHz, K, &mean_, indexes, - pf_gain); - } else { - newamp2_16k_indexes_to_rate_K_vec(rate_K_vec_, rate_K_vec_no_mean_, - rate_K_sample_freqs_kHz, K, &mean_, - indexes, pf_gain); - } - - /* decode latest Wo and voicing and plosive */ - int plosive_flag = 0; - - // Voiced with Wo - if (indexes[3] > 0 && indexes[3] < 63) { - Wo_right = decode_log_Wo(c2const, indexes[3], 6); - voicing_right = 1; - } - // Unvoiced - else if (indexes[3] == 0) { - Wo_right = 2.0 * M_PI / 100.0; - voicing_right = 0; - } - // indexes[3]=63 (= Plosive) and unvoiced - else { - Wo_right = 2.0 * M_PI / 100.0; - voicing_right = 0; - plosive_flag = 1; - } - - /* interpolate 25Hz rate K vec back to 100Hz */ - - float *left_vec = prev_rate_K_vec_; - float *right_vec = rate_K_vec_; - newamp2_interpolate(interpolated_surface_, left_vec, right_vec, K, - plosive_flag); - - /* interpolate 25Hz v and Wo back to 100Hz */ - - float aWo_[M]; - int avoicing_[M], aL_[M], i; - - interp_Wo_v(aWo_, aL_, avoicing_, *Wo_left, Wo_right, *voicing_left, - voicing_right); - - /* back to rate L amplitudes, synthesis phase for each frame */ - - for (i = 0; i < M; i++) { - model_[i].Wo = aWo_[i]; - model_[i].L = aL_[i]; - model_[i].voiced = avoicing_[i]; - // Plosive Detected - if (plosive_flag > 0) { - // First two frames are set to zero - if (i < 2) { - n2_resample_rate_L(c2const, &model_[i], &interpolated_surface_[K * i], - rate_K_sample_freqs_kHz, K, 1); - } else { - n2_resample_rate_L(c2const, &model_[i], &interpolated_surface_[K * i], - rate_K_sample_freqs_kHz, K, 0); - } - } - // No Plosive, standard resample - else { - n2_resample_rate_L(c2const, &model_[i], &interpolated_surface_[K * i], - rate_K_sample_freqs_kHz, K, 0); - } - determine_phase(c2const, &H[(MAX_AMP + 1) * i], &model_[i], - NEWAMP2_PHASE_NFFT, fwd_cfg, inv_cfg); - } - - /* update memories for next time */ - - for (k = 0; k < K; k++) { - prev_rate_K_vec_[k] = rate_K_vec_[k]; - } - *Wo_left = Wo_right; - *voicing_left = voicing_right; -} -- cgit v1.2.3