1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/*
19
20 Filename: pv_div.c
21
22------------------------------------------------------------------------------
23 REVISION HISTORY
24
25
26 Who:                                   Date: MM/DD/YYYY
27 Description:
28
29------------------------------------------------------------------------------
30 INPUT AND OUTPUT DEFINITIONS
31
32    Int32 x             32-bit integer numerator
33    Int32 y             32-bit integer denominator
34    Quotient *result    structure that hold result and shift factor
35
36
37------------------------------------------------------------------------------
38 FUNCTION DESCRIPTION
39
40    Implement division of two Int32 numbers, provides back quotient and a
41    shift factor
42------------------------------------------------------------------------------
43 REQUIREMENTS
44
45
46------------------------------------------------------------------------------
47 REFERENCES
48
49------------------------------------------------------------------------------
50 PSEUDO-CODE
51
52------------------------------------------------------------------------------
53*/
54
55
56/*----------------------------------------------------------------------------
57; INCLUDES
58----------------------------------------------------------------------------*/
59#ifdef AAC_PLUS
60
61
62#include "pv_audio_type_defs.h"
63#include "fxp_mul32.h"
64#include "pv_div.h"
65#include "pv_normalize.h"
66
67/*----------------------------------------------------------------------------
68; MACROS
69; Define module specific macros here
70----------------------------------------------------------------------------*/
71
72
73/*----------------------------------------------------------------------------
74; DEFINES
75; Include all pre-processor statements here. Include conditional
76; compile variables also.
77----------------------------------------------------------------------------*/
78
79/*----------------------------------------------------------------------------
80; LOCAL FUNCTION DEFINITIONS
81; Function Prototype declaration
82----------------------------------------------------------------------------*/
83
84/*----------------------------------------------------------------------------
85; LOCAL STORE/BUFFER/POINTER DEFINITIONS
86; Variable declaration - defined here and used outside this module
87----------------------------------------------------------------------------*/
88
89/*----------------------------------------------------------------------------
90; EXTERNAL FUNCTION REFERENCES
91; Declare functions defined elsewhere and referenced in this module
92----------------------------------------------------------------------------*/
93
94/*----------------------------------------------------------------------------
95; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
96; Declare variables used in this module but defined elsewhere
97----------------------------------------------------------------------------*/
98
99/*----------------------------------------------------------------------------
100; FUNCTION CODE
101----------------------------------------------------------------------------*/
102
103
104void pv_div(Int32 x, Int32 y, Quotient *result)
105{
106    /*----------------------------------------------------------------------------
107    ; Define all local variables
108    ----------------------------------------------------------------------------*/
109    Int32 quotient;
110    Int32 i;
111    Int32 j;
112    Int32 y_ov_y_hi;
113    Int32 flag = 0;     /* carries negative sign, if any  */
114
115
116    result->shift_factor = 0;   /* default  */
117
118    if (y == 0)
119    {
120        x = 0;   /* this will return 0 for any div/0 */
121    }
122    /*
123     *  make sure x and y are both positive
124     */
125
126    if (y < 0)
127    {
128        y = -y;
129        flag ^= 1;
130    }
131
132
133    if (x < 0)
134    {
135        x = -x;
136        flag ^= 1;
137    }
138
139    if (x != 0)
140    {
141        /*----------------------------------------------------------------------------
142        ; Scale the input to get maximum precision for x
143        ----------------------------------------------------------------------------*/
144
145        i = pv_normalize(x);
146
147        x <<= i;
148
149
150        /*----------------------------------------------------------------------------
151        ; Scale the input to get maximum precision for y
152        ----------------------------------------------------------------------------*/
153
154        j = pv_normalize(y);
155
156        y <<= j;
157
158        result->shift_factor = i - j;
159
160        /*----------------------------------------------------------------------------
161        ; Function body here
162        ----------------------------------------------------------------------------*/
163        /*---------------------------------------------------------------
164         ; take the inverse of the 16 MSB of y
165         ---------------------------------------------------------------*/
166
167        quotient = (0x40000000 / (y >> 15));
168
169        y_ov_y_hi = fxp_mul32_Q15(y, quotient);            /*  y*(1/y_hi)     */
170
171        y_ov_y_hi = 0x7FFFFFFF - y_ov_y_hi;                 /*  2 - y*(1/y_hi) */
172        y_ov_y_hi = fxp_mul32_Q14(quotient,  y_ov_y_hi);
173        i  = fxp_mul32_Q31(y_ov_y_hi,  x) << 1;
174
175        result->quotient = flag ? -i : i;
176    }
177    else
178    {
179        result->quotient = 0;
180    }
181
182
183
184}
185
186#endif
187
188
189