⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 98792 in webkit


Ignore:
Timestamp:
Oct 28, 2011, 6:47:50 PM (15 years ago)
Author:
crogers@google.com
Message:

SincResampler must be able to resample progressively
https://bugs.webkit.org/show_bug.cgi?id=71131

Reviewed by Kenneth Russell.

No new tests. There is not yet an implementation using progressive resampling to test.

  • platform/audio/SincResampler.cpp:

(WebCore::SincResampler::SincResampler):
(WebCore::SincResampler::consumeSource):
(WebCore::SincResampler::process):

  • platform/audio/SincResampler.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r98791 r98792  
     12011-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
    1162011-10-28  Adam Klein  <adamk@chromium.org>
    217
  • trunk/Source/WebCore/platform/audio/SincResampler.cpp

    r95901 r98792  
    3333#include "SincResampler.h"
    3434
     35#include "AudioBus.h"
    3536#include <wtf/MathExtras.h>
    3637
     
    7172    , m_numberOfKernelOffsets(numberOfKernelOffsets)
    7273    , m_kernelStorage(m_kernelSize * (m_numberOfKernelOffsets + 1))
    73     , m_virtualSourceIndex(0.0)
     74    , m_virtualSourceIndex(0)
    7475    , m_blockSize(512)
    7576    , m_inputBuffer(m_blockSize + m_kernelSize) // See input buffer layout above.
    7677    , m_source(0)
    7778    , m_sourceFramesAvailable(0)
     79    , m_sourceProvider(0)
     80    , m_isBufferPrimed(false)
    7881{
    7982    initializeKernel();
     
    123126void SincResampler::consumeSource(float* buffer, unsigned numberOfSourceFrames)
    124127{
    125     ASSERT(m_source);
    126     if (!m_source)
     128    ASSERT(m_sourceProvider);
     129    if (!m_sourceProvider)
    127130        return;
    128131   
    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
     139namespace {
     140
     141// BufferSourceProvider is an AudioSourceProvider wrapping an in-memory buffer.
     142
     143class BufferSourceProvider : public AudioSourceProvider {
     144public:
     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   
     172private:
     173    float* m_source;
     174    size_t m_sourceFramesAvailable;
     175};
     176
     177} // namespace
    140178
    141179void SincResampler::process(float* source, float* destination, unsigned numberOfSourceFrames)
    142180{
    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
     196void 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;
    146206   
    147207    // Setup various region pointers in the buffer (see diagram above).
     
    153213    float* r5 = r0 + m_kernelSize / 2;
    154214
    155     m_source = source;
    156     m_sourceFramesAvailable = numberOfSourceFrames;
    157 
    158     unsigned numberOfDestinationFrames = static_cast<unsigned>(numberOfSourceFrames / m_scaleFactor);
    159 
    160215    // 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    }
    163221   
    164222    // Step (2)
    165     m_virtualSourceIndex = 0;
    166223
    167224    while (numberOfDestinationFrames) {
     
    316373            *destination++ = result;
    317374
     375            // Advance the virtual index.
     376            m_virtualSourceIndex += m_scaleFactor;
     377
    318378            --numberOfDestinationFrames;
    319379            if (!numberOfDestinationFrames)
    320380                return;
    321 
    322             // Advance the virtual index.
    323             m_virtualSourceIndex += m_scaleFactor;
    324381        }
    325382
  • trunk/Source/WebCore/platform/audio/SincResampler.h

    r95901 r98792  
    3131
    3232#include "AudioArray.h"
     33#include "AudioSourceProvider.h"
    3334
    3435namespace WebCore {
     
    4546    // Processes numberOfSourceFrames from source to produce numberOfSourceFrames / scaleFactor frames in destination.
    4647    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 applications
    49     // 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
    5152protected:
    5253    void initializeKernel();
     
    7374    float* m_source;
    7475    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;
    7582};
    7683
Note: See TracChangeset for help on using the changeset viewer.