Changeset 121810 in webkit


Ignore:
Timestamp:
Jul 3, 2012 4:40:50 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

Add AudioFIFO class and simplify AudioPullFIFO
https://bugs.webkit.org/show_bug.cgi?id=90398

Patch by Raymond Toy <Raymond Toy> on 2012-07-03
Reviewed by Chris Rogers.

No new tests. This code will be used in audio back-end implementation.

Add AudioFIFO class to implement main parts of FIFO. Simplify
implementation of AudioPushFIFO by using AudioFIFO.

  • WebCore.gypi: Add new files.

New AudioFIFO class

  • platform/audio/AudioFIFO.cpp: Copied from Source/WebCore/platform/audio/AudioPullFIFO.cpp.

(WebCore):
(WebCore::AudioFIFO::AudioFIFO):
(WebCore::AudioFIFO::consume):
(WebCore::AudioFIFO::push):
(WebCore::AudioFIFO::findWrapLengths):

  • platform/audio/AudioFIFO.h: Copied from Source/WebCore/platform/audio/AudioPullFIFO.h.

(WebCore):
(AudioFIFO):
(WebCore::AudioFIFO::framesInFifo):
(WebCore::AudioFIFO::updateIndex):

Use AudioFIFO

  • platform/audio/AudioPullFIFO.cpp:

(WebCore::AudioPullFIFO::AudioPullFIFO):
(WebCore::AudioPullFIFO::consume):
(WebCore::AudioPullFIFO::fillBuffer):

  • platform/audio/AudioPullFIFO.h:

(AudioPullFIFO):

Location:
trunk/Source/WebCore
Files:
4 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r121803 r121810  
     12012-07-03  Raymond Toy  <rtoy@google.com>
     2
     3        Add AudioFIFO class and simplify AudioPullFIFO
     4        https://bugs.webkit.org/show_bug.cgi?id=90398
     5
     6        Reviewed by Chris Rogers.
     7
     8        No new tests. This code will be used in audio back-end implementation.
     9
     10        Add AudioFIFO class to implement main parts of FIFO.  Simplify
     11        implementation of AudioPushFIFO by using AudioFIFO.
     12       
     13        * WebCore.gypi: Add new files.
     14
     15        New AudioFIFO class
     16        * platform/audio/AudioFIFO.cpp: Copied from Source/WebCore/platform/audio/AudioPullFIFO.cpp.
     17        (WebCore):
     18        (WebCore::AudioFIFO::AudioFIFO):
     19        (WebCore::AudioFIFO::consume):
     20        (WebCore::AudioFIFO::push):
     21        (WebCore::AudioFIFO::findWrapLengths):
     22        * platform/audio/AudioFIFO.h: Copied from Source/WebCore/platform/audio/AudioPullFIFO.h.
     23        (WebCore):
     24        (AudioFIFO):
     25        (WebCore::AudioFIFO::framesInFifo):
     26        (WebCore::AudioFIFO::updateIndex):
     27
     28        Use AudioFIFO
     29        * platform/audio/AudioPullFIFO.cpp:
     30        (WebCore::AudioPullFIFO::AudioPullFIFO):
     31        (WebCore::AudioPullFIFO::consume):
     32        (WebCore::AudioPullFIFO::fillBuffer):
     33        * platform/audio/AudioPullFIFO.h:
     34        (AudioPullFIFO):
     35
    1362012-07-03  Nate Chapin  <japhet@chromium.org>
    237
  • trunk/Source/WebCore/WebCore.gypi

    r121778 r121810  
    32603260            'platform/audio/AudioDSPKernelProcessor.h',
    32613261            'platform/audio/AudioDestination.h',
     3262            'platform/audio/AudioFIFO.cpp',
     3263            'platform/audio/AudioFIFO.h',
    32623264            'platform/audio/AudioFileReader.h',
    32633265            'platform/audio/AudioProcessor.h',
  • trunk/Source/WebCore/platform/audio/AudioFIFO.cpp

    r121809 r121810  
    3131#if ENABLE(WEB_AUDIO)
    3232
    33 #include "AudioPullFIFO.h"
     33#include "AudioFIFO.h"
    3434
    3535namespace WebCore {
    3636
    37 AudioPullFIFO::AudioPullFIFO(AudioSourceProvider& audioProvider, unsigned numberOfChannels, size_t fifoLength, size_t providerSize)
    38     : m_provider(audioProvider)
    39     , m_fifoAudioBus(numberOfChannels, fifoLength)
     37AudioFIFO::AudioFIFO(unsigned numberOfChannels, size_t fifoLength)
     38    : m_fifoAudioBus(numberOfChannels, fifoLength)
    4039    , m_fifoLength(fifoLength)
    4140    , m_framesInFifo(0)
    4241    , m_readIndex(0)
    4342    , m_writeIndex(0)
    44     , m_providerSize(providerSize)
    45     , m_tempBus(numberOfChannels, providerSize)
    4643{
    4744}
    4845
    49 void AudioPullFIFO::consume(AudioBus* destination, size_t framesToConsume)
     46void AudioFIFO::consume(AudioBus* destination, size_t framesToConsume)
    5047{
    51     bool isGood = destination && (framesToConsume <= m_fifoLength);
     48    bool isGood = destination && (framesToConsume <= m_fifoLength) && (framesToConsume <= m_framesInFifo) && (destination->length() >= framesToConsume);
    5249    ASSERT(isGood);
    5350    if (!isGood)
    5451        return;
    5552
    56     if (framesToConsume > m_framesInFifo) {
    57         // We don't have enough data in the FIFO to fulfill the request. Ask for more data.
    58         fillBuffer(framesToConsume - m_framesInFifo);
    59     }
    60 
    61     // We have enough data now. Copy the requested number of samples to the destination.
     53    // Copy the requested number of samples to the destination.
    6254
    6355    size_t part1Length;
     
    8173        memcpy(destinationData, sourceData + m_readIndex, part1Length * sizeof(*sourceData));
    8274        // Handle wrap around of the FIFO, if needed.
    83         if (part2Length > 0)
     75        if (part2Length)
    8476            memcpy(destinationData + part1Length, sourceData, part2Length * sizeof(*sourceData));
    8577    }
    8678    m_readIndex = updateIndex(m_readIndex, framesToConsume);
     79    ASSERT(m_framesInFifo >= framesToConsume);
    8780    m_framesInFifo -= framesToConsume;
    88     ASSERT(m_framesInFifo >= 0);
    8981}
    9082
    91 void AudioPullFIFO::findWrapLengths(size_t index, size_t size, size_t& part1Length, size_t& part2Length)
     83void AudioFIFO::push(const AudioBus* sourceBus)
     84{
     85    // Copy the sourceBus into the FIFO buffer.
     86
     87    bool isGood = sourceBus && (m_framesInFifo + sourceBus->length() <= m_fifoLength);
     88    if (!isGood)
     89        return;
     90
     91    size_t sourceLength = sourceBus->length();
     92    size_t part1Length;
     93    size_t part2Length;
     94    findWrapLengths(m_readIndex, sourceLength, part1Length, part2Length);
     95
     96    size_t numberOfChannels = m_fifoAudioBus.numberOfChannels();
     97
     98    for (size_t channelIndex = 0; channelIndex < numberOfChannels; ++channelIndex) {
     99        float* destination = m_fifoAudioBus.channel(channelIndex)->mutableData();
     100        const float* source = sourceBus->channel(channelIndex)->data();
     101
     102        bool isCopyGood = ((m_writeIndex < m_fifoLength)
     103                           && (m_writeIndex + part1Length) <= m_fifoLength
     104                           && part2Length < m_fifoLength
     105                           && part1Length + part2Length <= sourceLength);
     106        ASSERT(isCopyGood);
     107        if (!isCopyGood)
     108            return;
     109
     110        memcpy(destination + m_writeIndex, source, part1Length * sizeof(*destination));
     111
     112        // Handle wrap around of the FIFO, if needed.
     113        if (part2Length)
     114            memcpy(destination, source + part1Length, part2Length * sizeof(*destination));
     115    }
     116       
     117    m_framesInFifo += sourceLength;
     118    ASSERT(m_framesInFifo <= m_fifoLength);
     119    m_writeIndex = updateIndex(m_writeIndex, sourceLength);
     120}
     121
     122void AudioFIFO::findWrapLengths(size_t index, size_t size, size_t& part1Length, size_t& part2Length)
    92123{
    93124    ASSERT(index < m_fifoLength && size <= m_fifoLength);
     
    109140}
    110141
    111 void AudioPullFIFO::fillBuffer(size_t numberOfFrames)
    112 {
    113     // Keep asking the provider to give us data until we have received at least |numberOfFrames| of
    114     // data. Stuff the data into the FIFO.
    115     size_t framesProvided = 0;
    116 
    117     while (framesProvided < numberOfFrames) {
    118         m_provider.provideInput(&m_tempBus, m_providerSize);
    119 
    120         size_t part1Length;
    121         size_t part2Length;
    122         findWrapLengths(m_writeIndex, m_providerSize, part1Length, part2Length);
    123 
    124         size_t numberOfChannels = m_fifoAudioBus.numberOfChannels();
    125        
    126         for (size_t channelIndex = 0; channelIndex < numberOfChannels; ++channelIndex) {
    127             float* destination = m_fifoAudioBus.channel(channelIndex)->mutableData();
    128             const float* source = m_tempBus.channel(channelIndex)->data();
    129 
    130             bool isCopyGood = (part1Length <= m_providerSize
    131                                && (part1Length + part2Length) <= m_providerSize
    132                                && (m_writeIndex < m_fifoLength)
    133                                && (m_writeIndex + part1Length) <= m_fifoLength
    134                                && part2Length < m_fifoLength);
    135             ASSERT(isCopyGood);
    136             if (!isCopyGood)
    137                 return;
    138 
    139             memcpy(destination + m_writeIndex, source, part1Length * sizeof(*destination));
    140             // Handle wrap around of the FIFO, if needed.
    141             if (part2Length > 0)
    142                 memcpy(destination, source + part1Length, part2Length * sizeof(*destination));
    143         }
    144 
    145         m_framesInFifo += m_providerSize;
    146         ASSERT(m_framesInFifo <= m_fifoLength);
    147         m_writeIndex = updateIndex(m_writeIndex, m_providerSize);
    148         framesProvided += m_providerSize;
    149     }
    150 }
    151 
    152142} // namespace WebCore
    153143
  • trunk/Source/WebCore/platform/audio/AudioFIFO.h

    r121809 r121810  
    2727 */
    2828
    29 #ifndef AudioPullFIFO_h
    30 #define AudioPullFIFO_h
     29#ifndef AudioFIFO_h
     30#define AudioFIFO_h
    3131
    3232#include "AudioBus.h"
    33 #include "AudioSourceProvider.h"
    3433
    3534namespace WebCore {
    3635
    37 // A FIFO (First In First Out) buffer to handle mismatches in buffer sizes between a provider and
    38 // receiver. The receiver will "pull" data from this FIFO. If data is already available in the
    39 // FIFO, it is provided to the receiver. If insufficient data is available to satisfy the request,
    40 // the FIFO will ask the provider for more data when necessary to fulfill a request. Contrast this
    41 // with a "push" FIFO, where the sender pushes data to the FIFO which will itself push the data to
    42 // the receiver when the FIFO is full.
    43 class AudioPullFIFO {
     36class AudioFIFO {
    4437public:
    45     // Create a FIFO that gets data from |provider|. The FIFO will be large enough to hold
    46     // |fifoLength| frames of data of |numberOfChannels| channels. The AudioSourceProvider will be
    47     // asked to produce |providerSize| frames when the FIFO needs more data.
    48     AudioPullFIFO(AudioSourceProvider& audioProvider, unsigned numberOfChannels, size_t fifoLength, size_t providerSize);
     38    // Create a FIFO large enough to hold |fifoLength| frames of data of |numberOfChannels| channels.
     39    AudioFIFO(unsigned numberOfChannels, size_t fifoLength);
    4940
    50     // Read |framesToConsume| frames from the FIFO into the destination. If the FIFO does not have
    51     // enough data, we ask the |provider| to get more data to fulfill the request.
     41    // Push the data from the bus into the FIFO.
     42    void push(const AudioBus*);
     43
     44    // Consume |framesToConsume| frames of data from the FIFO and put them in |destination|. The
     45    // corresponding frames are removed from the FIFO.
    5246    void consume(AudioBus* destination, size_t framesToConsume);
     47
     48    // Number of frames of data that are currently in the FIFO.
     49    size_t framesInFifo() const { return m_framesInFifo; }
    5350
    5451private:
     
    5855    void findWrapLengths(size_t index, size_t providerSize, size_t& part1Length, size_t& part2Length);
    5956   
    60     // Fill the FIFO buffer with at least |numberOfFrames| more data.
    61     void fillBuffer(size_t numberOfFrames);
    62 
    63     // The provider of the data in our FIFO.
    64     AudioSourceProvider& m_provider;
    65 
    6657    // The FIFO itself. In reality, the FIFO is a circular buffer.
    6758    AudioBus m_fifoAudioBus;
     
    7869    // Where to start writing to the FIFO.
    7970    size_t m_writeIndex;
    80 
    81     // Number of frames of data that the provider will produce per call.
    82     unsigned int m_providerSize;
    83 
    84     // Temporary workspace to hold the data from the provider.
    85     AudioBus m_tempBus;
    8671};
    8772
    8873} // namespace WebCore
    8974
    90 #endif // AudioPullFIFO.h
     75#endif // AudioFIFO.h
  • trunk/Source/WebCore/platform/audio/AudioPullFIFO.cpp

    r114970 r121810  
    3737AudioPullFIFO::AudioPullFIFO(AudioSourceProvider& audioProvider, unsigned numberOfChannels, size_t fifoLength, size_t providerSize)
    3838    : m_provider(audioProvider)
    39     , m_fifoAudioBus(numberOfChannels, fifoLength)
    40     , m_fifoLength(fifoLength)
    41     , m_framesInFifo(0)
    42     , m_readIndex(0)
    43     , m_writeIndex(0)
     39    , m_fifo(numberOfChannels, fifoLength)
    4440    , m_providerSize(providerSize)
    4541    , m_tempBus(numberOfChannels, providerSize)
     
    4945void AudioPullFIFO::consume(AudioBus* destination, size_t framesToConsume)
    5046{
    51     bool isGood = destination && (framesToConsume <= m_fifoLength);
    52     ASSERT(isGood);
    53     if (!isGood)
     47    if (!destination)
    5448        return;
    5549
    56     if (framesToConsume > m_framesInFifo) {
     50    if (framesToConsume > m_fifo.framesInFifo()) {
    5751        // We don't have enough data in the FIFO to fulfill the request. Ask for more data.
    58         fillBuffer(framesToConsume - m_framesInFifo);
     52        fillBuffer(framesToConsume - m_fifo.framesInFifo());
    5953    }
    6054
    61     // We have enough data now. Copy the requested number of samples to the destination.
    62 
    63     size_t part1Length;
    64     size_t part2Length;
    65     findWrapLengths(m_readIndex, framesToConsume, part1Length, part2Length);
    66 
    67     size_t numberOfChannels = m_fifoAudioBus.numberOfChannels();
    68 
    69     for (size_t channelIndex = 0; channelIndex < numberOfChannels; ++channelIndex) {
    70         float* destinationData = destination->channel(channelIndex)->mutableData();
    71         const float* sourceData = m_fifoAudioBus.channel(channelIndex)->data();
    72 
    73         bool isCopyGood = ((m_readIndex < m_fifoLength)
    74                            && (m_readIndex + part1Length) <= m_fifoLength
    75                            && (part1Length <= destination->length())
    76                            && (part1Length + part2Length) <= destination->length());
    77         ASSERT(isCopyGood);
    78         if (!isCopyGood)
    79             return;
    80 
    81         memcpy(destinationData, sourceData + m_readIndex, part1Length * sizeof(*sourceData));
    82         // Handle wrap around of the FIFO, if needed.
    83         if (part2Length > 0)
    84             memcpy(destinationData + part1Length, sourceData, part2Length * sizeof(*sourceData));
    85     }
    86     m_readIndex = updateIndex(m_readIndex, framesToConsume);
    87     m_framesInFifo -= framesToConsume;
    88     ASSERT(m_framesInFifo >= 0);
    89 }
    90 
    91 void AudioPullFIFO::findWrapLengths(size_t index, size_t size, size_t& part1Length, size_t& part2Length)
    92 {
    93     ASSERT(index < m_fifoLength && size <= m_fifoLength);
    94     if (index < m_fifoLength && size <= m_fifoLength) {
    95         if (index + size > m_fifoLength) {
    96             // Need to wrap. Figure out the length of each piece.
    97             part1Length = m_fifoLength - index;
    98             part2Length = size - part1Length;
    99         } else {
    100             // No wrap needed.
    101             part1Length = size;
    102             part2Length = 0;
    103         }
    104     } else {
    105         // Invalid values for index or size. Set the part lengths to zero so nothing is copied.
    106         part1Length = 0;
    107         part2Length = 0;
    108     }
     55    m_fifo.consume(destination, framesToConsume);
    10956}
    11057
     
    11865        m_provider.provideInput(&m_tempBus, m_providerSize);
    11966
    120         size_t part1Length;
    121         size_t part2Length;
    122         findWrapLengths(m_writeIndex, m_providerSize, part1Length, part2Length);
     67        m_fifo.push(&m_tempBus);
    12368
    124         size_t numberOfChannels = m_fifoAudioBus.numberOfChannels();
    125        
    126         for (size_t channelIndex = 0; channelIndex < numberOfChannels; ++channelIndex) {
    127             float* destination = m_fifoAudioBus.channel(channelIndex)->mutableData();
    128             const float* source = m_tempBus.channel(channelIndex)->data();
    129 
    130             bool isCopyGood = (part1Length <= m_providerSize
    131                                && (part1Length + part2Length) <= m_providerSize
    132                                && (m_writeIndex < m_fifoLength)
    133                                && (m_writeIndex + part1Length) <= m_fifoLength
    134                                && part2Length < m_fifoLength);
    135             ASSERT(isCopyGood);
    136             if (!isCopyGood)
    137                 return;
    138 
    139             memcpy(destination + m_writeIndex, source, part1Length * sizeof(*destination));
    140             // Handle wrap around of the FIFO, if needed.
    141             if (part2Length > 0)
    142                 memcpy(destination, source + part1Length, part2Length * sizeof(*destination));
    143         }
    144 
    145         m_framesInFifo += m_providerSize;
    146         ASSERT(m_framesInFifo <= m_fifoLength);
    147         m_writeIndex = updateIndex(m_writeIndex, m_providerSize);
    14869        framesProvided += m_providerSize;
    14970    }
  • trunk/Source/WebCore/platform/audio/AudioPullFIFO.h

    r114970 r121810  
    3131
    3232#include "AudioBus.h"
     33#include "AudioFIFO.h"
    3334#include "AudioSourceProvider.h"
    3435
     
    5354
    5455private:
    55     // Update the FIFO index by the step, with appropriate wrapping around the endpoint.
    56     int updateIndex(int index, int step) { return (index + step) % m_fifoLength; }
    57 
    58     void findWrapLengths(size_t index, size_t providerSize, size_t& part1Length, size_t& part2Length);
    59    
    6056    // Fill the FIFO buffer with at least |numberOfFrames| more data.
    6157    void fillBuffer(size_t numberOfFrames);
     
    6460    AudioSourceProvider& m_provider;
    6561
    66     // The FIFO itself. In reality, the FIFO is a circular buffer.
    67     AudioBus m_fifoAudioBus;
    68 
    69     // The total available space in the FIFO.
    70     size_t m_fifoLength;
    71 
    72     // The number of actual elements in the FIFO
    73     size_t m_framesInFifo;
    74 
    75     // Where to start reading from the FIFO.
    76     size_t m_readIndex;
    77 
    78     // Where to start writing to the FIFO.
    79     size_t m_writeIndex;
     62    // The actual FIFO
     63    AudioFIFO m_fifo;
    8064
    8165    // Number of frames of data that the provider will produce per call.
Note: See TracChangeset for help on using the changeset viewer.