2 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "platform/audio/AudioFIFO.h"
37 AudioFIFO::AudioFIFO(unsigned numberOfChannels
, size_t fifoLength
)
38 : m_fifoAudioBus(AudioBus::create(numberOfChannels
, fifoLength
))
39 , m_fifoLength(fifoLength
)
46 void AudioFIFO::consume(AudioBus
* destination
, size_t framesToConsume
)
48 bool isGood
= destination
&& (framesToConsume
<= m_fifoLength
) && (framesToConsume
<= m_framesInFifo
) && (destination
->length() >= framesToConsume
);
53 // Copy the requested number of samples to the destination.
57 findWrapLengths(m_readIndex
, framesToConsume
, part1Length
, part2Length
);
59 size_t numberOfChannels
= m_fifoAudioBus
->numberOfChannels();
61 for (size_t channelIndex
= 0; channelIndex
< numberOfChannels
; ++channelIndex
) {
62 float* destinationData
= destination
->channel(channelIndex
)->mutableData();
63 const float* sourceData
= m_fifoAudioBus
->channel(channelIndex
)->data();
65 bool isCopyGood
= ((m_readIndex
< m_fifoLength
)
66 && (m_readIndex
+ part1Length
) <= m_fifoLength
67 && (part1Length
<= destination
->length())
68 && (part1Length
+ part2Length
) <= destination
->length());
73 memcpy(destinationData
, sourceData
+ m_readIndex
, part1Length
* sizeof(*sourceData
));
74 // Handle wrap around of the FIFO, if needed.
76 memcpy(destinationData
+ part1Length
, sourceData
, part2Length
* sizeof(*sourceData
));
78 m_readIndex
= updateIndex(m_readIndex
, framesToConsume
);
79 ASSERT(m_framesInFifo
>= framesToConsume
);
80 m_framesInFifo
-= framesToConsume
;
83 void AudioFIFO::push(const AudioBus
* sourceBus
)
85 // Copy the sourceBus into the FIFO buffer.
87 bool isGood
= sourceBus
&& (m_framesInFifo
+ sourceBus
->length() <= m_fifoLength
);
91 size_t sourceLength
= sourceBus
->length();
94 findWrapLengths(m_writeIndex
, sourceLength
, part1Length
, part2Length
);
96 size_t numberOfChannels
= m_fifoAudioBus
->numberOfChannels();
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();
102 bool isCopyGood
= ((m_writeIndex
< m_fifoLength
)
103 && (m_writeIndex
+ part1Length
) <= m_fifoLength
104 && part2Length
< m_fifoLength
105 && part1Length
+ part2Length
<= sourceLength
);
110 memcpy(destination
+ m_writeIndex
, source
, part1Length
* sizeof(*destination
));
112 // Handle wrap around of the FIFO, if needed.
114 memcpy(destination
, source
+ part1Length
, part2Length
* sizeof(*destination
));
117 m_framesInFifo
+= sourceLength
;
118 ASSERT(m_framesInFifo
<= m_fifoLength
);
119 m_writeIndex
= updateIndex(m_writeIndex
, sourceLength
);
122 void AudioFIFO::findWrapLengths(size_t index
, size_t size
, size_t& part1Length
, size_t& part2Length
)
124 ASSERT_WITH_SECURITY_IMPLICATION(index
< m_fifoLength
&& size
<= m_fifoLength
);
125 if (index
< m_fifoLength
&& size
<= m_fifoLength
) {
126 if (index
+ size
> m_fifoLength
) {
127 // Need to wrap. Figure out the length of each piece.
128 part1Length
= m_fifoLength
- index
;
129 part2Length
= size
- part1Length
;
136 // Invalid values for index or size. Set the part lengths to zero so nothing is copied.
144 #endif // ENABLE(WEB_AUDIO)