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 :
13 :
14 0 : void processAdjustGlobalGain_fx(Word16 *gg_idx, Word16 gg_idx_min, Word16 gg_idx_off,
15 : #ifdef ENABLE_HR_MODE
16 : Word32 *gain,
17 : #else
18 : Word16 *gain,
19 : #endif
20 : Word16 *gain_e,
21 : Word16 target, Word16 nBits, Word16 *gainChange, Word16 fs_idx
22 : #ifdef ENABLE_HR_MODE
23 : , Word16 hrmode, Word16 frame_dms
24 : #endif
25 : )
26 : {
27 :
28 : Word32 L_tmp;
29 : Word16 delta, delta2;
30 : #ifdef ENABLE_HR_MODE
31 : Word16 gg_idx_inc;
32 : Word16 gg_idx_inc_max;
33 : Word16 gg_idx_inc_s;
34 : Word32 factor;
35 : #endif
36 :
37 : #ifdef DYNMEM_COUNT
38 : #if defined(ENABLE_HR_MODE)
39 : Dyn_Mem_In("processAdjustGlobalGain_fx", sizeof(struct {
40 : Word32 L_tmp;
41 : Word16 delta, delta2;
42 : Word16 gg_idx_inc;
43 : Word16 gg_idx_inc_max;
44 : Word16 gg_idx_inc_s;
45 : Word16 factor;
46 : }));
47 : #else
48 : Dyn_Mem_In("processAdjustGlobalGain_fx", sizeof(struct {
49 : Word32 L_tmp;
50 : Word16 delta, delta2;
51 : }));
52 : #endif /* ENABLE_HR_MODE */
53 : #endif /* DYNMEM_COUNT */
54 :
55 : #ifdef ENABLE_HR_MODE
56 0 : IF (sub(frame_dms, 25) == 0)
57 : {
58 0 : IF (sub(target, 520) < 0)
59 : {
60 0 : factor = 3; move16();
61 0 : gg_idx_inc_max = 30; move16();
62 : } ELSE {
63 0 : factor = 4; move16();
64 0 : gg_idx_inc_max = 40; move16();
65 : }
66 : }
67 0 : ELSE IF (sub(frame_dms, 50) == 0)
68 : {
69 0 : factor = 2; move16();
70 0 : gg_idx_inc_max = 20; move16();
71 : }
72 0 : ELSE IF (sub(frame_dms, 75) == 0)
73 : {
74 0 : factor = 40265318; move16(); // factor = 1.2 * 2^25
75 0 : gg_idx_inc_max = 12 ; move16();
76 : }
77 : ELSE
78 : {
79 0 : factor = 1; move16();
80 0 : gg_idx_inc_max = 10; move16();
81 : }
82 : #endif
83 :
84 0 : IF (sub(nBits, adjust_global_gain_tables[0][fs_idx]) < 0)
85 : {
86 0 : delta = mult_r(add(nBits, 48), 2048);
87 : }
88 0 : ELSE IF (sub(nBits, adjust_global_gain_tables[1][fs_idx]) < 0)
89 : {
90 0 : delta = mult_r(add(nBits, adjust_global_gain_tables[4][fs_idx]), adjust_global_gain_tables[3][fs_idx]);
91 : }
92 0 : ELSE IF (sub(nBits, adjust_global_gain_tables[2][fs_idx]) < 0)
93 : {
94 0 : delta = mult_r(nBits, 683);
95 : }
96 : ELSE
97 : {
98 0 : delta = mult_r(adjust_global_gain_tables[2][fs_idx], 683);
99 : }
100 0 : delta2 = add(delta, 2);
101 :
102 0 : *gainChange = 0; move16();
103 :
104 0 : test();
105 0 : IF (sub(*gg_idx, 255) == 0 && sub(nBits, target) > 0)
106 : {
107 0 : *gainChange = 1; move16();
108 : }
109 :
110 0 : test(); test(); test();
111 0 : IF ((sub(*gg_idx, 255) < 0 && sub(nBits, target) > 0) || (*gg_idx > 0 && sub(nBits, sub(target, delta2)) < 0))
112 : {
113 : #ifdef ENABLE_HR_MODE
114 0 : IF (hrmode)
115 : {
116 0 : IF (sub(nBits, target) > 0)
117 : {
118 0 : gg_idx_inc = sub(nBits, target);
119 0 : IF (sub(frame_dms, 75) == 0)
120 : {
121 0 : gg_idx_inc = extract_l(L_shr_pos(Mpy_32_16_lc3plus(factor, gg_idx_inc), 10)); // Mpy_32_16_lc3plus(1.2*2^25, gg_idx_inc), 25 - 15)
122 0 : gg_idx_inc = BASOP_Util_Divide1616_Scale_lc3plus(gg_idx_inc, delta, &gg_idx_inc_s);
123 0 : gg_idx_inc = shr_sat(gg_idx_inc, sub(15, gg_idx_inc_s));
124 0 : gg_idx_inc = add(gg_idx_inc, 1); // adding 1 instead of 1.2
125 : }
126 : ELSE
127 : {
128 0 : gg_idx_inc = extract_l(L_mult0(gg_idx_inc, factor));
129 0 : gg_idx_inc = BASOP_Util_Divide1616_Scale_lc3plus(gg_idx_inc, delta, &gg_idx_inc_s);
130 0 : gg_idx_inc = shr_sat(gg_idx_inc, sub(15, gg_idx_inc_s));
131 0 : gg_idx_inc = add(gg_idx_inc, factor);
132 : }
133 0 : gg_idx_inc = s_min(gg_idx_inc, gg_idx_inc_max);
134 :
135 0 : *gg_idx = add(*gg_idx, gg_idx_inc); move16();
136 : }
137 :
138 0 : *gg_idx = s_min(*gg_idx, 255); move16();
139 : }
140 : ELSE
141 : #endif
142 : {
143 0 : test();
144 0 : IF (sub(nBits, sub(target, delta2)) < 0)
145 : {
146 0 : *gg_idx = sub(*gg_idx, 1); move16();
147 : }
148 0 : ELSE IF (sub(*gg_idx, 254) == 0 || sub(nBits, add(target, delta)) < 0)
149 : {
150 0 : *gg_idx = add(*gg_idx, 1); move16();
151 : }
152 : ELSE
153 : {
154 0 : *gg_idx = add(*gg_idx, 2); move16();
155 : }
156 : }
157 :
158 0 : *gg_idx = s_max(*gg_idx, sub(gg_idx_min, gg_idx_off)); move16();
159 :
160 : #ifdef ENABLE_HR_MODE
161 0 : L_tmp = Mpy_32_16_lc3plus(0x3CBE6B83, L_shl_pos(add(*gg_idx, gg_idx_off), 7));
162 : #else
163 : L_tmp = L_shl_pos(L_mult0(add(*gg_idx, gg_idx_off), 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
164 : #endif
165 0 : *gain_e = add(extract_l(L_shr_pos(L_tmp, 25)), 1); /* get exponent */
166 : #ifdef ENABLE_HR_MODE
167 0 : *gain = BASOP_Util_InvLog2_lc3plus(L_or(L_tmp, (Word32)0xFE000000));
168 : #else
169 : *gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(L_tmp, (Word32)0xFE000000)));
170 : #endif
171 0 : *gainChange = 1; move16();
172 : }
173 :
174 : #ifdef DYNMEM_COUNT
175 : Dyn_Mem_Out();
176 : #endif
177 0 : }
178 :
|