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 "functions.h"
11 :
12 0 : void processSnsComputeScf_fx(Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 *scf,
13 : Word16 scf_smoothing_enabled, Word16 attdec_damping_factor, Word8 *scratchBuffer, Word16 sns_damping
14 : )
15 : {
16 : Dyn_Mem_Deluxe_In(
17 : Word16 i, s, s2, nf, tmp;
18 : Word32 L_mean, L_tmp;
19 : Word32 *d3_fx;
20 : Word16 *d3_fx_exp;
21 : Word16 *d4_fx;
22 : Word16 *scf_smooth;
23 : );
24 :
25 : UNUSED(attdec_damping_factor);
26 :
27 0 : d3_fx = scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_BANDS_NUMBER = 256 bytes */
28 0 : d3_fx_exp = scratchAlign(d3_fx, sizeof(*d3_fx) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */
29 0 : d4_fx = scratchAlign(d3_fx_exp, sizeof(*d3_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128bytes */
30 0 : scf_smooth = scratchAlign(d4_fx, sizeof(*d4_fx) * MAX_BANDS_NUMBER); /* Size = 2 * 16 */
31 :
32 : /* Smoothing and Pre-emphasis */
33 0 : IF (sub(n_bands, 32) < 0)
34 : {
35 0 : L_tmp = sub(32, n_bands);
36 0 : FOR (i = sub(n_bands, 1); i >= L_tmp; i--)
37 : {
38 0 : d2_fx[(i + L_tmp) * 2 + 1] = d2_fx[i]; move32();
39 0 : d2_fx[(i + L_tmp) * 2 + 0] = d2_fx[i]; move32();
40 : }
41 0 : FOR (i = sub(L_tmp, 1); i >= 0; i--)
42 : {
43 0 : d2_fx[i * 4 + 3] = d2_fx[i]; move32();
44 0 : d2_fx[i * 4 + 2] = d2_fx[i]; move32();
45 0 : d2_fx[i * 4 + 1] = d2_fx[i]; move32();
46 0 : d2_fx[i * 4 + 0] = d2_fx[i]; move32();
47 : }
48 0 : n_bands = 64; move16();
49 : }
50 : ELSE
51 0 : IF (sub(n_bands, 64) < 0)
52 : {
53 0 : L_tmp = sub(64, n_bands);
54 0 : FOR (i = sub(n_bands, 1); i >= L_tmp; i--)
55 : {
56 0 : d2_fx[i + L_tmp] = d2_fx[i]; move32();
57 : }
58 0 : FOR (i = sub(L_tmp, 1); i >= 0; i--)
59 : {
60 0 : d2_fx[i * 2 + 1] = d2_fx[i]; move32();
61 0 : d2_fx[i * 2 + 0] = d2_fx[i]; move32();
62 : }
63 0 : n_bands = 64; move16();
64 : }
65 :
66 0 : L_tmp = L_add(Mpy_32_16_lc3plus(d2_fx[0], 24576), L_shr_pos(d2_fx[1], 2));
67 0 : d3_fx[0] = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][0]); move32();
68 0 : d3_fx_exp[0] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][0]); move16();
69 0 : FOR (i = 1; i < n_bands - 1; i++)
70 : {
71 0 : L_tmp = L_add(L_shr_pos(d2_fx[i], 1), L_add(L_shr_pos(d2_fx[i - 1], 2), L_shr_pos(d2_fx[i + 1], 2)));
72 0 : d3_fx[i] = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][i]); move32();
73 0 : d3_fx_exp[i] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][i]); move16();
74 : }
75 0 : L_tmp = L_add(Mpy_32_16_lc3plus(d2_fx[n_bands - 1], 24576), L_shr_pos(d2_fx[n_bands - 2], 2));
76 0 : d3_fx[n_bands - 1] = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][n_bands - 1]); move32();
77 0 : d3_fx_exp[n_bands - 1] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][n_bands - 1]); move16();
78 :
79 : /* Mean */
80 0 : s = d3_fx_exp[MAX_BANDS_NUMBER - 1];
81 0 : s2 = add(s, 6);
82 :
83 0 : L_mean = L_shr(d3_fx[0], sub(s2, d3_fx_exp[0]));
84 0 : FOR (i = 1; i < MAX_BANDS_NUMBER; i++)
85 : {
86 0 : L_mean = L_add(L_mean, L_shr(d3_fx[i], sub(s2, d3_fx_exp[i])));
87 : }
88 :
89 : /* Noise floor at -40dB */
90 0 : nf = BASOP_Util_Log2_16(L_mean, s);
91 0 : nf = sub(s_max(nf, -25965), 6803);
92 :
93 : /* Log-domain */
94 0 : FOR (i = 0; i < MAX_BANDS_NUMBER; i++)
95 : {
96 0 : d4_fx[i] = s_max(nf, BASOP_Util_Log2_16(d3_fx[i], d3_fx_exp[i])); move16();
97 : }
98 :
99 : /* Downsampling */
100 0 : L_tmp = L_mult(d4_fx[0], 8192);
101 0 : L_tmp = L_mac(L_tmp, d4_fx[1], 8192);
102 0 : L_tmp = L_mac(L_tmp, d4_fx[2], 8192);
103 0 : L_tmp = L_mac(L_tmp, d4_fx[3], 5461);
104 0 : d3_fx[0] = L_mac(L_tmp, d4_fx[4], 2731); move32();
105 0 : FOR (i = 1; i < M - 1; i++)
106 : {
107 0 : L_tmp = L_mult(d4_fx[i * 4 - 1], 2731);
108 0 : L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 0], 5461);
109 0 : L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 1], 8192);
110 0 : L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 2], 8192);
111 0 : L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 3], 5461);
112 0 : d3_fx[i] = L_mac(L_tmp, d4_fx[i * 4 + 4], 2731); move32();
113 : }
114 0 : L_tmp = L_mult(d4_fx[59], 2731);
115 0 : L_tmp = L_mac(L_tmp, d4_fx[60], 5461);
116 0 : L_tmp = L_mac(L_tmp, d4_fx[61], 8192);
117 0 : L_tmp = L_mac(L_tmp, d4_fx[62], 8192);
118 0 : d3_fx[M - 1] = L_mac(L_tmp, d4_fx[63], 8192); move32();
119 :
120 : /* Remove mean and scaling */
121 0 : L_mean = L_shr_pos(d3_fx[0], 4);
122 0 : FOR (i = 1; i < M; i++)
123 : {
124 0 : L_mean = L_add(L_mean, L_shr_pos(d3_fx[i], 4));
125 : }
126 :
127 0 : FOR (i = 0; i < M; i++)
128 : {
129 0 : scf[i] = mult_r(sns_damping, round_fx(L_shl_pos(L_sub(d3_fx[i], L_mean), 1)));
130 0 : move16();
131 : }
132 :
133 : /* scale factor smoothing */
134 0 : IF (scf_smoothing_enabled)
135 : {
136 0 : scf_smooth[0] = L_shr(L_mult0(L_add(L_add(scf[0], scf[1]), scf[2]), 10923), 15);
137 0 : L_mean = scf_smooth[0]; move16();
138 0 : scf_smooth[1] = L_shr(L_add(L_add(L_add(scf[0], scf[1]), scf[2]), scf[3]), 2);
139 0 : L_mean = L_add(L_mean, scf_smooth[1]);
140 0 : FOR (i = 2; i < M - 2; i++)
141 : {
142 0 : L_tmp = L_add(L_add(L_add(L_add(scf[i - 2], scf[i - 1]), scf[i]), scf[i + 1]), scf[i + 2]);
143 0 : tmp = norm_s(L_shr(L_abs(L_tmp), 15));
144 0 : if (tmp > 0) {
145 0 : tmp = sub(16, tmp);
146 0 : L_tmp = L_shr(L_tmp, tmp);
147 : }
148 0 : scf_smooth[i] = L_shr(L_mult0(L_tmp, 13107), sub(16, tmp));
149 0 : L_mean = L_add(L_mean, scf_smooth[i]);
150 : }
151 0 : scf_smooth[M - 2] = L_shr(L_add(L_add(L_add(scf[M - 4], scf[M - 3]), scf[M - 2]), scf[M - 1]), 2);
152 0 : L_mean = L_add(L_mean, scf_smooth[M - 2]);
153 0 : scf_smooth[M - 1] = L_shr(L_mult0(L_add(L_add(scf[M - 3], scf[M - 2]), scf[M - 1]), 10923), 15);
154 0 : L_mean = L_add(L_mean, scf_smooth[M - 1]);
155 :
156 0 : L_mean = L_shr(L_mean, 4);
157 :
158 0 : FOR (i = 0; i < M; i++)
159 : {
160 0 : scf[i] = mult_r(attdec_damping_factor, sub(scf_smooth[i], L_mean));
161 : }
162 : }
163 :
164 : Dyn_Mem_Deluxe_Out();
165 0 : }
166 :
|