• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 
12 /*
13  * This file contains implementations of the divisions
14  * WebRtcSpl_DivU32U16()
15  * WebRtcSpl_DivW32W16()
16  * WebRtcSpl_DivW32W16ResW16()
17  * WebRtcSpl_DivResultInQ31()
18  * WebRtcSpl_DivW32HiLow()
19  *
20  * The description header can be found in signal_processing_library.h
21  *
22  */
23 
24 #include "signal_processing_library.h"
25 
WebRtcSpl_DivU32U16(WebRtc_UWord32 num,WebRtc_UWord16 den)26 WebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den)
27 {
28     // Guard against division with 0
29     if (den != 0)
30     {
31         return (WebRtc_UWord32)(num / den);
32     } else
33     {
34         return (WebRtc_UWord32)0xFFFFFFFF;
35     }
36 }
37 
WebRtcSpl_DivW32W16(WebRtc_Word32 num,WebRtc_Word16 den)38 WebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den)
39 {
40     // Guard against division with 0
41     if (den != 0)
42     {
43         return (WebRtc_Word32)(num / den);
44     } else
45     {
46         return (WebRtc_Word32)0x7FFFFFFF;
47     }
48 }
49 
WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num,WebRtc_Word16 den)50 WebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den)
51 {
52     // Guard against division with 0
53     if (den != 0)
54     {
55         return (WebRtc_Word16)(num / den);
56     } else
57     {
58         return (WebRtc_Word16)0x7FFF;
59     }
60 }
61 
WebRtcSpl_DivResultInQ31(WebRtc_Word32 num,WebRtc_Word32 den)62 WebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den)
63 {
64     WebRtc_Word32 L_num = num;
65     WebRtc_Word32 L_den = den;
66     WebRtc_Word32 div = 0;
67     int k = 31;
68     int change_sign = 0;
69 
70     if (num == 0)
71         return 0;
72 
73     if (num < 0)
74     {
75         change_sign++;
76         L_num = -num;
77     }
78     if (den < 0)
79     {
80         change_sign++;
81         L_den = -den;
82     }
83     while (k--)
84     {
85         div <<= 1;
86         L_num <<= 1;
87         if (L_num >= L_den)
88         {
89             L_num -= L_den;
90             div++;
91         }
92     }
93     if (change_sign == 1)
94     {
95         div = -div;
96     }
97     return div;
98 }
99 
WebRtcSpl_DivW32HiLow(WebRtc_Word32 num,WebRtc_Word16 den_hi,WebRtc_Word16 den_low)100 WebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi,
101                                     WebRtc_Word16 den_low)
102 {
103     WebRtc_Word16 approx, tmp_hi, tmp_low, num_hi, num_low;
104     WebRtc_Word32 tmpW32;
105 
106     approx = (WebRtc_Word16)WebRtcSpl_DivW32W16((WebRtc_Word32)0x1FFFFFFF, den_hi);
107     // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30)
108 
109     // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30)
110     tmpW32 = (WEBRTC_SPL_MUL_16_16(den_hi, approx) << 1)
111             + ((WEBRTC_SPL_MUL_16_16(den_low, approx) >> 15) << 1);
112     // tmpW32 = den * approx
113 
114     tmpW32 = (WebRtc_Word32)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))
115 
116     // Store tmpW32 in hi and low format
117     tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
118     tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32
119             - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
120 
121     // tmpW32 = 1/den in Q29
122     tmpW32 = ((WEBRTC_SPL_MUL_16_16(tmp_hi, approx) + (WEBRTC_SPL_MUL_16_16(tmp_low, approx)
123             >> 15)) << 1);
124 
125     // 1/den in hi and low format
126     tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
127     tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32
128             - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
129 
130     // Store num in hi and low format
131     num_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(num, 16);
132     num_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((num
133             - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)num_hi, 16)), 1);
134 
135     // num * (1/den) by 32 bit multiplication (result in Q28)
136 
137     tmpW32 = (WEBRTC_SPL_MUL_16_16(num_hi, tmp_hi) + (WEBRTC_SPL_MUL_16_16(num_hi, tmp_low)
138             >> 15) + (WEBRTC_SPL_MUL_16_16(num_low, tmp_hi) >> 15));
139 
140     // Put result in Q31 (convert from Q28)
141     tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
142 
143     return tmpW32;
144 }
145