• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "modules/audio_coding/neteq/audio_multi_vector.h"
12 
13 
14 #include <algorithm>
15 
16 #include "rtc_base/checks.h"
17 
18 namespace webrtc {
19 
AudioMultiVector(size_t N)20 AudioMultiVector::AudioMultiVector(size_t N) {
21   RTC_DCHECK_GT(N, 0);
22   if (N < 1)
23     N = 1;
24   for (size_t n = 0; n < N; ++n) {
25     channels_.push_back(new AudioVector);
26   }
27   num_channels_ = N;
28 }
29 
AudioMultiVector(size_t N,size_t initial_size)30 AudioMultiVector::AudioMultiVector(size_t N, size_t initial_size) {
31   RTC_DCHECK_GT(N, 0);
32   if (N < 1)
33     N = 1;
34   for (size_t n = 0; n < N; ++n) {
35     channels_.push_back(new AudioVector(initial_size));
36   }
37   num_channels_ = N;
38 }
39 
~AudioMultiVector()40 AudioMultiVector::~AudioMultiVector() {
41   std::vector<AudioVector*>::iterator it = channels_.begin();
42   while (it != channels_.end()) {
43     delete (*it);
44     ++it;
45   }
46 }
47 
Clear()48 void AudioMultiVector::Clear() {
49   for (size_t i = 0; i < num_channels_; ++i) {
50     channels_[i]->Clear();
51   }
52 }
53 
Zeros(size_t length)54 void AudioMultiVector::Zeros(size_t length) {
55   for (size_t i = 0; i < num_channels_; ++i) {
56     channels_[i]->Clear();
57     channels_[i]->Extend(length);
58   }
59 }
60 
CopyTo(AudioMultiVector * copy_to) const61 void AudioMultiVector::CopyTo(AudioMultiVector* copy_to) const {
62   if (copy_to) {
63     for (size_t i = 0; i < num_channels_; ++i) {
64       channels_[i]->CopyTo(&(*copy_to)[i]);
65     }
66   }
67 }
68 
PushBackInterleaved(rtc::ArrayView<const int16_t> append_this)69 void AudioMultiVector::PushBackInterleaved(
70     rtc::ArrayView<const int16_t> append_this) {
71   RTC_DCHECK_EQ(append_this.size() % num_channels_, 0);
72   if (append_this.empty()) {
73     return;
74   }
75   if (num_channels_ == 1) {
76     // Special case to avoid extra allocation and data shuffling.
77     channels_[0]->PushBack(append_this.data(), append_this.size());
78     return;
79   }
80   size_t length_per_channel = append_this.size() / num_channels_;
81   int16_t* temp_array = new int16_t[length_per_channel];  // Temporary storage.
82   for (size_t channel = 0; channel < num_channels_; ++channel) {
83     // Copy elements to `temp_array`.
84     for (size_t i = 0; i < length_per_channel; ++i) {
85       temp_array[i] = append_this[channel + i * num_channels_];
86     }
87     channels_[channel]->PushBack(temp_array, length_per_channel);
88   }
89   delete[] temp_array;
90 }
91 
PushBack(const AudioMultiVector & append_this)92 void AudioMultiVector::PushBack(const AudioMultiVector& append_this) {
93   RTC_DCHECK_EQ(num_channels_, append_this.num_channels_);
94   if (num_channels_ == append_this.num_channels_) {
95     for (size_t i = 0; i < num_channels_; ++i) {
96       channels_[i]->PushBack(append_this[i]);
97     }
98   }
99 }
100 
PushBackFromIndex(const AudioMultiVector & append_this,size_t index)101 void AudioMultiVector::PushBackFromIndex(const AudioMultiVector& append_this,
102                                          size_t index) {
103   RTC_DCHECK_LT(index, append_this.Size());
104   index = std::min(index, append_this.Size() - 1);
105   size_t length = append_this.Size() - index;
106   RTC_DCHECK_EQ(num_channels_, append_this.num_channels_);
107   if (num_channels_ == append_this.num_channels_) {
108     for (size_t i = 0; i < num_channels_; ++i) {
109       channels_[i]->PushBack(append_this[i], length, index);
110     }
111   }
112 }
113 
PopFront(size_t length)114 void AudioMultiVector::PopFront(size_t length) {
115   for (size_t i = 0; i < num_channels_; ++i) {
116     channels_[i]->PopFront(length);
117   }
118 }
119 
PopBack(size_t length)120 void AudioMultiVector::PopBack(size_t length) {
121   for (size_t i = 0; i < num_channels_; ++i) {
122     channels_[i]->PopBack(length);
123   }
124 }
125 
ReadInterleaved(size_t length,int16_t * destination) const126 size_t AudioMultiVector::ReadInterleaved(size_t length,
127                                          int16_t* destination) const {
128   return ReadInterleavedFromIndex(0, length, destination);
129 }
130 
ReadInterleavedFromIndex(size_t start_index,size_t length,int16_t * destination) const131 size_t AudioMultiVector::ReadInterleavedFromIndex(size_t start_index,
132                                                   size_t length,
133                                                   int16_t* destination) const {
134   RTC_DCHECK(destination);
135   size_t index = 0;  // Number of elements written to `destination` so far.
136   RTC_DCHECK_LE(start_index, Size());
137   start_index = std::min(start_index, Size());
138   if (length + start_index > Size()) {
139     length = Size() - start_index;
140   }
141   if (num_channels_ == 1) {
142     // Special case to avoid the nested for loop below.
143     (*this)[0].CopyTo(length, start_index, destination);
144     return length;
145   }
146   for (size_t i = 0; i < length; ++i) {
147     for (size_t channel = 0; channel < num_channels_; ++channel) {
148       destination[index] = (*this)[channel][i + start_index];
149       ++index;
150     }
151   }
152   return index;
153 }
154 
ReadInterleavedFromEnd(size_t length,int16_t * destination) const155 size_t AudioMultiVector::ReadInterleavedFromEnd(size_t length,
156                                                 int16_t* destination) const {
157   length = std::min(length, Size());  // Cannot read more than Size() elements.
158   return ReadInterleavedFromIndex(Size() - length, length, destination);
159 }
160 
OverwriteAt(const AudioMultiVector & insert_this,size_t length,size_t position)161 void AudioMultiVector::OverwriteAt(const AudioMultiVector& insert_this,
162                                    size_t length,
163                                    size_t position) {
164   RTC_DCHECK_EQ(num_channels_, insert_this.num_channels_);
165   // Cap `length` at the length of `insert_this`.
166   RTC_DCHECK_LE(length, insert_this.Size());
167   length = std::min(length, insert_this.Size());
168   if (num_channels_ == insert_this.num_channels_) {
169     for (size_t i = 0; i < num_channels_; ++i) {
170       channels_[i]->OverwriteAt(insert_this[i], length, position);
171     }
172   }
173 }
174 
CrossFade(const AudioMultiVector & append_this,size_t fade_length)175 void AudioMultiVector::CrossFade(const AudioMultiVector& append_this,
176                                  size_t fade_length) {
177   RTC_DCHECK_EQ(num_channels_, append_this.num_channels_);
178   if (num_channels_ == append_this.num_channels_) {
179     for (size_t i = 0; i < num_channels_; ++i) {
180       channels_[i]->CrossFade(append_this[i], fade_length);
181     }
182   }
183 }
184 
Channels() const185 size_t AudioMultiVector::Channels() const {
186   return num_channels_;
187 }
188 
Size() const189 size_t AudioMultiVector::Size() const {
190   RTC_DCHECK(channels_[0]);
191   return channels_[0]->Size();
192 }
193 
AssertSize(size_t required_size)194 void AudioMultiVector::AssertSize(size_t required_size) {
195   if (Size() < required_size) {
196     size_t extend_length = required_size - Size();
197     for (size_t channel = 0; channel < num_channels_; ++channel) {
198       channels_[channel]->Extend(extend_length);
199     }
200   }
201 }
202 
Empty() const203 bool AudioMultiVector::Empty() const {
204   RTC_DCHECK(channels_[0]);
205   return channels_[0]->Empty();
206 }
207 
CopyChannel(size_t from_channel,size_t to_channel)208 void AudioMultiVector::CopyChannel(size_t from_channel, size_t to_channel) {
209   RTC_DCHECK_LT(from_channel, num_channels_);
210   RTC_DCHECK_LT(to_channel, num_channels_);
211   channels_[from_channel]->CopyTo(channels_[to_channel]);
212 }
213 
operator [](size_t index) const214 const AudioVector& AudioMultiVector::operator[](size_t index) const {
215   return *(channels_[index]);
216 }
217 
operator [](size_t index)218 AudioVector& AudioMultiVector::operator[](size_t index) {
219   return *(channels_[index]);
220 }
221 
222 }  // namespace webrtc
223