/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 | 184k | { |
61 | 184k | WORD32 Q_a; |
62 | 184k | WORD32 Q_b; |
63 | | /* WORD32 final_Q; */ |
64 | 184k | WORD32 norm_a; |
65 | 184k | WORD32 norm_b; |
66 | | |
67 | 184k | norm_a = norm32(a.sm); /* norm32 defined in ia_basic_ops32.h */ |
68 | 184k | norm_b = norm32(b.sm); |
69 | | |
70 | 184k | Q_a = norm_a + a.e; |
71 | 184k | Q_b = norm_b + b.e; |
72 | | |
73 | 184k | a.sm = shl32_sat(a.sm, norm_a); |
74 | 184k | b.sm = shl32_sat(b.sm, norm_b); |
75 | | |
76 | 184k | c->sm = mult32(a.sm, b.sm); /* mult32 defined in ia_basic_ops40.h */ |
77 | 184k | c->e = a.e + b.e + norm_a + norm_b - 32; /* mult32 decreases the Q-format by 32 */ |
78 | 184k | } |
79 | | |
80 | | /* Division */ |
81 | | |
82 | | void div32_var_q(number_t a, number_t b, number_t *c) |
83 | 157k | { |
84 | 157k | WORD32 qoutient_q_format; |
85 | | |
86 | 157k | c->sm = div32(a.sm, b.sm, &qoutient_q_format); /* div32 defined in ia_basic_ops32.h */ |
87 | 157k | c->e = (a.e - b.e) + qoutient_q_format; |
88 | 157k | } |
89 | | |
90 | | /* Addition */ |
91 | | |
92 | | void add32_var_q(number_t a, number_t b, number_t *c) |
93 | 461k | { |
94 | 461k | WORD32 Q_a; |
95 | 461k | WORD32 Q_b; |
96 | 461k | WORD32 final_Q; |
97 | 461k | WORD32 norm_a; |
98 | 461k | WORD32 norm_b; |
99 | | |
100 | 461k | norm_a = norm32(a.sm) - 1; /* norm32 defined in ia_basic_ops32.h */ |
101 | 461k | norm_b = norm32(b.sm) - 1; /* we normalise a & b only to 30t bit |
102 | | instead of to 31st bit |
103 | | */ |
104 | | |
105 | 461k | Q_a = norm_a + a.e; |
106 | 461k | Q_b = norm_b + b.e; |
107 | | |
108 | 461k | if(Q_b < Q_a) |
109 | 39.1k | { |
110 | 39.1k | b.sm = shl32_dir_sat(b.sm, norm_b); |
111 | 39.1k | a.sm = shr32_dir_sat(a.sm, ((a.e - b.e) - norm_b)); |
112 | 39.1k | final_Q = Q_b; |
113 | 39.1k | } |
114 | 421k | else if(Q_a < Q_b) |
115 | 413k | { |
116 | 413k | a.sm = shl32_dir_sat(a.sm, norm_a); |
117 | 413k | b.sm = shr32_dir_sat(b.sm, ((b.e - a.e) - norm_a)); |
118 | 413k | final_Q = Q_a; |
119 | 413k | } |
120 | 7.84k | else |
121 | 7.84k | { |
122 | 7.84k | a.sm = shl32_dir_sat(a.sm, norm_a); |
123 | 7.84k | b.sm = shl32_dir_sat(b.sm, norm_b); |
124 | 7.84k | final_Q = Q_a; |
125 | 7.84k | } |
126 | | |
127 | 461k | c->sm = add32(a.sm, b.sm); /* add32_shr defined in ia_basic_ops32.h */ |
128 | 461k | c->e = final_Q; /* because add32_shr does right shift |
129 | | by 1 before adding */ |
130 | 461k | } |
131 | | |
132 | | /* Subtraction */ |
133 | | |
134 | | void sub32_var_q(number_t a, number_t b, number_t *c) |
135 | 66.1k | { |
136 | 66.1k | WORD32 Q_a; |
137 | 66.1k | WORD32 Q_b; |
138 | 66.1k | WORD32 final_Q; |
139 | 66.1k | WORD32 norm_a; |
140 | 66.1k | WORD32 norm_b; |
141 | | |
142 | 66.1k | norm_a = norm32(a.sm) - 1; /* norm32 defined in ia_basic_ops32.h */ |
143 | 66.1k | norm_b = norm32(b.sm) - 1; /* we normalise a & b only to 30t bit |
144 | | instead of to 31st bit |
145 | | */ |
146 | | |
147 | 66.1k | Q_a = norm_a + a.e; |
148 | 66.1k | Q_b = norm_b + b.e; |
149 | | |
150 | 66.1k | if(Q_b < Q_a) |
151 | 45.9k | { |
152 | 45.9k | b.sm = shl32_dir_sat(b.sm, norm_b); |
153 | 45.9k | a.sm = shr32_dir_sat(a.sm, ((a.e - b.e) - norm_b)); |
154 | 45.9k | final_Q = Q_b; |
155 | 45.9k | } |
156 | 20.1k | else if(Q_a < Q_b) |
157 | 6.47k | { |
158 | 6.47k | a.sm = shl32_dir_sat(a.sm, norm_a); |
159 | 6.47k | b.sm = shr32_dir_sat(b.sm, ((b.e - a.e) - norm_a)); |
160 | 6.47k | final_Q = Q_a; |
161 | 6.47k | } |
162 | 13.6k | else |
163 | 13.6k | { |
164 | 13.6k | a.sm = shl32_dir_sat(a.sm, norm_a); |
165 | 13.6k | b.sm = shl32_dir_sat(b.sm, norm_b); |
166 | 13.6k | final_Q = Q_a; |
167 | 13.6k | } |
168 | | |
169 | 66.1k | c->sm = sub32(a.sm, b.sm); /* add32_shr defined in ia_basic_ops32.h */ |
170 | 66.1k | c->e = final_Q; /* because add32_shr does right shift |
171 | | by 1 before adding */ |
172 | 66.1k | } |
173 | | |
174 | | /* square root */ |
175 | | |
176 | | void sqrt32_var_q(number_t a, number_t *c) |
177 | 1.25k | { |
178 | 1.25k | WORD32 q_temp; |
179 | 1.25k | q_temp = a.e; |
180 | 1.25k | c->sm = sqrtFix_interpolate(a.sm, &q_temp, gi4_sqrt_tab); |
181 | | /* c->sm = sqrtFix(a.sm, &q_temp, gi4_sqrt_tab); */ |
182 | 1.25k | c->e = q_temp; |
183 | 1.25k | } |
184 | | |
185 | | void number_t_to_word32(number_t num_a, WORD32 *a) |
186 | 413k | { |
187 | 413k | *a = shr32_dir_sat(num_a.sm, num_a.e); |
188 | 413k | } |
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 |