1/*
2Copyright 2018 Google Inc. All Rights Reserved.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS-IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef RESONANCE_AUDIO_BASE_AUDIO_BUFFER_H_
18#define RESONANCE_AUDIO_BASE_AUDIO_BUFFER_H_
19
20#include <algorithm>
21#include <memory>
22
23#include "base/integral_types.h"
24#include "base/aligned_allocator.h"
25#include "base/channel_view.h"
26#include "base/constants_and_types.h"
27#include "base/logging.h"
28#include "base/simd_utils.h"
29
30
31namespace vraudio {
32
33// Audio buffer that manages multi-channel audio data in a planar data format.
34// All channels are sequentially stored within a single consecutive chunk of
35// memory. To access individual channel data, the array subscript operator can
36// be used to obtain a |AudioBuffer::Channel|. Note that the user must guarantee
37// that the AudioBuffer instance lives as long as its channel data is accessed
38// via |AudioBuffer::Channel|s. Note that allocated buffers may *not* be
39// initialized to zero.
40//
41// Examples:
42//
43// // Range-based for-loop over all channels and all samples.
44// AudioBuffer audio_buffer(...)
45// for (AudioBuffer::Channel& channel : audio_buffer) {
46// for (float& sample : channel) {
47// sample *= gain;
48// }
49// }
50//
51// // Range-based for-loop over all channels and array subscripts-based for-loop
52// // to access samples.
53// AudioBuffer audio_buffer(...)
54// for (AudioBuffer::Channel& channel : audio_buffer) {
55// for (size_t i = 0; i < channel.num_frames(); ++i) {
56// channel[i] *= gain;
57// }
58// }
59//
60// // Array subscript-based for-loops over all channels samples.
61// // AudioBuffer audio_buffer(...)
62// for (size_t c=0; c < audio_buffer.num_channels(); ++c) {
63// // First obtain a reference to AudioBuffer::Channel.
64// AudioBuffer::Channel& channel = audio_buffer[c];
65// for (size_t i = 0; i < channel.num_frames(); ++i) {
66// channel[i] *= gain;
67// }
68// }
69//
70// Note do *NOT* use double array subscripts to iterate over multiple samples
71// since it performs a channel iterator lookup for every sample:
72// for (size_t c=0; c < audio_buffer.num_channels(); ++c) {
73// for (size_t i = 0; i < channel.size(); ++i) {
74// audio_buffer[c][i] *= gain; // *BAD*
75// }
76// }
77//
78class AudioBuffer {
79 public:
80 // View on separate audio channel.
81 typedef ChannelView Channel;
82
83 // Allocator class to allocate aligned floats.
84 typedef AlignedAllocator<float, kMemoryAlignmentBytes> FloatAllocator;
85
86 // Allocator class to allocate aligned int16s.
87 typedef AlignedAllocator<int16, kMemoryAlignmentBytes> Int16Allocator;
88
89 // AlignedFloatBuffer for storing audio data.
90 typedef std::vector<float, FloatAllocator> AlignedFloatVector;
91
92 // AlignedInt16Buffer for storing audio data.
93 typedef std::vector<int16, Int16Allocator> AlignedInt16Vector;
94
95 // Default constructor initializes an empty |AudioBuffer|.
96 AudioBuffer();
97
98 // Constructor.
99 //
100 // @param num_channels Number of channels.
101 // @param num_frames Number of frames.
102 AudioBuffer(size_t num_channels, size_t num_frames);
103
104 // Move constructor.
105 AudioBuffer(AudioBuffer&& other);
106
107 // Copy constructor is explicitly deleted to prevent accidental copies.
108 // Use copy assignment operator instead.
109 AudioBuffer(const AudioBuffer& other) = delete;
110
111 // Copy assignment from AudioBuffer.
112 AudioBuffer& operator=(const AudioBuffer& other);
113
114 // Returns the number of audio channels.
115 size_t num_channels() const { return channel_views_.size(); }
116
117 // Returns the number of frames per buffer.
118 size_t num_frames() const { return num_frames_; }
119
120 // Returns this buffer's source id.
121 SourceId source_id() const { return source_id_; }
122
123 // Returns a reference to the selected ChannelView.
124 Channel& operator[](size_t channel) {
125 DCHECK_LT(channel, channel_views_.size());
126 return channel_views_[channel];
127 }
128
129 // Returns a const reference to the selected ChannelView.
130 const Channel& operator[](size_t channel) const {
131 DCHECK_LT(channel, channel_views_.size());
132 return channel_views_[channel];
133 }
134
135 // Copy assignment from std::vector<std::vector<float>>.
136 AudioBuffer& operator=(const std::vector<std::vector<float>>& other) {
137 DCHECK_EQ(other.size(), channel_views_.size());
138 for (size_t channel = 0; channel < channel_views_.size(); ++channel) {
139 channel_views_[channel] = other[channel];
140 }
141 return *this;
142 }
143
144 // += operator
145 AudioBuffer& operator+=(const AudioBuffer& other) {
146 DCHECK_EQ(other.num_channels(), num_channels());
147 DCHECK_EQ(other.num_frames(), num_frames());
148 for (size_t i = 0; i < channel_views_.size(); ++i)
149 channel_views_[i] += other[i];
150
151 return *this;
152 }
153
154 // -= operator
155 AudioBuffer& operator-=(const AudioBuffer& other) {
156 DCHECK_EQ(other.num_channels(), num_channels());
157 DCHECK_EQ(other.num_frames(), num_frames());
158 for (size_t i = 0; i < channel_views_.size(); ++i)
159 channel_views_[i] -= other[i];
160
161 return *this;
162 }
163
164 // Returns an iterator to the ChannelView of the first channel.
165 std::vector<Channel>::iterator begin() { return channel_views_.begin(); }
166
167 // Returns an iterator to the end of the ChannelView vector.
168 std::vector<Channel>::iterator end() { return channel_views_.end(); }
169
170 // Returns a const_iterator to the ChannelView of the first channel.
171 std::vector<Channel>::const_iterator begin() const {
172 return channel_views_.begin();
173 }
174
175 // Returns an const_iterator to the end of the ChannelView vector.
176 std::vector<Channel>::const_iterator end() const {
177 return channel_views_.end();
178 }
179
180 // Fills all channels with zeros and reenables |Channel|s.
181 void Clear() {
182 for (Channel& channel : channel_views_) {
183 channel.SetEnabled(true);
184 channel.Clear();
185 }
186 }
187
188 // Returns the number of allocated frames per |Channel|. Note this may
189 // differ from the actual size of the |Channel| to ensure alignment of all
190 // |Channel|s.
191 size_t GetChannelStride() const {
192 return FindNextAlignedArrayIndex(length: num_frames_, type_size_bytes: sizeof(float),
193 memory_alignment_bytes: kMemoryAlignmentBytes);
194 }
195
196 // Sets the source id of which the buffer belongs to.
197 void set_source_id(SourceId source_id) { source_id_ = source_id; }
198
199 private:
200 // Allocates memory and initializes vector of |ChannelView|s.
201 void InitChannelViews(size_t num_channels);
202
203 // Number of frames per buffer.
204 size_t num_frames_;
205
206 // Audio buffer that sequentially stores multiple audio channels in a planar
207 // format.
208 AlignedFloatVector data_;
209
210 // Size of audio buffer.
211 size_t data_size_;
212
213 // Vector of |AudioBuffer::Channel|s.
214 std::vector<Channel> channel_views_;
215
216 // Id of a source that this buffer belongs to.
217 SourceId source_id_;
218};
219
220} // namespace vraudio
221
222#endif // RESONANCE_AUDIO_BASE_AUDIO_BUFFER_H_
223

source code of qtmultimedia/src/3rdparty/resonance-audio/resonance_audio/base/audio_buffer.h