Changeset 98792 in webkit
- Timestamp:
- Oct 28, 2011, 6:47:50 PM (15 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
-
ChangeLog (modified) (1 diff)
-
platform/audio/SincResampler.cpp (modified) (5 diffs)
-
platform/audio/SincResampler.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r98791 r98792 1 2011-10-28 Chris Rogers <crogers@google.com> 2 3 SincResampler must be able to resample progressively 4 https://bugs.webkit.org/show_bug.cgi?id=71131 5 6 Reviewed by Kenneth Russell. 7 8 No new tests. There is not yet an implementation using progressive resampling to test. 9 10 * platform/audio/SincResampler.cpp: 11 (WebCore::SincResampler::SincResampler): 12 (WebCore::SincResampler::consumeSource): 13 (WebCore::SincResampler::process): 14 * platform/audio/SincResampler.h: 15 1 16 2011-10-28 Adam Klein <adamk@chromium.org> 2 17 -
trunk/Source/WebCore/platform/audio/SincResampler.cpp
r95901 r98792 33 33 #include "SincResampler.h" 34 34 35 #include "AudioBus.h" 35 36 #include <wtf/MathExtras.h> 36 37 … … 71 72 , m_numberOfKernelOffsets(numberOfKernelOffsets) 72 73 , m_kernelStorage(m_kernelSize * (m_numberOfKernelOffsets + 1)) 73 , m_virtualSourceIndex(0 .0)74 , m_virtualSourceIndex(0) 74 75 , m_blockSize(512) 75 76 , m_inputBuffer(m_blockSize + m_kernelSize) // See input buffer layout above. 76 77 , m_source(0) 77 78 , m_sourceFramesAvailable(0) 79 , m_sourceProvider(0) 80 , m_isBufferPrimed(false) 78 81 { 79 82 initializeKernel(); … … 123 126 void SincResampler::consumeSource(float* buffer, unsigned numberOfSourceFrames) 124 127 { 125 ASSERT(m_source );126 if (!m_source )128 ASSERT(m_sourceProvider); 129 if (!m_sourceProvider) 127 130 return; 128 131 129 // Clamp to number of frames available and zero-pad. 130 unsigned framesToCopy = min(m_sourceFramesAvailable, numberOfSourceFrames); 131 memcpy(buffer, m_source, sizeof(float) * framesToCopy); 132 133 // Zero-pad if necessary. 134 if (framesToCopy < numberOfSourceFrames) 135 memset(buffer + framesToCopy, 0, sizeof(float) * (numberOfSourceFrames - framesToCopy)); 136 137 m_sourceFramesAvailable -= framesToCopy; 138 m_source += numberOfSourceFrames; 139 } 132 // Wrap the provided buffer by an AudioBus for use by the source provider. 133 AudioBus bus(1, numberOfSourceFrames, false); 134 bus.setChannelMemory(0, buffer, numberOfSourceFrames); 135 136 m_sourceProvider->provideInput(&bus, numberOfSourceFrames); 137 } 138 139 namespace { 140 141 // BufferSourceProvider is an AudioSourceProvider wrapping an in-memory buffer. 142 143 class BufferSourceProvider : public AudioSourceProvider { 144 public: 145 BufferSourceProvider(float* source, size_t numberOfSourceFrames) 146 : m_source(source) 147 , m_sourceFramesAvailable(numberOfSourceFrames) 148 { 149 } 150 151 // Consumes samples from the in-memory buffer. 152 virtual void provideInput(AudioBus* bus, size_t framesToProcess) 153 { 154 ASSERT(m_source && bus); 155 if (!m_source || !bus) 156 return; 157 158 float* buffer = bus->channel(0)->data(); 159 160 // Clamp to number of frames available and zero-pad. 161 size_t framesToCopy = min(m_sourceFramesAvailable, framesToProcess); 162 memcpy(buffer, m_source, sizeof(float) * framesToCopy); 163 164 // Zero-pad if necessary. 165 if (framesToCopy < framesToProcess) 166 memset(buffer + framesToCopy, 0, sizeof(float) * (framesToProcess - framesToCopy)); 167 168 m_sourceFramesAvailable -= framesToCopy; 169 m_source += framesToCopy; 170 } 171 172 private: 173 float* m_source; 174 size_t m_sourceFramesAvailable; 175 }; 176 177 } // namespace 140 178 141 179 void SincResampler::process(float* source, float* destination, unsigned numberOfSourceFrames) 142 180 { 143 ASSERT(m_blockSize > m_kernelSize); 144 ASSERT(m_inputBuffer.size() >= m_blockSize + m_kernelSize); 145 ASSERT(!(m_kernelSize % 2)); 181 // Resample an in-memory buffer using an AudioSourceProvider. 182 BufferSourceProvider sourceProvider(source, numberOfSourceFrames); 183 184 unsigned numberOfDestinationFrames = static_cast<unsigned>(numberOfSourceFrames / m_scaleFactor); 185 unsigned remaining = numberOfDestinationFrames; 186 187 while (remaining) { 188 unsigned framesThisTime = min(remaining, m_blockSize); 189 process(&sourceProvider, destination, framesThisTime); 190 191 destination += framesThisTime; 192 remaining -= framesThisTime; 193 } 194 } 195 196 void SincResampler::process(AudioSourceProvider* sourceProvider, float* destination, size_t framesToProcess) 197 { 198 bool isGood = sourceProvider && m_blockSize > m_kernelSize && m_inputBuffer.size() >= m_blockSize + m_kernelSize && !(m_kernelSize % 2); 199 ASSERT(isGood); 200 if (!isGood) 201 return; 202 203 m_sourceProvider = sourceProvider; 204 205 unsigned numberOfDestinationFrames = framesToProcess; 146 206 147 207 // Setup various region pointers in the buffer (see diagram above). … … 153 213 float* r5 = r0 + m_kernelSize / 2; 154 214 155 m_source = source;156 m_sourceFramesAvailable = numberOfSourceFrames;157 158 unsigned numberOfDestinationFrames = static_cast<unsigned>(numberOfSourceFrames / m_scaleFactor);159 160 215 // Step (1) 161 // Prime the input buffer. 162 consumeSource(r0, m_blockSize + m_kernelSize / 2); 216 // Prime the input buffer at the start of the input stream. 217 if (!m_isBufferPrimed) { 218 consumeSource(r0, m_blockSize + m_kernelSize / 2); 219 m_isBufferPrimed = true; 220 } 163 221 164 222 // Step (2) 165 m_virtualSourceIndex = 0;166 223 167 224 while (numberOfDestinationFrames) { … … 316 373 *destination++ = result; 317 374 375 // Advance the virtual index. 376 m_virtualSourceIndex += m_scaleFactor; 377 318 378 --numberOfDestinationFrames; 319 379 if (!numberOfDestinationFrames) 320 380 return; 321 322 // Advance the virtual index.323 m_virtualSourceIndex += m_scaleFactor;324 381 } 325 382 -
trunk/Source/WebCore/platform/audio/SincResampler.h
r95901 r98792 31 31 32 32 #include "AudioArray.h" 33 #include "AudioSourceProvider.h" 33 34 34 35 namespace WebCore { … … 45 46 // Processes numberOfSourceFrames from source to produce numberOfSourceFrames / scaleFactor frames in destination. 46 47 void process(float* source, float* destination, unsigned numberOfSourceFrames); 47 48 // FIXME: we can add a process() method which takes an input source callback function for streaming applications49 // where the entire input buffer is not all available.50 48 49 // Process with input source callback function for streaming applications. 50 void process(AudioSourceProvider*, float* destination, size_t framesToProcess); 51 51 52 protected: 52 53 void initializeKernel(); … … 73 74 float* m_source; 74 75 unsigned m_sourceFramesAvailable; 76 77 // m_sourceProvider is used to provide the audio input stream to the resampler. 78 AudioSourceProvider* m_sourceProvider; 79 80 // The buffer is primed once at the very beginning of processing. 81 bool m_isBufferPrimed; 75 82 }; 76 83
Note:
See TracChangeset
for help on using the changeset viewer.