1 /*---------------------------------------------------------------------------*\
2 
3   FILE........: newamp2.c
4   AUTHOR......: Thomas Kurin and Stefan Erhardt
5   INSTITUTE...:	Institute for Electronics Engineering, University of Erlangen-Nuremberg
6   DATE CREATED: July 2018
7   BASED ON....:	"newamp1" by David Rowe
8 
9   Quantisation functions for the sinusoidal coder, using "newamp1"
10   algorithm that resamples variable rate L [Am} to a fixed rate K then
11   VQs.
12 
13 \*---------------------------------------------------------------------------*/
14 
15 /*
16   Copyright David Rowe 2017
17 
18   All rights reserved.
19 
20   This program is free software; you can redistribute it and/or modify
21   it under the terms of the GNU Lesser General Public License version 2.1, as
22   published by the Free Software Foundation.  This program is
23   distributed in the hope that it will be useful, but WITHOUT ANY
24   WARRANTY; without even the implied warranty of MERCHANTABILITY or
25   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
26   License for more details.
27 
28   You should have received a copy of the GNU Lesser General Public License
29   along with this program; if not, see <http://www.gnu.org/licenses/>.
30 
31 */
32 
33 #include <assert.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <math.h>
38 
39 #include "defines.h"
40 #include "phase.h"
41 #include "quantise.h"
42 #include "mbest.h"
43 #include "newamp1.h"
44 #include "newamp2.h"
45 
46 /*---------------------------------------------------------------------------*\
47 
48   FUNCTION....: n2_mel_sample_freqs_kHz()
49   AUTHOR......: Thomas Kurin and Stefan Erhardt
50   INSTITUTE...:	Institute for Electronics Engineering, University of Erlangen-Nuremberg
51   DATE CREATED: July 2018
52 
53   Outputs fixed frequencies for the K-Vectors to be able to work with both 8k and 16k mode.
54 
55 \*---------------------------------------------------------------------------*/
56 
n2_mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[],int K)57 void n2_mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K)
58 {
59 	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,
60 					1.088948, 1.194384, 1.306034, 1.424264, 1.549463, 1.682041, 1.822432, 1.971098, 2.128525, 2.295232, 2.471763, 2.658699,
61 					2.856652, 3.066272, 3.288246, 3.523303, 3.772214, 4.035795, 4.314912, 4.610478, 4.923465, 5.254899, 5.605865, 5.977518,
62 					6.371075, 6.787827, 7.229141, 7.696465};
63     int k;
64 	//printf("\n\n");
65     for (k=0; k<K; k++) {
66         rate_K_sample_freqs_kHz[k] = freq[k];
67     //    printf("%f ",mel);
68     //    printf("%f \n",rate_K_sample_freqs_kHz[k]);
69     }
70 
71 }
72 
73 
74 /*---------------------------------------------------------------------------*\
75 
76   FUNCTION....: n2_resample_const_rate_f() still equal to resample_const_rate_f()
77   AUTHOR......: David Rowe
78   DATE CREATED: Jan 2017
79 
80   Resample Am from time-varying rate L=floor(pi/Wo) to fixed rate K.
81 
82 \*---------------------------------------------------------------------------*/
83 
n2_resample_const_rate_f(C2CONST * c2const,MODEL * model,float rate_K_vec[],float rate_K_sample_freqs_kHz[],int K)84 void n2_resample_const_rate_f(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K)
85 {
86     int m;
87     float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1], AmdB_peak;
88 
89     /* convert rate L=pi/Wo amplitude samples to fixed rate K */
90 
91     AmdB_peak = -100.0;
92     for(m=1; m<=model->L; m++) {
93         AmdB[m] = 20.0*log10(model->A[m]+1E-16);
94         if (AmdB[m] > AmdB_peak) {
95             AmdB_peak = AmdB[m];
96         }
97         rate_L_sample_freqs_kHz[m] = m*model->Wo*(c2const->Fs/2000.0)/M_PI;
98         //printf("m: %d AmdB: %f AmdB_peak: %f  sf: %f\n", m, AmdB[m], AmdB_peak, rate_L_sample_freqs_kHz[m]);
99     }
100 
101     /* clip between peak and peak -50dB, to reduce dynamic range */
102 
103     for(m=1; m<=model->L; m++) {
104         if (AmdB[m] < (AmdB_peak-50.0)) {
105             AmdB[m] = AmdB_peak-50.0;
106         }
107     }
108 
109     interp_para(rate_K_vec, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, rate_K_sample_freqs_kHz, K);
110 }
111 
112 
113 /*---------------------------------------------------------------------------*\
114 
115   FUNCTION....: n2_rate_K_mbest_encode
116   AUTHOR......: Thomas Kurin and Stefan Erhardt
117   INSTITUTE...:	Institute for Electronics Engineering, University of Erlangen-Nuremberg
118   DATE CREATED: July 2018
119 
120   One stage rate K newamp2 VQ quantiser using mbest search.
121 
122 \*---------------------------------------------------------------------------*/
123 
n2_rate_K_mbest_encode(int * indexes,float * x,float * xq,int ndim)124 void n2_rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim)
125 {
126   int i, n1;
127   const float *codebook1 = newamp2vq_cb[0].cb;
128   struct MBEST *mbest_stage1;
129   float w[ndim];
130   int   index[1];
131 
132   /* codebook is compiled for a fixed K */
133 
134   //assert(ndim == newamp2vq_cb[0].k);
135 
136   /* equal weights, could be argued mel freq axis gives freq dep weighting */
137 
138   for(i=0; i<ndim; i++)
139       w[i] = 1.0;
140 
141   mbest_stage1 = mbest_create(1);
142 
143   index[0] = 0;
144 
145   /* Stage 1 */
146 
147   mbest_search450(codebook1, x, w, ndim,NEWAMP2_K, newamp2vq_cb[0].m, mbest_stage1, index);
148   n1 = mbest_stage1->list[0].index[0];
149 
150   mbest_destroy(mbest_stage1);
151 
152   //indexes[1]: legacy from newamp1
153   indexes[0] = n1; indexes[1] = n1;
154 
155 }
156 
157 
158 /*---------------------------------------------------------------------------*\
159 
160   FUNCTION....: n2_resample_rate_L
161   AUTHOR......: Thomas Kurin and Stefan Erhardt
162   INSTITUTE...:	Institute for Electronics Engineering, University of Erlangen-Nuremberg
163   DATE CREATED: July 2018
164 
165   Decoder side conversion of rate K vector back to rate L.
166   Plosives are set to zero for the first 2 of 4 frames.
167 
168 \*---------------------------------------------------------------------------*/
169 
n2_resample_rate_L(C2CONST * c2const,MODEL * model,float rate_K_vec[],float rate_K_sample_freqs_kHz[],int K,int plosive_flag)170 void n2_resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K,int plosive_flag)
171 {
172    float rate_K_vec_term[K+2], rate_K_sample_freqs_kHz_term[K+2];
173    float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1];
174    int m,k;
175 
176    /* terminate either end of the rate K vecs with 0dB points */
177 
178    rate_K_vec_term[0] = rate_K_vec_term[K+1] = 0.0;
179    rate_K_sample_freqs_kHz_term[0] = 0.0;
180    rate_K_sample_freqs_kHz_term[K+1] = 4.0;
181 
182    for(k=0; k<K; k++) {
183        rate_K_vec_term[k+1] = rate_K_vec[k];
184        rate_K_sample_freqs_kHz_term[k+1] = rate_K_sample_freqs_kHz[k];
185 
186        //printf("k: %d f: %f rate_K: %f\n", k, rate_K_sample_freqs_kHz[k], rate_K_vec[k]);
187    }
188 
189    for(m=1; m<=model->L; m++) {
190        rate_L_sample_freqs_kHz[m] = m*model->Wo*(c2const->Fs/2000.0)/M_PI;
191    }
192 
193    interp_para(&AmdB[1], rate_K_sample_freqs_kHz_term, rate_K_vec_term, K+2, &rate_L_sample_freqs_kHz[1], model->L);
194    for(m=1; m<=model->L; m++) {
195 		if(plosive_flag==0){
196 			model->A[m] = pow(10.0,  AmdB[m]/20.0);
197 		}else{
198 			model->A[m] = 0.1;
199 		}
200        // printf("m: %d f: %f AdB: %f A: %f\n", m, rate_L_sample_freqs_kHz[m], AmdB[m], model->A[m]);
201    }
202 }
203 
204 /*---------------------------------------------------------------------------*\
205 
206   FUNCTION....: n2_post_filter_newamp2
207   AUTHOR......: Thomas Kurin and Stefan Erhardt
208   INSTITUTE...:	Institute for Electronics Engineering, University of Erlangen-Nuremberg
209   DATE CREATED: July 2018
210 
211   Postfilter for the pseudo wideband mode. Still has to be adapted!
212 
213 \*---------------------------------------------------------------------------*/
214 
n2_post_filter_newamp2(float vec[],float sample_freq_kHz[],int K,float pf_gain)215 void n2_post_filter_newamp2(float vec[], float sample_freq_kHz[], int K, float pf_gain)
216 {
217     int k;
218 
219     /*
220       vec is rate K vector describing spectrum of current frame lets
221       pre-emp before applying PF. 20dB/dec over 300Hz.  Postfilter
222       affects energy of frame so we measure energy before and after
223       and normalise.  Plenty of room for experiment here as well.
224     */
225 
226     float pre[K];
227     float e_before = 0.0;
228     float e_after = 0.0;
229     for(k=0; k<K; k++) {
230         pre[k] = 20.0*log10f(sample_freq_kHz[k]/0.3);
231         vec[k] += pre[k];
232         e_before += POW10F(vec[k]/10.0);
233         vec[k] *= pf_gain;
234         e_after += POW10F(vec[k]/10.0);
235     }
236 
237     float gain = e_after/e_before;
238     float gaindB = 10*log10f(gain);
239 
240     for(k=0; k<K; k++) {
241         vec[k] -= gaindB;
242         vec[k] -= pre[k];
243     }
244 }
245 
246 
247 /*---------------------------------------------------------------------------*\
248 
249   FUNCTION....: newamp2_model_to_indexes
250   AUTHOR......: Thomas Kurin and Stefan Erhardt
251   INSTITUTE...:	Institute for Electronics Engineering, University of Erlangen-Nuremberg
252   DATE CREATED: July 2018
253 
254   newamp2 encoder: Encodes the 8k sampled samples using mbest search (one stage)
255 
256 \*---------------------------------------------------------------------------*/
257 
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)258 void newamp2_model_to_indexes(C2CONST *c2const,
259                               int    indexes[],
260                               MODEL *model,
261                               float  rate_K_vec[],
262                               float  rate_K_sample_freqs_kHz[],
263                               int    K,
264                               float *mean,
265                               float  rate_K_vec_no_mean[],
266                               float  rate_K_vec_no_mean_[],
267 							  int    plosive
268                               )
269 {
270     int k;
271 
272     /* convert variable rate L to fixed rate K */
273 
274     resample_const_rate_f(c2const, model, rate_K_vec, rate_K_sample_freqs_kHz, K);
275 
276     /* remove mean and two stage VQ */
277 
278     float sum = 0.0;
279     for(k=0; k<K; k++)
280         sum += rate_K_vec[k];
281     *mean = sum/K;
282     for(k=0; k<K; k++)
283     {
284         rate_K_vec_no_mean[k] = rate_K_vec[k] - *mean;
285 	}
286 	//NEWAMP2_16K_K+1 because the last vector is not a vector for VQ (and not included in the constant)
287 	//but a calculated medium mean value
288     n2_rate_K_mbest_encode(indexes, rate_K_vec_no_mean, rate_K_vec_no_mean_, NEWAMP2_16K_K+1);
289 
290     /* scalar quantise mean (effectively the frame energy) */
291 
292     float w[1] = {1.0};
293     float se;
294     indexes[2] = quantise(newamp2_energy_cb[0].cb,
295                           mean,
296                           w,
297                           newamp2_energy_cb[0].k,
298                           newamp2_energy_cb[0].m,
299                           &se);
300 
301     /* scalar quantise Wo.  We steal the smallest Wo index to signal
302        an unvoiced frame */
303 
304     if (model->voiced) {
305         int index = encode_log_Wo(c2const, model->Wo, 6);
306         if (index == 0) {
307             index = 1;
308         }
309         if (index == 63) {
310             index = 62;
311         }
312         indexes[3] = index;
313     }
314     else {
315         indexes[3] = 0;
316     }
317     if(plosive != 0){
318 		indexes[3] = 63;
319 		}
320  }
321 
322 
323 /*---------------------------------------------------------------------------*\
324 
325   FUNCTION....: newamp2_indexes_to_rate_K_vec
326   AUTHOR......: Thomas Kurin and Stefan Erhardt
327   INSTITUTE...:	Institute for Electronics Engineering, University of Erlangen-Nuremberg
328   DATE CREATED: July 2018
329 
330   newamp2 decoder for amplitudes {Am}.  Given the rate K VQ and energy
331   indexes, outputs rate K vector. Equal to newamp1 but using only one stage VQ.
332 
333 \*---------------------------------------------------------------------------*/
334 
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)335 void newamp2_indexes_to_rate_K_vec(float  rate_K_vec_[],
336                                    float  rate_K_vec_no_mean_[],
337                                    float  rate_K_sample_freqs_kHz[],
338                                    int    K,
339                                    float *mean_,
340                                    int    indexes[],
341                                    float  pf_gain)
342 {
343     int   k;
344     const float *codebook1 = newamp2vq_cb[0].cb;
345     int n1 = indexes[0];
346 
347     for(k=0; k<K; k++) {
348       rate_K_vec_no_mean_[k] = codebook1[(NEWAMP2_16K_K+1)*n1+k];
349     }
350 
351     post_filter_newamp1(rate_K_vec_no_mean_, rate_K_sample_freqs_kHz, K, pf_gain);
352 
353     *mean_ = newamp2_energy_cb[0].cb[indexes[2]];
354 
355     for(k=0; k<K; k++) {
356         rate_K_vec_[k] = rate_K_vec_no_mean_[k] + *mean_;
357     }
358 }
359 
360 /*---------------------------------------------------------------------------*\
361 
362   FUNCTION....: newamp2_16k_indexes_to_rate_K_vec
363   AUTHOR......: Thomas Kurin and Stefan Erhardt
364   INSTITUTE...:	Institute for Electronics Engineering, University of Erlangen-Nuremberg
365   DATE CREATED: July 2018
366 
367   newamp2 decoder for amplitudes {Am}.  Given the rate K VQ and energy
368   indexes, outputs rate K vector. Extends the sample rate by looking up the corresponding
369   higher frequency values with their energy difference to the base energy (=>mean2)
370 
371 \*---------------------------------------------------------------------------*/
372 
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)373 void newamp2_16k_indexes_to_rate_K_vec(float  rate_K_vec_[],
374                                    float  rate_K_vec_no_mean_[],
375                                    float  rate_K_sample_freqs_kHz[],
376                                    int    K,
377                                    float *mean_,
378                                    int    indexes[],
379                                    float  pf_gain)
380 {
381     int   k;
382     const float *codebook1 = newamp2vq_cb[0].cb;
383     float mean2 = 0;
384     int n1 = indexes[0];
385 
386     for(k=0; k<K; k++) {
387       rate_K_vec_no_mean_[k] = codebook1[(K+1)*n1+k];
388     }
389 
390     n2_post_filter_newamp2(rate_K_vec_no_mean_, rate_K_sample_freqs_kHz, K, pf_gain);
391 
392     *mean_ = newamp2_energy_cb[0].cb[indexes[2]];
393     mean2 = *mean_  + codebook1[(K+1)*n1+K] -10;
394 
395     //HF ear Protection
396     if(mean2>50){
397 		mean2 = 50;
398 		}
399 
400     for(k=0; k<K; k++) {
401 		if(k<NEWAMP2_K){
402 			rate_K_vec_[k] = rate_K_vec_no_mean_[k] + *mean_;
403 		}
404 		else{
405 			//Amplify or Reduce ??
406 			rate_K_vec_[k] = rate_K_vec_no_mean_[k] + mean2;
407 			}
408     }
409 }
410 /*---------------------------------------------------------------------------*\
411 
412   FUNCTION....: newamp2_interpolate
413   AUTHOR......: Thomas Kurin and Stefan Erhardt
414   INSTITUTE...:	Institute for Electronics Engineering, University of Erlangen-Nuremberg
415   DATE CREATED: July 2018
416 
417   Interpolates to the 4 10ms Frames and leaves the forst 2 empty for plosives
418 
419 \*---------------------------------------------------------------------------*/
420 
newamp2_interpolate(float interpolated_surface_[],float left_vec[],float right_vec[],int K,int plosive_flag)421 void newamp2_interpolate(float interpolated_surface_[], float left_vec[], float right_vec[], int K, int plosive_flag)
422 {
423     int  i, k;
424     int  M = 4;
425     float c;
426 
427     /* (linearly) interpolate 25Hz amplitude vectors back to 100Hz */
428 
429 	if(plosive_flag == 0){
430 		for(i=0,c=1.0; i<M; i++,c-=1.0/M) {
431 			for(k=0; k<K; k++) {
432 				interpolated_surface_[i*K+k] = left_vec[k]*c + right_vec[k]*(1.0-c);
433 			}
434 		}
435 	}
436 	else{
437 		for(i=0,c=1.0; i<M; i++,c-=1.0/M) {
438 			for(k=0; k<K; k++) {
439 				if(i<2){
440 					interpolated_surface_[i*K+k] = 0;
441 				}
442 				else{
443 					//perhaps add some dB ?
444 					interpolated_surface_[i*K+k] = right_vec[k];
445 				}
446 			}
447 		}
448 
449 	}
450 }
451 
452 
453 /*---------------------------------------------------------------------------*\
454 
455   FUNCTION....: newamp2_indexes_to_model
456   AUTHOR......: Thomas Kurin and Stefan Erhardt
457   INSTITUTE...:	Institute for Electronics Engineering, University of Erlangen-Nuremberg
458   DATE CREATED: July 2018
459 
460   newamp2 decoder. Chooses whether to decode to 16k mode or to 8k mode
461 
462 \*---------------------------------------------------------------------------*/
463 
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)464 void newamp2_indexes_to_model(C2CONST *c2const,
465                               MODEL  model_[],
466                               COMP   H[],
467                               float *interpolated_surface_,
468                               float  prev_rate_K_vec_[],
469                               float  *Wo_left,
470                               int    *voicing_left,
471                               float  rate_K_sample_freqs_kHz[],
472                               int    K,
473                               codec2_fft_cfg fwd_cfg,
474                               codec2_fft_cfg inv_cfg,
475                               int    indexes[],
476                               float pf_gain,
477                               int flag16k)
478 {
479     float rate_K_vec_[K], rate_K_vec_no_mean_[K], mean_, Wo_right;
480     int   voicing_right, k;
481     int   M = 4;
482 
483     /* extract latest rate K vector */
484 
485 	if(flag16k == 0){
486 		newamp2_indexes_to_rate_K_vec(rate_K_vec_,
487 									rate_K_vec_no_mean_,
488 									rate_K_sample_freqs_kHz,
489 									K,
490 									&mean_,
491 									indexes,
492 									pf_gain);
493 	}else{
494 		newamp2_16k_indexes_to_rate_K_vec(rate_K_vec_,
495 									rate_K_vec_no_mean_,
496 									rate_K_sample_freqs_kHz,
497 									K,
498 									&mean_,
499 									indexes,
500 									pf_gain);
501 	}
502 
503 
504     /* decode latest Wo and voicing and plosive */
505 	int plosive_flag = 0;
506 
507 	//Voiced with Wo
508     if (indexes[3]>0 && indexes[3]<63) {
509         Wo_right = decode_log_Wo(c2const, indexes[3], 6);
510         voicing_right = 1;
511     }
512     //Unvoiced
513     else if(indexes[3] == 0){
514         Wo_right  = 2.0*M_PI/100.0;
515         voicing_right = 0;
516     }
517     //indexes[3]=63 (= Plosive) and unvoiced
518     else {
519 		Wo_right  = 2.0*M_PI/100.0;
520         voicing_right = 0;
521         plosive_flag = 1;
522 	}
523 
524     /* interpolate 25Hz rate K vec back to 100Hz */
525 
526     float *left_vec = prev_rate_K_vec_;
527     float *right_vec = rate_K_vec_;
528     newamp2_interpolate(interpolated_surface_, left_vec, right_vec, K,plosive_flag);
529 
530     /* interpolate 25Hz v and Wo back to 100Hz */
531 
532     float aWo_[M];
533     int avoicing_[M], aL_[M], i;
534 
535     interp_Wo_v(aWo_, aL_, avoicing_, *Wo_left, Wo_right, *voicing_left, voicing_right);
536 
537     /* back to rate L amplitudes, synthesis phase for each frame */
538 
539     for(i=0; i<M; i++) {
540         model_[i].Wo = aWo_[i];
541         model_[i].L  = aL_[i];
542         model_[i].voiced = avoicing_[i];
543         //Plosive Detected
544 		if(plosive_flag>0){
545 			//First two frames are set to zero
546 			if (i<2){
547 				n2_resample_rate_L(c2const, &model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K,1);
548 			}
549 			else{
550 				n2_resample_rate_L(c2const, &model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K,0);
551 			}
552 		}
553 		//No Plosive, standard resample
554 		else{
555 			n2_resample_rate_L(c2const, &model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K,0);
556 		}
557 		determine_phase(c2const, &H[(MAX_AMP+1)*i], &model_[i], NEWAMP2_PHASE_NFFT, fwd_cfg, inv_cfg);
558     }
559 
560     /* update memories for next time */
561 
562     for(k=0; k<K; k++) {
563         prev_rate_K_vec_[k] = rate_K_vec_[k];
564     }
565     *Wo_left = Wo_right;
566     *voicing_left = voicing_right;
567 
568 }
569 
570