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 "functions.h"
13 :
14 0 : void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor, LC3_INT fs_idx)
15 : {
16 : LC3_INT bands_number, d, i, j, n, n2, n4, mapping[64];
17 : LC3_FLOAT x_tmp1[MAX_LEN], sum, mean, nf, gains_smooth[M], ratio;
18 : LC3_FLOAT sum_gains_smooth;
19 : const LC3_FLOAT* sns_preemph;
20 :
21 0 : sum_gains_smooth = 0; sum = 0;
22 0 : sns_preemph = sns_preemph_all[fs_idx];
23 :
24 0 : bands_number = xLen;
25 0 : assert(bands_number <= 64);
26 :
27 : /* 5 ms */
28 0 : if (bands_number < 64) {
29 0 : d = 64 - bands_number;
30 :
31 0 : if (d < xLen)
32 : {
33 0 : j = 0;
34 0 : for (i = 0; i < 2 * d; i = i + 2) {
35 0 : x_tmp1[i] = x[j];
36 0 : x_tmp1[i + 1] = x[j];
37 0 : j++;
38 : }
39 :
40 0 : move_float(&x_tmp1[2 * d], &x[d], 64 - 2 * d);
41 : }
42 0 : else if (bands_number < 32)
43 : {
44 0 : ratio = LC3_FABS((LC3_FLOAT) (1.0 - 32.0 / (LC3_FLOAT) xLen));
45 0 : n4 = round(ratio * xLen);
46 0 : n2 = xLen - n4;
47 :
48 0 : j = 0;
49 0 : for(i = 1; i <= n4; i++)
50 : {
51 0 : mapping[j] = i;
52 0 : mapping[j + 1] = i;
53 0 : mapping[j + 2] = i;
54 0 : mapping[j + 3] = i;
55 0 : j += 4;
56 : }
57 :
58 0 : for (i = n4 + 1; i <= n4 + n2; i++)
59 : {
60 0 : mapping[j] = i;
61 0 : mapping[j + 1] = i;
62 0 : j += 2;
63 : }
64 :
65 :
66 0 : for (i = 0; i < 64; i++)
67 : {
68 0 : x_tmp1[i] = x[mapping[i] - 1];
69 : }
70 : } else {
71 0 : assert(0 && "Unsupported number of bands!");
72 : }
73 :
74 0 : move_float(x, x_tmp1, 64);
75 :
76 0 : bands_number = 64;
77 0 : xLen = bands_number;
78 : }
79 :
80 :
81 : /* Smoothing */
82 :
83 0 : x_tmp1[0] = x[0];
84 0 : move_float(&x_tmp1[1], &x[0], 63);
85 :
86 0 : for (i = 0; i < 63; i++) {
87 0 : x[i] = 0.5 * x[i] + 0.25 * (x_tmp1[i] + x[i + 1]);
88 : }
89 :
90 0 : x[63] = 0.5 * x[63] + 0.25 * (x_tmp1[63] + x[63]);
91 :
92 : /* Pre-emphasis */
93 0 : for (i = 0; i < 64; i++) {
94 0 : x[i] = x[i] * sns_preemph[i];
95 : }
96 :
97 : /* Noise floor at -40dB */
98 0 : for (i = 0; i < 64; i++) {
99 0 : sum += x[i];
100 : }
101 :
102 0 : mean = sum * 0.015625; /* 1/64 */
103 :
104 0 : nf = mean * 1.00e-04;
105 0 : nf = MAX(nf, 2.328306436538696e-10);
106 :
107 0 : for (i = 0; i < 64; i++) {
108 0 : if (x[i] < nf) {
109 0 : x[i] = nf;
110 : }
111 : }
112 :
113 : /* Log-domain */
114 0 : for (i = 0; i < 64; i++) {
115 0 : x[i] = LC3_LOGTWO(x[i]) * 0.5;
116 : }
117 :
118 : /* Downsampling */
119 0 : for (n = 0; n < 16; n++) {
120 0 : if (n == 0) {
121 0 : x_tmp1[0] = x[0];
122 :
123 0 : move_float(&x_tmp1[1], &x[0], 5);
124 :
125 0 : } else if (n == 15) {
126 0 : move_float(x_tmp1, &x[59], 5);
127 :
128 0 : x_tmp1[5] = x[63];
129 :
130 : } else {
131 0 : move_float(x_tmp1, &x[n * 4 - 1], ((n * 4 + 5 - 1) - (n * 4 - 1) + 1));
132 : }
133 :
134 0 : sum = 0;
135 0 : for (i = 0; i < 6; i++) {
136 0 : sum += x_tmp1[i] * sns_W[i];
137 : }
138 :
139 0 : gains_smooth[n] = sum;
140 0 : sum_gains_smooth += sum;
141 : }
142 :
143 :
144 : /* Remove mean and scaling */
145 0 : mean = sum_gains_smooth / 16.0;
146 :
147 0 : for (i = 0; i < 16; i++) {
148 0 : gains[i] = sns_damping * (gains_smooth[i] - mean);
149 : }
150 :
151 : /* Smoothing */
152 0 : if (smooth) {
153 0 : gains_smooth[0] = (gains[0] + gains[1] + gains[2]) / 3.0;
154 0 : gains_smooth[1] = (gains[0] + gains[1] + gains[2] + gains[3]) / 4.0;
155 :
156 0 : for (i = 2; i < 14; i++) {
157 0 : gains_smooth[i] = (gains[i - 2] + gains[i - 1] + gains[i] + gains[i + 1] + gains[i + 2]) / 5.0;
158 : }
159 :
160 0 : gains_smooth[M - 2] = (gains[M - 4] + gains[M - 3] + gains[M - 2] + gains[M - 1]) / 4.0;
161 0 : gains_smooth[M - 1] = (gains[M - 3] + gains[M - 2] + gains[M - 1]) / 3.0;
162 :
163 0 : sum = 0;
164 0 : for (i = 0; i < M; i++) {
165 0 : sum += gains_smooth[i];
166 : }
167 :
168 0 : mean = sum / (LC3_FLOAT)M;
169 :
170 0 : for (i = 0; i < M; i++) {
171 0 : gains[i] = attdec_damping_factor * (gains_smooth[i] - mean);
172 : }
173 : }
174 0 : }
|