/src/libhevc/encoder/var_q_operator.c
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2018 The Android Open Source Project |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at: |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | * |
17 | | ***************************************************************************** |
18 | | * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
19 | | */ |
20 | | /*! |
21 | | ****************************************************************************** |
22 | | * \file var_q_operator.c |
23 | | * |
24 | | * \brief |
25 | | * This files to be used for basic fixed Q-point functions |
26 | | * |
27 | | * \date |
28 | | * |
29 | | * \author |
30 | | * ittiam |
31 | | * |
32 | | ****************************************************************************** |
33 | | */ |
34 | | /*****************************************************************************/ |
35 | | /* File Includes */ |
36 | | /*****************************************************************************/ |
37 | | /* User include files */ |
38 | | #include "ia_type_def.h" |
39 | | #include "defs.h" |
40 | | #include "ia_basic_ops32.h" |
41 | | #include "ia_basic_ops40.h" |
42 | | /* #include "num_struct.h" */ |
43 | | #include "var_q_operator.h" |
44 | | #include "sqrt_interp.h" |
45 | | #include "common_rom.h" |
46 | | |
47 | | #define NUM_BITS_MAG 32 |
48 | | |
49 | | /************************************************************************************/ |
50 | | /* The files to be used for basic fixed Q-point functions : */ |
51 | | /* */ |
52 | | /* audio/ia_standards/c64x/include/ia_basic_ops32.h cvs_version : FULL_V1_16 */ |
53 | | /* audio/ia_standards/c64x/include/ia_basic_ops40.h cvs_version : FULL_V1_16 */ |
54 | | /* */ |
55 | | /************************************************************************************/ |
56 | | |
57 | | /* Multiply */ |
58 | | |
59 | | void mult32_var_q(number_t a, number_t b, number_t *c) |
60 | 1.98M | { |
61 | 1.98M | WORD32 Q_a; |
62 | 1.98M | WORD32 Q_b; |
63 | | /* WORD32 final_Q; */ |
64 | 1.98M | WORD32 norm_a; |
65 | 1.98M | WORD32 norm_b; |
66 | | |
67 | 1.98M | norm_a = norm32(a.sm); /* norm32 defined in ia_basic_ops32.h */ |
68 | 1.98M | norm_b = norm32(b.sm); |
69 | | |
70 | 1.98M | Q_a = norm_a + a.e; |
71 | 1.98M | Q_b = norm_b + b.e; |
72 | | |
73 | 1.98M | a.sm = shl32_sat(a.sm, norm_a); |
74 | 1.98M | b.sm = shl32_sat(b.sm, norm_b); |
75 | | |
76 | 1.98M | c->sm = mult32(a.sm, b.sm); /* mult32 defined in ia_basic_ops40.h */ |
77 | 1.98M | c->e = a.e + b.e + norm_a + norm_b - 32; /* mult32 decreases the Q-format by 32 */ |
78 | 1.98M | } |
79 | | |
80 | | /* Division */ |
81 | | |
82 | | void div32_var_q(number_t a, number_t b, number_t *c) |
83 | 1.79M | { |
84 | 1.79M | WORD32 qoutient_q_format; |
85 | | |
86 | 1.79M | c->sm = div32(a.sm, b.sm, &qoutient_q_format); /* div32 defined in ia_basic_ops32.h */ |
87 | 1.79M | c->e = (a.e - b.e) + qoutient_q_format; |
88 | 1.79M | } |
89 | | |
90 | | /* Addition */ |
91 | | |
92 | | void add32_var_q(number_t a, number_t b, number_t *c) |
93 | 2.19M | { |
94 | 2.19M | WORD32 Q_a; |
95 | 2.19M | WORD32 Q_b; |
96 | 2.19M | WORD32 final_Q; |
97 | 2.19M | WORD32 norm_a; |
98 | 2.19M | WORD32 norm_b; |
99 | | |
100 | 2.19M | norm_a = norm32(a.sm) - 1; /* norm32 defined in ia_basic_ops32.h */ |
101 | 2.19M | norm_b = norm32(b.sm) - 1; /* we normalise a & b only to 30t bit |
102 | | instead of to 31st bit |
103 | | */ |
104 | | |
105 | 2.19M | Q_a = norm_a + a.e; |
106 | 2.19M | Q_b = norm_b + b.e; |
107 | | |
108 | 2.19M | if(Q_b < Q_a) |
109 | 367k | { |
110 | 367k | b.sm = shl32_dir_sat(b.sm, norm_b); |
111 | 367k | a.sm = shr32_dir_sat(a.sm, ((a.e - b.e) - norm_b)); |
112 | 367k | final_Q = Q_b; |
113 | 367k | } |
114 | 1.83M | else if(Q_a < Q_b) |
115 | 1.73M | { |
116 | 1.73M | a.sm = shl32_dir_sat(a.sm, norm_a); |
117 | 1.73M | b.sm = shr32_dir_sat(b.sm, ((b.e - a.e) - norm_a)); |
118 | 1.73M | final_Q = Q_a; |
119 | 1.73M | } |
120 | 100k | else |
121 | 100k | { |
122 | 100k | a.sm = shl32_dir_sat(a.sm, norm_a); |
123 | 100k | b.sm = shl32_dir_sat(b.sm, norm_b); |
124 | 100k | final_Q = Q_a; |
125 | 100k | } |
126 | | |
127 | 2.19M | c->sm = add32(a.sm, b.sm); /* add32_shr defined in ia_basic_ops32.h */ |
128 | 2.19M | c->e = final_Q; /* because add32_shr does right shift |
129 | | by 1 before adding */ |
130 | 2.19M | } |
131 | | |
132 | | /* Subtraction */ |
133 | | |
134 | | void sub32_var_q(number_t a, number_t b, number_t *c) |
135 | 768k | { |
136 | 768k | WORD32 Q_a; |
137 | 768k | WORD32 Q_b; |
138 | 768k | WORD32 final_Q; |
139 | 768k | WORD32 norm_a; |
140 | 768k | WORD32 norm_b; |
141 | | |
142 | 768k | norm_a = norm32(a.sm) - 1; /* norm32 defined in ia_basic_ops32.h */ |
143 | 768k | norm_b = norm32(b.sm) - 1; /* we normalise a & b only to 30t bit |
144 | | instead of to 31st bit |
145 | | */ |
146 | | |
147 | 768k | Q_a = norm_a + a.e; |
148 | 768k | Q_b = norm_b + b.e; |
149 | | |
150 | 768k | if(Q_b < Q_a) |
151 | 570k | { |
152 | 570k | b.sm = shl32_dir_sat(b.sm, norm_b); |
153 | 570k | a.sm = shr32_dir_sat(a.sm, ((a.e - b.e) - norm_b)); |
154 | 570k | final_Q = Q_b; |
155 | 570k | } |
156 | 198k | else if(Q_a < Q_b) |
157 | 80.4k | { |
158 | 80.4k | a.sm = shl32_dir_sat(a.sm, norm_a); |
159 | 80.4k | b.sm = shr32_dir_sat(b.sm, ((b.e - a.e) - norm_a)); |
160 | 80.4k | final_Q = Q_a; |
161 | 80.4k | } |
162 | 117k | else |
163 | 117k | { |
164 | 117k | a.sm = shl32_dir_sat(a.sm, norm_a); |
165 | 117k | b.sm = shl32_dir_sat(b.sm, norm_b); |
166 | 117k | final_Q = Q_a; |
167 | 117k | } |
168 | | |
169 | 768k | c->sm = sub32(a.sm, b.sm); /* add32_shr defined in ia_basic_ops32.h */ |
170 | 768k | c->e = final_Q; /* because add32_shr does right shift |
171 | | by 1 before adding */ |
172 | 768k | } |
173 | | |
174 | | /* square root */ |
175 | | |
176 | | void sqrt32_var_q(number_t a, number_t *c) |
177 | 26.0k | { |
178 | 26.0k | WORD32 q_temp; |
179 | 26.0k | q_temp = a.e; |
180 | 26.0k | c->sm = sqrtFix_interpolate(a.sm, &q_temp, gi4_sqrt_tab); |
181 | | /* c->sm = sqrtFix(a.sm, &q_temp, gi4_sqrt_tab); */ |
182 | 26.0k | c->e = q_temp; |
183 | 26.0k | } |
184 | | |
185 | | void number_t_to_word32(number_t num_a, WORD32 *a) |
186 | 1.72M | { |
187 | 1.72M | *a = shr32_dir_sat(num_a.sm, num_a.e); |
188 | 1.72M | } |
189 | | |
190 | | /* |
191 | | convert_float_to_fix(float a_f, |
192 | | number_t *a) |
193 | | { |
194 | | double log_a_f; |
195 | | log_a_f = log(ABS(a_f))/log(2); |
196 | | |
197 | | a->e = 30 - (WORD32)ceil(log_a_f); |
198 | | a->sm = (WORD32) (a_f * pow(2, a->e)); |
199 | | } |
200 | | */ |
201 | | |
202 | | #ifdef ITT_C6678 |
203 | | #pragma CODE_SECTION(number_t_to_word32, "itt_varq_l1pram"); |
204 | | #pragma CODE_SECTION(sqrt32_var_q, "itt_varq_l1pram"); |
205 | | #pragma CODE_SECTION(sub32_var_q, "itt_varq_l1pram"); |
206 | | #pragma CODE_SECTION(add32_var_q, "itt_varq_l1pram"); |
207 | | #pragma CODE_SECTION(div32_var_q, "itt_varq_l1pram"); |
208 | | #pragma CODE_SECTION(mult32_var_q, "itt_varq_l1pram"); |
209 | | #endif |