• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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