OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "platform/audio/SincResampler.h" | 33 #include "platform/audio/SincResampler.h" |
34 | 34 |
35 #include "platform/audio/AudioBus.h" | 35 #include "platform/audio/AudioBus.h" |
36 #include "wtf/CPU.h" | 36 #include "wtf/CPU.h" |
37 #include "wtf/MathExtras.h" | 37 #include "wtf/MathExtras.h" |
38 | 38 |
39 #if CPU(X86) || CPU(X86_64) | 39 #if CPU(X86) || CPU(X86_64) |
40 #include <emmintrin.h> | 40 #include <emmintrin.h> |
41 #endif | 41 #endif |
42 | 42 |
43 using namespace std; | |
44 | |
45 // Input buffer layout, dividing the total buffer into regions (r0 - r5): | 43 // Input buffer layout, dividing the total buffer into regions (r0 - r5): |
46 // | 44 // |
47 // |----------------|-----------------------------------------------------------
-----|----------------| | 45 // |----------------|-----------------------------------------------------------
-----|----------------| |
48 // | 46 // |
49 // blockSize + kernelSize / 2 | 47 // blockSize + kernelSize / 2 |
50 // <----------------------------------------------------------
----------------------> | 48 // <----------------------------------------------------------
----------------------> |
51 // r0 | 49 // r0 |
52 // | 50 // |
53 // kernelSize / 2 kernelSize / 2 kernelSize
/ 2 kernelSize / 2 | 51 // kernelSize / 2 kernelSize / 2 kernelSize
/ 2 kernelSize / 2 |
54 // <---------------> <---------------> <-----------
----> <---------------> | 52 // <---------------> <---------------> <-----------
----> <---------------> |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 int halfSize = n / 2; | 106 int halfSize = n / 2; |
109 | 107 |
110 // Generates a set of windowed sinc() kernels. | 108 // Generates a set of windowed sinc() kernels. |
111 // We generate a range of sub-sample offsets from 0.0 to 1.0. | 109 // We generate a range of sub-sample offsets from 0.0 to 1.0. |
112 for (unsigned offsetIndex = 0; offsetIndex <= m_numberOfKernelOffsets; ++off
setIndex) { | 110 for (unsigned offsetIndex = 0; offsetIndex <= m_numberOfKernelOffsets; ++off
setIndex) { |
113 double subsampleOffset = static_cast<double>(offsetIndex) / m_numberOfKe
rnelOffsets; | 111 double subsampleOffset = static_cast<double>(offsetIndex) / m_numberOfKe
rnelOffsets; |
114 | 112 |
115 for (int i = 0; i < n; ++i) { | 113 for (int i = 0; i < n; ++i) { |
116 // Compute the sinc() with offset. | 114 // Compute the sinc() with offset. |
117 double s = sincScaleFactor * piDouble * (i - halfSize - subsampleOff
set); | 115 double s = sincScaleFactor * piDouble * (i - halfSize - subsampleOff
set); |
118 double sinc = !s ? 1.0 : sin(s) / s; | 116 double sinc = !s ? 1.0 : std::sin(s) / s; |
119 sinc *= sincScaleFactor; | 117 sinc *= sincScaleFactor; |
120 | 118 |
121 // Compute Blackman window, matching the offset of the sinc(). | 119 // Compute Blackman window, matching the offset of the sinc(). |
122 double x = (i - subsampleOffset) / n; | 120 double x = (i - subsampleOffset) / n; |
123 double window = a0 - a1 * cos(twoPiDouble * x) + a2 * cos(twoPiDoubl
e * 2.0 * x); | 121 double window = a0 - a1 * std::cos(twoPiDouble * x) + a2 * std::cos(
twoPiDouble * 2.0 * x); |
124 | 122 |
125 // Window the sinc() function and store at the correct offset. | 123 // Window the sinc() function and store at the correct offset. |
126 m_kernelStorage[i + offsetIndex * m_kernelSize] = sinc * window; | 124 m_kernelStorage[i + offsetIndex * m_kernelSize] = sinc * window; |
127 } | 125 } |
128 } | 126 } |
129 } | 127 } |
130 | 128 |
131 void SincResampler::consumeSource(float* buffer, unsigned numberOfSourceFrames) | 129 void SincResampler::consumeSource(float* buffer, unsigned numberOfSourceFrames) |
132 { | 130 { |
133 ASSERT(m_sourceProvider); | 131 ASSERT(m_sourceProvider); |
(...skipping 24 matching lines...) Expand all Loading... |
158 // Consumes samples from the in-memory buffer. | 156 // Consumes samples from the in-memory buffer. |
159 virtual void provideInput(AudioBus* bus, size_t framesToProcess) OVERRIDE | 157 virtual void provideInput(AudioBus* bus, size_t framesToProcess) OVERRIDE |
160 { | 158 { |
161 ASSERT(m_source && bus); | 159 ASSERT(m_source && bus); |
162 if (!m_source || !bus) | 160 if (!m_source || !bus) |
163 return; | 161 return; |
164 | 162 |
165 float* buffer = bus->channel(0)->mutableData(); | 163 float* buffer = bus->channel(0)->mutableData(); |
166 | 164 |
167 // Clamp to number of frames available and zero-pad. | 165 // Clamp to number of frames available and zero-pad. |
168 size_t framesToCopy = min(m_sourceFramesAvailable, framesToProcess); | 166 size_t framesToCopy = std::min(m_sourceFramesAvailable, framesToProcess)
; |
169 memcpy(buffer, m_source, sizeof(float) * framesToCopy); | 167 memcpy(buffer, m_source, sizeof(float) * framesToCopy); |
170 | 168 |
171 // Zero-pad if necessary. | 169 // Zero-pad if necessary. |
172 if (framesToCopy < framesToProcess) | 170 if (framesToCopy < framesToProcess) |
173 memset(buffer + framesToCopy, 0, sizeof(float) * (framesToProcess -
framesToCopy)); | 171 memset(buffer + framesToCopy, 0, sizeof(float) * (framesToProcess -
framesToCopy)); |
174 | 172 |
175 m_sourceFramesAvailable -= framesToCopy; | 173 m_sourceFramesAvailable -= framesToCopy; |
176 m_source += framesToCopy; | 174 m_source += framesToCopy; |
177 } | 175 } |
178 | 176 |
179 private: | 177 private: |
180 const float* m_source; | 178 const float* m_source; |
181 size_t m_sourceFramesAvailable; | 179 size_t m_sourceFramesAvailable; |
182 }; | 180 }; |
183 | 181 |
184 } // namespace | 182 } // namespace |
185 | 183 |
186 void SincResampler::process(const float* source, float* destination, unsigned nu
mberOfSourceFrames) | 184 void SincResampler::process(const float* source, float* destination, unsigned nu
mberOfSourceFrames) |
187 { | 185 { |
188 // Resample an in-memory buffer using an AudioSourceProvider. | 186 // Resample an in-memory buffer using an AudioSourceProvider. |
189 BufferSourceProvider sourceProvider(source, numberOfSourceFrames); | 187 BufferSourceProvider sourceProvider(source, numberOfSourceFrames); |
190 | 188 |
191 unsigned numberOfDestinationFrames = static_cast<unsigned>(numberOfSourceFra
mes / m_scaleFactor); | 189 unsigned numberOfDestinationFrames = static_cast<unsigned>(numberOfSourceFra
mes / m_scaleFactor); |
192 unsigned remaining = numberOfDestinationFrames; | 190 unsigned remaining = numberOfDestinationFrames; |
193 | 191 |
194 while (remaining) { | 192 while (remaining) { |
195 unsigned framesThisTime = min(remaining, m_blockSize); | 193 unsigned framesThisTime = std::min(remaining, m_blockSize); |
196 process(&sourceProvider, destination, framesThisTime); | 194 process(&sourceProvider, destination, framesThisTime); |
197 | 195 |
198 destination += framesThisTime; | 196 destination += framesThisTime; |
199 remaining -= framesThisTime; | 197 remaining -= framesThisTime; |
200 } | 198 } |
201 } | 199 } |
202 | 200 |
203 void SincResampler::process(AudioSourceProvider* sourceProvider, float* destinat
ion, size_t framesToProcess) | 201 void SincResampler::process(AudioSourceProvider* sourceProvider, float* destinat
ion, size_t framesToProcess) |
204 { | 202 { |
205 bool isGood = sourceProvider && m_blockSize > m_kernelSize && m_inputBuffer.
size() >= m_blockSize + m_kernelSize && !(m_kernelSize % 2); | 203 bool isGood = sourceProvider && m_blockSize > m_kernelSize && m_inputBuffer.
size() >= m_blockSize + m_kernelSize && !(m_kernelSize % 2); |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 | 464 |
467 // Step (4) | 465 // Step (4) |
468 // Refresh the buffer with more input. | 466 // Refresh the buffer with more input. |
469 consumeSource(r5, m_blockSize); | 467 consumeSource(r5, m_blockSize); |
470 } | 468 } |
471 } | 469 } |
472 | 470 |
473 } // namespace blink | 471 } // namespace blink |
474 | 472 |
475 #endif // ENABLE(WEB_AUDIO) | 473 #endif // ENABLE(WEB_AUDIO) |
OLD | NEW |