1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 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. 16 * 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. 27 */ 28 29 #ifndef AudioBus_h 30 #define AudioBus_h 31 32 #include "AudioChannel.h" 33 #include <wtf/Noncopyable.h> 34 #include <wtf/PassOwnPtr.h> 35 #include <wtf/Vector.h> 36 37 namespace WebCore { 38 39 // An AudioBus represents a collection of one or more AudioChannels. 40 // The data layout is "planar" as opposed to "interleaved". 41 // An AudioBus with one channel is mono, an AudioBus with two channels is stereo, etc. 42 class AudioBus { 43 WTF_MAKE_NONCOPYABLE(AudioBus); 44 public: 45 enum { 46 ChannelLeft = 0, 47 ChannelRight = 1, 48 ChannelCenter = 2, // center and mono are the same 49 ChannelMono = 2, 50 ChannelLFE = 3, 51 ChannelSurroundLeft = 4, 52 ChannelSurroundRight = 5, 53 }; 54 55 enum { 56 LayoutCanonical = 0 57 // Can define non-standard layouts here 58 }; 59 60 // allocate indicates whether or not to initially have the AudioChannels created with managed storage. 61 // Normal usage is to pass true here, in which case the AudioChannels will memory-manage their own storage. 62 // If allocate is false then setChannelMemory() has to be called later on for each channel before the AudioBus is useable... 63 AudioBus(unsigned numberOfChannels, size_t length, bool allocate = true); 64 65 // Tells the given channel to use an externally allocated buffer. 66 void setChannelMemory(unsigned channelIndex, float* storage, size_t length); 67 68 // Channels numberOfChannels()69 unsigned numberOfChannels() const { return m_channels.size(); } 70 channel(unsigned channel)71 AudioChannel* channel(unsigned channel) { return m_channels[channel].get(); } channel(unsigned channel)72 const AudioChannel* channel(unsigned channel) const { return const_cast<AudioBus*>(this)->m_channels[channel].get(); } 73 AudioChannel* channelByType(unsigned type); 74 75 // Number of sample-frames length()76 size_t length() const { return m_length; } 77 78 // Sample-rate : 0.0 if unknown or "don't care" sampleRate()79 double sampleRate() const { return m_sampleRate; } setSampleRate(double sampleRate)80 void setSampleRate(double sampleRate) { m_sampleRate = sampleRate; } 81 82 // Zeroes all channels. 83 void zero(); 84 85 // Returns true if the channel count and frame-size match. 86 bool topologyMatches(const AudioBus &sourceBus) const; 87 88 // Creates a new buffer from a range in the source buffer. 89 // 0 may be returned if the range does not fit in the sourceBuffer 90 static PassOwnPtr<AudioBus> createBufferFromRange(AudioBus* sourceBuffer, unsigned startFrame, unsigned endFrame); 91 92 93 #if !PLATFORM(MAC) 94 // Creates a new AudioBus by sample-rate converting sourceBus to the newSampleRate. 95 // setSampleRate() must have been previously called on sourceBus. 96 // Note: sample-rate conversion is already handled in the file-reading code for the mac port, so we don't need this. 97 static PassOwnPtr<AudioBus> createBySampleRateConverting(AudioBus* sourceBus, bool mixToMono, double newSampleRate); 98 #endif 99 100 // Creates a new AudioBus by mixing all the channels down to mono. 101 // If sourceBus is already mono, then the returned AudioBus will simply be a copy. 102 static PassOwnPtr<AudioBus> createByMixingToMono(AudioBus* sourceBus); 103 104 // Scales all samples by the same amount. 105 void scale(double scale); 106 107 // Master gain for this bus - used with sumWithGainFrom() below setGain(double gain)108 void setGain(double gain) { m_busGain = gain; } gain()109 double gain() { return m_busGain; } 110 reset()111 void reset() { m_isFirstTime = true; } // for de-zippering 112 113 // Assuming sourceBus has the same topology, copies sample data from each channel of sourceBus to our corresponding channel. 114 void copyFrom(const AudioBus &sourceBus); 115 116 // Sums the sourceBus into our bus with unity gain. 117 // Our own internal gain m_busGain is ignored. 118 void sumFrom(const AudioBus &sourceBus); 119 120 // Copy or sum each channel from sourceBus into our corresponding channel. 121 // We scale by targetGain (and our own internal gain m_busGain), performing "de-zippering" to smoothly change from *lastMixGain to (targetGain*m_busGain). 122 // The caller is responsible for setting up lastMixGain to point to storage which is unique for every "stream" which will be summed to this bus. 123 // This represents the dezippering memory. 124 void copyWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain); 125 void sumWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain); 126 127 // Returns maximum absolute value across all channels (useful for normalization). 128 float maxAbsValue() const; 129 130 // Makes maximum absolute value == 1.0 (if possible). 131 void normalize(); 132 133 static PassOwnPtr<AudioBus> loadPlatformResource(const char* name, double sampleRate); 134 135 protected: AudioBus()136 AudioBus() { }; 137 138 void processWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain, bool sumToBus); 139 void processWithGainFromMonoStereo(const AudioBus &sourceBus, double* lastMixGain, double targetGain, bool sumToBus); 140 141 size_t m_length; 142 143 Vector<OwnPtr<AudioChannel> > m_channels; 144 145 int m_layout; 146 147 double m_busGain; 148 bool m_isFirstTime; 149 double m_sampleRate; // 0.0 if unknown or N/A 150 }; 151 152 } // WebCore 153 154 #endif // AudioBus_h 155