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 : #ifdef ENABLE_HR_MODE /* HRMODE enables packing of residual bits */
13 :
14 0 : void processResidualDecoding_fx(Word32 x[], Word16 x_e, Word16 L_spec, UWord8 prm[], Word16 resQBits
15 : #ifdef ENABLE_HR_MODE
16 : , Word16 hrmode
17 : #endif
18 : )
19 : {
20 :
21 : Counter i;
22 : Word32 fac_m, fac_p;
23 : Word16 s, bits;
24 : Word32 tmp;
25 : Counter idx;
26 0 : Word16 N_nz = 0;
27 : Word16 iter;
28 : Word32 fac_hr;
29 :
30 : #ifdef DYNMEM_COUNT
31 : Dyn_Mem_In("processResidualDecoding_fx", sizeof(struct {
32 : Counter i;
33 : Word32 fac_m, fac_p;
34 : Word16 s, bits;
35 : Word32 tmp;
36 : Counter idx;
37 : Word16 N_nz;
38 : Word16 *nz_idx;
39 : Word16 iter;
40 : }));
41 : #endif
42 :
43 0 : tmp = 0;
44 0 : s = sub(x_e, 1);
45 0 : s = s_min(s, 31);
46 :
47 0 : IF (hrmode)
48 : {
49 0 : fac_hr = L_shr(0x10000000, s); /* 0.25 in 1Q30 */
50 : }
51 : ELSE
52 : {
53 0 : fac_m = L_shr(0xC000000, s); /* 0.1875 in 1Q30 */
54 0 : fac_p = L_shr(0x14000000, s); /* 0.3125 in 1Q30 */
55 : }
56 :
57 0 : bits = 0;
58 0 : move16();
59 :
60 : Word16 nz_idx[MAX_LEN];
61 :
62 0 : IF (hrmode)
63 : {
64 0 : FOR (i = 0; i < L_spec; i++)
65 : {
66 0 : IF (x[i])
67 : {
68 0 : nz_idx[N_nz] = i; move16();
69 0 : N_nz = add(N_nz, 1);
70 : }
71 : }
72 0 : FOR (iter = 0; iter < EXT_RES_ITER_MAX; iter++)
73 : {
74 0 : IF (sub(bits, resQBits) >= 0)
75 : {
76 0 : BREAK;
77 : }
78 0 : FOR (i = 0; i < N_nz; i++)
79 : {
80 0 : idx = nz_idx[i]; move16();
81 :
82 0 : IF (sub(bits, resQBits) >= 0)
83 : {
84 0 : BREAK;
85 : }
86 :
87 0 : IF (! (s_and(prm[shr(bits, RESBITS_PACK_SHIFT)], shl(1, s_and(bits, RESBITS_PACK_MASK)))))
88 : {
89 0 : tmp = L_sub_sat(x[idx], fac_hr);
90 : }
91 : ELSE
92 : {
93 0 : tmp = L_add_sat(x[idx], fac_hr);
94 : }
95 0 : x[idx] = tmp;
96 0 : move32();
97 0 : bits = add(bits, 1);
98 : }
99 0 : fac_hr = L_shr(fac_hr, 1);
100 : }
101 : }
102 : ELSE
103 : {
104 0 : FOR (i = 0; i < L_spec; i++)
105 : {
106 0 : IF (sub(bits, resQBits) >= 0)
107 : {
108 0 : BREAK;
109 : }
110 :
111 0 : IF (x[i] != 0)
112 : {
113 0 : IF (! (s_and(prm[shr(bits, RESBITS_PACK_SHIFT)], shl(1, s_and(bits, RESBITS_PACK_MASK)))))
114 : {
115 0 : if (x[i] > 0)
116 0 : tmp = L_sub(x[i], fac_m);
117 0 : if (x[i] < 0)
118 0 : tmp = L_sub(x[i], fac_p);
119 : }
120 : ELSE
121 : {
122 0 : if (x[i] > 0)
123 0 : tmp = L_add(x[i], fac_p);
124 0 : if (x[i] < 0)
125 0 : tmp = L_add(x[i], fac_m);
126 : }
127 0 : x[i] = tmp;
128 0 : move32();
129 0 : bits = add(bits, 1);
130 : }
131 : }
132 : }
133 :
134 : #ifdef DYNMEM_COUNT
135 : Dyn_Mem_Out();
136 : #endif
137 0 : }
138 :
139 : #else
140 :
141 : void processResidualDecoding_fx(Word32 x[], Word16 x_e, Word16 L_spec, UWord8 prm[], Word16 resQBits
142 : )
143 : {
144 :
145 : Counter i;
146 : Word32 fac_m, fac_p;
147 : Word16 s, bits;
148 : Word32 tmp;
149 :
150 : #ifdef DYNMEM_COUNT
151 : Dyn_Mem_In("processResidualDecoding_fx", sizeof(struct {
152 : Counter i;
153 : Word32 fac_m, fac_p;
154 : Word16 s, bits;
155 : Word32 tmp;
156 : }));
157 : #endif
158 :
159 : tmp = 0;
160 : s = sub(x_e, 1);
161 : s = s_min(s, 31);
162 :
163 : {
164 : fac_m = L_shr(0xC000000, s); /* 0.1875 in 1Q30 */
165 : fac_p = L_shr(0x14000000, s); /* 0.3125 in 1Q30 */
166 : }
167 :
168 : bits = 0;
169 : move16();
170 :
171 : {
172 : FOR (i = 0; i < L_spec; i++)
173 : {
174 : IF (sub(bits, resQBits) >= 0)
175 : {
176 : BREAK;
177 : }
178 :
179 : IF (x[i] != 0)
180 : {
181 : IF (prm[bits] == 0)
182 : {
183 : if (x[i] > 0)
184 : tmp = L_sub(x[i], fac_m);
185 : if (x[i] < 0)
186 : tmp = L_sub(x[i], fac_p);
187 : }
188 : ELSE
189 : {
190 : if (x[i] > 0)
191 : tmp = L_add(x[i], fac_p);
192 : if (x[i] < 0)
193 : tmp = L_add(x[i], fac_m);
194 : }
195 : x[i] = tmp;
196 : move32();
197 : bits = add(bits, 1);
198 : }
199 : }
200 : }
201 :
202 : #ifdef DYNMEM_COUNT
203 : Dyn_Mem_Out();
204 : #endif
205 : }
206 :
207 : #endif
|