webrtcvad 0.1.0 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/ext/webrtcvad/extconf.rb +29 -0
  3. data/ext/webrtcvad/webrtc/common_audio/signal_processing/division_operations.c +141 -0
  4. data/ext/webrtcvad/webrtc/common_audio/signal_processing/dot_product_with_scale.h +40 -0
  5. data/ext/webrtcvad/webrtc/common_audio/signal_processing/energy.c +39 -0
  6. data/ext/webrtcvad/webrtc/common_audio/signal_processing/get_scaling_square.c +46 -0
  7. data/ext/webrtcvad/webrtc/common_audio/signal_processing/include/signal_processing_library.h +1605 -0
  8. data/ext/webrtcvad/webrtc/common_audio/signal_processing/include/spl_inl.h +153 -0
  9. data/ext/webrtcvad/webrtc/common_audio/signal_processing/resample_48khz.c +186 -0
  10. data/ext/webrtcvad/webrtc/common_audio/signal_processing/resample_by_2_internal.c +689 -0
  11. data/ext/webrtcvad/webrtc/common_audio/signal_processing/resample_by_2_internal.h +60 -0
  12. data/ext/webrtcvad/webrtc/common_audio/signal_processing/resample_fractional.c +239 -0
  13. data/ext/webrtcvad/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.c +77 -0
  14. data/ext/webrtcvad/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h +29 -0
  15. data/ext/webrtcvad/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor_mips.c +207 -0
  16. data/ext/webrtcvad/webrtc/common_audio/vad/include/webrtc_vad.h +87 -0
  17. data/ext/webrtcvad/webrtc/common_audio/vad/vad_core.c +685 -0
  18. data/ext/webrtcvad/webrtc/common_audio/vad/vad_core.h +114 -0
  19. data/ext/webrtcvad/webrtc/common_audio/vad/vad_filterbank.c +329 -0
  20. data/ext/webrtcvad/webrtc/common_audio/vad/vad_filterbank.h +45 -0
  21. data/ext/webrtcvad/webrtc/common_audio/vad/vad_gmm.c +82 -0
  22. data/ext/webrtcvad/webrtc/common_audio/vad/vad_gmm.h +39 -0
  23. data/ext/webrtcvad/webrtc/common_audio/vad/vad_sp.c +176 -0
  24. data/ext/webrtcvad/webrtc/common_audio/vad/vad_sp.h +54 -0
  25. data/ext/webrtcvad/webrtc/common_audio/vad/webrtc_vad.c +114 -0
  26. data/ext/webrtcvad/webrtc/rtc_base/checks.cc +207 -0
  27. data/ext/webrtcvad/webrtc/rtc_base/checks.h +400 -0
  28. data/ext/webrtcvad/webrtc/rtc_base/compile_assert_c.h +25 -0
  29. data/ext/webrtcvad/webrtc/rtc_base/numerics/safe_compare.h +176 -0
  30. data/ext/webrtcvad/webrtc/rtc_base/sanitizer.h +144 -0
  31. data/ext/webrtcvad/webrtc/rtc_base/system/inline.h +31 -0
  32. data/ext/webrtcvad/webrtc/rtc_base/system/rtc_export.h +43 -0
  33. data/ext/webrtcvad/webrtc/rtc_base/type_traits.h +140 -0
  34. data/ext/webrtcvad/webrtcvad.c +112 -0
  35. metadata +37 -3
@@ -0,0 +1,153 @@
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 "rtc_base/compile_assert_c.h"
18
+
19
+ extern const int8_t kWebRtcSpl_CountLeadingZeros32_Table[64];
20
+
21
+ // Don't call this directly except in tests!
22
+ static __inline int WebRtcSpl_CountLeadingZeros32_NotBuiltin(uint32_t n) {
23
+ // Normalize n by rounding up to the nearest number that is a sequence of 0
24
+ // bits followed by a sequence of 1 bits. This number has the same number of
25
+ // leading zeros as the original n. There are exactly 33 such values.
26
+ n |= n >> 1;
27
+ n |= n >> 2;
28
+ n |= n >> 4;
29
+ n |= n >> 8;
30
+ n |= n >> 16;
31
+
32
+ // Multiply the modified n with a constant selected (by exhaustive search)
33
+ // such that each of the 33 possible values of n give a product whose 6 most
34
+ // significant bits are unique. Then look up the answer in the table.
35
+ return kWebRtcSpl_CountLeadingZeros32_Table[(n * 0x8c0b2891) >> 26];
36
+ }
37
+
38
+ // Don't call this directly except in tests!
39
+ static __inline int WebRtcSpl_CountLeadingZeros64_NotBuiltin(uint64_t n) {
40
+ const int leading_zeros = n >> 32 == 0 ? 32 : 0;
41
+ return leading_zeros + WebRtcSpl_CountLeadingZeros32_NotBuiltin(
42
+ (uint32_t)(n >> (32 - leading_zeros)));
43
+ }
44
+
45
+ // Returns the number of leading zero bits in the argument.
46
+ static __inline int WebRtcSpl_CountLeadingZeros32(uint32_t n) {
47
+ #ifdef __GNUC__
48
+ RTC_COMPILE_ASSERT(sizeof(unsigned int) == sizeof(uint32_t));
49
+ return n == 0 ? 32 : __builtin_clz(n);
50
+ #else
51
+ return WebRtcSpl_CountLeadingZeros32_NotBuiltin(n);
52
+ #endif
53
+ }
54
+
55
+ // Returns the number of leading zero bits in the argument.
56
+ static __inline int WebRtcSpl_CountLeadingZeros64(uint64_t n) {
57
+ #ifdef __GNUC__
58
+ RTC_COMPILE_ASSERT(sizeof(unsigned long long) == sizeof(uint64_t)); // NOLINT
59
+ return n == 0 ? 64 : __builtin_clzll(n);
60
+ #else
61
+ return WebRtcSpl_CountLeadingZeros64_NotBuiltin(n);
62
+ #endif
63
+ }
64
+
65
+ #ifdef WEBRTC_ARCH_ARM_V7
66
+ #include "common_audio/signal_processing/include/spl_inl_armv7.h"
67
+ #else
68
+
69
+ #if defined(MIPS32_LE)
70
+ #include "common_audio/signal_processing/include/spl_inl_mips.h"
71
+ #endif
72
+
73
+ #if !defined(MIPS_DSP_R1_LE)
74
+ static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
75
+ int16_t out16 = (int16_t)value32;
76
+
77
+ if (value32 > 32767)
78
+ out16 = 32767;
79
+ else if (value32 < -32768)
80
+ out16 = -32768;
81
+
82
+ return out16;
83
+ }
84
+
85
+ static __inline int32_t WebRtcSpl_AddSatW32(int32_t a, int32_t b) {
86
+ // Do the addition in unsigned numbers, since signed overflow is undefined
87
+ // behavior.
88
+ const int32_t sum = (int32_t)((uint32_t)a + (uint32_t)b);
89
+
90
+ // a + b can't overflow if a and b have different signs. If they have the
91
+ // same sign, a + b also has the same sign iff it didn't overflow.
92
+ if ((a < 0) == (b < 0) && (a < 0) != (sum < 0)) {
93
+ // The direction of the overflow is obvious from the sign of a + b.
94
+ return sum < 0 ? INT32_MAX : INT32_MIN;
95
+ }
96
+ return sum;
97
+ }
98
+
99
+ static __inline int32_t WebRtcSpl_SubSatW32(int32_t a, int32_t b) {
100
+ // Do the subtraction in unsigned numbers, since signed overflow is undefined
101
+ // behavior.
102
+ const int32_t diff = (int32_t)((uint32_t)a - (uint32_t)b);
103
+
104
+ // a - b can't overflow if a and b have the same sign. If they have different
105
+ // signs, a - b has the same sign as a iff it didn't overflow.
106
+ if ((a < 0) != (b < 0) && (a < 0) != (diff < 0)) {
107
+ // The direction of the overflow is obvious from the sign of a - b.
108
+ return diff < 0 ? INT32_MAX : INT32_MIN;
109
+ }
110
+ return diff;
111
+ }
112
+
113
+ static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
114
+ return WebRtcSpl_SatW32ToW16((int32_t)a + (int32_t)b);
115
+ }
116
+
117
+ static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
118
+ return WebRtcSpl_SatW32ToW16((int32_t)var1 - (int32_t)var2);
119
+ }
120
+ #endif // #if !defined(MIPS_DSP_R1_LE)
121
+
122
+ #if !defined(MIPS32_LE)
123
+ static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
124
+ return 32 - WebRtcSpl_CountLeadingZeros32(n);
125
+ }
126
+
127
+ // Return the number of steps a can be left-shifted without overflow,
128
+ // or 0 if a == 0.
129
+ static __inline int16_t WebRtcSpl_NormW32(int32_t a) {
130
+ return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a : a) - 1;
131
+ }
132
+
133
+ // Return the number of steps a can be left-shifted without overflow,
134
+ // or 0 if a == 0.
135
+ static __inline int16_t WebRtcSpl_NormU32(uint32_t a) {
136
+ return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a);
137
+ }
138
+
139
+ // Return the number of steps a can be left-shifted without overflow,
140
+ // or 0 if a == 0.
141
+ static __inline int16_t WebRtcSpl_NormW16(int16_t a) {
142
+ const int32_t a32 = a;
143
+ return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a32 : a32) - 17;
144
+ }
145
+
146
+ static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) {
147
+ return (a * b + c);
148
+ }
149
+ #endif // #if !defined(MIPS32_LE)
150
+
151
+ #endif // WEBRTC_ARCH_ARM_V7
152
+
153
+ #endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_
@@ -0,0 +1,186 @@
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 resampling functions between 48 kHz and nb/wb.
14
+ * The description header can be found in signal_processing_library.h
15
+ *
16
+ */
17
+
18
+ #include <string.h>
19
+ #include "common_audio/signal_processing/include/signal_processing_library.h"
20
+ #include "common_audio/signal_processing/resample_by_2_internal.h"
21
+
22
+ ////////////////////////////
23
+ ///// 48 kHz -> 16 kHz /////
24
+ ////////////////////////////
25
+
26
+ // 48 -> 16 resampler
27
+ void WebRtcSpl_Resample48khzTo16khz(const int16_t* in, int16_t* out,
28
+ WebRtcSpl_State48khzTo16khz* state, int32_t* tmpmem)
29
+ {
30
+ ///// 48 --> 48(LP) /////
31
+ // int16_t in[480]
32
+ // int32_t out[480]
33
+ /////
34
+ WebRtcSpl_LPBy2ShortToInt(in, 480, tmpmem + 16, state->S_48_48);
35
+
36
+ ///// 48 --> 32 /////
37
+ // int32_t in[480]
38
+ // int32_t out[320]
39
+ /////
40
+ // copy state to and from input array
41
+ memcpy(tmpmem + 8, state->S_48_32, 8 * sizeof(int32_t));
42
+ memcpy(state->S_48_32, tmpmem + 488, 8 * sizeof(int32_t));
43
+ WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 160);
44
+
45
+ ///// 32 --> 16 /////
46
+ // int32_t in[320]
47
+ // int16_t out[160]
48
+ /////
49
+ WebRtcSpl_DownBy2IntToShort(tmpmem, 320, out, state->S_32_16);
50
+ }
51
+
52
+ // initialize state of 48 -> 16 resampler
53
+ void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state)
54
+ {
55
+ memset(state->S_48_48, 0, 16 * sizeof(int32_t));
56
+ memset(state->S_48_32, 0, 8 * sizeof(int32_t));
57
+ memset(state->S_32_16, 0, 8 * sizeof(int32_t));
58
+ }
59
+
60
+ ////////////////////////////
61
+ ///// 16 kHz -> 48 kHz /////
62
+ ////////////////////////////
63
+
64
+ // 16 -> 48 resampler
65
+ void WebRtcSpl_Resample16khzTo48khz(const int16_t* in, int16_t* out,
66
+ WebRtcSpl_State16khzTo48khz* state, int32_t* tmpmem)
67
+ {
68
+ ///// 16 --> 32 /////
69
+ // int16_t in[160]
70
+ // int32_t out[320]
71
+ /////
72
+ WebRtcSpl_UpBy2ShortToInt(in, 160, tmpmem + 16, state->S_16_32);
73
+
74
+ ///// 32 --> 24 /////
75
+ // int32_t in[320]
76
+ // int32_t out[240]
77
+ // copy state to and from input array
78
+ /////
79
+ memcpy(tmpmem + 8, state->S_32_24, 8 * sizeof(int32_t));
80
+ memcpy(state->S_32_24, tmpmem + 328, 8 * sizeof(int32_t));
81
+ WebRtcSpl_Resample32khzTo24khz(tmpmem + 8, tmpmem, 80);
82
+
83
+ ///// 24 --> 48 /////
84
+ // int32_t in[240]
85
+ // int16_t out[480]
86
+ /////
87
+ WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48);
88
+ }
89
+
90
+ // initialize state of 16 -> 48 resampler
91
+ void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state)
92
+ {
93
+ memset(state->S_16_32, 0, 8 * sizeof(int32_t));
94
+ memset(state->S_32_24, 0, 8 * sizeof(int32_t));
95
+ memset(state->S_24_48, 0, 8 * sizeof(int32_t));
96
+ }
97
+
98
+ ////////////////////////////
99
+ ///// 48 kHz -> 8 kHz /////
100
+ ////////////////////////////
101
+
102
+ // 48 -> 8 resampler
103
+ void WebRtcSpl_Resample48khzTo8khz(const int16_t* in, int16_t* out,
104
+ WebRtcSpl_State48khzTo8khz* state, int32_t* tmpmem)
105
+ {
106
+ ///// 48 --> 24 /////
107
+ // int16_t in[480]
108
+ // int32_t out[240]
109
+ /////
110
+ WebRtcSpl_DownBy2ShortToInt(in, 480, tmpmem + 256, state->S_48_24);
111
+
112
+ ///// 24 --> 24(LP) /////
113
+ // int32_t in[240]
114
+ // int32_t out[240]
115
+ /////
116
+ WebRtcSpl_LPBy2IntToInt(tmpmem + 256, 240, tmpmem + 16, state->S_24_24);
117
+
118
+ ///// 24 --> 16 /////
119
+ // int32_t in[240]
120
+ // int32_t out[160]
121
+ /////
122
+ // copy state to and from input array
123
+ memcpy(tmpmem + 8, state->S_24_16, 8 * sizeof(int32_t));
124
+ memcpy(state->S_24_16, tmpmem + 248, 8 * sizeof(int32_t));
125
+ WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 80);
126
+
127
+ ///// 16 --> 8 /////
128
+ // int32_t in[160]
129
+ // int16_t out[80]
130
+ /////
131
+ WebRtcSpl_DownBy2IntToShort(tmpmem, 160, out, state->S_16_8);
132
+ }
133
+
134
+ // initialize state of 48 -> 8 resampler
135
+ void WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state)
136
+ {
137
+ memset(state->S_48_24, 0, 8 * sizeof(int32_t));
138
+ memset(state->S_24_24, 0, 16 * sizeof(int32_t));
139
+ memset(state->S_24_16, 0, 8 * sizeof(int32_t));
140
+ memset(state->S_16_8, 0, 8 * sizeof(int32_t));
141
+ }
142
+
143
+ ////////////////////////////
144
+ ///// 8 kHz -> 48 kHz /////
145
+ ////////////////////////////
146
+
147
+ // 8 -> 48 resampler
148
+ void WebRtcSpl_Resample8khzTo48khz(const int16_t* in, int16_t* out,
149
+ WebRtcSpl_State8khzTo48khz* state, int32_t* tmpmem)
150
+ {
151
+ ///// 8 --> 16 /////
152
+ // int16_t in[80]
153
+ // int32_t out[160]
154
+ /////
155
+ WebRtcSpl_UpBy2ShortToInt(in, 80, tmpmem + 264, state->S_8_16);
156
+
157
+ ///// 16 --> 12 /////
158
+ // int32_t in[160]
159
+ // int32_t out[120]
160
+ /////
161
+ // copy state to and from input array
162
+ memcpy(tmpmem + 256, state->S_16_12, 8 * sizeof(int32_t));
163
+ memcpy(state->S_16_12, tmpmem + 416, 8 * sizeof(int32_t));
164
+ WebRtcSpl_Resample32khzTo24khz(tmpmem + 256, tmpmem + 240, 40);
165
+
166
+ ///// 12 --> 24 /////
167
+ // int32_t in[120]
168
+ // int16_t out[240]
169
+ /////
170
+ WebRtcSpl_UpBy2IntToInt(tmpmem + 240, 120, tmpmem, state->S_12_24);
171
+
172
+ ///// 24 --> 48 /////
173
+ // int32_t in[240]
174
+ // int16_t out[480]
175
+ /////
176
+ WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48);
177
+ }
178
+
179
+ // initialize state of 8 -> 48 resampler
180
+ void WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state)
181
+ {
182
+ memset(state->S_8_16, 0, 8 * sizeof(int32_t));
183
+ memset(state->S_16_12, 0, 8 * sizeof(int32_t));
184
+ memset(state->S_12_24, 0, 8 * sizeof(int32_t));
185
+ memset(state->S_24_48, 0, 8 * sizeof(int32_t));
186
+ }
@@ -0,0 +1,689 @@
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 header file contains some internal resampling functions.
14
+ *
15
+ */
16
+
17
+ #include "common_audio/signal_processing/resample_by_2_internal.h"
18
+ #include "rtc_base/sanitizer.h"
19
+
20
+ // allpass filter coefficients.
21
+ static const int16_t kResampleAllpass[2][3] = {
22
+ {821, 6110, 12382},
23
+ {3050, 9368, 15063}
24
+ };
25
+
26
+ //
27
+ // decimator
28
+ // input: int32_t (shifted 15 positions to the left, + offset 16384) OVERWRITTEN!
29
+ // output: int16_t (saturated) (of length len/2)
30
+ // state: filter state array; length = 8
31
+
32
+ void RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486
33
+ WebRtcSpl_DownBy2IntToShort(int32_t *in, int32_t len, int16_t *out,
34
+ int32_t *state)
35
+ {
36
+ int32_t tmp0, tmp1, diff;
37
+ int32_t i;
38
+
39
+ len >>= 1;
40
+
41
+ // lower allpass filter (operates on even input samples)
42
+ for (i = 0; i < len; i++)
43
+ {
44
+ tmp0 = in[i << 1];
45
+ diff = tmp0 - state[1];
46
+ // UBSan: -1771017321 - 999586185 cannot be represented in type 'int'
47
+
48
+ // scale down and round
49
+ diff = (diff + (1 << 13)) >> 14;
50
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
51
+ state[0] = tmp0;
52
+ diff = tmp1 - state[2];
53
+ // scale down and truncate
54
+ diff = diff >> 14;
55
+ if (diff < 0)
56
+ diff += 1;
57
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
58
+ state[1] = tmp1;
59
+ diff = tmp0 - state[3];
60
+ // scale down and truncate
61
+ diff = diff >> 14;
62
+ if (diff < 0)
63
+ diff += 1;
64
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
65
+ state[2] = tmp0;
66
+
67
+ // divide by two and store temporarily
68
+ in[i << 1] = (state[3] >> 1);
69
+ }
70
+
71
+ in++;
72
+
73
+ // upper allpass filter (operates on odd input samples)
74
+ for (i = 0; i < len; i++)
75
+ {
76
+ tmp0 = in[i << 1];
77
+ diff = tmp0 - state[5];
78
+ // scale down and round
79
+ diff = (diff + (1 << 13)) >> 14;
80
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
81
+ state[4] = tmp0;
82
+ diff = tmp1 - state[6];
83
+ // scale down and round
84
+ diff = diff >> 14;
85
+ if (diff < 0)
86
+ diff += 1;
87
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
88
+ state[5] = tmp1;
89
+ diff = tmp0 - state[7];
90
+ // scale down and truncate
91
+ diff = diff >> 14;
92
+ if (diff < 0)
93
+ diff += 1;
94
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
95
+ state[6] = tmp0;
96
+
97
+ // divide by two and store temporarily
98
+ in[i << 1] = (state[7] >> 1);
99
+ }
100
+
101
+ in--;
102
+
103
+ // combine allpass outputs
104
+ for (i = 0; i < len; i += 2)
105
+ {
106
+ // divide by two, add both allpass outputs and round
107
+ tmp0 = (in[i << 1] + in[(i << 1) + 1]) >> 15;
108
+ tmp1 = (in[(i << 1) + 2] + in[(i << 1) + 3]) >> 15;
109
+ if (tmp0 > (int32_t)0x00007FFF)
110
+ tmp0 = 0x00007FFF;
111
+ if (tmp0 < (int32_t)0xFFFF8000)
112
+ tmp0 = 0xFFFF8000;
113
+ out[i] = (int16_t)tmp0;
114
+ if (tmp1 > (int32_t)0x00007FFF)
115
+ tmp1 = 0x00007FFF;
116
+ if (tmp1 < (int32_t)0xFFFF8000)
117
+ tmp1 = 0xFFFF8000;
118
+ out[i + 1] = (int16_t)tmp1;
119
+ }
120
+ }
121
+
122
+ //
123
+ // decimator
124
+ // input: int16_t
125
+ // output: int32_t (shifted 15 positions to the left, + offset 16384) (of length len/2)
126
+ // state: filter state array; length = 8
127
+
128
+ void RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486
129
+ WebRtcSpl_DownBy2ShortToInt(const int16_t *in,
130
+ int32_t len,
131
+ int32_t *out,
132
+ int32_t *state)
133
+ {
134
+ int32_t tmp0, tmp1, diff;
135
+ int32_t i;
136
+
137
+ len >>= 1;
138
+
139
+ // lower allpass filter (operates on even input samples)
140
+ for (i = 0; i < len; i++)
141
+ {
142
+ tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
143
+ diff = tmp0 - state[1];
144
+ // scale down and round
145
+ diff = (diff + (1 << 13)) >> 14;
146
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
147
+ state[0] = tmp0;
148
+ diff = tmp1 - state[2];
149
+ // UBSan: -1379909682 - 834099714 cannot be represented in type 'int'
150
+
151
+ // scale down and truncate
152
+ diff = diff >> 14;
153
+ if (diff < 0)
154
+ diff += 1;
155
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
156
+ state[1] = tmp1;
157
+ diff = tmp0 - state[3];
158
+ // scale down and truncate
159
+ diff = diff >> 14;
160
+ if (diff < 0)
161
+ diff += 1;
162
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
163
+ state[2] = tmp0;
164
+
165
+ // divide by two and store temporarily
166
+ out[i] = (state[3] >> 1);
167
+ }
168
+
169
+ in++;
170
+
171
+ // upper allpass filter (operates on odd input samples)
172
+ for (i = 0; i < len; i++)
173
+ {
174
+ tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
175
+ diff = tmp0 - state[5];
176
+ // scale down and round
177
+ diff = (diff + (1 << 13)) >> 14;
178
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
179
+ state[4] = tmp0;
180
+ diff = tmp1 - state[6];
181
+ // scale down and round
182
+ diff = diff >> 14;
183
+ if (diff < 0)
184
+ diff += 1;
185
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
186
+ state[5] = tmp1;
187
+ diff = tmp0 - state[7];
188
+ // scale down and truncate
189
+ diff = diff >> 14;
190
+ if (diff < 0)
191
+ diff += 1;
192
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
193
+ state[6] = tmp0;
194
+
195
+ // divide by two and store temporarily
196
+ out[i] += (state[7] >> 1);
197
+ }
198
+
199
+ in--;
200
+ }
201
+
202
+ //
203
+ // interpolator
204
+ // input: int16_t
205
+ // output: int32_t (normalized, not saturated) (of length len*2)
206
+ // state: filter state array; length = 8
207
+ void WebRtcSpl_UpBy2ShortToInt(const int16_t *in, int32_t len, int32_t *out,
208
+ int32_t *state)
209
+ {
210
+ int32_t tmp0, tmp1, diff;
211
+ int32_t i;
212
+
213
+ // upper allpass filter (generates odd output samples)
214
+ for (i = 0; i < len; i++)
215
+ {
216
+ tmp0 = ((int32_t)in[i] << 15) + (1 << 14);
217
+ diff = tmp0 - state[5];
218
+ // scale down and round
219
+ diff = (diff + (1 << 13)) >> 14;
220
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
221
+ state[4] = tmp0;
222
+ diff = tmp1 - state[6];
223
+ // scale down and truncate
224
+ diff = diff >> 14;
225
+ if (diff < 0)
226
+ diff += 1;
227
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
228
+ state[5] = tmp1;
229
+ diff = tmp0 - state[7];
230
+ // scale down and truncate
231
+ diff = diff >> 14;
232
+ if (diff < 0)
233
+ diff += 1;
234
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
235
+ state[6] = tmp0;
236
+
237
+ // scale down, round and store
238
+ out[i << 1] = state[7] >> 15;
239
+ }
240
+
241
+ out++;
242
+
243
+ // lower allpass filter (generates even output samples)
244
+ for (i = 0; i < len; i++)
245
+ {
246
+ tmp0 = ((int32_t)in[i] << 15) + (1 << 14);
247
+ diff = tmp0 - state[1];
248
+ // scale down and round
249
+ diff = (diff + (1 << 13)) >> 14;
250
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
251
+ state[0] = tmp0;
252
+ diff = tmp1 - state[2];
253
+ // scale down and truncate
254
+ diff = diff >> 14;
255
+ if (diff < 0)
256
+ diff += 1;
257
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
258
+ state[1] = tmp1;
259
+ diff = tmp0 - state[3];
260
+ // scale down and truncate
261
+ diff = diff >> 14;
262
+ if (diff < 0)
263
+ diff += 1;
264
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
265
+ state[2] = tmp0;
266
+
267
+ // scale down, round and store
268
+ out[i << 1] = state[3] >> 15;
269
+ }
270
+ }
271
+
272
+ //
273
+ // interpolator
274
+ // input: int32_t (shifted 15 positions to the left, + offset 16384)
275
+ // output: int32_t (shifted 15 positions to the left, + offset 16384) (of length len*2)
276
+ // state: filter state array; length = 8
277
+ void WebRtcSpl_UpBy2IntToInt(const int32_t *in, int32_t len, int32_t *out,
278
+ int32_t *state)
279
+ {
280
+ int32_t tmp0, tmp1, diff;
281
+ int32_t i;
282
+
283
+ // upper allpass filter (generates odd output samples)
284
+ for (i = 0; i < len; i++)
285
+ {
286
+ tmp0 = in[i];
287
+ diff = tmp0 - state[5];
288
+ // scale down and round
289
+ diff = (diff + (1 << 13)) >> 14;
290
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
291
+ state[4] = tmp0;
292
+ diff = tmp1 - state[6];
293
+ // scale down and truncate
294
+ diff = diff >> 14;
295
+ if (diff < 0)
296
+ diff += 1;
297
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
298
+ state[5] = tmp1;
299
+ diff = tmp0 - state[7];
300
+ // scale down and truncate
301
+ diff = diff >> 14;
302
+ if (diff < 0)
303
+ diff += 1;
304
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
305
+ state[6] = tmp0;
306
+
307
+ // scale down, round and store
308
+ out[i << 1] = state[7];
309
+ }
310
+
311
+ out++;
312
+
313
+ // lower allpass filter (generates even output samples)
314
+ for (i = 0; i < len; i++)
315
+ {
316
+ tmp0 = in[i];
317
+ diff = tmp0 - state[1];
318
+ // scale down and round
319
+ diff = (diff + (1 << 13)) >> 14;
320
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
321
+ state[0] = tmp0;
322
+ diff = tmp1 - state[2];
323
+ // scale down and truncate
324
+ diff = diff >> 14;
325
+ if (diff < 0)
326
+ diff += 1;
327
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
328
+ state[1] = tmp1;
329
+ diff = tmp0 - state[3];
330
+ // scale down and truncate
331
+ diff = diff >> 14;
332
+ if (diff < 0)
333
+ diff += 1;
334
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
335
+ state[2] = tmp0;
336
+
337
+ // scale down, round and store
338
+ out[i << 1] = state[3];
339
+ }
340
+ }
341
+
342
+ //
343
+ // interpolator
344
+ // input: int32_t (shifted 15 positions to the left, + offset 16384)
345
+ // output: int16_t (saturated) (of length len*2)
346
+ // state: filter state array; length = 8
347
+ void WebRtcSpl_UpBy2IntToShort(const int32_t *in, int32_t len, int16_t *out,
348
+ int32_t *state)
349
+ {
350
+ int32_t tmp0, tmp1, diff;
351
+ int32_t i;
352
+
353
+ // upper allpass filter (generates odd output samples)
354
+ for (i = 0; i < len; i++)
355
+ {
356
+ tmp0 = in[i];
357
+ diff = tmp0 - state[5];
358
+ // scale down and round
359
+ diff = (diff + (1 << 13)) >> 14;
360
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
361
+ state[4] = tmp0;
362
+ diff = tmp1 - state[6];
363
+ // scale down and round
364
+ diff = diff >> 14;
365
+ if (diff < 0)
366
+ diff += 1;
367
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
368
+ state[5] = tmp1;
369
+ diff = tmp0 - state[7];
370
+ // scale down and truncate
371
+ diff = diff >> 14;
372
+ if (diff < 0)
373
+ diff += 1;
374
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
375
+ state[6] = tmp0;
376
+
377
+ // scale down, saturate and store
378
+ tmp1 = state[7] >> 15;
379
+ if (tmp1 > (int32_t)0x00007FFF)
380
+ tmp1 = 0x00007FFF;
381
+ if (tmp1 < (int32_t)0xFFFF8000)
382
+ tmp1 = 0xFFFF8000;
383
+ out[i << 1] = (int16_t)tmp1;
384
+ }
385
+
386
+ out++;
387
+
388
+ // lower allpass filter (generates even output samples)
389
+ for (i = 0; i < len; i++)
390
+ {
391
+ tmp0 = in[i];
392
+ diff = tmp0 - state[1];
393
+ // scale down and round
394
+ diff = (diff + (1 << 13)) >> 14;
395
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
396
+ state[0] = tmp0;
397
+ diff = tmp1 - state[2];
398
+ // scale down and truncate
399
+ diff = diff >> 14;
400
+ if (diff < 0)
401
+ diff += 1;
402
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
403
+ state[1] = tmp1;
404
+ diff = tmp0 - state[3];
405
+ // scale down and truncate
406
+ diff = diff >> 14;
407
+ if (diff < 0)
408
+ diff += 1;
409
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
410
+ state[2] = tmp0;
411
+
412
+ // scale down, saturate and store
413
+ tmp1 = state[3] >> 15;
414
+ if (tmp1 > (int32_t)0x00007FFF)
415
+ tmp1 = 0x00007FFF;
416
+ if (tmp1 < (int32_t)0xFFFF8000)
417
+ tmp1 = 0xFFFF8000;
418
+ out[i << 1] = (int16_t)tmp1;
419
+ }
420
+ }
421
+
422
+ // lowpass filter
423
+ // input: int16_t
424
+ // output: int32_t (normalized, not saturated)
425
+ // state: filter state array; length = 8
426
+ void WebRtcSpl_LPBy2ShortToInt(const int16_t* in, int32_t len, int32_t* out,
427
+ int32_t* state)
428
+ {
429
+ int32_t tmp0, tmp1, diff;
430
+ int32_t i;
431
+
432
+ len >>= 1;
433
+
434
+ // lower allpass filter: odd input -> even output samples
435
+ in++;
436
+ // initial state of polyphase delay element
437
+ tmp0 = state[12];
438
+ for (i = 0; i < len; i++)
439
+ {
440
+ diff = tmp0 - state[1];
441
+ // scale down and round
442
+ diff = (diff + (1 << 13)) >> 14;
443
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
444
+ state[0] = tmp0;
445
+ diff = tmp1 - state[2];
446
+ // scale down and truncate
447
+ diff = diff >> 14;
448
+ if (diff < 0)
449
+ diff += 1;
450
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
451
+ state[1] = tmp1;
452
+ diff = tmp0 - state[3];
453
+ // scale down and truncate
454
+ diff = diff >> 14;
455
+ if (diff < 0)
456
+ diff += 1;
457
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
458
+ state[2] = tmp0;
459
+
460
+ // scale down, round and store
461
+ out[i << 1] = state[3] >> 1;
462
+ tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
463
+ }
464
+ in--;
465
+
466
+ // upper allpass filter: even input -> even output samples
467
+ for (i = 0; i < len; i++)
468
+ {
469
+ tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
470
+ diff = tmp0 - state[5];
471
+ // scale down and round
472
+ diff = (diff + (1 << 13)) >> 14;
473
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
474
+ state[4] = tmp0;
475
+ diff = tmp1 - state[6];
476
+ // scale down and round
477
+ diff = diff >> 14;
478
+ if (diff < 0)
479
+ diff += 1;
480
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
481
+ state[5] = tmp1;
482
+ diff = tmp0 - state[7];
483
+ // scale down and truncate
484
+ diff = diff >> 14;
485
+ if (diff < 0)
486
+ diff += 1;
487
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
488
+ state[6] = tmp0;
489
+
490
+ // average the two allpass outputs, scale down and store
491
+ out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;
492
+ }
493
+
494
+ // switch to odd output samples
495
+ out++;
496
+
497
+ // lower allpass filter: even input -> odd output samples
498
+ for (i = 0; i < len; i++)
499
+ {
500
+ tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
501
+ diff = tmp0 - state[9];
502
+ // scale down and round
503
+ diff = (diff + (1 << 13)) >> 14;
504
+ tmp1 = state[8] + diff * kResampleAllpass[1][0];
505
+ state[8] = tmp0;
506
+ diff = tmp1 - state[10];
507
+ // scale down and truncate
508
+ diff = diff >> 14;
509
+ if (diff < 0)
510
+ diff += 1;
511
+ tmp0 = state[9] + diff * kResampleAllpass[1][1];
512
+ state[9] = tmp1;
513
+ diff = tmp0 - state[11];
514
+ // scale down and truncate
515
+ diff = diff >> 14;
516
+ if (diff < 0)
517
+ diff += 1;
518
+ state[11] = state[10] + diff * kResampleAllpass[1][2];
519
+ state[10] = tmp0;
520
+
521
+ // scale down, round and store
522
+ out[i << 1] = state[11] >> 1;
523
+ }
524
+
525
+ // upper allpass filter: odd input -> odd output samples
526
+ in++;
527
+ for (i = 0; i < len; i++)
528
+ {
529
+ tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
530
+ diff = tmp0 - state[13];
531
+ // scale down and round
532
+ diff = (diff + (1 << 13)) >> 14;
533
+ tmp1 = state[12] + diff * kResampleAllpass[0][0];
534
+ state[12] = tmp0;
535
+ diff = tmp1 - state[14];
536
+ // scale down and round
537
+ diff = diff >> 14;
538
+ if (diff < 0)
539
+ diff += 1;
540
+ tmp0 = state[13] + diff * kResampleAllpass[0][1];
541
+ state[13] = tmp1;
542
+ diff = tmp0 - state[15];
543
+ // scale down and truncate
544
+ diff = diff >> 14;
545
+ if (diff < 0)
546
+ diff += 1;
547
+ state[15] = state[14] + diff * kResampleAllpass[0][2];
548
+ state[14] = tmp0;
549
+
550
+ // average the two allpass outputs, scale down and store
551
+ out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;
552
+ }
553
+ }
554
+
555
+ // lowpass filter
556
+ // input: int32_t (shifted 15 positions to the left, + offset 16384)
557
+ // output: int32_t (normalized, not saturated)
558
+ // state: filter state array; length = 8
559
+ void RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486
560
+ WebRtcSpl_LPBy2IntToInt(const int32_t* in, int32_t len, int32_t* out,
561
+ int32_t* state)
562
+ {
563
+ int32_t tmp0, tmp1, diff;
564
+ int32_t i;
565
+
566
+ len >>= 1;
567
+
568
+ // lower allpass filter: odd input -> even output samples
569
+ in++;
570
+ // initial state of polyphase delay element
571
+ tmp0 = state[12];
572
+ for (i = 0; i < len; i++)
573
+ {
574
+ diff = tmp0 - state[1];
575
+ // scale down and round
576
+ diff = (diff + (1 << 13)) >> 14;
577
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
578
+ state[0] = tmp0;
579
+ diff = tmp1 - state[2];
580
+ // scale down and truncate
581
+ diff = diff >> 14;
582
+ if (diff < 0)
583
+ diff += 1;
584
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
585
+ state[1] = tmp1;
586
+ diff = tmp0 - state[3];
587
+ // scale down and truncate
588
+ diff = diff >> 14;
589
+ if (diff < 0)
590
+ diff += 1;
591
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
592
+ state[2] = tmp0;
593
+
594
+ // scale down, round and store
595
+ out[i << 1] = state[3] >> 1;
596
+ tmp0 = in[i << 1];
597
+ }
598
+ in--;
599
+
600
+ // upper allpass filter: even input -> even output samples
601
+ for (i = 0; i < len; i++)
602
+ {
603
+ tmp0 = in[i << 1];
604
+ diff = tmp0 - state[5];
605
+ // UBSan: -794814117 - 1566149201 cannot be represented in type 'int'
606
+
607
+ // scale down and round
608
+ diff = (diff + (1 << 13)) >> 14;
609
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
610
+ state[4] = tmp0;
611
+ diff = tmp1 - state[6];
612
+ // scale down and round
613
+ diff = diff >> 14;
614
+ if (diff < 0)
615
+ diff += 1;
616
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
617
+ state[5] = tmp1;
618
+ diff = tmp0 - state[7];
619
+ // scale down and truncate
620
+ diff = diff >> 14;
621
+ if (diff < 0)
622
+ diff += 1;
623
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
624
+ state[6] = tmp0;
625
+
626
+ // average the two allpass outputs, scale down and store
627
+ out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;
628
+ }
629
+
630
+ // switch to odd output samples
631
+ out++;
632
+
633
+ // lower allpass filter: even input -> odd output samples
634
+ for (i = 0; i < len; i++)
635
+ {
636
+ tmp0 = in[i << 1];
637
+ diff = tmp0 - state[9];
638
+ // scale down and round
639
+ diff = (diff + (1 << 13)) >> 14;
640
+ tmp1 = state[8] + diff * kResampleAllpass[1][0];
641
+ state[8] = tmp0;
642
+ diff = tmp1 - state[10];
643
+ // scale down and truncate
644
+ diff = diff >> 14;
645
+ if (diff < 0)
646
+ diff += 1;
647
+ tmp0 = state[9] + diff * kResampleAllpass[1][1];
648
+ state[9] = tmp1;
649
+ diff = tmp0 - state[11];
650
+ // scale down and truncate
651
+ diff = diff >> 14;
652
+ if (diff < 0)
653
+ diff += 1;
654
+ state[11] = state[10] + diff * kResampleAllpass[1][2];
655
+ state[10] = tmp0;
656
+
657
+ // scale down, round and store
658
+ out[i << 1] = state[11] >> 1;
659
+ }
660
+
661
+ // upper allpass filter: odd input -> odd output samples
662
+ in++;
663
+ for (i = 0; i < len; i++)
664
+ {
665
+ tmp0 = in[i << 1];
666
+ diff = tmp0 - state[13];
667
+ // scale down and round
668
+ diff = (diff + (1 << 13)) >> 14;
669
+ tmp1 = state[12] + diff * kResampleAllpass[0][0];
670
+ state[12] = tmp0;
671
+ diff = tmp1 - state[14];
672
+ // scale down and round
673
+ diff = diff >> 14;
674
+ if (diff < 0)
675
+ diff += 1;
676
+ tmp0 = state[13] + diff * kResampleAllpass[0][1];
677
+ state[13] = tmp1;
678
+ diff = tmp0 - state[15];
679
+ // scale down and truncate
680
+ diff = diff >> 14;
681
+ if (diff < 0)
682
+ diff += 1;
683
+ state[15] = state[14] + diff * kResampleAllpass[0][2];
684
+ state[14] = tmp0;
685
+
686
+ // average the two allpass outputs, scale down and store
687
+ out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;
688
+ }
689
+ }