| 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 |