Line data Source code
1 : /****************************************************************************** 2 : * ETSI TS 103 634 V1.5.1 * 3 : * Low Complexity Communication Codec Plus (LC3plus) * 4 : * * 5 : * Copyright licence is solely granted through ETSI Intellectual Property * 6 : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * 7 : * estoppel or otherwise. * 8 : ******************************************************************************/ 9 : 10 : #include "options.h" 11 : #include "wmc_auto.h" 12 : #include "defines.h" 13 : #include "functions.h" 14 : 15 0 : void plc_phEcu_LF_peak_analysis(LC3_INT32 *plocs, /* i/o 0 ... Lprot/2 +1*/ 16 : LC3_INT32 *n_plocs, /* i/o 0.. MAX_PLOCS */ 17 : LC3_FLOAT *f0est, /* i/o Q16*/ 18 : const LC3_FLOAT *Xabs, 19 : LC3_FLOAT *f0binPtr, 20 : LC3_FLOAT *f0gainPtr, 21 : const LC3_INT32 nSubm 22 : ) 23 : { 24 : LC3_INT32 i, j, fin, f_ind, prel_low, prel_high, start; 25 : LC3_FLOAT f0est_prel[3]; 26 : LC3_INT32 plocs_prel[3]; 27 : LC3_INT32 n_prel; 28 : LC3_FLOAT f0est_old[MAX_PLC_NPLOCS]; 29 : LC3_INT32 plocs_old[MAX_PLC_NPLOCS]; 30 : LC3_FLOAT peakLF_Xval, f; 31 : LC3_FLOAT f0bin ; 32 : LC3_FLOAT f0gain ; 33 : 34 0 : f0bin = *f0binPtr; 35 0 : f0gain = *f0gainPtr; 36 : 37 0 : if (*n_plocs > 0 && f0gain > 0.25 && f0bin < 2.75) { 38 : 39 : /* Assumes sorted plocs */ 40 0 : if (plocs[0] < 3) { 41 0 : fin = MIN(3, *n_plocs); 42 0 : peakLF_Xval = Xabs[plocs[0]]; 43 0 : for (i = 1; i < fin; i++) { 44 0 : peakLF_Xval = MAX(peakLF_Xval, Xabs[plocs[i]]); 45 : } 46 : 47 0 : n_prel = 0; 48 0 : for (i = 0; i < nSubm; i++) { 49 0 : f = (i+1)*f0bin; 50 0 : f_ind = (LC3_INT32)LC3_ROUND(f); 51 0 : if (f*PHECU_FRES <= 400 && Xabs[f_ind] > peakLF_Xval*0.375) { 52 0 : f0est_prel[n_prel] = f; 53 0 : plocs_prel[n_prel] = f_ind; 54 0 : n_prel++; 55 : } 56 : } 57 : 58 0 : if (n_prel > 0) { 59 0 : prel_low = plocs_prel[0]; 60 0 : prel_high = plocs_prel[n_prel-1]; 61 : 62 : /* initial assumption:: all original peaks (1 or 2 of them) are positioned below prel_low */ 63 0 : start = (*n_plocs); /* at this point 'start' is the location_c where to add any harmonics peaks */ 64 0 : for (i = (*n_plocs)-1; i >= 0; i--) { 65 0 : if (plocs[i] >= prel_low) { 66 0 : start = i; 67 : } 68 : } 69 : 70 : /* found position_c where to start adding */ 71 0 : start = (start-1 ); /* one step lower, now start is of original LF peaks to keep */ 72 0 : start = MAX(start, -1); /* limit for loop */ 73 : 74 0 : if (prel_high < plocs[0]) { 75 0 : fin = 0; 76 : } else { 77 0 : fin = (*n_plocs)+1; 78 0 : for (i = 0; i < *n_plocs; i++) { 79 0 : if (plocs[i] <= prel_high) { 80 0 : fin = i; 81 : } 82 : } 83 0 : fin++; 84 : } 85 : 86 0 : move_int(plocs_old, plocs, *n_plocs); 87 0 : move_float(f0est_old, f0est, *n_plocs); 88 : 89 0 : j = (start+1); /* [0..(j-1)] of original LF peaks will be kept */ 90 : /* j now points to first location_c where to add peaks */ 91 : 92 0 : for (i = 0; i < n_prel; i++) { 93 0 : plocs[j] = plocs_prel[i]; 94 0 : f0est[j] = f0est_prel[i]; 95 0 : j++; 96 : } 97 0 : for (i = fin; i < *n_plocs; i++) { 98 0 : plocs[j] = plocs_old[i]; 99 0 : f0est[j] = f0est_old[i]; 100 0 : j++; 101 : } 102 : 103 0 : *n_plocs = j; 104 : 105 : } 106 : } 107 : } 108 : 109 0 : return; 110 : } 111 :