1 | /* |
2 | * Copyright (C) 2012 Intel Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * |
8 | * 1. Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. |
10 | * 2. Redistributions in binary form must reproduce the above copyright |
11 | * notice, this list of conditions and the following disclaimer in the |
12 | * documentation and/or other materials provided with the distribution. |
13 | * 3. Neither the name of Apple Inc. ("Apple") nor the names of |
14 | * its contributors may be used to endorse or promote products derived |
15 | * from this software without specific prior written permission. |
16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
18 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
20 | * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
28 | |
29 | #include "config.h" |
30 | |
31 | #if ENABLE(WEB_AUDIO) |
32 | |
33 | #include "DirectConvolver.h" |
34 | |
35 | #if OS(DARWIN) |
36 | #include <Accelerate/Accelerate.h> |
37 | #endif |
38 | |
39 | #include "VectorMath.h" |
40 | |
41 | namespace WebCore { |
42 | |
43 | using namespace VectorMath; |
44 | |
45 | DirectConvolver::DirectConvolver(size_t inputBlockSize) |
46 | : m_inputBlockSize(inputBlockSize) |
47 | , m_buffer(inputBlockSize * 2) |
48 | { |
49 | } |
50 | |
51 | void DirectConvolver::process(AudioFloatArray* convolutionKernel, const float* sourceP, float* destP, size_t framesToProcess) |
52 | { |
53 | ASSERT(framesToProcess == m_inputBlockSize); |
54 | if (framesToProcess != m_inputBlockSize) |
55 | return; |
56 | |
57 | // Only support kernelSize <= m_inputBlockSize |
58 | size_t kernelSize = convolutionKernel->size(); |
59 | ASSERT(kernelSize <= m_inputBlockSize); |
60 | if (kernelSize > m_inputBlockSize) |
61 | return; |
62 | |
63 | float* kernelP = convolutionKernel->data(); |
64 | |
65 | // Sanity check |
66 | bool isCopyGood = kernelP && sourceP && destP && m_buffer.data(); |
67 | ASSERT(isCopyGood); |
68 | if (!isCopyGood) |
69 | return; |
70 | |
71 | float* inputP = m_buffer.data() + m_inputBlockSize; |
72 | |
73 | // Copy samples to 2nd half of input buffer. |
74 | memcpy(inputP, sourceP, sizeof(float) * framesToProcess); |
75 | |
76 | #if USE(ACCELERATE) |
77 | vDSP_conv(inputP - kernelSize + 1, 1, kernelP + kernelSize - 1, -1, destP, 1, framesToProcess, kernelSize); |
78 | #else |
79 | // FIXME: The macro can be further optimized to avoid pipeline stalls. One possibility is to maintain 4 separate sums and change the macro to CONVOLVE_FOUR_SAMPLES. |
80 | #define CONVOLVE_ONE_SAMPLE \ |
81 | sum += inputP[i - j] * kernelP[j]; \ |
82 | j++; |
83 | |
84 | size_t i = 0; |
85 | while (i < framesToProcess) { |
86 | size_t j = 0; |
87 | float sum = 0; |
88 | |
89 | // FIXME: SSE optimization may be applied here. |
90 | if (kernelSize == 32) { |
91 | CONVOLVE_ONE_SAMPLE // 1 |
92 | CONVOLVE_ONE_SAMPLE // 2 |
93 | CONVOLVE_ONE_SAMPLE // 3 |
94 | CONVOLVE_ONE_SAMPLE // 4 |
95 | CONVOLVE_ONE_SAMPLE // 5 |
96 | CONVOLVE_ONE_SAMPLE // 6 |
97 | CONVOLVE_ONE_SAMPLE // 7 |
98 | CONVOLVE_ONE_SAMPLE // 8 |
99 | CONVOLVE_ONE_SAMPLE // 9 |
100 | CONVOLVE_ONE_SAMPLE // 10 |
101 | |
102 | CONVOLVE_ONE_SAMPLE // 11 |
103 | CONVOLVE_ONE_SAMPLE // 12 |
104 | CONVOLVE_ONE_SAMPLE // 13 |
105 | CONVOLVE_ONE_SAMPLE // 14 |
106 | CONVOLVE_ONE_SAMPLE // 15 |
107 | CONVOLVE_ONE_SAMPLE // 16 |
108 | CONVOLVE_ONE_SAMPLE // 17 |
109 | CONVOLVE_ONE_SAMPLE // 18 |
110 | CONVOLVE_ONE_SAMPLE // 19 |
111 | CONVOLVE_ONE_SAMPLE // 20 |
112 | |
113 | CONVOLVE_ONE_SAMPLE // 21 |
114 | CONVOLVE_ONE_SAMPLE // 22 |
115 | CONVOLVE_ONE_SAMPLE // 23 |
116 | CONVOLVE_ONE_SAMPLE // 24 |
117 | CONVOLVE_ONE_SAMPLE // 25 |
118 | CONVOLVE_ONE_SAMPLE // 26 |
119 | CONVOLVE_ONE_SAMPLE // 27 |
120 | CONVOLVE_ONE_SAMPLE // 28 |
121 | CONVOLVE_ONE_SAMPLE // 29 |
122 | CONVOLVE_ONE_SAMPLE // 30 |
123 | |
124 | CONVOLVE_ONE_SAMPLE // 31 |
125 | CONVOLVE_ONE_SAMPLE // 32 |
126 | |
127 | } else if (kernelSize == 64) { |
128 | CONVOLVE_ONE_SAMPLE // 1 |
129 | CONVOLVE_ONE_SAMPLE // 2 |
130 | CONVOLVE_ONE_SAMPLE // 3 |
131 | CONVOLVE_ONE_SAMPLE // 4 |
132 | CONVOLVE_ONE_SAMPLE // 5 |
133 | CONVOLVE_ONE_SAMPLE // 6 |
134 | CONVOLVE_ONE_SAMPLE // 7 |
135 | CONVOLVE_ONE_SAMPLE // 8 |
136 | CONVOLVE_ONE_SAMPLE // 9 |
137 | CONVOLVE_ONE_SAMPLE // 10 |
138 | |
139 | CONVOLVE_ONE_SAMPLE // 11 |
140 | CONVOLVE_ONE_SAMPLE // 12 |
141 | CONVOLVE_ONE_SAMPLE // 13 |
142 | CONVOLVE_ONE_SAMPLE // 14 |
143 | CONVOLVE_ONE_SAMPLE // 15 |
144 | CONVOLVE_ONE_SAMPLE // 16 |
145 | CONVOLVE_ONE_SAMPLE // 17 |
146 | CONVOLVE_ONE_SAMPLE // 18 |
147 | CONVOLVE_ONE_SAMPLE // 19 |
148 | CONVOLVE_ONE_SAMPLE // 20 |
149 | |
150 | CONVOLVE_ONE_SAMPLE // 21 |
151 | CONVOLVE_ONE_SAMPLE // 22 |
152 | CONVOLVE_ONE_SAMPLE // 23 |
153 | CONVOLVE_ONE_SAMPLE // 24 |
154 | CONVOLVE_ONE_SAMPLE // 25 |
155 | CONVOLVE_ONE_SAMPLE // 26 |
156 | CONVOLVE_ONE_SAMPLE // 27 |
157 | CONVOLVE_ONE_SAMPLE // 28 |
158 | CONVOLVE_ONE_SAMPLE // 29 |
159 | CONVOLVE_ONE_SAMPLE // 30 |
160 | |
161 | CONVOLVE_ONE_SAMPLE // 31 |
162 | CONVOLVE_ONE_SAMPLE // 32 |
163 | CONVOLVE_ONE_SAMPLE // 33 |
164 | CONVOLVE_ONE_SAMPLE // 34 |
165 | CONVOLVE_ONE_SAMPLE // 35 |
166 | CONVOLVE_ONE_SAMPLE // 36 |
167 | CONVOLVE_ONE_SAMPLE // 37 |
168 | CONVOLVE_ONE_SAMPLE // 38 |
169 | CONVOLVE_ONE_SAMPLE // 39 |
170 | CONVOLVE_ONE_SAMPLE // 40 |
171 | |
172 | CONVOLVE_ONE_SAMPLE // 41 |
173 | CONVOLVE_ONE_SAMPLE // 42 |
174 | CONVOLVE_ONE_SAMPLE // 43 |
175 | CONVOLVE_ONE_SAMPLE // 44 |
176 | CONVOLVE_ONE_SAMPLE // 45 |
177 | CONVOLVE_ONE_SAMPLE // 46 |
178 | CONVOLVE_ONE_SAMPLE // 47 |
179 | CONVOLVE_ONE_SAMPLE // 48 |
180 | CONVOLVE_ONE_SAMPLE // 49 |
181 | CONVOLVE_ONE_SAMPLE // 50 |
182 | |
183 | CONVOLVE_ONE_SAMPLE // 51 |
184 | CONVOLVE_ONE_SAMPLE // 52 |
185 | CONVOLVE_ONE_SAMPLE // 53 |
186 | CONVOLVE_ONE_SAMPLE // 54 |
187 | CONVOLVE_ONE_SAMPLE // 55 |
188 | CONVOLVE_ONE_SAMPLE // 56 |
189 | CONVOLVE_ONE_SAMPLE // 57 |
190 | CONVOLVE_ONE_SAMPLE // 58 |
191 | CONVOLVE_ONE_SAMPLE // 59 |
192 | CONVOLVE_ONE_SAMPLE // 60 |
193 | |
194 | CONVOLVE_ONE_SAMPLE // 61 |
195 | CONVOLVE_ONE_SAMPLE // 62 |
196 | CONVOLVE_ONE_SAMPLE // 63 |
197 | CONVOLVE_ONE_SAMPLE // 64 |
198 | |
199 | } else if (kernelSize == 128) { |
200 | CONVOLVE_ONE_SAMPLE // 1 |
201 | CONVOLVE_ONE_SAMPLE // 2 |
202 | CONVOLVE_ONE_SAMPLE // 3 |
203 | CONVOLVE_ONE_SAMPLE // 4 |
204 | CONVOLVE_ONE_SAMPLE // 5 |
205 | CONVOLVE_ONE_SAMPLE // 6 |
206 | CONVOLVE_ONE_SAMPLE // 7 |
207 | CONVOLVE_ONE_SAMPLE // 8 |
208 | CONVOLVE_ONE_SAMPLE // 9 |
209 | CONVOLVE_ONE_SAMPLE // 10 |
210 | |
211 | CONVOLVE_ONE_SAMPLE // 11 |
212 | CONVOLVE_ONE_SAMPLE // 12 |
213 | CONVOLVE_ONE_SAMPLE // 13 |
214 | CONVOLVE_ONE_SAMPLE // 14 |
215 | CONVOLVE_ONE_SAMPLE // 15 |
216 | CONVOLVE_ONE_SAMPLE // 16 |
217 | CONVOLVE_ONE_SAMPLE // 17 |
218 | CONVOLVE_ONE_SAMPLE // 18 |
219 | CONVOLVE_ONE_SAMPLE // 19 |
220 | CONVOLVE_ONE_SAMPLE // 20 |
221 | |
222 | CONVOLVE_ONE_SAMPLE // 21 |
223 | CONVOLVE_ONE_SAMPLE // 22 |
224 | CONVOLVE_ONE_SAMPLE // 23 |
225 | CONVOLVE_ONE_SAMPLE // 24 |
226 | CONVOLVE_ONE_SAMPLE // 25 |
227 | CONVOLVE_ONE_SAMPLE // 26 |
228 | CONVOLVE_ONE_SAMPLE // 27 |
229 | CONVOLVE_ONE_SAMPLE // 28 |
230 | CONVOLVE_ONE_SAMPLE // 29 |
231 | CONVOLVE_ONE_SAMPLE // 30 |
232 | |
233 | CONVOLVE_ONE_SAMPLE // 31 |
234 | CONVOLVE_ONE_SAMPLE // 32 |
235 | CONVOLVE_ONE_SAMPLE // 33 |
236 | CONVOLVE_ONE_SAMPLE // 34 |
237 | CONVOLVE_ONE_SAMPLE // 35 |
238 | CONVOLVE_ONE_SAMPLE // 36 |
239 | CONVOLVE_ONE_SAMPLE // 37 |
240 | CONVOLVE_ONE_SAMPLE // 38 |
241 | CONVOLVE_ONE_SAMPLE // 39 |
242 | CONVOLVE_ONE_SAMPLE // 40 |
243 | |
244 | CONVOLVE_ONE_SAMPLE // 41 |
245 | CONVOLVE_ONE_SAMPLE // 42 |
246 | CONVOLVE_ONE_SAMPLE // 43 |
247 | CONVOLVE_ONE_SAMPLE // 44 |
248 | CONVOLVE_ONE_SAMPLE // 45 |
249 | CONVOLVE_ONE_SAMPLE // 46 |
250 | CONVOLVE_ONE_SAMPLE // 47 |
251 | CONVOLVE_ONE_SAMPLE // 48 |
252 | CONVOLVE_ONE_SAMPLE // 49 |
253 | CONVOLVE_ONE_SAMPLE // 50 |
254 | |
255 | CONVOLVE_ONE_SAMPLE // 51 |
256 | CONVOLVE_ONE_SAMPLE // 52 |
257 | CONVOLVE_ONE_SAMPLE // 53 |
258 | CONVOLVE_ONE_SAMPLE // 54 |
259 | CONVOLVE_ONE_SAMPLE // 55 |
260 | CONVOLVE_ONE_SAMPLE // 56 |
261 | CONVOLVE_ONE_SAMPLE // 57 |
262 | CONVOLVE_ONE_SAMPLE // 58 |
263 | CONVOLVE_ONE_SAMPLE // 59 |
264 | CONVOLVE_ONE_SAMPLE // 60 |
265 | |
266 | CONVOLVE_ONE_SAMPLE // 61 |
267 | CONVOLVE_ONE_SAMPLE // 62 |
268 | CONVOLVE_ONE_SAMPLE // 63 |
269 | CONVOLVE_ONE_SAMPLE // 64 |
270 | CONVOLVE_ONE_SAMPLE // 65 |
271 | CONVOLVE_ONE_SAMPLE // 66 |
272 | CONVOLVE_ONE_SAMPLE // 67 |
273 | CONVOLVE_ONE_SAMPLE // 68 |
274 | CONVOLVE_ONE_SAMPLE // 69 |
275 | CONVOLVE_ONE_SAMPLE // 70 |
276 | |
277 | CONVOLVE_ONE_SAMPLE // 71 |
278 | CONVOLVE_ONE_SAMPLE // 72 |
279 | CONVOLVE_ONE_SAMPLE // 73 |
280 | CONVOLVE_ONE_SAMPLE // 74 |
281 | CONVOLVE_ONE_SAMPLE // 75 |
282 | CONVOLVE_ONE_SAMPLE // 76 |
283 | CONVOLVE_ONE_SAMPLE // 77 |
284 | CONVOLVE_ONE_SAMPLE // 78 |
285 | CONVOLVE_ONE_SAMPLE // 79 |
286 | CONVOLVE_ONE_SAMPLE // 80 |
287 | |
288 | CONVOLVE_ONE_SAMPLE // 81 |
289 | CONVOLVE_ONE_SAMPLE // 82 |
290 | CONVOLVE_ONE_SAMPLE // 83 |
291 | CONVOLVE_ONE_SAMPLE // 84 |
292 | CONVOLVE_ONE_SAMPLE // 85 |
293 | CONVOLVE_ONE_SAMPLE // 86 |
294 | CONVOLVE_ONE_SAMPLE // 87 |
295 | CONVOLVE_ONE_SAMPLE // 88 |
296 | CONVOLVE_ONE_SAMPLE // 89 |
297 | CONVOLVE_ONE_SAMPLE // 90 |
298 | |
299 | CONVOLVE_ONE_SAMPLE // 91 |
300 | CONVOLVE_ONE_SAMPLE // 92 |
301 | CONVOLVE_ONE_SAMPLE // 93 |
302 | CONVOLVE_ONE_SAMPLE // 94 |
303 | CONVOLVE_ONE_SAMPLE // 95 |
304 | CONVOLVE_ONE_SAMPLE // 96 |
305 | CONVOLVE_ONE_SAMPLE // 97 |
306 | CONVOLVE_ONE_SAMPLE // 98 |
307 | CONVOLVE_ONE_SAMPLE // 99 |
308 | CONVOLVE_ONE_SAMPLE // 100 |
309 | |
310 | CONVOLVE_ONE_SAMPLE // 101 |
311 | CONVOLVE_ONE_SAMPLE // 102 |
312 | CONVOLVE_ONE_SAMPLE // 103 |
313 | CONVOLVE_ONE_SAMPLE // 104 |
314 | CONVOLVE_ONE_SAMPLE // 105 |
315 | CONVOLVE_ONE_SAMPLE // 106 |
316 | CONVOLVE_ONE_SAMPLE // 107 |
317 | CONVOLVE_ONE_SAMPLE // 108 |
318 | CONVOLVE_ONE_SAMPLE // 109 |
319 | CONVOLVE_ONE_SAMPLE // 110 |
320 | |
321 | CONVOLVE_ONE_SAMPLE // 111 |
322 | CONVOLVE_ONE_SAMPLE // 112 |
323 | CONVOLVE_ONE_SAMPLE // 113 |
324 | CONVOLVE_ONE_SAMPLE // 114 |
325 | CONVOLVE_ONE_SAMPLE // 115 |
326 | CONVOLVE_ONE_SAMPLE // 116 |
327 | CONVOLVE_ONE_SAMPLE // 117 |
328 | CONVOLVE_ONE_SAMPLE // 118 |
329 | CONVOLVE_ONE_SAMPLE // 119 |
330 | CONVOLVE_ONE_SAMPLE // 120 |
331 | |
332 | CONVOLVE_ONE_SAMPLE // 121 |
333 | CONVOLVE_ONE_SAMPLE // 122 |
334 | CONVOLVE_ONE_SAMPLE // 123 |
335 | CONVOLVE_ONE_SAMPLE // 124 |
336 | CONVOLVE_ONE_SAMPLE // 125 |
337 | CONVOLVE_ONE_SAMPLE // 126 |
338 | CONVOLVE_ONE_SAMPLE // 127 |
339 | CONVOLVE_ONE_SAMPLE // 128 |
340 | } else { |
341 | while (j < kernelSize) { |
342 | // Non-optimized using actual while loop. |
343 | CONVOLVE_ONE_SAMPLE |
344 | } |
345 | } |
346 | destP[i++] = sum; |
347 | } |
348 | #endif // USE(ACCELERATE) |
349 | |
350 | // Copy 2nd half of input buffer to 1st half. |
351 | memcpy(m_buffer.data(), inputP, sizeof(float) * framesToProcess); |
352 | } |
353 | |
354 | void DirectConvolver::reset() |
355 | { |
356 | m_buffer.zero(); |
357 | } |
358 | |
359 | } // namespace WebCore |
360 | |
361 | #endif // ENABLE(WEB_AUDIO) |
362 | |