Line data Source code
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 "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
25 :
26 0 : uint32_t WebRtcSpl_DivU32U16(uint32_t num, uint16_t den)
27 : {
28 : // Guard against division with 0
29 0 : if (den != 0)
30 : {
31 0 : return (uint32_t)(num / den);
32 : } else
33 : {
34 0 : return (uint32_t)0xFFFFFFFF;
35 : }
36 : }
37 :
38 0 : int32_t WebRtcSpl_DivW32W16(int32_t num, int16_t den)
39 : {
40 : // Guard against division with 0
41 0 : if (den != 0)
42 : {
43 0 : return (int32_t)(num / den);
44 : } else
45 : {
46 0 : return (int32_t)0x7FFFFFFF;
47 : }
48 : }
49 :
50 0 : int16_t WebRtcSpl_DivW32W16ResW16(int32_t num, int16_t den)
51 : {
52 : // Guard against division with 0
53 0 : if (den != 0)
54 : {
55 0 : return (int16_t)(num / den);
56 : } else
57 : {
58 0 : return (int16_t)0x7FFF;
59 : }
60 : }
61 :
62 0 : int32_t WebRtcSpl_DivResultInQ31(int32_t num, int32_t den)
63 : {
64 0 : int32_t L_num = num;
65 0 : int32_t L_den = den;
66 0 : int32_t div = 0;
67 0 : int k = 31;
68 0 : int change_sign = 0;
69 :
70 0 : if (num == 0)
71 0 : return 0;
72 :
73 0 : if (num < 0)
74 : {
75 0 : change_sign++;
76 0 : L_num = -num;
77 : }
78 0 : if (den < 0)
79 : {
80 0 : change_sign++;
81 0 : L_den = -den;
82 : }
83 0 : while (k--)
84 : {
85 0 : div <<= 1;
86 0 : L_num <<= 1;
87 0 : if (L_num >= L_den)
88 : {
89 0 : L_num -= L_den;
90 0 : div++;
91 : }
92 : }
93 0 : if (change_sign == 1)
94 : {
95 0 : div = -div;
96 : }
97 0 : return div;
98 : }
99 :
100 0 : int32_t WebRtcSpl_DivW32HiLow(int32_t num, int16_t den_hi, int16_t den_low)
101 : {
102 : int16_t approx, tmp_hi, tmp_low, num_hi, num_low;
103 : int32_t tmpW32;
104 :
105 0 : approx = (int16_t)WebRtcSpl_DivW32W16((int32_t)0x1FFFFFFF, den_hi);
106 : // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30)
107 :
108 : // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30)
109 0 : tmpW32 = (den_hi * approx << 1) + ((den_low * approx >> 15) << 1);
110 : // tmpW32 = den * approx
111 :
112 0 : tmpW32 = (int32_t)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))
113 :
114 : // Store tmpW32 in hi and low format
115 0 : tmp_hi = (int16_t)(tmpW32 >> 16);
116 0 : tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1);
117 :
118 : // tmpW32 = 1/den in Q29
119 0 : tmpW32 = (tmp_hi * approx + (tmp_low * approx >> 15)) << 1;
120 :
121 : // 1/den in hi and low format
122 0 : tmp_hi = (int16_t)(tmpW32 >> 16);
123 0 : tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1);
124 :
125 : // Store num in hi and low format
126 0 : num_hi = (int16_t)(num >> 16);
127 0 : num_low = (int16_t)((num - ((int32_t)num_hi << 16)) >> 1);
128 :
129 : // num * (1/den) by 32 bit multiplication (result in Q28)
130 :
131 0 : tmpW32 = num_hi * tmp_hi + (num_hi * tmp_low >> 15) +
132 0 : (num_low * tmp_hi >> 15);
133 :
134 : // Put result in Q31 (convert from Q28)
135 0 : tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
136 :
137 0 : return tmpW32;
138 : }
|