1c55a96383497a772a307b346368133960b02ad03Eric Laurent/*
2c55a96383497a772a307b346368133960b02ad03Eric Laurent *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3c55a96383497a772a307b346368133960b02ad03Eric Laurent *
4c55a96383497a772a307b346368133960b02ad03Eric Laurent *  Use of this source code is governed by a BSD-style license
5c55a96383497a772a307b346368133960b02ad03Eric Laurent *  that can be found in the LICENSE file in the root of the source
6c55a96383497a772a307b346368133960b02ad03Eric Laurent *  tree. An additional intellectual property rights grant can be found
7c55a96383497a772a307b346368133960b02ad03Eric Laurent *  in the file PATENTS.  All contributing project authors may
8c55a96383497a772a307b346368133960b02ad03Eric Laurent *  be found in the AUTHORS file in the root of the source tree.
9c55a96383497a772a307b346368133960b02ad03Eric Laurent */
10c55a96383497a772a307b346368133960b02ad03Eric Laurent
11c55a96383497a772a307b346368133960b02ad03Eric Laurent
12c55a96383497a772a307b346368133960b02ad03Eric Laurent// This header file includes the inline functions in
13c55a96383497a772a307b346368133960b02ad03Eric Laurent// the fix point signal processing library.
14c55a96383497a772a307b346368133960b02ad03Eric Laurent
15c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifndef WEBRTC_SPL_SPL_INL_H_
16c55a96383497a772a307b346368133960b02ad03Eric Laurent#define WEBRTC_SPL_SPL_INL_H_
17c55a96383497a772a307b346368133960b02ad03Eric Laurent
18c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_ARCH_ARM_V7A
19c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "spl_inl_armv7.h"
20c55a96383497a772a307b346368133960b02ad03Eric Laurent#else
21c55a96383497a772a307b346368133960b02ad03Eric Laurent
22c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic __inline WebRtc_Word16 WebRtcSpl_SatW32ToW16(WebRtc_Word32 value32) {
23c55a96383497a772a307b346368133960b02ad03Eric Laurent  WebRtc_Word16 out16 = (WebRtc_Word16) value32;
24c55a96383497a772a307b346368133960b02ad03Eric Laurent
25c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (value32 > 32767)
26c55a96383497a772a307b346368133960b02ad03Eric Laurent    out16 = 32767;
27c55a96383497a772a307b346368133960b02ad03Eric Laurent  else if (value32 < -32768)
28c55a96383497a772a307b346368133960b02ad03Eric Laurent    out16 = -32768;
29c55a96383497a772a307b346368133960b02ad03Eric Laurent
30c55a96383497a772a307b346368133960b02ad03Eric Laurent  return out16;
31c55a96383497a772a307b346368133960b02ad03Eric Laurent}
32c55a96383497a772a307b346368133960b02ad03Eric Laurent
33c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic __inline WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a,
34c55a96383497a772a307b346368133960b02ad03Eric Laurent                                                  WebRtc_Word16 b) {
35c55a96383497a772a307b346368133960b02ad03Eric Laurent  return WebRtcSpl_SatW32ToW16((WebRtc_Word32) a + (WebRtc_Word32) b);
36c55a96383497a772a307b346368133960b02ad03Eric Laurent}
37c55a96383497a772a307b346368133960b02ad03Eric Laurent
38c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic __inline WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1,
39c55a96383497a772a307b346368133960b02ad03Eric Laurent                                                  WebRtc_Word32 l_var2) {
40c55a96383497a772a307b346368133960b02ad03Eric Laurent  WebRtc_Word32 l_sum;
41c55a96383497a772a307b346368133960b02ad03Eric Laurent
42c55a96383497a772a307b346368133960b02ad03Eric Laurent  // perform long addition
43c55a96383497a772a307b346368133960b02ad03Eric Laurent  l_sum = l_var1 + l_var2;
44c55a96383497a772a307b346368133960b02ad03Eric Laurent
45c55a96383497a772a307b346368133960b02ad03Eric Laurent  // check for under or overflow
46c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (WEBRTC_SPL_IS_NEG(l_var1)) {
47c55a96383497a772a307b346368133960b02ad03Eric Laurent    if (WEBRTC_SPL_IS_NEG(l_var2) && !WEBRTC_SPL_IS_NEG(l_sum)) {
48c55a96383497a772a307b346368133960b02ad03Eric Laurent        l_sum = (WebRtc_Word32)0x80000000;
49c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
50c55a96383497a772a307b346368133960b02ad03Eric Laurent  } else {
51c55a96383497a772a307b346368133960b02ad03Eric Laurent    if (!WEBRTC_SPL_IS_NEG(l_var2) && WEBRTC_SPL_IS_NEG(l_sum)) {
52c55a96383497a772a307b346368133960b02ad03Eric Laurent        l_sum = (WebRtc_Word32)0x7FFFFFFF;
53c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
54c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
55c55a96383497a772a307b346368133960b02ad03Eric Laurent
56c55a96383497a772a307b346368133960b02ad03Eric Laurent  return l_sum;
57c55a96383497a772a307b346368133960b02ad03Eric Laurent}
58c55a96383497a772a307b346368133960b02ad03Eric Laurent
59c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic __inline WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1,
60c55a96383497a772a307b346368133960b02ad03Eric Laurent                                                  WebRtc_Word16 var2) {
61c55a96383497a772a307b346368133960b02ad03Eric Laurent  return WebRtcSpl_SatW32ToW16((WebRtc_Word32) var1 - (WebRtc_Word32) var2);
62c55a96383497a772a307b346368133960b02ad03Eric Laurent}
63c55a96383497a772a307b346368133960b02ad03Eric Laurent
64c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic __inline WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1,
65c55a96383497a772a307b346368133960b02ad03Eric Laurent                                                  WebRtc_Word32 l_var2) {
66c55a96383497a772a307b346368133960b02ad03Eric Laurent  WebRtc_Word32 l_diff;
67c55a96383497a772a307b346368133960b02ad03Eric Laurent
68c55a96383497a772a307b346368133960b02ad03Eric Laurent  // perform subtraction
69c55a96383497a772a307b346368133960b02ad03Eric Laurent  l_diff = l_var1 - l_var2;
70c55a96383497a772a307b346368133960b02ad03Eric Laurent
71c55a96383497a772a307b346368133960b02ad03Eric Laurent  // check for underflow
72c55a96383497a772a307b346368133960b02ad03Eric Laurent  if ((l_var1 < 0) && (l_var2 > 0) && (l_diff > 0))
73c55a96383497a772a307b346368133960b02ad03Eric Laurent    l_diff = (WebRtc_Word32)0x80000000;
74c55a96383497a772a307b346368133960b02ad03Eric Laurent  // check for overflow
75c55a96383497a772a307b346368133960b02ad03Eric Laurent  if ((l_var1 > 0) && (l_var2 < 0) && (l_diff < 0))
76c55a96383497a772a307b346368133960b02ad03Eric Laurent    l_diff = (WebRtc_Word32)0x7FFFFFFF;
77c55a96383497a772a307b346368133960b02ad03Eric Laurent
78c55a96383497a772a307b346368133960b02ad03Eric Laurent  return l_diff;
79c55a96383497a772a307b346368133960b02ad03Eric Laurent}
80c55a96383497a772a307b346368133960b02ad03Eric Laurent
81c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic __inline WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) {
82c55a96383497a772a307b346368133960b02ad03Eric Laurent  int bits;
83c55a96383497a772a307b346368133960b02ad03Eric Laurent
84c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (0xFFFF0000 & n) {
85c55a96383497a772a307b346368133960b02ad03Eric Laurent    bits = 16;
86c55a96383497a772a307b346368133960b02ad03Eric Laurent  } else {
87c55a96383497a772a307b346368133960b02ad03Eric Laurent    bits = 0;
88c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
89c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (0x0000FF00 & (n >> bits)) bits += 8;
90c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (0x000000F0 & (n >> bits)) bits += 4;
91c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (0x0000000C & (n >> bits)) bits += 2;
92c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (0x00000002 & (n >> bits)) bits += 1;
93c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (0x00000001 & (n >> bits)) bits += 1;
94c55a96383497a772a307b346368133960b02ad03Eric Laurent
95c55a96383497a772a307b346368133960b02ad03Eric Laurent  return bits;
96c55a96383497a772a307b346368133960b02ad03Eric Laurent}
97c55a96383497a772a307b346368133960b02ad03Eric Laurent
98c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic __inline int WebRtcSpl_NormW32(WebRtc_Word32 a) {
99c55a96383497a772a307b346368133960b02ad03Eric Laurent  int zeros;
100c55a96383497a772a307b346368133960b02ad03Eric Laurent
101c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (a <= 0) a ^= 0xFFFFFFFF;
102c55a96383497a772a307b346368133960b02ad03Eric Laurent
103c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xFFFF8000 & a)) {
104c55a96383497a772a307b346368133960b02ad03Eric Laurent    zeros = 16;
105c55a96383497a772a307b346368133960b02ad03Eric Laurent  } else {
106c55a96383497a772a307b346368133960b02ad03Eric Laurent    zeros = 0;
107c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
108c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xFF800000 & (a << zeros))) zeros += 8;
109c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xF8000000 & (a << zeros))) zeros += 4;
110c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xE0000000 & (a << zeros))) zeros += 2;
111c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xC0000000 & (a << zeros))) zeros += 1;
112c55a96383497a772a307b346368133960b02ad03Eric Laurent
113c55a96383497a772a307b346368133960b02ad03Eric Laurent  return zeros;
114c55a96383497a772a307b346368133960b02ad03Eric Laurent}
115c55a96383497a772a307b346368133960b02ad03Eric Laurent
116c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic __inline int WebRtcSpl_NormU32(WebRtc_UWord32 a) {
117c55a96383497a772a307b346368133960b02ad03Eric Laurent  int zeros;
118c55a96383497a772a307b346368133960b02ad03Eric Laurent
119c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (a == 0) return 0;
120c55a96383497a772a307b346368133960b02ad03Eric Laurent
121c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xFFFF0000 & a)) {
122c55a96383497a772a307b346368133960b02ad03Eric Laurent    zeros = 16;
123c55a96383497a772a307b346368133960b02ad03Eric Laurent  } else {
124c55a96383497a772a307b346368133960b02ad03Eric Laurent    zeros = 0;
125c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
126c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xFF000000 & (a << zeros))) zeros += 8;
127c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xF0000000 & (a << zeros))) zeros += 4;
128c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xC0000000 & (a << zeros))) zeros += 2;
129c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0x80000000 & (a << zeros))) zeros += 1;
130c55a96383497a772a307b346368133960b02ad03Eric Laurent
131c55a96383497a772a307b346368133960b02ad03Eric Laurent  return zeros;
132c55a96383497a772a307b346368133960b02ad03Eric Laurent}
133c55a96383497a772a307b346368133960b02ad03Eric Laurent
134c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic __inline int WebRtcSpl_NormW16(WebRtc_Word16 a) {
135c55a96383497a772a307b346368133960b02ad03Eric Laurent  int zeros;
136c55a96383497a772a307b346368133960b02ad03Eric Laurent
137c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (a <= 0) a ^= 0xFFFF;
138c55a96383497a772a307b346368133960b02ad03Eric Laurent
139c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xFF80 & a)) {
140c55a96383497a772a307b346368133960b02ad03Eric Laurent    zeros = 8;
141c55a96383497a772a307b346368133960b02ad03Eric Laurent  } else {
142c55a96383497a772a307b346368133960b02ad03Eric Laurent    zeros = 0;
143c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
144c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xF800 & (a << zeros))) zeros += 4;
145c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xE000 & (a << zeros))) zeros += 2;
146c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(0xC000 & (a << zeros))) zeros += 1;
147c55a96383497a772a307b346368133960b02ad03Eric Laurent
148c55a96383497a772a307b346368133960b02ad03Eric Laurent  return zeros;
149c55a96383497a772a307b346368133960b02ad03Eric Laurent}
150c55a96383497a772a307b346368133960b02ad03Eric Laurent
151c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic __inline int32_t WebRtc_MulAccumW16(int16_t a,
152c55a96383497a772a307b346368133960b02ad03Eric Laurent                                          int16_t b,
153c55a96383497a772a307b346368133960b02ad03Eric Laurent                                          int32_t c) {
154c55a96383497a772a307b346368133960b02ad03Eric Laurent  return (a * b + c);
155c55a96383497a772a307b346368133960b02ad03Eric Laurent}
156c55a96383497a772a307b346368133960b02ad03Eric Laurent
157c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif  // WEBRTC_ARCH_ARM_V7A
158c55a96383497a772a307b346368133960b02ad03Eric Laurent
159c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif  // WEBRTC_SPL_SPL_INL_H_
160