2
* Copyright (C) 2012 Intel Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
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 Computer, 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.
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.
33
#include "DirectConvolver.h"
36
#include <Accelerate/Accelerate.h>
39
#include "VectorMath.h"
43
using namespace VectorMath;
45
DirectConvolver::DirectConvolver(size_t inputBlockSize)
46
: m_inputBlockSize(inputBlockSize)
48
, m_overlayBuffer(inputBlockSize)
49
#endif // USE(WEBAUDIO_IPP)
50
, m_buffer(inputBlockSize * 2)
54
void DirectConvolver::process(AudioFloatArray* convolutionKernel, const float* sourceP, float* destP, size_t framesToProcess)
56
ASSERT(framesToProcess == m_inputBlockSize);
57
if (framesToProcess != m_inputBlockSize)
60
// Only support kernelSize <= m_inputBlockSize
61
size_t kernelSize = convolutionKernel->size();
62
ASSERT(kernelSize <= m_inputBlockSize);
63
if (kernelSize > m_inputBlockSize)
66
float* kernelP = convolutionKernel->data();
69
bool isCopyGood = kernelP && sourceP && destP && m_buffer.data();
75
float* outputBuffer = m_buffer.data();
76
float* overlayBuffer = m_overlayBuffer.data();
77
bool isCopyGood2 = overlayBuffer && m_overlayBuffer.size() >= kernelSize && m_buffer.size() == m_inputBlockSize * 2;
82
ippsConv_32f(static_cast<const Ipp32f*>(sourceP), framesToProcess, static_cast<Ipp32f*>(kernelP), kernelSize, static_cast<Ipp32f*>(outputBuffer));
84
vadd(outputBuffer, 1, overlayBuffer, 1, destP, 1, framesToProcess);
85
memcpy(overlayBuffer, outputBuffer + m_inputBlockSize, sizeof(float) * kernelSize);
87
float* inputP = m_buffer.data() + m_inputBlockSize;
89
// Copy samples to 2nd half of input buffer.
90
memcpy(inputP, sourceP, sizeof(float) * framesToProcess);
93
#if defined(__ppc__) || defined(__i386__)
94
conv(inputP - kernelSize + 1, 1, kernelP + kernelSize - 1, -1, destP, 1, framesToProcess, kernelSize);
96
vDSP_conv(inputP - kernelSize + 1, 1, kernelP + kernelSize - 1, -1, destP, 1, framesToProcess, kernelSize);
97
#endif // defined(__ppc__) || defined(__i386__)
99
// 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.
100
#define CONVOLVE_ONE_SAMPLE \
101
sum += inputP[i - j] * kernelP[j]; \
105
while (i < framesToProcess) {
109
// FIXME: SSE optimization may be applied here.
110
if (kernelSize == 32) {
111
CONVOLVE_ONE_SAMPLE // 1
112
CONVOLVE_ONE_SAMPLE // 2
113
CONVOLVE_ONE_SAMPLE // 3
114
CONVOLVE_ONE_SAMPLE // 4
115
CONVOLVE_ONE_SAMPLE // 5
116
CONVOLVE_ONE_SAMPLE // 6
117
CONVOLVE_ONE_SAMPLE // 7
118
CONVOLVE_ONE_SAMPLE // 8
119
CONVOLVE_ONE_SAMPLE // 9
120
CONVOLVE_ONE_SAMPLE // 10
122
CONVOLVE_ONE_SAMPLE // 11
123
CONVOLVE_ONE_SAMPLE // 12
124
CONVOLVE_ONE_SAMPLE // 13
125
CONVOLVE_ONE_SAMPLE // 14
126
CONVOLVE_ONE_SAMPLE // 15
127
CONVOLVE_ONE_SAMPLE // 16
128
CONVOLVE_ONE_SAMPLE // 17
129
CONVOLVE_ONE_SAMPLE // 18
130
CONVOLVE_ONE_SAMPLE // 19
131
CONVOLVE_ONE_SAMPLE // 20
133
CONVOLVE_ONE_SAMPLE // 21
134
CONVOLVE_ONE_SAMPLE // 22
135
CONVOLVE_ONE_SAMPLE // 23
136
CONVOLVE_ONE_SAMPLE // 24
137
CONVOLVE_ONE_SAMPLE // 25
138
CONVOLVE_ONE_SAMPLE // 26
139
CONVOLVE_ONE_SAMPLE // 27
140
CONVOLVE_ONE_SAMPLE // 28
141
CONVOLVE_ONE_SAMPLE // 29
142
CONVOLVE_ONE_SAMPLE // 30
144
CONVOLVE_ONE_SAMPLE // 31
145
CONVOLVE_ONE_SAMPLE // 32
147
} else if (kernelSize == 64) {
148
CONVOLVE_ONE_SAMPLE // 1
149
CONVOLVE_ONE_SAMPLE // 2
150
CONVOLVE_ONE_SAMPLE // 3
151
CONVOLVE_ONE_SAMPLE // 4
152
CONVOLVE_ONE_SAMPLE // 5
153
CONVOLVE_ONE_SAMPLE // 6
154
CONVOLVE_ONE_SAMPLE // 7
155
CONVOLVE_ONE_SAMPLE // 8
156
CONVOLVE_ONE_SAMPLE // 9
157
CONVOLVE_ONE_SAMPLE // 10
159
CONVOLVE_ONE_SAMPLE // 11
160
CONVOLVE_ONE_SAMPLE // 12
161
CONVOLVE_ONE_SAMPLE // 13
162
CONVOLVE_ONE_SAMPLE // 14
163
CONVOLVE_ONE_SAMPLE // 15
164
CONVOLVE_ONE_SAMPLE // 16
165
CONVOLVE_ONE_SAMPLE // 17
166
CONVOLVE_ONE_SAMPLE // 18
167
CONVOLVE_ONE_SAMPLE // 19
168
CONVOLVE_ONE_SAMPLE // 20
170
CONVOLVE_ONE_SAMPLE // 21
171
CONVOLVE_ONE_SAMPLE // 22
172
CONVOLVE_ONE_SAMPLE // 23
173
CONVOLVE_ONE_SAMPLE // 24
174
CONVOLVE_ONE_SAMPLE // 25
175
CONVOLVE_ONE_SAMPLE // 26
176
CONVOLVE_ONE_SAMPLE // 27
177
CONVOLVE_ONE_SAMPLE // 28
178
CONVOLVE_ONE_SAMPLE // 29
179
CONVOLVE_ONE_SAMPLE // 30
181
CONVOLVE_ONE_SAMPLE // 31
182
CONVOLVE_ONE_SAMPLE // 32
183
CONVOLVE_ONE_SAMPLE // 33
184
CONVOLVE_ONE_SAMPLE // 34
185
CONVOLVE_ONE_SAMPLE // 35
186
CONVOLVE_ONE_SAMPLE // 36
187
CONVOLVE_ONE_SAMPLE // 37
188
CONVOLVE_ONE_SAMPLE // 38
189
CONVOLVE_ONE_SAMPLE // 39
190
CONVOLVE_ONE_SAMPLE // 40
192
CONVOLVE_ONE_SAMPLE // 41
193
CONVOLVE_ONE_SAMPLE // 42
194
CONVOLVE_ONE_SAMPLE // 43
195
CONVOLVE_ONE_SAMPLE // 44
196
CONVOLVE_ONE_SAMPLE // 45
197
CONVOLVE_ONE_SAMPLE // 46
198
CONVOLVE_ONE_SAMPLE // 47
199
CONVOLVE_ONE_SAMPLE // 48
200
CONVOLVE_ONE_SAMPLE // 49
201
CONVOLVE_ONE_SAMPLE // 50
203
CONVOLVE_ONE_SAMPLE // 51
204
CONVOLVE_ONE_SAMPLE // 52
205
CONVOLVE_ONE_SAMPLE // 53
206
CONVOLVE_ONE_SAMPLE // 54
207
CONVOLVE_ONE_SAMPLE // 55
208
CONVOLVE_ONE_SAMPLE // 56
209
CONVOLVE_ONE_SAMPLE // 57
210
CONVOLVE_ONE_SAMPLE // 58
211
CONVOLVE_ONE_SAMPLE // 59
212
CONVOLVE_ONE_SAMPLE // 60
214
CONVOLVE_ONE_SAMPLE // 61
215
CONVOLVE_ONE_SAMPLE // 62
216
CONVOLVE_ONE_SAMPLE // 63
217
CONVOLVE_ONE_SAMPLE // 64
219
} else if (kernelSize == 128) {
220
CONVOLVE_ONE_SAMPLE // 1
221
CONVOLVE_ONE_SAMPLE // 2
222
CONVOLVE_ONE_SAMPLE // 3
223
CONVOLVE_ONE_SAMPLE // 4
224
CONVOLVE_ONE_SAMPLE // 5
225
CONVOLVE_ONE_SAMPLE // 6
226
CONVOLVE_ONE_SAMPLE // 7
227
CONVOLVE_ONE_SAMPLE // 8
228
CONVOLVE_ONE_SAMPLE // 9
229
CONVOLVE_ONE_SAMPLE // 10
231
CONVOLVE_ONE_SAMPLE // 11
232
CONVOLVE_ONE_SAMPLE // 12
233
CONVOLVE_ONE_SAMPLE // 13
234
CONVOLVE_ONE_SAMPLE // 14
235
CONVOLVE_ONE_SAMPLE // 15
236
CONVOLVE_ONE_SAMPLE // 16
237
CONVOLVE_ONE_SAMPLE // 17
238
CONVOLVE_ONE_SAMPLE // 18
239
CONVOLVE_ONE_SAMPLE // 19
240
CONVOLVE_ONE_SAMPLE // 20
242
CONVOLVE_ONE_SAMPLE // 21
243
CONVOLVE_ONE_SAMPLE // 22
244
CONVOLVE_ONE_SAMPLE // 23
245
CONVOLVE_ONE_SAMPLE // 24
246
CONVOLVE_ONE_SAMPLE // 25
247
CONVOLVE_ONE_SAMPLE // 26
248
CONVOLVE_ONE_SAMPLE // 27
249
CONVOLVE_ONE_SAMPLE // 28
250
CONVOLVE_ONE_SAMPLE // 29
251
CONVOLVE_ONE_SAMPLE // 30
253
CONVOLVE_ONE_SAMPLE // 31
254
CONVOLVE_ONE_SAMPLE // 32
255
CONVOLVE_ONE_SAMPLE // 33
256
CONVOLVE_ONE_SAMPLE // 34
257
CONVOLVE_ONE_SAMPLE // 35
258
CONVOLVE_ONE_SAMPLE // 36
259
CONVOLVE_ONE_SAMPLE // 37
260
CONVOLVE_ONE_SAMPLE // 38
261
CONVOLVE_ONE_SAMPLE // 39
262
CONVOLVE_ONE_SAMPLE // 40
264
CONVOLVE_ONE_SAMPLE // 41
265
CONVOLVE_ONE_SAMPLE // 42
266
CONVOLVE_ONE_SAMPLE // 43
267
CONVOLVE_ONE_SAMPLE // 44
268
CONVOLVE_ONE_SAMPLE // 45
269
CONVOLVE_ONE_SAMPLE // 46
270
CONVOLVE_ONE_SAMPLE // 47
271
CONVOLVE_ONE_SAMPLE // 48
272
CONVOLVE_ONE_SAMPLE // 49
273
CONVOLVE_ONE_SAMPLE // 50
275
CONVOLVE_ONE_SAMPLE // 51
276
CONVOLVE_ONE_SAMPLE // 52
277
CONVOLVE_ONE_SAMPLE // 53
278
CONVOLVE_ONE_SAMPLE // 54
279
CONVOLVE_ONE_SAMPLE // 55
280
CONVOLVE_ONE_SAMPLE // 56
281
CONVOLVE_ONE_SAMPLE // 57
282
CONVOLVE_ONE_SAMPLE // 58
283
CONVOLVE_ONE_SAMPLE // 59
284
CONVOLVE_ONE_SAMPLE // 60
286
CONVOLVE_ONE_SAMPLE // 61
287
CONVOLVE_ONE_SAMPLE // 62
288
CONVOLVE_ONE_SAMPLE // 63
289
CONVOLVE_ONE_SAMPLE // 64
290
CONVOLVE_ONE_SAMPLE // 65
291
CONVOLVE_ONE_SAMPLE // 66
292
CONVOLVE_ONE_SAMPLE // 67
293
CONVOLVE_ONE_SAMPLE // 68
294
CONVOLVE_ONE_SAMPLE // 69
295
CONVOLVE_ONE_SAMPLE // 70
297
CONVOLVE_ONE_SAMPLE // 71
298
CONVOLVE_ONE_SAMPLE // 72
299
CONVOLVE_ONE_SAMPLE // 73
300
CONVOLVE_ONE_SAMPLE // 74
301
CONVOLVE_ONE_SAMPLE // 75
302
CONVOLVE_ONE_SAMPLE // 76
303
CONVOLVE_ONE_SAMPLE // 77
304
CONVOLVE_ONE_SAMPLE // 78
305
CONVOLVE_ONE_SAMPLE // 79
306
CONVOLVE_ONE_SAMPLE // 80
308
CONVOLVE_ONE_SAMPLE // 81
309
CONVOLVE_ONE_SAMPLE // 82
310
CONVOLVE_ONE_SAMPLE // 83
311
CONVOLVE_ONE_SAMPLE // 84
312
CONVOLVE_ONE_SAMPLE // 85
313
CONVOLVE_ONE_SAMPLE // 86
314
CONVOLVE_ONE_SAMPLE // 87
315
CONVOLVE_ONE_SAMPLE // 88
316
CONVOLVE_ONE_SAMPLE // 89
317
CONVOLVE_ONE_SAMPLE // 90
319
CONVOLVE_ONE_SAMPLE // 91
320
CONVOLVE_ONE_SAMPLE // 92
321
CONVOLVE_ONE_SAMPLE // 93
322
CONVOLVE_ONE_SAMPLE // 94
323
CONVOLVE_ONE_SAMPLE // 95
324
CONVOLVE_ONE_SAMPLE // 96
325
CONVOLVE_ONE_SAMPLE // 97
326
CONVOLVE_ONE_SAMPLE // 98
327
CONVOLVE_ONE_SAMPLE // 99
328
CONVOLVE_ONE_SAMPLE // 100
330
CONVOLVE_ONE_SAMPLE // 101
331
CONVOLVE_ONE_SAMPLE // 102
332
CONVOLVE_ONE_SAMPLE // 103
333
CONVOLVE_ONE_SAMPLE // 104
334
CONVOLVE_ONE_SAMPLE // 105
335
CONVOLVE_ONE_SAMPLE // 106
336
CONVOLVE_ONE_SAMPLE // 107
337
CONVOLVE_ONE_SAMPLE // 108
338
CONVOLVE_ONE_SAMPLE // 109
339
CONVOLVE_ONE_SAMPLE // 110
341
CONVOLVE_ONE_SAMPLE // 111
342
CONVOLVE_ONE_SAMPLE // 112
343
CONVOLVE_ONE_SAMPLE // 113
344
CONVOLVE_ONE_SAMPLE // 114
345
CONVOLVE_ONE_SAMPLE // 115
346
CONVOLVE_ONE_SAMPLE // 116
347
CONVOLVE_ONE_SAMPLE // 117
348
CONVOLVE_ONE_SAMPLE // 118
349
CONVOLVE_ONE_SAMPLE // 119
350
CONVOLVE_ONE_SAMPLE // 120
352
CONVOLVE_ONE_SAMPLE // 121
353
CONVOLVE_ONE_SAMPLE // 122
354
CONVOLVE_ONE_SAMPLE // 123
355
CONVOLVE_ONE_SAMPLE // 124
356
CONVOLVE_ONE_SAMPLE // 125
357
CONVOLVE_ONE_SAMPLE // 126
358
CONVOLVE_ONE_SAMPLE // 127
359
CONVOLVE_ONE_SAMPLE // 128
361
while (j < kernelSize) {
362
// Non-optimized using actual while loop.
370
// Copy 2nd half of input buffer to 1st half.
371
memcpy(m_buffer.data(), inputP, sizeof(float) * framesToProcess);
375
void DirectConvolver::reset()
378
#if USE(WEBAUDIO_IPP)
379
m_overlayBuffer.zero();
380
#endif // USE(WEBAUDIO_IPP)
383
} // namespace WebCore
385
#endif // ENABLE(WEB_AUDIO)