webrtcvad 0.1.0 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/webrtcvad/extconf.rb +29 -0
- data/ext/webrtcvad/webrtc/common_audio/signal_processing/division_operations.c +141 -0
- data/ext/webrtcvad/webrtc/common_audio/signal_processing/dot_product_with_scale.h +40 -0
- data/ext/webrtcvad/webrtc/common_audio/signal_processing/energy.c +39 -0
- data/ext/webrtcvad/webrtc/common_audio/signal_processing/get_scaling_square.c +46 -0
- data/ext/webrtcvad/webrtc/common_audio/signal_processing/include/signal_processing_library.h +1605 -0
- data/ext/webrtcvad/webrtc/common_audio/signal_processing/include/spl_inl.h +153 -0
- data/ext/webrtcvad/webrtc/common_audio/signal_processing/resample_48khz.c +186 -0
- data/ext/webrtcvad/webrtc/common_audio/signal_processing/resample_by_2_internal.c +689 -0
- data/ext/webrtcvad/webrtc/common_audio/signal_processing/resample_by_2_internal.h +60 -0
- data/ext/webrtcvad/webrtc/common_audio/signal_processing/resample_fractional.c +239 -0
- data/ext/webrtcvad/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.c +77 -0
- data/ext/webrtcvad/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h +29 -0
- data/ext/webrtcvad/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor_mips.c +207 -0
- data/ext/webrtcvad/webrtc/common_audio/vad/include/webrtc_vad.h +87 -0
- data/ext/webrtcvad/webrtc/common_audio/vad/vad_core.c +685 -0
- data/ext/webrtcvad/webrtc/common_audio/vad/vad_core.h +114 -0
- data/ext/webrtcvad/webrtc/common_audio/vad/vad_filterbank.c +329 -0
- data/ext/webrtcvad/webrtc/common_audio/vad/vad_filterbank.h +45 -0
- data/ext/webrtcvad/webrtc/common_audio/vad/vad_gmm.c +82 -0
- data/ext/webrtcvad/webrtc/common_audio/vad/vad_gmm.h +39 -0
- data/ext/webrtcvad/webrtc/common_audio/vad/vad_sp.c +176 -0
- data/ext/webrtcvad/webrtc/common_audio/vad/vad_sp.h +54 -0
- data/ext/webrtcvad/webrtc/common_audio/vad/webrtc_vad.c +114 -0
- data/ext/webrtcvad/webrtc/rtc_base/checks.cc +207 -0
- data/ext/webrtcvad/webrtc/rtc_base/checks.h +400 -0
- data/ext/webrtcvad/webrtc/rtc_base/compile_assert_c.h +25 -0
- data/ext/webrtcvad/webrtc/rtc_base/numerics/safe_compare.h +176 -0
- data/ext/webrtcvad/webrtc/rtc_base/sanitizer.h +144 -0
- data/ext/webrtcvad/webrtc/rtc_base/system/inline.h +31 -0
- data/ext/webrtcvad/webrtc/rtc_base/system/rtc_export.h +43 -0
- data/ext/webrtcvad/webrtc/rtc_base/type_traits.h +140 -0
- data/ext/webrtcvad/webrtcvad.c +112 -0
- metadata +37 -3
@@ -0,0 +1,60 @@
|
|
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 contains some internal resampling functions.
|
13
|
+
*
|
14
|
+
*/
|
15
|
+
|
16
|
+
#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_RESAMPLE_BY_2_INTERNAL_H_
|
17
|
+
#define COMMON_AUDIO_SIGNAL_PROCESSING_RESAMPLE_BY_2_INTERNAL_H_
|
18
|
+
|
19
|
+
#include <stdint.h>
|
20
|
+
|
21
|
+
/*******************************************************************
|
22
|
+
* resample_by_2_fast.c
|
23
|
+
* Functions for internal use in the other resample functions
|
24
|
+
******************************************************************/
|
25
|
+
void WebRtcSpl_DownBy2IntToShort(int32_t* in,
|
26
|
+
int32_t len,
|
27
|
+
int16_t* out,
|
28
|
+
int32_t* state);
|
29
|
+
|
30
|
+
void WebRtcSpl_DownBy2ShortToInt(const int16_t* in,
|
31
|
+
int32_t len,
|
32
|
+
int32_t* out,
|
33
|
+
int32_t* state);
|
34
|
+
|
35
|
+
void WebRtcSpl_UpBy2ShortToInt(const int16_t* in,
|
36
|
+
int32_t len,
|
37
|
+
int32_t* out,
|
38
|
+
int32_t* state);
|
39
|
+
|
40
|
+
void WebRtcSpl_UpBy2IntToInt(const int32_t* in,
|
41
|
+
int32_t len,
|
42
|
+
int32_t* out,
|
43
|
+
int32_t* state);
|
44
|
+
|
45
|
+
void WebRtcSpl_UpBy2IntToShort(const int32_t* in,
|
46
|
+
int32_t len,
|
47
|
+
int16_t* out,
|
48
|
+
int32_t* state);
|
49
|
+
|
50
|
+
void WebRtcSpl_LPBy2ShortToInt(const int16_t* in,
|
51
|
+
int32_t len,
|
52
|
+
int32_t* out,
|
53
|
+
int32_t* state);
|
54
|
+
|
55
|
+
void WebRtcSpl_LPBy2IntToInt(const int32_t* in,
|
56
|
+
int32_t len,
|
57
|
+
int32_t* out,
|
58
|
+
int32_t* state);
|
59
|
+
|
60
|
+
#endif // COMMON_AUDIO_SIGNAL_PROCESSING_RESAMPLE_BY_2_INTERNAL_H_
|
@@ -0,0 +1,239 @@
|
|
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 the resampling functions between 48, 44, 32 and 24 kHz.
|
14
|
+
* The description headers can be found in signal_processing_library.h
|
15
|
+
*
|
16
|
+
*/
|
17
|
+
|
18
|
+
#include "common_audio/signal_processing/include/signal_processing_library.h"
|
19
|
+
|
20
|
+
// interpolation coefficients
|
21
|
+
static const int16_t kCoefficients48To32[2][8] = {
|
22
|
+
{778, -2050, 1087, 23285, 12903, -3783, 441, 222},
|
23
|
+
{222, 441, -3783, 12903, 23285, 1087, -2050, 778}
|
24
|
+
};
|
25
|
+
|
26
|
+
static const int16_t kCoefficients32To24[3][8] = {
|
27
|
+
{767, -2362, 2434, 24406, 10620, -3838, 721, 90},
|
28
|
+
{386, -381, -2646, 19062, 19062, -2646, -381, 386},
|
29
|
+
{90, 721, -3838, 10620, 24406, 2434, -2362, 767}
|
30
|
+
};
|
31
|
+
|
32
|
+
static const int16_t kCoefficients44To32[4][9] = {
|
33
|
+
{117, -669, 2245, -6183, 26267, 13529, -3245, 845, -138},
|
34
|
+
{-101, 612, -2283, 8532, 29790, -5138, 1789, -524, 91},
|
35
|
+
{50, -292, 1016, -3064, 32010, 3933, -1147, 315, -53},
|
36
|
+
{-156, 974, -3863, 18603, 21691, -6246, 2353, -712, 126}
|
37
|
+
};
|
38
|
+
|
39
|
+
// Resampling ratio: 2/3
|
40
|
+
// input: int32_t (normalized, not saturated) :: size 3 * K
|
41
|
+
// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 2 * K
|
42
|
+
// K: number of blocks
|
43
|
+
|
44
|
+
void WebRtcSpl_Resample48khzTo32khz(const int32_t *In, int32_t *Out, size_t K)
|
45
|
+
{
|
46
|
+
/////////////////////////////////////////////////////////////
|
47
|
+
// Filter operation:
|
48
|
+
//
|
49
|
+
// Perform resampling (3 input samples -> 2 output samples);
|
50
|
+
// process in sub blocks of size 3 samples.
|
51
|
+
int32_t tmp;
|
52
|
+
size_t m;
|
53
|
+
|
54
|
+
for (m = 0; m < K; m++)
|
55
|
+
{
|
56
|
+
tmp = 1 << 14;
|
57
|
+
tmp += kCoefficients48To32[0][0] * In[0];
|
58
|
+
tmp += kCoefficients48To32[0][1] * In[1];
|
59
|
+
tmp += kCoefficients48To32[0][2] * In[2];
|
60
|
+
tmp += kCoefficients48To32[0][3] * In[3];
|
61
|
+
tmp += kCoefficients48To32[0][4] * In[4];
|
62
|
+
tmp += kCoefficients48To32[0][5] * In[5];
|
63
|
+
tmp += kCoefficients48To32[0][6] * In[6];
|
64
|
+
tmp += kCoefficients48To32[0][7] * In[7];
|
65
|
+
Out[0] = tmp;
|
66
|
+
|
67
|
+
tmp = 1 << 14;
|
68
|
+
tmp += kCoefficients48To32[1][0] * In[1];
|
69
|
+
tmp += kCoefficients48To32[1][1] * In[2];
|
70
|
+
tmp += kCoefficients48To32[1][2] * In[3];
|
71
|
+
tmp += kCoefficients48To32[1][3] * In[4];
|
72
|
+
tmp += kCoefficients48To32[1][4] * In[5];
|
73
|
+
tmp += kCoefficients48To32[1][5] * In[6];
|
74
|
+
tmp += kCoefficients48To32[1][6] * In[7];
|
75
|
+
tmp += kCoefficients48To32[1][7] * In[8];
|
76
|
+
Out[1] = tmp;
|
77
|
+
|
78
|
+
// update pointers
|
79
|
+
In += 3;
|
80
|
+
Out += 2;
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
// Resampling ratio: 3/4
|
85
|
+
// input: int32_t (normalized, not saturated) :: size 4 * K
|
86
|
+
// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 3 * K
|
87
|
+
// K: number of blocks
|
88
|
+
|
89
|
+
void WebRtcSpl_Resample32khzTo24khz(const int32_t *In, int32_t *Out, size_t K)
|
90
|
+
{
|
91
|
+
/////////////////////////////////////////////////////////////
|
92
|
+
// Filter operation:
|
93
|
+
//
|
94
|
+
// Perform resampling (4 input samples -> 3 output samples);
|
95
|
+
// process in sub blocks of size 4 samples.
|
96
|
+
size_t m;
|
97
|
+
int32_t tmp;
|
98
|
+
|
99
|
+
for (m = 0; m < K; m++)
|
100
|
+
{
|
101
|
+
tmp = 1 << 14;
|
102
|
+
tmp += kCoefficients32To24[0][0] * In[0];
|
103
|
+
tmp += kCoefficients32To24[0][1] * In[1];
|
104
|
+
tmp += kCoefficients32To24[0][2] * In[2];
|
105
|
+
tmp += kCoefficients32To24[0][3] * In[3];
|
106
|
+
tmp += kCoefficients32To24[0][4] * In[4];
|
107
|
+
tmp += kCoefficients32To24[0][5] * In[5];
|
108
|
+
tmp += kCoefficients32To24[0][6] * In[6];
|
109
|
+
tmp += kCoefficients32To24[0][7] * In[7];
|
110
|
+
Out[0] = tmp;
|
111
|
+
|
112
|
+
tmp = 1 << 14;
|
113
|
+
tmp += kCoefficients32To24[1][0] * In[1];
|
114
|
+
tmp += kCoefficients32To24[1][1] * In[2];
|
115
|
+
tmp += kCoefficients32To24[1][2] * In[3];
|
116
|
+
tmp += kCoefficients32To24[1][3] * In[4];
|
117
|
+
tmp += kCoefficients32To24[1][4] * In[5];
|
118
|
+
tmp += kCoefficients32To24[1][5] * In[6];
|
119
|
+
tmp += kCoefficients32To24[1][6] * In[7];
|
120
|
+
tmp += kCoefficients32To24[1][7] * In[8];
|
121
|
+
Out[1] = tmp;
|
122
|
+
|
123
|
+
tmp = 1 << 14;
|
124
|
+
tmp += kCoefficients32To24[2][0] * In[2];
|
125
|
+
tmp += kCoefficients32To24[2][1] * In[3];
|
126
|
+
tmp += kCoefficients32To24[2][2] * In[4];
|
127
|
+
tmp += kCoefficients32To24[2][3] * In[5];
|
128
|
+
tmp += kCoefficients32To24[2][4] * In[6];
|
129
|
+
tmp += kCoefficients32To24[2][5] * In[7];
|
130
|
+
tmp += kCoefficients32To24[2][6] * In[8];
|
131
|
+
tmp += kCoefficients32To24[2][7] * In[9];
|
132
|
+
Out[2] = tmp;
|
133
|
+
|
134
|
+
// update pointers
|
135
|
+
In += 4;
|
136
|
+
Out += 3;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
//
|
141
|
+
// fractional resampling filters
|
142
|
+
// Fout = 11/16 * Fin
|
143
|
+
// Fout = 8/11 * Fin
|
144
|
+
//
|
145
|
+
|
146
|
+
// compute two inner-products and store them to output array
|
147
|
+
static void WebRtcSpl_ResampDotProduct(const int32_t *in1, const int32_t *in2,
|
148
|
+
const int16_t *coef_ptr, int32_t *out1,
|
149
|
+
int32_t *out2)
|
150
|
+
{
|
151
|
+
int32_t tmp1 = 16384;
|
152
|
+
int32_t tmp2 = 16384;
|
153
|
+
int16_t coef;
|
154
|
+
|
155
|
+
coef = coef_ptr[0];
|
156
|
+
tmp1 += coef * in1[0];
|
157
|
+
tmp2 += coef * in2[-0];
|
158
|
+
|
159
|
+
coef = coef_ptr[1];
|
160
|
+
tmp1 += coef * in1[1];
|
161
|
+
tmp2 += coef * in2[-1];
|
162
|
+
|
163
|
+
coef = coef_ptr[2];
|
164
|
+
tmp1 += coef * in1[2];
|
165
|
+
tmp2 += coef * in2[-2];
|
166
|
+
|
167
|
+
coef = coef_ptr[3];
|
168
|
+
tmp1 += coef * in1[3];
|
169
|
+
tmp2 += coef * in2[-3];
|
170
|
+
|
171
|
+
coef = coef_ptr[4];
|
172
|
+
tmp1 += coef * in1[4];
|
173
|
+
tmp2 += coef * in2[-4];
|
174
|
+
|
175
|
+
coef = coef_ptr[5];
|
176
|
+
tmp1 += coef * in1[5];
|
177
|
+
tmp2 += coef * in2[-5];
|
178
|
+
|
179
|
+
coef = coef_ptr[6];
|
180
|
+
tmp1 += coef * in1[6];
|
181
|
+
tmp2 += coef * in2[-6];
|
182
|
+
|
183
|
+
coef = coef_ptr[7];
|
184
|
+
tmp1 += coef * in1[7];
|
185
|
+
tmp2 += coef * in2[-7];
|
186
|
+
|
187
|
+
coef = coef_ptr[8];
|
188
|
+
*out1 = tmp1 + coef * in1[8];
|
189
|
+
*out2 = tmp2 + coef * in2[-8];
|
190
|
+
}
|
191
|
+
|
192
|
+
// Resampling ratio: 8/11
|
193
|
+
// input: int32_t (normalized, not saturated) :: size 11 * K
|
194
|
+
// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 8 * K
|
195
|
+
// K: number of blocks
|
196
|
+
|
197
|
+
void WebRtcSpl_Resample44khzTo32khz(const int32_t *In, int32_t *Out, size_t K)
|
198
|
+
{
|
199
|
+
/////////////////////////////////////////////////////////////
|
200
|
+
// Filter operation:
|
201
|
+
//
|
202
|
+
// Perform resampling (11 input samples -> 8 output samples);
|
203
|
+
// process in sub blocks of size 11 samples.
|
204
|
+
int32_t tmp;
|
205
|
+
size_t m;
|
206
|
+
|
207
|
+
for (m = 0; m < K; m++)
|
208
|
+
{
|
209
|
+
tmp = 1 << 14;
|
210
|
+
|
211
|
+
// first output sample
|
212
|
+
Out[0] = ((int32_t)In[3] << 15) + tmp;
|
213
|
+
|
214
|
+
// sum and accumulate filter coefficients and input samples
|
215
|
+
tmp += kCoefficients44To32[3][0] * In[5];
|
216
|
+
tmp += kCoefficients44To32[3][1] * In[6];
|
217
|
+
tmp += kCoefficients44To32[3][2] * In[7];
|
218
|
+
tmp += kCoefficients44To32[3][3] * In[8];
|
219
|
+
tmp += kCoefficients44To32[3][4] * In[9];
|
220
|
+
tmp += kCoefficients44To32[3][5] * In[10];
|
221
|
+
tmp += kCoefficients44To32[3][6] * In[11];
|
222
|
+
tmp += kCoefficients44To32[3][7] * In[12];
|
223
|
+
tmp += kCoefficients44To32[3][8] * In[13];
|
224
|
+
Out[4] = tmp;
|
225
|
+
|
226
|
+
// sum and accumulate filter coefficients and input samples
|
227
|
+
WebRtcSpl_ResampDotProduct(&In[0], &In[17], kCoefficients44To32[0], &Out[1], &Out[7]);
|
228
|
+
|
229
|
+
// sum and accumulate filter coefficients and input samples
|
230
|
+
WebRtcSpl_ResampDotProduct(&In[2], &In[15], kCoefficients44To32[1], &Out[2], &Out[6]);
|
231
|
+
|
232
|
+
// sum and accumulate filter coefficients and input samples
|
233
|
+
WebRtcSpl_ResampDotProduct(&In[3], &In[14], kCoefficients44To32[2], &Out[3], &Out[5]);
|
234
|
+
|
235
|
+
// update pointers
|
236
|
+
In += 11;
|
237
|
+
Out += 8;
|
238
|
+
}
|
239
|
+
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
/*
|
2
|
+
* Written by Wilco Dijkstra, 1996. The following email exchange establishes the
|
3
|
+
* license.
|
4
|
+
*
|
5
|
+
* From: Wilco Dijkstra <Wilco.Dijkstra@ntlworld.com>
|
6
|
+
* Date: Fri, Jun 24, 2011 at 3:20 AM
|
7
|
+
* Subject: Re: sqrt routine
|
8
|
+
* To: Kevin Ma <kma@google.com>
|
9
|
+
* Hi Kevin,
|
10
|
+
* Thanks for asking. Those routines are public domain (originally posted to
|
11
|
+
* comp.sys.arm a long time ago), so you can use them freely for any purpose.
|
12
|
+
* Cheers,
|
13
|
+
* Wilco
|
14
|
+
*
|
15
|
+
* ----- Original Message -----
|
16
|
+
* From: "Kevin Ma" <kma@google.com>
|
17
|
+
* To: <Wilco.Dijkstra@ntlworld.com>
|
18
|
+
* Sent: Thursday, June 23, 2011 11:44 PM
|
19
|
+
* Subject: Fwd: sqrt routine
|
20
|
+
* Hi Wilco,
|
21
|
+
* I saw your sqrt routine from several web sites, including
|
22
|
+
* http://www.finesse.demon.co.uk/steven/sqrt.html.
|
23
|
+
* Just wonder if there's any copyright information with your Successive
|
24
|
+
* approximation routines, or if I can freely use it for any purpose.
|
25
|
+
* Thanks.
|
26
|
+
* Kevin
|
27
|
+
*/
|
28
|
+
|
29
|
+
// Minor modifications in code style for WebRTC, 2012.
|
30
|
+
|
31
|
+
#include "common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h"
|
32
|
+
|
33
|
+
/*
|
34
|
+
* Algorithm:
|
35
|
+
* Successive approximation of the equation (root + delta) ^ 2 = N
|
36
|
+
* until delta < 1. If delta < 1 we have the integer part of SQRT (N).
|
37
|
+
* Use delta = 2^i for i = 15 .. 0.
|
38
|
+
*
|
39
|
+
* Output precision is 16 bits. Note for large input values (close to
|
40
|
+
* 0x7FFFFFFF), bit 15 (the highest bit of the low 16-bit half word)
|
41
|
+
* contains the MSB information (a non-sign value). Do with caution
|
42
|
+
* if you need to cast the output to int16_t type.
|
43
|
+
*
|
44
|
+
* If the input value is negative, it returns 0.
|
45
|
+
*/
|
46
|
+
|
47
|
+
#define WEBRTC_SPL_SQRT_ITER(N) \
|
48
|
+
try1 = root + (1 << (N)); \
|
49
|
+
if (value >= try1 << (N)) \
|
50
|
+
{ \
|
51
|
+
value -= try1 << (N); \
|
52
|
+
root |= 2 << (N); \
|
53
|
+
}
|
54
|
+
|
55
|
+
int32_t WebRtcSpl_SqrtFloor(int32_t value)
|
56
|
+
{
|
57
|
+
int32_t root = 0, try1;
|
58
|
+
|
59
|
+
WEBRTC_SPL_SQRT_ITER (15);
|
60
|
+
WEBRTC_SPL_SQRT_ITER (14);
|
61
|
+
WEBRTC_SPL_SQRT_ITER (13);
|
62
|
+
WEBRTC_SPL_SQRT_ITER (12);
|
63
|
+
WEBRTC_SPL_SQRT_ITER (11);
|
64
|
+
WEBRTC_SPL_SQRT_ITER (10);
|
65
|
+
WEBRTC_SPL_SQRT_ITER ( 9);
|
66
|
+
WEBRTC_SPL_SQRT_ITER ( 8);
|
67
|
+
WEBRTC_SPL_SQRT_ITER ( 7);
|
68
|
+
WEBRTC_SPL_SQRT_ITER ( 6);
|
69
|
+
WEBRTC_SPL_SQRT_ITER ( 5);
|
70
|
+
WEBRTC_SPL_SQRT_ITER ( 4);
|
71
|
+
WEBRTC_SPL_SQRT_ITER ( 3);
|
72
|
+
WEBRTC_SPL_SQRT_ITER ( 2);
|
73
|
+
WEBRTC_SPL_SQRT_ITER ( 1);
|
74
|
+
WEBRTC_SPL_SQRT_ITER ( 0);
|
75
|
+
|
76
|
+
return root >> 1;
|
77
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2018 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
|
+
#include <stdint.h>
|
12
|
+
|
13
|
+
//
|
14
|
+
// WebRtcSpl_SqrtFloor(...)
|
15
|
+
//
|
16
|
+
// Returns the square root of the input value |value|. The precision of this
|
17
|
+
// function is rounding down integer precision, i.e., sqrt(8) gives 2 as answer.
|
18
|
+
// If |value| is a negative number then 0 is returned.
|
19
|
+
//
|
20
|
+
// Algorithm:
|
21
|
+
//
|
22
|
+
// An iterative 4 cylce/bit routine
|
23
|
+
//
|
24
|
+
// Input:
|
25
|
+
// - value : Value to calculate sqrt of
|
26
|
+
//
|
27
|
+
// Return value : Result of the sqrt calculation
|
28
|
+
//
|
29
|
+
int32_t WebRtcSpl_SqrtFloor(int32_t value);
|
@@ -0,0 +1,207 @@
|
|
1
|
+
/*
|
2
|
+
* Written by Wilco Dijkstra, 1996. The following email exchange establishes the
|
3
|
+
* license.
|
4
|
+
*
|
5
|
+
* From: Wilco Dijkstra <Wilco.Dijkstra@ntlworld.com>
|
6
|
+
* Date: Fri, Jun 24, 2011 at 3:20 AM
|
7
|
+
* Subject: Re: sqrt routine
|
8
|
+
* To: Kevin Ma <kma@google.com>
|
9
|
+
* Hi Kevin,
|
10
|
+
* Thanks for asking. Those routines are public domain (originally posted to
|
11
|
+
* comp.sys.arm a long time ago), so you can use them freely for any purpose.
|
12
|
+
* Cheers,
|
13
|
+
* Wilco
|
14
|
+
*
|
15
|
+
* ----- Original Message -----
|
16
|
+
* From: "Kevin Ma" <kma@google.com>
|
17
|
+
* To: <Wilco.Dijkstra@ntlworld.com>
|
18
|
+
* Sent: Thursday, June 23, 2011 11:44 PM
|
19
|
+
* Subject: Fwd: sqrt routine
|
20
|
+
* Hi Wilco,
|
21
|
+
* I saw your sqrt routine from several web sites, including
|
22
|
+
* http://www.finesse.demon.co.uk/steven/sqrt.html.
|
23
|
+
* Just wonder if there's any copyright information with your Successive
|
24
|
+
* approximation routines, or if I can freely use it for any purpose.
|
25
|
+
* Thanks.
|
26
|
+
* Kevin
|
27
|
+
*/
|
28
|
+
|
29
|
+
// Minor modifications in code style for WebRTC, 2012.
|
30
|
+
// Code optimizations for MIPS, 2013.
|
31
|
+
|
32
|
+
#include "common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h"
|
33
|
+
|
34
|
+
/*
|
35
|
+
* Algorithm:
|
36
|
+
* Successive approximation of the equation (root + delta) ^ 2 = N
|
37
|
+
* until delta < 1. If delta < 1 we have the integer part of SQRT (N).
|
38
|
+
* Use delta = 2^i for i = 15 .. 0.
|
39
|
+
*
|
40
|
+
* Output precision is 16 bits. Note for large input values (close to
|
41
|
+
* 0x7FFFFFFF), bit 15 (the highest bit of the low 16-bit half word)
|
42
|
+
* contains the MSB information (a non-sign value). Do with caution
|
43
|
+
* if you need to cast the output to int16_t type.
|
44
|
+
*
|
45
|
+
* If the input value is negative, it returns 0.
|
46
|
+
*/
|
47
|
+
|
48
|
+
|
49
|
+
int32_t WebRtcSpl_SqrtFloor(int32_t value)
|
50
|
+
{
|
51
|
+
int32_t root = 0, tmp1, tmp2, tmp3, tmp4;
|
52
|
+
|
53
|
+
__asm __volatile(
|
54
|
+
".set push \n\t"
|
55
|
+
".set noreorder \n\t"
|
56
|
+
|
57
|
+
"lui %[tmp1], 0x4000 \n\t"
|
58
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
59
|
+
"sub %[tmp3], %[value], %[tmp1] \n\t"
|
60
|
+
"lui %[tmp1], 0x1 \n\t"
|
61
|
+
"or %[tmp4], %[root], %[tmp1] \n\t"
|
62
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
63
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
64
|
+
|
65
|
+
"addiu %[tmp1], $0, 0x4000 \n\t"
|
66
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
67
|
+
"sll %[tmp1], 14 \n\t"
|
68
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
69
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
70
|
+
"ori %[tmp4], %[root], 0x8000 \n\t"
|
71
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
72
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
73
|
+
|
74
|
+
"addiu %[tmp1], $0, 0x2000 \n\t"
|
75
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
76
|
+
"sll %[tmp1], 13 \n\t"
|
77
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
78
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
79
|
+
"ori %[tmp4], %[root], 0x4000 \n\t"
|
80
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
81
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
82
|
+
|
83
|
+
"addiu %[tmp1], $0, 0x1000 \n\t"
|
84
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
85
|
+
"sll %[tmp1], 12 \n\t"
|
86
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
87
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
88
|
+
"ori %[tmp4], %[root], 0x2000 \n\t"
|
89
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
90
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
91
|
+
|
92
|
+
"addiu %[tmp1], $0, 0x800 \n\t"
|
93
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
94
|
+
"sll %[tmp1], 11 \n\t"
|
95
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
96
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
97
|
+
"ori %[tmp4], %[root], 0x1000 \n\t"
|
98
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
99
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
100
|
+
|
101
|
+
"addiu %[tmp1], $0, 0x400 \n\t"
|
102
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
103
|
+
"sll %[tmp1], 10 \n\t"
|
104
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
105
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
106
|
+
"ori %[tmp4], %[root], 0x800 \n\t"
|
107
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
108
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
109
|
+
|
110
|
+
"addiu %[tmp1], $0, 0x200 \n\t"
|
111
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
112
|
+
"sll %[tmp1], 9 \n\t"
|
113
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
114
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
115
|
+
"ori %[tmp4], %[root], 0x400 \n\t"
|
116
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
117
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
118
|
+
|
119
|
+
"addiu %[tmp1], $0, 0x100 \n\t"
|
120
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
121
|
+
"sll %[tmp1], 8 \n\t"
|
122
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
123
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
124
|
+
"ori %[tmp4], %[root], 0x200 \n\t"
|
125
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
126
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
127
|
+
|
128
|
+
"addiu %[tmp1], $0, 0x80 \n\t"
|
129
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
130
|
+
"sll %[tmp1], 7 \n\t"
|
131
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
132
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
133
|
+
"ori %[tmp4], %[root], 0x100 \n\t"
|
134
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
135
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
136
|
+
|
137
|
+
"addiu %[tmp1], $0, 0x40 \n\t"
|
138
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
139
|
+
"sll %[tmp1], 6 \n\t"
|
140
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
141
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
142
|
+
"ori %[tmp4], %[root], 0x80 \n\t"
|
143
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
144
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
145
|
+
|
146
|
+
"addiu %[tmp1], $0, 0x20 \n\t"
|
147
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
148
|
+
"sll %[tmp1], 5 \n\t"
|
149
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
150
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
151
|
+
"ori %[tmp4], %[root], 0x40 \n\t"
|
152
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
153
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
154
|
+
|
155
|
+
"addiu %[tmp1], $0, 0x10 \n\t"
|
156
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
157
|
+
"sll %[tmp1], 4 \n\t"
|
158
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
159
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
160
|
+
"ori %[tmp4], %[root], 0x20 \n\t"
|
161
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
162
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
163
|
+
|
164
|
+
"addiu %[tmp1], $0, 0x8 \n\t"
|
165
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
166
|
+
"sll %[tmp1], 3 \n\t"
|
167
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
168
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
169
|
+
"ori %[tmp4], %[root], 0x10 \n\t"
|
170
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
171
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
172
|
+
|
173
|
+
"addiu %[tmp1], $0, 0x4 \n\t"
|
174
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
175
|
+
"sll %[tmp1], 2 \n\t"
|
176
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
177
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
178
|
+
"ori %[tmp4], %[root], 0x8 \n\t"
|
179
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
180
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
181
|
+
|
182
|
+
"addiu %[tmp1], $0, 0x2 \n\t"
|
183
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
184
|
+
"sll %[tmp1], 1 \n\t"
|
185
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
186
|
+
"subu %[tmp3], %[value], %[tmp1] \n\t"
|
187
|
+
"ori %[tmp4], %[root], 0x4 \n\t"
|
188
|
+
"movz %[value], %[tmp3], %[tmp2] \n\t"
|
189
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
190
|
+
|
191
|
+
"addiu %[tmp1], $0, 0x1 \n\t"
|
192
|
+
"addu %[tmp1], %[tmp1], %[root] \n\t"
|
193
|
+
"slt %[tmp2], %[value], %[tmp1] \n\t"
|
194
|
+
"ori %[tmp4], %[root], 0x2 \n\t"
|
195
|
+
"movz %[root], %[tmp4], %[tmp2] \n\t"
|
196
|
+
|
197
|
+
".set pop \n\t"
|
198
|
+
|
199
|
+
: [root] "+r" (root), [value] "+r" (value),
|
200
|
+
[tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2),
|
201
|
+
[tmp3] "=&r" (tmp3), [tmp4] "=&r" (tmp4)
|
202
|
+
:
|
203
|
+
);
|
204
|
+
|
205
|
+
return root >> 1;
|
206
|
+
}
|
207
|
+
|