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 : // This header file includes the inline functions in
13 : // the fix point signal processing library.
14 :
15 : #ifndef WEBRTC_SPL_SPL_INL_H_
16 : #define WEBRTC_SPL_SPL_INL_H_
17 :
18 : #include "webrtc/system_wrappers/include/compile_assert_c.h"
19 :
20 : extern const int8_t kWebRtcSpl_CountLeadingZeros32_Table[64];
21 :
22 : // Don't call this directly except in tests!
23 : static __inline int WebRtcSpl_CountLeadingZeros32_NotBuiltin(uint32_t n) {
24 : // Normalize n by rounding up to the nearest number that is a sequence of 0
25 : // bits followed by a sequence of 1 bits. This number has the same number of
26 : // leading zeros as the original n. There are exactly 33 such values.
27 : n |= n >> 1;
28 : n |= n >> 2;
29 : n |= n >> 4;
30 : n |= n >> 8;
31 : n |= n >> 16;
32 :
33 : // Multiply the modified n with a constant selected (by exhaustive search)
34 : // such that each of the 33 possible values of n give a product whose 6 most
35 : // significant bits are unique. Then look up the answer in the table.
36 : return kWebRtcSpl_CountLeadingZeros32_Table[(n * 0x8c0b2891) >> 26];
37 : }
38 :
39 : // Don't call this directly except in tests!
40 : static __inline int WebRtcSpl_CountLeadingZeros64_NotBuiltin(uint64_t n) {
41 : const int leading_zeros = n >> 32 == 0 ? 32 : 0;
42 : return leading_zeros + WebRtcSpl_CountLeadingZeros32_NotBuiltin(
43 : (uint32_t)(n >> (32 - leading_zeros)));
44 : }
45 :
46 : // Returns the number of leading zero bits in the argument.
47 0 : static __inline int WebRtcSpl_CountLeadingZeros32(uint32_t n) {
48 : #ifdef __GNUC__
49 : COMPILE_ASSERT(sizeof(unsigned int) == sizeof(uint32_t));
50 0 : return n == 0 ? 32 : __builtin_clz(n);
51 : #else
52 : return WebRtcSpl_CountLeadingZeros32_NotBuiltin(n);
53 : #endif
54 : }
55 :
56 : // Returns the number of leading zero bits in the argument.
57 : static __inline int WebRtcSpl_CountLeadingZeros64(uint64_t n) {
58 : #ifdef __GNUC__
59 : COMPILE_ASSERT(sizeof(unsigned long long) == sizeof(uint64_t));
60 : return n == 0 ? 64 : __builtin_clzll(n);
61 : #else
62 : return WebRtcSpl_CountLeadingZeros64_NotBuiltin(n);
63 : #endif
64 : }
65 :
66 : #ifdef WEBRTC_ARCH_ARM_V7
67 : #include "webrtc/common_audio/signal_processing/include/spl_inl_armv7.h"
68 : #else
69 :
70 : #if defined(MIPS32_LE)
71 : #include "webrtc/common_audio/signal_processing/include/spl_inl_mips.h"
72 : #endif
73 :
74 : #if !defined(MIPS_DSP_R1_LE)
75 0 : static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
76 0 : int16_t out16 = (int16_t) value32;
77 :
78 0 : if (value32 > 32767)
79 0 : out16 = 32767;
80 0 : else if (value32 < -32768)
81 0 : out16 = -32768;
82 :
83 0 : return out16;
84 : }
85 :
86 0 : static __inline int32_t WebRtcSpl_AddSatW32(int32_t a, int32_t b) {
87 : // Do the addition in unsigned numbers, since signed overflow is undefined
88 : // behavior.
89 0 : const int32_t sum = (int32_t)((uint32_t)a + (uint32_t)b);
90 :
91 : // a + b can't overflow if a and b have different signs. If they have the
92 : // same sign, a + b also has the same sign iff it didn't overflow.
93 0 : if ((a < 0) == (b < 0) && (a < 0) != (sum < 0)) {
94 : // The direction of the overflow is obvious from the sign of a + b.
95 0 : return sum < 0 ? INT32_MAX : INT32_MIN;
96 : }
97 0 : return sum;
98 : }
99 :
100 0 : static __inline int32_t WebRtcSpl_SubSatW32(int32_t a, int32_t b) {
101 : // Do the subtraction in unsigned numbers, since signed overflow is undefined
102 : // behavior.
103 0 : const int32_t diff = (int32_t)((uint32_t)a - (uint32_t)b);
104 :
105 : // a - b can't overflow if a and b have the same sign. If they have different
106 : // signs, a - b has the same sign as a iff it didn't overflow.
107 0 : if ((a < 0) != (b < 0) && (a < 0) != (diff < 0)) {
108 : // The direction of the overflow is obvious from the sign of a - b.
109 0 : return diff < 0 ? INT32_MAX : INT32_MIN;
110 : }
111 0 : return diff;
112 : }
113 :
114 0 : static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
115 0 : return WebRtcSpl_SatW32ToW16((int32_t) a + (int32_t) b);
116 : }
117 :
118 0 : static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
119 0 : return WebRtcSpl_SatW32ToW16((int32_t) var1 - (int32_t) var2);
120 : }
121 : #endif // #if !defined(MIPS_DSP_R1_LE)
122 :
123 : #if !defined(MIPS32_LE)
124 0 : static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
125 0 : return 32 - WebRtcSpl_CountLeadingZeros32(n);
126 : }
127 :
128 : // Return the number of steps a can be left-shifted without overflow,
129 : // or 0 if a == 0.
130 0 : static __inline int16_t WebRtcSpl_NormW32(int32_t a) {
131 0 : return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a : a) - 1;
132 : }
133 :
134 : // Return the number of steps a can be left-shifted without overflow,
135 : // or 0 if a == 0.
136 0 : static __inline int16_t WebRtcSpl_NormU32(uint32_t a) {
137 0 : return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a);
138 : }
139 :
140 : // Return the number of steps a can be left-shifted without overflow,
141 : // or 0 if a == 0.
142 0 : static __inline int16_t WebRtcSpl_NormW16(int16_t a) {
143 0 : const int32_t a32 = a;
144 0 : return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a32 : a32) - 17;
145 : }
146 :
147 : static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) {
148 : return (a * b + c);
149 : }
150 : #endif // #if !defined(MIPS32_LE)
151 :
152 : #endif // WEBRTC_ARCH_ARM_V7
153 :
154 : #endif // WEBRTC_SPL_SPL_INL_H_
|