a87f55d3132ec3a956e2e946fb64f1a045791e75
[WebKit-https.git] / Source / WebCore / platform / audio / AudioBus.h
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
69     unsigned numberOfChannels() const { return m_channels.size(); }
70
71     AudioChannel* channel(unsigned channel) { return m_channels[channel].get(); }
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
76     size_t length() const { return m_length; }
77
78     // Sample-rate : 0.0 if unknown or "don't care"
79     double sampleRate() const { return m_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
108     void setGain(double gain) { m_busGain = gain; }
109     double gain() { return m_busGain; }
110
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     // Copies the sourceBus by scaling with sample-accurate gain values.
128     void copyWithSampleAccurateGainValuesFrom(const AudioBus &sourceBus, float* gainValues, unsigned numberOfGainValues);
129
130     // Returns maximum absolute value across all channels (useful for normalization).
131     float maxAbsValue() const;
132
133     // Makes maximum absolute value == 1.0 (if possible).
134     void normalize();
135
136     static PassOwnPtr<AudioBus> loadPlatformResource(const char* name, double sampleRate);
137
138 protected:
139     AudioBus() { };
140
141     void processWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain, bool sumToBus);
142     void processWithGainFromMonoStereo(const AudioBus &sourceBus, double* lastMixGain, double targetGain, bool sumToBus);
143
144     size_t m_length;
145
146     Vector<OwnPtr<AudioChannel> > m_channels;
147
148     int m_layout;
149
150     double m_busGain;
151     bool m_isFirstTime;
152     double m_sampleRate; // 0.0 if unknown or N/A
153 };
154
155 } // WebCore
156
157 #endif // AudioBus_h