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