From: drowe67 Date: Tue, 10 Jan 2017 23:16:59 +0000 (+0000) Subject: refactoring: moved newamp1 and mbest vq search functions into a separate source file X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=d9293405ec0af2ee7f05f2ce117b9a7394dda1c7;p=freetel-svn-tracking.git refactoring: moved newamp1 and mbest vq search functions into a separate source file git-svn-id: https://svn.code.sf.net/p/freetel/code@2955 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/src/CMakeLists.txt b/codec2-dev/src/CMakeLists.txt index fee648d9..9e9b8bb3 100644 --- a/codec2-dev/src/CMakeLists.txt +++ b/codec2-dev/src/CMakeLists.txt @@ -172,6 +172,8 @@ set(CODEC2_SRCS linreg.c interp.c lsp.c + mbest.c + newamp1.c phase.c quantise.c pack.c diff --git a/codec2-dev/src/mbest.c b/codec2-dev/src/mbest.c new file mode 100644 index 00000000..e092d714 --- /dev/null +++ b/codec2-dev/src/mbest.c @@ -0,0 +1,142 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: mbest.c + AUTHOR......: David Rowe + DATE CREATED: Jan 2017 + + Multistage vector quantiser search algorithm that keeps multiple + candidates from each stage. + +\*---------------------------------------------------------------------------*/ + +/* + 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 +#include +#include +#include +#include + +#include "mbest.h" + +struct MBEST *mbest_create(int entries) { + int i,j; + struct MBEST *mbest; + + assert(entries > 0); + mbest = (struct MBEST *)malloc(sizeof(struct MBEST)); + assert(mbest != NULL); + + mbest->entries = entries; + mbest->list = (struct MBEST_LIST *)malloc(entries*sizeof(struct MBEST_LIST)); + assert(mbest->list != NULL); + + for(i=0; ientries; i++) { + for(j=0; jlist[i].index[j] = 0; + mbest->list[i].error = 1E32; + } + + return mbest; +} + + +void mbest_destroy(struct MBEST *mbest) { + assert(mbest != NULL); + free(mbest->list); + free(mbest); +} + + +/*---------------------------------------------------------------------------*\ + + mbest_insert + + Insert the results of a vector to codebook entry comparison. The + list is ordered in order or error, so those entries with the + smallest error will be first on the list. + +\*---------------------------------------------------------------------------*/ + +void mbest_insert(struct MBEST *mbest, int index[], float error) { + int i, j, found; + struct MBEST_LIST *list = mbest->list; + int entries = mbest->entries; + + found = 0; + for(i=0; ii; j--) + list[j] = list[j-1]; + for(j=0; jentries; i++) { + for(j=0; jlist[i].index[j]); + fprintf(stderr, " %f\n", mbest->list[i].error); + } +} +#endif + + +/*---------------------------------------------------------------------------*\ + + mbest_search + + Searches vec[] to a codebbook of vectors, and maintains a list of the mbest + closest matches. + +\*---------------------------------------------------------------------------*/ + +void mbest_search( + const float *cb, /* VQ codebook to search */ + float vec[], /* target vector */ + float w[], /* weighting vector */ + int k, /* dimension of vector */ + int m, /* number on entries in codebook */ + struct MBEST *mbest, /* list of closest matches */ + int index[] /* indexes that lead us here */ +) +{ + float e; + int i,j; + float diff; + + for(j=0; j. + +*/ + +#ifndef __MBEST__ +#define __MBEST__ + +#define MBEST_STAGES 4 + +struct MBEST_LIST { + int index[MBEST_STAGES]; /* index of each stage that lead us to this error */ + float error; +}; + +struct MBEST { + int entries; /* number of entries in mbest list */ + struct MBEST_LIST *list; +}; + +struct MBEST *mbest_create(int entries); +void mbest_destroy(struct MBEST *mbest); +void mbest_insert(struct MBEST *mbest, int index[], float error); +void mbest_search(const float *cb, float vec[], float w[], int k, int m, struct MBEST *mbest, int index[]); + +// #define MBEST_PRINT_OUT +#ifdef MBEST_PRINT_OUT + #define MBEST_PRINT(a,b) mbest_print((a),(b)) +#else + #define MBEST_PRINT(a,b) +#endif + + +#endif diff --git a/codec2-dev/src/newamp1.c b/codec2-dev/src/newamp1.c new file mode 100644 index 00000000..45fe39b1 --- /dev/null +++ b/codec2-dev/src/newamp1.c @@ -0,0 +1,405 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: newamp1.c + AUTHOR......: David Rowe + DATE CREATED: Jan 2017 + + 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 +#include +#include +#include +#include + +#include "defines.h" +#include "phase.h" +#include "quantise.h" +#include "mbest.h" +#include "newamp1.h" + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: interp_para() + AUTHOR......: David Rowe + DATE CREATED: Jan 2017 + + General 2nd order parabolic interpolator. Used splines orginally, + but this is much simpler and we don't need much accuracy. Given two + vectors of points xp and yp, find interpolated values y at points x. + +\*---------------------------------------------------------------------------*/ + +void interp_para(float y[], float xp[], float yp[], int np, float x[], int n) +{ + assert(np >= 3); + + int k,i; + float xi, x1, y1, x2, y2, x3, y3, a, b; + + k = 0; + for (i=0; iL; 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*4.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....: rate_K_mbest_encode + AUTHOR......: David Rowe + DATE CREATED: Jan 2017 + + Two stage rate K newamp1 VQ quantiser using mbest search. + +\*---------------------------------------------------------------------------*/ + +float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries) +{ + int i, j, n1, n2; + const float *codebook1 = newamp1vq_cb[0].cb; + const float *codebook2 = newamp1vq_cb[1].cb; + struct MBEST *mbest_stage1, *mbest_stage2; + float target[ndim]; + float w[ndim]; + int index[MBEST_STAGES]; + float mse, tmp; + + for(i=0; ilist[j].index[0]; + for(i=0; ilist[0].index[1]; + n2 = mbest_stage2->list[0].index[0]; + mse = 0.0; + for (i=0;iL; m++) { + rate_L_sample_freqs_kHz[m] = m*model->Wo*4.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++) { + model->A[m] = pow(10.0, AmdB[m]/20.0); + // printf("m: %d f: %f AdB: %f A: %f\n", m, rate_L_sample_freqs_kHz[m], AmdB[m], model->A[m]); + } +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: determine_phase + AUTHOR......: David Rowe + DATE CREATED: Jan 2017 + + Given a magnitude spectrum determine a phase spectrum, used for + phase synthesis with newamp1. + +\*---------------------------------------------------------------------------*/ + +void determine_phase(MODEL *model, int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg) +{ + int i,m,b; + int Ns = Nfft/2+1; + float Gdbfk[Ns], sample_freqs_kHz[Ns], phase[Ns]; + float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1]; + + printf(" AmdB.: "); + for(m=1; m<=model->L; m++) { + AmdB[m] = 20.0*log10(model->A[m]); + rate_L_sample_freqs_kHz[m] = (float)m*model->Wo*4.0/M_PI; + if (m <=5) { + printf("%5.2f ", AmdB[m]); + } + } + printf("\n"); + + for(i=0; iL, sample_freqs_kHz, Ns); + + printf(" Gdbfk: "); + for(i=0; i<5; i++) { + printf("%5.2f ", Gdbfk[i]); + } + printf("\n"); + + mag_to_phase(phase, Gdbfk, Nfft, fwd_cfg, inv_cfg); + + printf(" b....: "); + for(m=1; m<=model->L; m++) { + b = floorf(0.5+m*model->Wo*Nfft/(2.0*M_PI)); + model->phi[m] = phase[b]; + if (m <= 5) { + printf("%5d ", b); + } + } + printf("\n"); + printf(" phi..: "); + for(m=1; m<=5; m++) { + printf("% 5.2f ", model->phi[m]); + } + printf("\n"); +} diff --git a/codec2-dev/src/newamp1.h b/codec2-dev/src/newamp1.h new file mode 100644 index 00000000..e576a1f3 --- /dev/null +++ b/codec2-dev/src/newamp1.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: newamp1.h + AUTHOR......: David Rowe + DATE CREATED: Jan 2017 + + 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 . +*/ + +#ifndef __NEWAMP1__ +#define __NEWAMP1__ + +#include "codec2_fft.h" +#include "comp.h" + +void interp_para(float y[], float xp[], float yp[], int np, float x[], int n); +float ftomel(float fHz); +void mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K); +void resample_const_rate_f(MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K); +float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries); +void post_filter_newamp1(float vec[], float sample_freq_kHz[], int K, float pf_gain); +void interp_Wo_v(float Wo_[], int voicing_[], float Wo1, float Wo2, int voicing1, int voicing2); +void resample_rate_L(MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K); +void determine_phase(MODEL *model, int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg); + +#endif diff --git a/codec2-dev/src/quantise.c b/codec2-dev/src/quantise.c index ca9f615a..a4fa96eb 100644 --- a/codec2-dev/src/quantise.c +++ b/codec2-dev/src/quantise.c @@ -38,16 +38,12 @@ #include "lsp.h" #include "codec2_fft.h" #include "phase.h" +#include "mbest.h" + #undef PROFILE #include "machdep.h" #define LSP_DELTA1 0.01 /* grid spacing for LSP root searches */ -// #define MBEST_PRINT_OUT -#ifdef MBEST_PRINT_OUT - #define MBEST_PRINT(a,b) mbest_print((a),(b)) -#else - #define MBEST_PRINT(a,b) -#endif /*---------------------------------------------------------------------------*\ @@ -593,125 +589,6 @@ float lspmelvq_quantise(float *x, float *xq, int order) return mse; } -#define MBEST_STAGES 4 - -struct MBEST_LIST { - int index[MBEST_STAGES]; /* index of each stage that lead us to this error */ - float error; -}; - -struct MBEST { - int entries; /* number of entries in mbest list */ - struct MBEST_LIST *list; -}; - - -static struct MBEST *mbest_create(int entries) { - int i,j; - struct MBEST *mbest; - - assert(entries > 0); - mbest = (struct MBEST *)malloc(sizeof(struct MBEST)); - assert(mbest != NULL); - - mbest->entries = entries; - mbest->list = (struct MBEST_LIST *)malloc(entries*sizeof(struct MBEST_LIST)); - assert(mbest->list != NULL); - - for(i=0; ientries; i++) { - for(j=0; jlist[i].index[j] = 0; - mbest->list[i].error = 1E32; - } - - return mbest; -} - - -static void mbest_destroy(struct MBEST *mbest) { - assert(mbest != NULL); - free(mbest->list); - free(mbest); -} - - -/*---------------------------------------------------------------------------*\ - - mbest_insert - - Insert the results of a vector to codebook entry comparison. The - list is ordered in order or error, so those entries with the - smallest error will be first on the list. - -\*---------------------------------------------------------------------------*/ - -static void mbest_insert(struct MBEST *mbest, int index[], float error) { - int i, j, found; - struct MBEST_LIST *list = mbest->list; - int entries = mbest->entries; - - found = 0; - for(i=0; ii; j--) - list[j] = list[j-1]; - for(j=0; jentries; i++) { - for(j=0; jlist[i].index[j]); - fprintf(stderr, " %f\n", mbest->list[i].error); - } -} -#endif - - -/*---------------------------------------------------------------------------*\ - - mbest_search - - Searches vec[] to a codebbook of vectors, and maintains a list of the mbest - closest matches. - -\*---------------------------------------------------------------------------*/ - -static void mbest_search( - const float *cb, /* VQ codebook to search */ - float vec[], /* target vector */ - float w[], /* weighting vector */ - int k, /* dimension of vector */ - int m, /* number on entries in codebook */ - struct MBEST *mbest, /* list of closest matches */ - int index[] /* indexes that lead us here */ -) -{ - float e; - int i,j; - float diff; - - for(j=0; j= 3); - - int k,i; - float xi, x1, y1, x2, y2, x3, y3, a, b; - - k = 0; - for (i=0; iL; 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*4.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....: rate_K_mbest_encode - AUTHOR......: David Rowe - DATE CREATED: Jan 2017 - - Two stage rate K newamp1 VQ quantiser using mbest search. - -\*---------------------------------------------------------------------------*/ - -float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries) -{ - int i, j, n1, n2; - const float *codebook1 = newamp1vq_cb[0].cb; - const float *codebook2 = newamp1vq_cb[1].cb; - struct MBEST *mbest_stage1, *mbest_stage2; - float target[ndim]; - float w[ndim]; - int index[MBEST_STAGES]; - float mse, tmp; - - for(i=0; ilist[j].index[0]; - for(i=0; ilist[0].index[1]; - n2 = mbest_stage2->list[0].index[0]; - mse = 0.0; - for (i=0;iL; m++) { - rate_L_sample_freqs_kHz[m] = m*model->Wo*4.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++) { - model->A[m] = pow(10.0, AmdB[m]/20.0); - // printf("m: %d f: %f AdB: %f A: %f\n", m, rate_L_sample_freqs_kHz[m], AmdB[m], model->A[m]); - } -} - - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: determine_phase - AUTHOR......: David Rowe - DATE CREATED: Jan 2017 - - Given a magnitude spectrum determine a phase spectrum, used for - phase synthesis with newamp1. - -\*---------------------------------------------------------------------------*/ - -void determine_phase(MODEL *model, int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg) -{ - int i,m,b; - int Ns = Nfft/2+1; - float Gdbfk[Ns], sample_freqs_kHz[Ns], phase[Ns]; - float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1]; - - printf(" AmdB.: "); - for(m=1; m<=model->L; m++) { - AmdB[m] = 20.0*log10(model->A[m]); - rate_L_sample_freqs_kHz[m] = (float)m*model->Wo*4.0/M_PI; - if (m <=5) { - printf("%5.2f ", AmdB[m]); - } - } - printf("\n"); - - for(i=0; iL, sample_freqs_kHz, Ns); - - printf(" Gdbfk: "); - for(i=0; i<5; i++) { - printf("%5.2f ", Gdbfk[i]); - } - printf("\n"); - - mag_to_phase(phase, Gdbfk, Nfft, fwd_cfg, inv_cfg); - - printf(" b....: "); - for(m=1; m<=model->L; m++) { - b = floorf(0.5+m*model->Wo*Nfft/(2.0*M_PI)); - model->phi[m] = phase[b]; - if (m <= 5) { - printf("%5d ", b); - } - } - printf("\n"); - printf(" phi..: "); - for(m=1; m<=5; m++) { - printf("% 5.2f ", model->phi[m]); - } - printf("\n"); -} diff --git a/codec2-dev/src/quantise.h b/codec2-dev/src/quantise.h index 399a523a..bc8c056a 100644 --- a/codec2-dev/src/quantise.h +++ b/codec2-dev/src/quantise.h @@ -135,14 +135,4 @@ float decode_amplitudes(MODEL *model, float lsps[], float *e); -void interp_para(float y[], float xp[], float yp[], int np, float x[], int n); -float ftomel(float fHz); -void mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K); -void resample_const_rate_f(MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K); -float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries); -void post_filter_newamp1(float vec[], float sample_freq_kHz[], int K, float pf_gain); -void interp_Wo_v(float Wo_[], int voicing_[], float Wo1, float Wo2, int voicing1, int voicing2); -void resample_rate_L(MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K); -void determine_phase(MODEL *model, int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg); - #endif diff --git a/codec2-dev/unittest/CMakeLists.txt b/codec2-dev/unittest/CMakeLists.txt index 5c328f9d..839fc919 100644 --- a/codec2-dev/unittest/CMakeLists.txt +++ b/codec2-dev/unittest/CMakeLists.txt @@ -114,5 +114,5 @@ add_definitions(-D__UNITTEST__) add_executable(c2validate c2validate.c) target_link_libraries(c2validate codec2) -add_executable(tnewamp1 tnewamp1.c ../src/quantise.c ../src/kiss_fft.c ../src/sine.c ../src/nlp.c ../src/dump.c ../src/octave.c ${CODEBOOKS}) +add_executable(tnewamp1 tnewamp1.c ../src/quantise.c ../src/newamp1.c ../src/mbest.c ../src/kiss_fft.c ../src/sine.c ../src/nlp.c ../src/dump.c ../src/octave.c ${CODEBOOKS}) target_link_libraries(tnewamp1 codec2)