Line data Source code
1 : /*
2 : * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h"
12 :
13 : #include <assert.h>
14 :
15 : #include <algorithm>
16 :
17 : #include "webrtc/base/checks.h"
18 : #include "webrtc/typedefs.h"
19 :
20 : namespace webrtc {
21 :
22 0 : AudioMultiVector::AudioMultiVector(size_t N) {
23 0 : assert(N > 0);
24 0 : if (N < 1) N = 1;
25 0 : for (size_t n = 0; n < N; ++n) {
26 0 : channels_.push_back(new AudioVector);
27 : }
28 0 : num_channels_ = N;
29 0 : }
30 :
31 0 : AudioMultiVector::AudioMultiVector(size_t N, size_t initial_size) {
32 0 : assert(N > 0);
33 0 : if (N < 1) N = 1;
34 0 : for (size_t n = 0; n < N; ++n) {
35 0 : channels_.push_back(new AudioVector(initial_size));
36 : }
37 0 : num_channels_ = N;
38 0 : }
39 :
40 0 : AudioMultiVector::~AudioMultiVector() {
41 0 : std::vector<AudioVector*>::iterator it = channels_.begin();
42 0 : while (it != channels_.end()) {
43 0 : delete (*it);
44 0 : ++it;
45 : }
46 0 : }
47 :
48 0 : void AudioMultiVector::Clear() {
49 0 : for (size_t i = 0; i < num_channels_; ++i) {
50 0 : channels_[i]->Clear();
51 : }
52 0 : }
53 :
54 0 : void AudioMultiVector::Zeros(size_t length) {
55 0 : for (size_t i = 0; i < num_channels_; ++i) {
56 0 : channels_[i]->Clear();
57 0 : channels_[i]->Extend(length);
58 : }
59 0 : }
60 :
61 0 : void AudioMultiVector::CopyTo(AudioMultiVector* copy_to) const {
62 0 : if (copy_to) {
63 0 : for (size_t i = 0; i < num_channels_; ++i) {
64 0 : channels_[i]->CopyTo(&(*copy_to)[i]);
65 : }
66 : }
67 0 : }
68 :
69 0 : void AudioMultiVector::PushBackInterleaved(const int16_t* append_this,
70 : size_t length) {
71 0 : assert(length % num_channels_ == 0);
72 0 : if (num_channels_ == 1) {
73 : // Special case to avoid extra allocation and data shuffling.
74 0 : channels_[0]->PushBack(append_this, length);
75 0 : return;
76 : }
77 0 : size_t length_per_channel = length / num_channels_;
78 0 : int16_t* temp_array = new int16_t[length_per_channel]; // Temporary storage.
79 0 : for (size_t channel = 0; channel < num_channels_; ++channel) {
80 : // Copy elements to |temp_array|.
81 : // Set |source_ptr| to first element of this channel.
82 0 : const int16_t* source_ptr = &append_this[channel];
83 0 : for (size_t i = 0; i < length_per_channel; ++i) {
84 0 : temp_array[i] = *source_ptr;
85 0 : source_ptr += num_channels_; // Jump to next element of this channel.
86 : }
87 0 : channels_[channel]->PushBack(temp_array, length_per_channel);
88 : }
89 0 : delete [] temp_array;
90 : }
91 :
92 0 : void AudioMultiVector::PushBack(const AudioMultiVector& append_this) {
93 0 : assert(num_channels_ == append_this.num_channels_);
94 0 : if (num_channels_ == append_this.num_channels_) {
95 0 : for (size_t i = 0; i < num_channels_; ++i) {
96 0 : channels_[i]->PushBack(append_this[i]);
97 : }
98 : }
99 0 : }
100 :
101 0 : void AudioMultiVector::PushBackFromIndex(const AudioMultiVector& append_this,
102 : size_t index) {
103 0 : assert(index < append_this.Size());
104 0 : index = std::min(index, append_this.Size() - 1);
105 0 : size_t length = append_this.Size() - index;
106 0 : assert(num_channels_ == append_this.num_channels_);
107 0 : if (num_channels_ == append_this.num_channels_) {
108 0 : for (size_t i = 0; i < num_channels_; ++i) {
109 0 : channels_[i]->PushBack(append_this[i], length, index);
110 : }
111 : }
112 0 : }
113 :
114 0 : void AudioMultiVector::PopFront(size_t length) {
115 0 : for (size_t i = 0; i < num_channels_; ++i) {
116 0 : channels_[i]->PopFront(length);
117 : }
118 0 : }
119 :
120 0 : void AudioMultiVector::PopBack(size_t length) {
121 0 : for (size_t i = 0; i < num_channels_; ++i) {
122 0 : channels_[i]->PopBack(length);
123 : }
124 0 : }
125 :
126 0 : size_t AudioMultiVector::ReadInterleaved(size_t length,
127 : int16_t* destination) const {
128 0 : return ReadInterleavedFromIndex(0, length, destination);
129 : }
130 :
131 0 : size_t AudioMultiVector::ReadInterleavedFromIndex(size_t start_index,
132 : size_t length,
133 : int16_t* destination) const {
134 0 : RTC_DCHECK(destination);
135 0 : size_t index = 0; // Number of elements written to |destination| so far.
136 0 : RTC_DCHECK_LE(start_index, Size());
137 0 : start_index = std::min(start_index, Size());
138 0 : if (length + start_index > Size()) {
139 0 : length = Size() - start_index;
140 : }
141 0 : if (num_channels_ == 1) {
142 : // Special case to avoid the nested for loop below.
143 0 : (*this)[0].CopyTo(length, start_index, destination);
144 0 : return length;
145 : }
146 0 : for (size_t i = 0; i < length; ++i) {
147 0 : for (size_t channel = 0; channel < num_channels_; ++channel) {
148 0 : destination[index] = (*this)[channel][i + start_index];
149 0 : ++index;
150 : }
151 : }
152 0 : return index;
153 : }
154 :
155 0 : size_t AudioMultiVector::ReadInterleavedFromEnd(size_t length,
156 : int16_t* destination) const {
157 0 : length = std::min(length, Size()); // Cannot read more than Size() elements.
158 0 : return ReadInterleavedFromIndex(Size() - length, length, destination);
159 : }
160 :
161 0 : void AudioMultiVector::OverwriteAt(const AudioMultiVector& insert_this,
162 : size_t length,
163 : size_t position) {
164 0 : assert(num_channels_ == insert_this.num_channels_);
165 : // Cap |length| at the length of |insert_this|.
166 0 : assert(length <= insert_this.Size());
167 0 : length = std::min(length, insert_this.Size());
168 0 : if (num_channels_ == insert_this.num_channels_) {
169 0 : for (size_t i = 0; i < num_channels_; ++i) {
170 0 : channels_[i]->OverwriteAt(insert_this[i], length, position);
171 : }
172 : }
173 0 : }
174 :
175 0 : void AudioMultiVector::CrossFade(const AudioMultiVector& append_this,
176 : size_t fade_length) {
177 0 : assert(num_channels_ == append_this.num_channels_);
178 0 : if (num_channels_ == append_this.num_channels_) {
179 0 : for (size_t i = 0; i < num_channels_; ++i) {
180 0 : channels_[i]->CrossFade(append_this[i], fade_length);
181 : }
182 : }
183 0 : }
184 :
185 0 : size_t AudioMultiVector::Channels() const {
186 0 : return num_channels_;
187 : }
188 :
189 0 : size_t AudioMultiVector::Size() const {
190 0 : assert(channels_[0]);
191 0 : return channels_[0]->Size();
192 : }
193 :
194 0 : void AudioMultiVector::AssertSize(size_t required_size) {
195 0 : if (Size() < required_size) {
196 0 : size_t extend_length = required_size - Size();
197 0 : for (size_t channel = 0; channel < num_channels_; ++channel) {
198 0 : channels_[channel]->Extend(extend_length);
199 : }
200 : }
201 0 : }
202 :
203 0 : bool AudioMultiVector::Empty() const {
204 0 : assert(channels_[0]);
205 0 : return channels_[0]->Empty();
206 : }
207 :
208 0 : void AudioMultiVector::CopyChannel(size_t from_channel, size_t to_channel) {
209 0 : assert(from_channel < num_channels_);
210 0 : assert(to_channel < num_channels_);
211 0 : channels_[from_channel]->CopyTo(channels_[to_channel]);
212 0 : }
213 :
214 0 : const AudioVector& AudioMultiVector::operator[](size_t index) const {
215 0 : return *(channels_[index]);
216 : }
217 :
218 0 : AudioVector& AudioMultiVector::operator[](size_t index) {
219 0 : return *(channels_[index]);
220 : }
221 :
222 : } // namespace webrtc
|