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