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/typedefs.h" 18 19 namespace webrtc { 20 21 AudioMultiVector::AudioMultiVector(size_t N) { 22 assert(N > 0); 23 if (N < 1) N = 1; 24 for (size_t n = 0; n < N; ++n) { 25 channels_.push_back(new AudioVector); 26 } 27 num_channels_ = N; 28 } 29 30 AudioMultiVector::AudioMultiVector(size_t N, size_t initial_size) { 31 assert(N > 0); 32 if (N < 1) N = 1; 33 for (size_t n = 0; n < N; ++n) { 34 channels_.push_back(new AudioVector(initial_size)); 35 } 36 num_channels_ = N; 37 } 38 39 AudioMultiVector::~AudioMultiVector() { 40 std::vector<AudioVector*>::iterator it = channels_.begin(); 41 while (it != channels_.end()) { 42 delete (*it); 43 ++it; 44 } 45 } 46 47 void AudioMultiVector::Clear() { 48 for (size_t i = 0; i < num_channels_; ++i) { 49 channels_[i]->Clear(); 50 } 51 } 52 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); 57 } 58 } 59 60 void AudioMultiVector::CopyFrom(AudioMultiVector* copy_to) const { 61 if (copy_to) { 62 for (size_t i = 0; i < num_channels_; ++i) { 63 channels_[i]->CopyFrom(&(*copy_to)[i]); 64 } 65 } 66 } 67 68 void AudioMultiVector::PushBackInterleaved(const int16_t* append_this, 69 size_t length) { 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); 74 return; 75 } 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. 85 } 86 channels_[channel]->PushBack(temp_array, length_per_channel); 87 } 88 delete [] temp_array; 89 } 90 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]); 96 } 97 } 98 } 99 100 void AudioMultiVector::PushBackFromIndex(const AudioMultiVector& append_this, 101 size_t index) { 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); 109 } 110 } 111 } 112 113 void AudioMultiVector::PopFront(size_t length) { 114 for (size_t i = 0; i < num_channels_; ++i) { 115 channels_[i]->PopFront(length); 116 } 117 } 118 119 void AudioMultiVector::PopBack(size_t length) { 120 for (size_t i = 0; i < num_channels_; ++i) { 121 channels_[i]->PopBack(length); 122 } 123 } 124 125 size_t AudioMultiVector::ReadInterleaved(size_t length, 126 int16_t* destination) const { 127 return ReadInterleavedFromIndex(0, length, destination); 128 } 129 130 size_t AudioMultiVector::ReadInterleavedFromIndex(size_t start_index, 131 size_t length, 132 int16_t* destination) const { 133 if (!destination) { 134 return 0; 135 } 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; 141 } 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)); 145 return length; 146 } 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]; 150 ++index; 151 } 152 } 153 return index; 154 } 155 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); 160 } 161 162 void AudioMultiVector::OverwriteAt(const AudioMultiVector& insert_this, 163 size_t length, 164 size_t position) { 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); 172 } 173 } 174 } 175 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); 182 } 183 } 184 } 185 186 size_t AudioMultiVector::Size() const { 187 assert(channels_[0]); 188 return channels_[0]->Size(); 189 } 190 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); 196 } 197 } 198 } 199 200 bool AudioMultiVector::Empty() const { 201 assert(channels_[0]); 202 return channels_[0]->Empty(); 203 } 204 205 const AudioVector& AudioMultiVector::operator[](size_t index) const { 206 return *(channels_[index]); 207 } 208 209 AudioVector& AudioMultiVector::operator[](size_t index) { 210 return *(channels_[index]); 211 } 212 213 } // namespace webrtc 214