Changeset 121810 in webkit
- Timestamp:
- Jul 3, 2012 4:40:50 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r121803 r121810 1 2012-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 1 36 2012-07-03 Nate Chapin <japhet@chromium.org> 2 37 -
trunk/Source/WebCore/WebCore.gypi
r121778 r121810 3260 3260 'platform/audio/AudioDSPKernelProcessor.h', 3261 3261 'platform/audio/AudioDestination.h', 3262 'platform/audio/AudioFIFO.cpp', 3263 'platform/audio/AudioFIFO.h', 3262 3264 'platform/audio/AudioFileReader.h', 3263 3265 'platform/audio/AudioProcessor.h', -
trunk/Source/WebCore/platform/audio/AudioFIFO.cpp
r121809 r121810 31 31 #if ENABLE(WEB_AUDIO) 32 32 33 #include "Audio PullFIFO.h"33 #include "AudioFIFO.h" 34 34 35 35 namespace WebCore { 36 36 37 AudioPullFIFO::AudioPullFIFO(AudioSourceProvider& audioProvider, unsigned numberOfChannels, size_t fifoLength, size_t providerSize) 38 : m_provider(audioProvider) 39 , m_fifoAudioBus(numberOfChannels, fifoLength) 37 AudioFIFO::AudioFIFO(unsigned numberOfChannels, size_t fifoLength) 38 : m_fifoAudioBus(numberOfChannels, fifoLength) 40 39 , m_fifoLength(fifoLength) 41 40 , m_framesInFifo(0) 42 41 , m_readIndex(0) 43 42 , m_writeIndex(0) 44 , m_providerSize(providerSize)45 , m_tempBus(numberOfChannels, providerSize)46 43 { 47 44 } 48 45 49 void Audio PullFIFO::consume(AudioBus* destination, size_t framesToConsume)46 void AudioFIFO::consume(AudioBus* destination, size_t framesToConsume) 50 47 { 51 bool isGood = destination && (framesToConsume <= m_fifoLength) ;48 bool isGood = destination && (framesToConsume <= m_fifoLength) && (framesToConsume <= m_framesInFifo) && (destination->length() >= framesToConsume); 52 49 ASSERT(isGood); 53 50 if (!isGood) 54 51 return; 55 52 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. 62 54 63 55 size_t part1Length; … … 81 73 memcpy(destinationData, sourceData + m_readIndex, part1Length * sizeof(*sourceData)); 82 74 // Handle wrap around of the FIFO, if needed. 83 if (part2Length > 0)75 if (part2Length) 84 76 memcpy(destinationData + part1Length, sourceData, part2Length * sizeof(*sourceData)); 85 77 } 86 78 m_readIndex = updateIndex(m_readIndex, framesToConsume); 79 ASSERT(m_framesInFifo >= framesToConsume); 87 80 m_framesInFifo -= framesToConsume; 88 ASSERT(m_framesInFifo >= 0);89 81 } 90 82 91 void AudioPullFIFO::findWrapLengths(size_t index, size_t size, size_t& part1Length, size_t& part2Length) 83 void 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 122 void AudioFIFO::findWrapLengths(size_t index, size_t size, size_t& part1Length, size_t& part2Length) 92 123 { 93 124 ASSERT(index < m_fifoLength && size <= m_fifoLength); … … 109 140 } 110 141 111 void AudioPullFIFO::fillBuffer(size_t numberOfFrames)112 {113 // Keep asking the provider to give us data until we have received at least |numberOfFrames| of114 // 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_providerSize131 && (part1Length + part2Length) <= m_providerSize132 && (m_writeIndex < m_fifoLength)133 && (m_writeIndex + part1Length) <= m_fifoLength134 && 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 152 142 } // namespace WebCore 153 143 -
trunk/Source/WebCore/platform/audio/AudioFIFO.h
r121809 r121810 27 27 */ 28 28 29 #ifndef Audio PullFIFO_h30 #define Audio PullFIFO_h29 #ifndef AudioFIFO_h 30 #define AudioFIFO_h 31 31 32 32 #include "AudioBus.h" 33 #include "AudioSourceProvider.h"34 33 35 34 namespace WebCore { 36 35 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 { 36 class AudioFIFO { 44 37 public: 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); 49 40 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. 52 46 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; } 53 50 54 51 private: … … 58 55 void findWrapLengths(size_t index, size_t providerSize, size_t& part1Length, size_t& part2Length); 59 56 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 66 57 // The FIFO itself. In reality, the FIFO is a circular buffer. 67 58 AudioBus m_fifoAudioBus; … … 78 69 // Where to start writing to the FIFO. 79 70 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;86 71 }; 87 72 88 73 } // namespace WebCore 89 74 90 #endif // Audio PullFIFO.h75 #endif // AudioFIFO.h -
trunk/Source/WebCore/platform/audio/AudioPullFIFO.cpp
r114970 r121810 37 37 AudioPullFIFO::AudioPullFIFO(AudioSourceProvider& audioProvider, unsigned numberOfChannels, size_t fifoLength, size_t providerSize) 38 38 : 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) 44 40 , m_providerSize(providerSize) 45 41 , m_tempBus(numberOfChannels, providerSize) … … 49 45 void AudioPullFIFO::consume(AudioBus* destination, size_t framesToConsume) 50 46 { 51 bool isGood = destination && (framesToConsume <= m_fifoLength); 52 ASSERT(isGood); 53 if (!isGood) 47 if (!destination) 54 48 return; 55 49 56 if (framesToConsume > m_f ramesInFifo) {50 if (framesToConsume > m_fifo.framesInFifo()) { 57 51 // We don't have enough data in the FIFO to fulfill the request. Ask for more data. 58 fillBuffer(framesToConsume - m_f ramesInFifo);52 fillBuffer(framesToConsume - m_fifo.framesInFifo()); 59 53 } 60 54 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); 109 56 } 110 57 … … 118 65 m_provider.provideInput(&m_tempBus, m_providerSize); 119 66 120 size_t part1Length; 121 size_t part2Length; 122 findWrapLengths(m_writeIndex, m_providerSize, part1Length, part2Length); 67 m_fifo.push(&m_tempBus); 123 68 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_providerSize131 && (part1Length + part2Length) <= m_providerSize132 && (m_writeIndex < m_fifoLength)133 && (m_writeIndex + part1Length) <= m_fifoLength134 && 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 69 framesProvided += m_providerSize; 149 70 } -
trunk/Source/WebCore/platform/audio/AudioPullFIFO.h
r114970 r121810 31 31 32 32 #include "AudioBus.h" 33 #include "AudioFIFO.h" 33 34 #include "AudioSourceProvider.h" 34 35 … … 53 54 54 55 private: 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 60 56 // Fill the FIFO buffer with at least |numberOfFrames| more data. 61 57 void fillBuffer(size_t numberOfFrames); … … 64 60 AudioSourceProvider& m_provider; 65 61 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; 80 64 81 65 // Number of frames of data that the provider will produce per call.
Note: See TracChangeset
for help on using the changeset viewer.