2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h"
17 #include "webrtc/typedefs.h"
21 AudioMultiVector::AudioMultiVector(size_t N) {
24 for (size_t n = 0; n < N; ++n) {
25 channels_.push_back(new AudioVector);
30 AudioMultiVector::AudioMultiVector(size_t N, size_t initial_size) {
33 for (size_t n = 0; n < N; ++n) {
34 channels_.push_back(new AudioVector(initial_size));
39 AudioMultiVector::~AudioMultiVector() {
40 std::vector<AudioVector*>::iterator it = channels_.begin();
41 while (it != channels_.end()) {
47 void AudioMultiVector::Clear() {
48 for (size_t i = 0; i < num_channels_; ++i) {
49 channels_[i]->Clear();
53 void AudioMultiVector::Zeros(size_t length) {
54 for (size_t i = 0; i < num_channels_; ++i) {
55 channels_[i]->Clear();
56 channels_[i]->Extend(length);
60 void AudioMultiVector::CopyFrom(AudioMultiVector* copy_to) const {
62 for (size_t i = 0; i < num_channels_; ++i) {
63 channels_[i]->CopyFrom(&(*copy_to)[i]);
68 void AudioMultiVector::PushBackInterleaved(const int16_t* append_this,
70 assert(length % num_channels_ == 0);
71 if (num_channels_ == 1) {
72 // Special case to avoid extra allocation and data shuffling.
73 channels_[0]->PushBack(append_this, length);
76 size_t length_per_channel = length / num_channels_;
77 int16_t* temp_array = new int16_t[length_per_channel]; // Temporary storage.
78 for (size_t channel = 0; channel < num_channels_; ++channel) {
79 // Copy elements to |temp_array|.
80 // Set |source_ptr| to first element of this channel.
81 const int16_t* source_ptr = &append_this[channel];
82 for (size_t i = 0; i < length_per_channel; ++i) {
83 temp_array[i] = *source_ptr;
84 source_ptr += num_channels_; // Jump to next element of this channel.
86 channels_[channel]->PushBack(temp_array, length_per_channel);
91 void AudioMultiVector::PushBack(const AudioMultiVector& append_this) {
92 assert(num_channels_ == append_this.num_channels_);
93 if (num_channels_ == append_this.num_channels_) {
94 for (size_t i = 0; i < num_channels_; ++i) {
95 channels_[i]->PushBack(append_this[i]);
100 void AudioMultiVector::PushBackFromIndex(const AudioMultiVector& append_this,
102 assert(index < append_this.Size());
103 index = std::min(index, append_this.Size() - 1);
104 size_t length = append_this.Size() - index;
105 assert(num_channels_ == append_this.num_channels_);
106 if (num_channels_ == append_this.num_channels_) {
107 for (size_t i = 0; i < num_channels_; ++i) {
108 channels_[i]->PushBack(&append_this[i][index], length);
113 void AudioMultiVector::PopFront(size_t length) {
114 for (size_t i = 0; i < num_channels_; ++i) {
115 channels_[i]->PopFront(length);
119 void AudioMultiVector::PopBack(size_t length) {
120 for (size_t i = 0; i < num_channels_; ++i) {
121 channels_[i]->PopBack(length);
125 size_t AudioMultiVector::ReadInterleaved(size_t length,
126 int16_t* destination) const {
127 return ReadInterleavedFromIndex(0, length, destination);
130 size_t AudioMultiVector::ReadInterleavedFromIndex(size_t start_index,
132 int16_t* destination) const {
136 size_t index = 0; // Number of elements written to |destination| so far.
137 assert(start_index <= Size());
138 start_index = std::min(start_index, Size());
139 if (length + start_index > Size()) {
140 length = Size() - start_index;
142 if (num_channels_ == 1) {
143 // Special case to avoid the nested for loop below.
144 memcpy(destination, &(*this)[0][start_index], length * sizeof(int16_t));
147 for (size_t i = 0; i < length; ++i) {
148 for (size_t channel = 0; channel < num_channels_; ++channel) {
149 destination[index] = (*this)[channel][i + start_index];
156 size_t AudioMultiVector::ReadInterleavedFromEnd(size_t length,
157 int16_t* destination) const {
158 length = std::min(length, Size()); // Cannot read more than Size() elements.
159 return ReadInterleavedFromIndex(Size() - length, length, destination);
162 void AudioMultiVector::OverwriteAt(const AudioMultiVector& insert_this,
165 assert(num_channels_ == insert_this.num_channels_);
166 // Cap |length| at the length of |insert_this|.
167 assert(length <= insert_this.Size());
168 length = std::min(length, insert_this.Size());
169 if (num_channels_ == insert_this.num_channels_) {
170 for (size_t i = 0; i < num_channels_; ++i) {
171 channels_[i]->OverwriteAt(&insert_this[i][0], length, position);
176 void AudioMultiVector::CrossFade(const AudioMultiVector& append_this,
177 size_t fade_length) {
178 assert(num_channels_ == append_this.num_channels_);
179 if (num_channels_ == append_this.num_channels_) {
180 for (size_t i = 0; i < num_channels_; ++i) {
181 channels_[i]->CrossFade(append_this[i], fade_length);
186 size_t AudioMultiVector::Size() const {
187 assert(channels_[0]);
188 return channels_[0]->Size();
191 void AudioMultiVector::AssertSize(size_t required_size) {
192 if (Size() < required_size) {
193 size_t extend_length = required_size - Size();
194 for (size_t channel = 0; channel < num_channels_; ++channel) {
195 channels_[channel]->Extend(extend_length);
200 bool AudioMultiVector::Empty() const {
201 assert(channels_[0]);
202 return channels_[0]->Empty();
205 const AudioVector& AudioMultiVector::operator[](size_t index) const {
206 return *(channels_[index]);
209 AudioVector& AudioMultiVector::operator[](size_t index) {
210 return *(channels_[index]);
213 } // namespace webrtc