1 /*---------------------------------------------------------------------------*\
2 
3   FILE........: newamp1.c
4   AUTHOR......: David Rowe
5   DATE CREATED: Jan 2017
6 
7   Quantisation functions for the sinusoidal coder, using "newamp1"
8   algorithm that resamples variable rate L [Am} to a fixed rate K then
9   VQs.
10 
11 \*---------------------------------------------------------------------------*/
12 
13 /*
14   Copyright David Rowe 2017
15 
16   All rights reserved.
17 
18   This program is free software; you can redistribute it and/or modify
19   it under the terms of the GNU Lesser General Public License version 2.1, as
20   published by the Free Software Foundation.  This program is
21   distributed in the hope that it will be useful, but WITHOUT ANY
22   WARRANTY; without even the implied warranty of MERCHANTABILITY or
23   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
24   License for more details.
25 
26   You should have received a copy of the GNU Lesser General Public License
27   along with this program; if not, see <http://www.gnu.org/licenses/>.
28 
29 */
30 
31 #include <assert.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <math.h>
36 
37 #include "defines.h"
38 #include "phase.h"
39 #include "quantise.h"
40 #include "mbest.h"
41 #include "newamp1.h"
42 
43 /*---------------------------------------------------------------------------*\
44 
45   FUNCTION....: interp_para()
46   AUTHOR......: David Rowe
47   DATE CREATED: Jan 2017
48 
49   General 2nd order parabolic interpolator.  Used splines orginally,
50   but this is much simpler and we don't need much accuracy.  Given two
51   vectors of points xp and yp, find interpolated values y at points x.
52 
53 \*---------------------------------------------------------------------------*/
54 
interp_para(float y[],float xp[],float yp[],int np,float x[],int n)55 void interp_para(float y[], float xp[], float yp[], int np, float x[], int n)
56 {
57     assert(np >= 3);
58 
59     int k,i;
60     float xi, x1, y1, x2, y2, x3, y3, a, b;
61 
62     k = 0;
63     for (i=0; i<n; i++) {
64         xi = x[i];
65 
66         /* k is index into xp of where we start 3 points used to form parabola */
67 
68         while ((xp[k+1] < xi) && (k < (np-3)))
69             k++;
70 
71         x1 = xp[k]; y1 = yp[k]; x2 = xp[k+1]; y2 = yp[k+1]; x3 = xp[k+2]; y3 = yp[k+2];
72 
73         //printf("k: %d np: %d i: %d xi: %f x1: %f y1: %f\n", k, np, i, xi, x1, y1);
74 
75         a = ((y3-y2)/(x3-x2)-(y2-y1)/(x2-x1))/(x3-x1);
76         b = ((y3-y2)/(x3-x2)*(x2-x1)+(y2-y1)/(x2-x1)*(x3-x2))/(x3-x1);
77 
78         y[i] = a*(xi-x2)*(xi-x2) + b*(xi-x2) + y2;
79     }
80 }
81 
82 
83 /*---------------------------------------------------------------------------*\
84 
85   FUNCTION....: ftomel()
86   AUTHOR......: David Rowe
87   DATE CREATED: Jan 2017
88 
89   Non linear sampling of frequency axis, reducing the "rate" is a
90   first step before VQ
91 
92 \*---------------------------------------------------------------------------*/
93 
ftomel(float fHz)94 float ftomel(float fHz) {
95     float mel = floorf(2595.0*log10f(1.0 + fHz/700.0)+0.5);
96     return mel;
97 }
98 
mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[],int K,float mel_start,float mel_end)99 void mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K, float mel_start, float mel_end)
100 {
101     float step = (mel_end-mel_start)/(K-1);
102     float mel;
103     int k;
104 
105     mel = mel_start;
106     for (k=0; k<K; k++) {
107         rate_K_sample_freqs_kHz[k] = 0.7*(POW10F(mel/2595.0) - 1.0);
108         mel += step;
109     }
110 }
111 
112 
113 /*---------------------------------------------------------------------------*\
114 
115   FUNCTION....: resample_const_rate_f()
116   AUTHOR......: David Rowe
117   DATE CREATED: Jan 2017
118 
119   Resample Am from time-varying rate L=floor(pi/Wo) to fixed rate K.
120 
121 \*---------------------------------------------------------------------------*/
122 
resample_const_rate_f(C2CONST * c2const,MODEL * model,float rate_K_vec[],float rate_K_sample_freqs_kHz[],int K)123 void resample_const_rate_f(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K)
124 {
125     int m;
126     float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1], AmdB_peak;
127 
128     /* convert rate L=pi/Wo amplitude samples to fixed rate K */
129 
130     AmdB_peak = -100.0;
131     for(m=1; m<=model->L; m++) {
132         AmdB[m] = 20.0*log10f(model->A[m]+1E-16);
133         if (AmdB[m] > AmdB_peak) {
134             AmdB_peak = AmdB[m];
135         }
136         rate_L_sample_freqs_kHz[m] = m*model->Wo*(c2const->Fs/2000.0)/M_PI;
137         //printf("m: %d AmdB: %f AmdB_peak: %f  sf: %f\n", m, AmdB[m], AmdB_peak, rate_L_sample_freqs_kHz[m]);
138     }
139 
140     /* clip between peak and peak -50dB, to reduce dynamic range */
141 
142     for(m=1; m<=model->L; m++) {
143         if (AmdB[m] < (AmdB_peak-50.0)) {
144             AmdB[m] = AmdB_peak-50.0;
145         }
146     }
147 
148     interp_para(rate_K_vec, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, rate_K_sample_freqs_kHz, K);
149 }
150 
151 
152 /*---------------------------------------------------------------------------*\
153 
154   FUNCTION....: rate_K_mbest_encode
155   AUTHOR......: David Rowe
156   DATE CREATED: Jan 2017
157 
158   Two stage rate K newamp1 VQ quantiser using mbest search.
159 
160 \*---------------------------------------------------------------------------*/
161 
rate_K_mbest_encode(int * indexes,float * x,float * xq,int ndim,int mbest_entries)162 float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries)
163 {
164   int i, j, n1, n2;
165   const float *codebook1 = newamp1vq_cb[0].cb;
166   const float *codebook2 = newamp1vq_cb[1].cb;
167   struct MBEST *mbest_stage1, *mbest_stage2;
168   float target[ndim];
169   int   index[MBEST_STAGES];
170   float mse, tmp;
171 
172   /* codebook is compiled for a fixed K */
173 
174   assert(ndim == newamp1vq_cb[0].k);
175 
176   mbest_stage1 = mbest_create(mbest_entries);
177   mbest_stage2 = mbest_create(mbest_entries);
178   for(i=0; i<MBEST_STAGES; i++)
179       index[i] = 0;
180 
181   /* Stage 1 */
182 
183   mbest_search(codebook1, x, ndim, newamp1vq_cb[0].m, mbest_stage1, index);
184 
185   /* Stage 2 */
186 
187   for (j=0; j<mbest_entries; j++) {
188       index[1] = n1 = mbest_stage1->list[j].index[0];
189       for(i=0; i<ndim; i++)
190 	  target[i] = x[i] - codebook1[ndim*n1+i];
191       mbest_search(codebook2, target, ndim, newamp1vq_cb[1].m, mbest_stage2, index);
192   }
193 
194   n1 = mbest_stage2->list[0].index[1];
195   n2 = mbest_stage2->list[0].index[0];
196   mse = 0.0;
197   for (i=0;i<ndim;i++) {
198       tmp = codebook1[ndim*n1+i] + codebook2[ndim*n2+i];
199       mse += (x[i]-tmp)*(x[i]-tmp);
200       xq[i] = tmp;
201   }
202 
203   mbest_destroy(mbest_stage1);
204   mbest_destroy(mbest_stage2);
205 
206   indexes[0] = n1; indexes[1] = n2;
207 
208   return mse;
209 }
210 
211 
212 /*---------------------------------------------------------------------------*\
213 
214   FUNCTION....: post_filter
215   AUTHOR......: David Rowe
216   DATE CREATED: Jan 2017
217 
218   Post Filter, has a big impact on speech quality after VQ.  When used
219   on a mean removed rate K vector, it raises formants, and supresses
220   anti-formants.  As it manipulates amplitudes, we normalise energy to
221   prevent clipping or large level variations.  pf_gain of 1.2 to 1.5
222   (dB) seems to work OK.  Good area for further investigations and
223   improvements in speech quality.
224 
225 \*---------------------------------------------------------------------------*/
226 
post_filter_newamp1(float vec[],float sample_freq_kHz[],int K,float pf_gain)227 void post_filter_newamp1(float vec[], float sample_freq_kHz[], int K, float pf_gain)
228 {
229     int k;
230 
231     /*
232       vec is rate K vector describing spectrum of current frame lets
233       pre-emp before applying PF. 20dB/dec over 300Hz.  Postfilter
234       affects energy of frame so we measure energy before and after
235       and normalise.  Plenty of room for experimentation here.
236     */
237 
238     float pre[K];
239     float e_before = 0.0;
240     float e_after = 0.0;
241     for(k=0; k<K; k++) {
242         pre[k] = 20.0*log10f(sample_freq_kHz[k]/0.3);
243         vec[k] += pre[k];
244         e_before += POW10F(vec[k]/10.0);
245         vec[k] *= pf_gain;
246         e_after += POW10F(vec[k]/10.0);
247     }
248 
249     float gain = e_after/e_before;
250     float gaindB = 10*log10f(gain);
251 
252     for(k=0; k<K; k++) {
253         vec[k] -= gaindB;
254         vec[k] -= pre[k];
255     }
256 }
257 
258 
259 /*---------------------------------------------------------------------------*\
260 
261   FUNCTION....: interp_Wo_v
262   AUTHOR......: David Rowe
263   DATE CREATED: Jan 2017
264 
265   Decoder side interpolation of Wo and voicing, to go from 25 Hz
266   sample rate used over channle to 100Hz internal sample rate of Codec 2.
267 
268 \*---------------------------------------------------------------------------*/
269 
interp_Wo_v(float Wo_[],int L_[],int voicing_[],float Wo1,float Wo2,int voicing1,int voicing2)270 void interp_Wo_v(float Wo_[], int L_[], int voicing_[], float Wo1, float Wo2, int voicing1, int voicing2)
271 {
272     int i;
273     int M = 4;  /* interpolation rate */
274 
275     for(i=0; i<M; i++)
276         voicing_[i] = 0;
277 
278     if (!voicing1 && !voicing2) {
279         for(i=0; i<M; i++)
280             Wo_[i] = 2.0*M_PI/100.0;
281     }
282 
283     if (voicing1 && !voicing2) {
284        Wo_[0] = Wo_[1] = Wo1;
285        Wo_[2] = Wo_[3] = 2.0*M_PI/100.0;
286        voicing_[0] = voicing_[1] = 1;
287     }
288 
289     if (!voicing1 && voicing2) {
290        Wo_[0] = Wo_[1] = 2.0*M_PI/100.0;
291        Wo_[2] = Wo_[3] = Wo2;
292        voicing_[2] = voicing_[3] = 1;
293     }
294 
295     if (voicing1 && voicing2) {
296         float c;
297         for(i=0,c=1.0; i<M; i++,c-=1.0/M) {
298             Wo_[i] = Wo1*c + Wo2*(1.0-c);
299             voicing_[i] = 1;
300         }
301     }
302 
303     for(i=0; i<M; i++) {
304         L_[i] = floorf(M_PI/Wo_[i]);
305     }
306 }
307 
308 
309 /*---------------------------------------------------------------------------*\
310 
311   FUNCTION....: resample_rate_L
312   AUTHOR......: David Rowe
313   DATE CREATED: Jan 2017
314 
315   Decoder side conversion of rate K vector back to rate L.
316 
317 \*---------------------------------------------------------------------------*/
318 
resample_rate_L(C2CONST * c2const,MODEL * model,float rate_K_vec[],float rate_K_sample_freqs_kHz[],int K)319 void resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K)
320 {
321    float rate_K_vec_term[K+2], rate_K_sample_freqs_kHz_term[K+2];
322    float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1];
323    int m,k;
324 
325    /* terminate either end of the rate K vecs with 0dB points */
326 
327    rate_K_vec_term[0] = rate_K_vec_term[K+1] = 0.0;
328    rate_K_sample_freqs_kHz_term[0] = 0.0;
329    rate_K_sample_freqs_kHz_term[K+1] = 4.0;
330 
331    for(k=0; k<K; k++) {
332        rate_K_vec_term[k+1] = rate_K_vec[k];
333        rate_K_sample_freqs_kHz_term[k+1] = rate_K_sample_freqs_kHz[k];
334        //printf("k: %d f: %f rate_K: %f\n", k, rate_K_sample_freqs_kHz[k], rate_K_vec[k]);
335    }
336 
337    for(m=1; m<=model->L; m++) {
338        rate_L_sample_freqs_kHz[m] = m*model->Wo*(c2const->Fs/2000.0)/M_PI;
339    }
340 
341    interp_para(&AmdB[1], rate_K_sample_freqs_kHz_term, rate_K_vec_term, K+2, &rate_L_sample_freqs_kHz[1], model->L);
342    for(m=1; m<=model->L; m++) {
343        model->A[m] = POW10F(AmdB[m]/20.0);
344        // printf("m: %d f: %f AdB: %f A: %f\n", m, rate_L_sample_freqs_kHz[m], AmdB[m], model->A[m]);
345    }
346 }
347 
348 
349 /*---------------------------------------------------------------------------*\
350 
351   FUNCTION....: determine_phase
352   AUTHOR......: David Rowe
353   DATE CREATED: Jan 2017
354 
355   Given a magnitude spectrum determine a phase spectrum, used for
356   phase synthesis with newamp1.
357 
358 \*---------------------------------------------------------------------------*/
359 
determine_phase(C2CONST * c2const,COMP H[],MODEL * model,int Nfft,codec2_fft_cfg fwd_cfg,codec2_fft_cfg inv_cfg)360 void determine_phase(C2CONST *c2const, COMP H[], MODEL *model, int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg)
361 {
362     int i,m,b;
363     int Ns = Nfft/2+1;
364     float Gdbfk[Ns], sample_freqs_kHz[Ns], phase[Ns];
365     float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1];
366 
367     for(m=1; m<=model->L; m++) {
368         assert(model->A[m] != 0.0);
369         AmdB[m] = 20.0*log10f(model->A[m]);
370         rate_L_sample_freqs_kHz[m] = (float)m*model->Wo*(c2const->Fs/2000.0)/M_PI;
371     }
372 
373     for(i=0; i<Ns; i++) {
374         sample_freqs_kHz[i] = (c2const->Fs/1000.0)*(float)i/Nfft;
375     }
376 
377     interp_para(Gdbfk, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, sample_freqs_kHz, Ns);
378     mag_to_phase(phase, Gdbfk, Nfft, fwd_cfg, inv_cfg);
379 
380     for(m=1; m<=model->L; m++) {
381         b = floorf(0.5+m*model->Wo*Nfft/(2.0*M_PI));
382         H[m].real = cosf(phase[b]); H[m].imag = sinf(phase[b]);
383     }
384 }
385 
386 /*---------------------------------------------------------------------------* \
387 
388   FUNCTION....: determine_autoc
389   AUTHOR......: David Rowe
390   DATE CREATED: April 2020
391 
392   Determine autocorrelation coefficients from model params, for machine
393   learning experiments.
394 
395 \*---------------------------------------------------------------------------*/
396 
determine_autoc(C2CONST * c2const,float Rk[],int order,MODEL * model,int Nfft,codec2_fft_cfg fwd_cfg,codec2_fft_cfg inv_cfg)397 void determine_autoc(C2CONST *c2const, float Rk[], int order, MODEL *model, int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg)
398 {
399     int i,m;
400     int Ns = Nfft/2+1;
401     float Gdbfk[Ns], sample_freqs_kHz[Ns];
402     float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1];
403 
404     /* interpolate in the log domain */
405     for(m=1; m<=model->L; m++) {
406         assert(model->A[m] != 0.0);
407         AmdB[m] = 20.0*log10f(model->A[m]);
408         rate_L_sample_freqs_kHz[m] = (float)m*model->Wo*(c2const->Fs/2000.0)/M_PI;
409     }
410 
411     for(i=0; i<Ns; i++) {
412         sample_freqs_kHz[i] = (c2const->Fs/1000.0)*(float)i/Nfft;
413     }
414 
415     interp_para(Gdbfk, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, sample_freqs_kHz, Ns);
416 
417     COMP S[Nfft], R[Nfft];
418 
419     /* install negative frequency components, convert to mag squared of spectrum */
420     S[0].real = pow(10.0, Gdbfk[0]/10.0);
421     S[0].imag = 0.0;
422     for(i=1; i<Ns; i++) {
423 	S[i].real = S[Nfft-i].real = pow(10.0, Gdbfk[i]/10.0);
424 	S[i].imag = S[Nfft-i].imag = 0.0;
425     }
426 
427     /* IDFT of mag squared is autocorrelation function */
428     codec2_fft(inv_cfg, S, R);
429     for(int k=0; k<order+1; k++) Rk[k] = R[k].real;
430 }
431 
432 
433 /* update and optionally run "front eq" equaliser on before VQ */
newamp1_eq(float rate_K_vec_no_mean[],float eq[],int K,int eq_en)434 void newamp1_eq(float rate_K_vec_no_mean[], float eq[], int K, int eq_en) {
435     static float ideal[] = {8,10,12,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,-20};
436     float gain = 0.02;
437     float update;
438 
439     for(int k=0; k<K; k++) {
440         update = rate_K_vec_no_mean[k] - ideal[k];
441         eq[k] = (1.0-gain)*eq[k] + gain*update;
442         if (eq[k] < 0.0) eq[k] = 0.0;
443         if (eq_en)
444             rate_K_vec_no_mean[k] -= eq[k];
445     }
446 }
447 
448 /*---------------------------------------------------------------------------* \
449 
450   FUNCTION....: newamp1_model_to_indexes
451   AUTHOR......: David Rowe
452   DATE CREATED: Jan 2017
453 
454   newamp1 encoder for amplitdues {Am}.  Given the rate L model
455   parameters, outputs VQ and energy quantiser indexes.
456 
457 \*---------------------------------------------------------------------------*/
458 
newamp1_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_[],float * se,float * eq,int eq_en)459 void newamp1_model_to_indexes(C2CONST *c2const,
460                               int    indexes[],
461                               MODEL *model,
462                               float  rate_K_vec[],
463                               float  rate_K_sample_freqs_kHz[],
464                               int    K,
465                               float *mean,
466                               float  rate_K_vec_no_mean[],
467                               float  rate_K_vec_no_mean_[],
468                               float *se,
469                               float *eq,
470                               int    eq_en
471                               )
472 {
473     int k;
474 
475     /* convert variable rate L to fixed rate K */
476     resample_const_rate_f(c2const, model, rate_K_vec, rate_K_sample_freqs_kHz, K);
477 
478     /* remove mean */
479     float sum = 0.0;
480     for(k=0; k<K; k++)
481         sum += rate_K_vec[k];
482     *mean = sum/K;
483     for(k=0; k<K; k++)
484         rate_K_vec_no_mean[k] = rate_K_vec[k] - *mean;
485 
486     /* update and optionally run "front eq" equaliser on before VQ */
487     newamp1_eq(rate_K_vec_no_mean, eq, K, eq_en);
488 
489     /* two stage VQ */
490     rate_K_mbest_encode(indexes, rate_K_vec_no_mean, rate_K_vec_no_mean_, K, NEWAMP1_VQ_MBEST_DEPTH);
491 
492     /* running sum of squared error for variance calculation */
493     for(k=0; k<K; k++)
494         *se += (float)pow(rate_K_vec_no_mean[k]-rate_K_vec_no_mean_[k],2.0);
495 
496     /* scalar quantise mean (effectively the frame energy) */
497     float w[1] = {1.0};
498     float se_mean;
499     indexes[2] = quantise(newamp1_energy_cb[0].cb,
500                           mean,
501                           w,
502                           newamp1_energy_cb[0].k,
503                           newamp1_energy_cb[0].m,
504                           &se_mean);
505 
506     /* scalar quantise Wo.  We steal the smallest Wo index to signal
507        an unvoiced frame */
508     if (model->voiced) {
509         int index = encode_log_Wo(c2const, model->Wo, 6);
510         if (index == 0) {
511             index = 1;
512         }
513         indexes[3] = index;
514     }
515     else {
516         indexes[3] = 0;
517     }
518 }
519 
520 
521 /*---------------------------------------------------------------------------*\
522 
523   FUNCTION....: newamp1_interpolate
524   AUTHOR......: David Rowe
525   DATE CREATED: Jan 2017
526 
527 \*---------------------------------------------------------------------------*/
528 
newamp1_interpolate(float interpolated_surface_[],float left_vec[],float right_vec[],int K)529 void newamp1_interpolate(float interpolated_surface_[], float left_vec[], float right_vec[], int K)
530 {
531     int  i, k;
532     int  M = 4;
533     float c;
534 
535     /* (linearly) interpolate 25Hz amplitude vectors back to 100Hz */
536 
537     for(i=0,c=1.0; i<M; i++,c-=1.0/M) {
538         for(k=0; k<K; k++) {
539             interpolated_surface_[i*K+k] = left_vec[k]*c + right_vec[k]*(1.0-c);
540         }
541     }
542 }
543 
544 
545 /*---------------------------------------------------------------------------*\
546 
547   FUNCTION....: newamp1_indexes_to_rate_K_vec
548   AUTHOR......: David Rowe
549   DATE CREATED: Jan 2017
550 
551   newamp1 decoder for amplitudes {Am}.  Given the rate K VQ and energy
552   indexes, outputs rate K vector.
553 
554 \*---------------------------------------------------------------------------*/
555 
newamp1_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 user_rate_K_vec_no_mean_[],int post_filter_en)556 void newamp1_indexes_to_rate_K_vec(float  rate_K_vec_[],
557                                    float  rate_K_vec_no_mean_[],
558                                    float  rate_K_sample_freqs_kHz[],
559                                    int    K,
560                                    float *mean_,
561                                    int    indexes[],
562                                    float user_rate_K_vec_no_mean_[],
563                                    int post_filter_en)
564 {
565     int   k;
566     const float *codebook1 = newamp1vq_cb[0].cb;
567     const float *codebook2 = newamp1vq_cb[1].cb;
568     int n1 = indexes[0];
569     int n2 = indexes[1];
570 
571     if (user_rate_K_vec_no_mean_ == NULL) {
572         /* normal operation */
573         for(k=0; k<K; k++) {
574             rate_K_vec_no_mean_[k] = codebook1[K*n1+k] + codebook2[K*n2+k];
575         }
576     } else {
577         /* for development we can optionally inject the quantised rate K vector here */
578         for(k=0; k<K; k++)
579             rate_K_vec_no_mean_[k] = user_rate_K_vec_no_mean_[k];
580     }
581 
582     if (post_filter_en)
583         post_filter_newamp1(rate_K_vec_no_mean_, rate_K_sample_freqs_kHz, K, 1.5);
584 
585     *mean_ = newamp1_energy_cb[0].cb[indexes[2]];
586 
587     for(k=0; k<K; k++) {
588         rate_K_vec_[k] = rate_K_vec_no_mean_[k] + *mean_;
589     }
590 }
591 
592 
593 /*---------------------------------------------------------------------------*\
594 
595   FUNCTION....: newamp1_indexes_to_model
596   AUTHOR......: David Rowe
597   DATE CREATED: Jan 2017
598 
599   newamp1 decoder.
600 
601 \*---------------------------------------------------------------------------*/
602 
newamp1_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 user_rate_K_vec_no_mean_[],int post_filter_en)603 void newamp1_indexes_to_model(C2CONST *c2const,
604                               MODEL  model_[],
605                               COMP   H[],
606                               float *interpolated_surface_,
607                               float  prev_rate_K_vec_[],
608                               float  *Wo_left,
609                               int    *voicing_left,
610                               float  rate_K_sample_freqs_kHz[],
611                               int    K,
612                               codec2_fft_cfg fwd_cfg,
613                               codec2_fft_cfg inv_cfg,
614                               int    indexes[],
615                               float  user_rate_K_vec_no_mean_[],
616                               int    post_filter_en)
617 {
618     float rate_K_vec_[K], rate_K_vec_no_mean_[K], mean_, Wo_right;
619     int   voicing_right, k;
620     int   M = 4;
621 
622     /* extract latest rate K vector */
623 
624     newamp1_indexes_to_rate_K_vec(rate_K_vec_,
625                                   rate_K_vec_no_mean_,
626                                   rate_K_sample_freqs_kHz,
627                                   K,
628                                   &mean_,
629                                   indexes,
630                                   user_rate_K_vec_no_mean_,
631                                   post_filter_en);
632 
633     /* decode latest Wo and voicing */
634 
635     if (indexes[3]) {
636         Wo_right = decode_log_Wo(c2const, indexes[3], 6);
637         voicing_right = 1;
638     }
639     else {
640         Wo_right  = 2.0*M_PI/100.0;
641         voicing_right = 0;
642     }
643 
644     /* interpolate 25Hz rate K vec back to 100Hz */
645 
646     float *left_vec = prev_rate_K_vec_;
647     float *right_vec = rate_K_vec_;
648     newamp1_interpolate(interpolated_surface_, left_vec, right_vec, K);
649 
650     /* interpolate 25Hz v and Wo back to 100Hz */
651 
652     float aWo_[M];
653     int avoicing_[M], aL_[M], i;
654 
655     interp_Wo_v(aWo_, aL_, avoicing_, *Wo_left, Wo_right, *voicing_left, voicing_right);
656 
657     /* back to rate L amplitudes, synthesise phase for each frame */
658 
659     for(i=0; i<M; i++) {
660         model_[i].Wo = aWo_[i];
661         model_[i].L  = aL_[i];
662         model_[i].voiced = avoicing_[i];
663 
664         resample_rate_L(c2const, &model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K);
665         determine_phase(c2const, &H[(MAX_AMP+1)*i], &model_[i], NEWAMP1_PHASE_NFFT, fwd_cfg, inv_cfg);
666     }
667 
668     /* update memories for next time */
669 
670     for(k=0; k<K; k++) {
671         prev_rate_K_vec_[k] = rate_K_vec_[k];
672     }
673     *Wo_left = Wo_right;
674     *voicing_left = voicing_right;
675 
676 }
677 
678