Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/modules/audio_coding/neteq/audio_vector.h" | 11 #include "webrtc/modules/audio_coding/neteq/audio_vector.h" |
| 12 | 12 |
| 13 #include <assert.h> | 13 #include <assert.h> |
| 14 | 14 |
| 15 #include <algorithm> | 15 #include <algorithm> |
| 16 #include <memory> | 16 #include <memory> |
| 17 | 17 |
| 18 #include "webrtc/typedefs.h" | 18 #include "webrtc/typedefs.h" |
| 19 | 19 |
| 20 namespace webrtc { | 20 namespace webrtc { |
| 21 | 21 |
| 22 AudioVector::AudioVector() | 22 AudioVector::AudioVector() |
| 23 : array_(new int16_t[kDefaultInitialSize]), | 23 : array_(new int16_t[kDefaultInitialSize + 1]), |
|
hlundin-webrtc
2016/05/10 07:53:18
You can just delegate this to the other ctor:
Audi
minyue-webrtc
2016/05/10 12:48:07
Done.
| |
| 24 first_free_ix_(0), | 24 capacity_(kDefaultInitialSize + 1), |
| 25 capacity_(kDefaultInitialSize) { | 25 begin_index_(0), |
| 26 end_index_(begin_index_) { | |
| 26 } | 27 } |
| 27 | 28 |
| 28 AudioVector::AudioVector(size_t initial_size) | 29 AudioVector::AudioVector(size_t initial_size) |
| 29 : array_(new int16_t[initial_size]), | 30 : array_(new int16_t[initial_size + 1]), |
| 30 first_free_ix_(initial_size), | 31 capacity_(initial_size + 1), |
| 31 capacity_(initial_size) { | 32 begin_index_(0), |
| 32 memset(array_.get(), 0, initial_size * sizeof(int16_t)); | 33 end_index_(capacity_ - 1) { |
| 34 memset(array_.get(), 0, capacity_ * sizeof(int16_t)); | |
| 33 } | 35 } |
| 34 | 36 |
| 35 AudioVector::~AudioVector() = default; | 37 AudioVector::~AudioVector() = default; |
| 36 | 38 |
| 37 void AudioVector::Clear() { | 39 void AudioVector::Clear() { |
| 38 first_free_ix_ = 0; | 40 end_index_ = begin_index_ = 0; |
| 39 } | 41 } |
| 40 | 42 |
| 41 void AudioVector::CopyTo(AudioVector* copy_to) const { | 43 void AudioVector::CopyTo(AudioVector* copy_to) const { |
| 42 if (copy_to) { | 44 if (!copy_to) |
|
hlundin-webrtc
2016/05/10 07:53:17
Simply RTC_DCHECK(copy_to). I think the old implem
minyue-webrtc
2016/05/10 12:48:07
Done.
| |
| 43 copy_to->Reserve(Size()); | 45 return; |
| 44 assert(copy_to->capacity_ >= Size()); | 46 copy_to->Reserve(Size()); |
| 45 memcpy(copy_to->array_.get(), array_.get(), Size() * sizeof(int16_t)); | 47 CopyTo(Size(), 0, copy_to->array_.get()); |
| 46 copy_to->first_free_ix_ = first_free_ix_; | 48 copy_to->begin_index_ = 0; |
| 49 copy_to->end_index_ = Size(); | |
| 50 } | |
| 51 | |
| 52 void AudioVector::CopyTo( | |
| 53 size_t length, size_t position, int16_t* copy_to) const { | |
| 54 if (length == 0) | |
| 55 return; | |
| 56 length = std::min(length, Size() - position); | |
| 57 const size_t copy_index = (begin_index_ + position) % capacity_; | |
| 58 const size_t first_chunk_length = | |
| 59 std::min(length, capacity_ - copy_index); | |
| 60 memcpy(copy_to, &array_[copy_index], | |
| 61 first_chunk_length * sizeof(int16_t)); | |
| 62 const size_t remaining_length = length - first_chunk_length; | |
| 63 if (remaining_length > 0) { | |
| 64 memcpy(©_to[first_chunk_length], array_.get(), | |
| 65 remaining_length * sizeof(int16_t)); | |
| 47 } | 66 } |
| 48 } | 67 } |
| 49 | 68 |
| 50 void AudioVector::PushFront(const AudioVector& prepend_this) { | 69 void AudioVector::PushFront(const AudioVector& prepend_this) { |
| 51 size_t insert_length = prepend_this.Size(); | 70 const size_t length = prepend_this.Size(); |
| 52 Reserve(Size() + insert_length); | 71 if (length == 0) |
| 53 memmove(&array_[insert_length], &array_[0], Size() * sizeof(int16_t)); | 72 return; |
| 54 memcpy(&array_[0], &prepend_this.array_[0], insert_length * sizeof(int16_t)); | 73 |
| 55 first_free_ix_ += insert_length; | 74 // Although the subsequent calling to PushFront does Reserve in it, it is |
| 75 // always more efficient to do a big Reserve first. | |
| 76 Reserve(Size() + length); | |
| 77 | |
| 78 const size_t first_chunk_length = | |
| 79 std::min(length, prepend_this.capacity_ - prepend_this.begin_index_); | |
| 80 const size_t remaining_length = length - first_chunk_length; | |
| 81 if (remaining_length > 0) | |
| 82 PushFront(prepend_this.array_.get(), remaining_length); | |
| 83 PushFront(&prepend_this.array_[prepend_this.begin_index_], | |
| 84 first_chunk_length); | |
| 56 } | 85 } |
| 57 | 86 |
| 58 void AudioVector::PushFront(const int16_t* prepend_this, size_t length) { | 87 void AudioVector::PushFront(const int16_t* prepend_this, size_t length) { |
| 59 // Same operation as InsertAt beginning. | 88 if (length == 0) |
| 60 InsertAt(prepend_this, length, 0); | 89 return; |
| 90 Reserve(Size() + length); | |
| 91 const size_t first_chunk_length = std::min(length, begin_index_); | |
| 92 memcpy(&array_[begin_index_ - first_chunk_length], | |
| 93 &prepend_this[length - first_chunk_length], | |
| 94 first_chunk_length * sizeof(int16_t)); | |
| 95 const size_t remaining_length = length - first_chunk_length; | |
| 96 if (remaining_length > 0) { | |
| 97 memcpy(&array_[capacity_ - remaining_length], prepend_this, | |
| 98 remaining_length * sizeof(int16_t)); | |
| 99 } | |
| 100 begin_index_ = (begin_index_ + capacity_ - length) % capacity_; | |
| 61 } | 101 } |
| 62 | 102 |
| 63 void AudioVector::PushBack(const AudioVector& append_this) { | 103 void AudioVector::PushBack(const AudioVector& append_this) { |
| 64 PushBack(append_this.array_.get(), append_this.Size()); | 104 PushBack(append_this, append_this.Size(), 0); |
| 105 } | |
| 106 | |
| 107 void AudioVector::PushBack( | |
| 108 const AudioVector& append_this, size_t length, size_t position) { | |
| 109 position = std::min(append_this.Size(), position); | |
|
hlundin-webrtc
2016/05/10 07:53:18
Is it valid to call with a position larger than Si
minyue-webrtc
2016/05/10 12:48:07
good point. since |length| and |position| refers t
| |
| 110 length = std::min(length, append_this.Size() - position); | |
|
hlundin-webrtc
2016/05/10 07:53:17
Same with length...
minyue-webrtc
2016/05/10 12:48:07
Done.
| |
| 111 if (length == 0) | |
| 112 return; | |
| 113 | |
| 114 // Although the subsequent calling to PushBack does Reserve in it, it is | |
| 115 // always more efficient to do a big Reserve first. | |
| 116 Reserve(Size() + length); | |
| 117 | |
| 118 const size_t start_index = | |
| 119 (append_this.begin_index_ + position) % append_this.capacity_; | |
| 120 const size_t first_chunk_length = std::min( | |
| 121 length, append_this.capacity_ - start_index); | |
| 122 PushBack(&append_this.array_[start_index], first_chunk_length); | |
| 123 | |
| 124 const size_t remaining_length = length - first_chunk_length; | |
| 125 if (remaining_length > 0) | |
| 126 PushBack(append_this.array_.get(), remaining_length); | |
| 65 } | 127 } |
| 66 | 128 |
| 67 void AudioVector::PushBack(const int16_t* append_this, size_t length) { | 129 void AudioVector::PushBack(const int16_t* append_this, size_t length) { |
| 68 Reserve(Size() + length); | 130 if (length == 0) |
| 69 memcpy(&array_[first_free_ix_], append_this, length * sizeof(int16_t)); | 131 return; |
| 70 first_free_ix_ += length; | 132 Reserve(Size() + length); |
| 133 const size_t first_chunk_length = std::min(length, capacity_ - end_index_); | |
| 134 memcpy(&array_[end_index_], append_this, | |
| 135 first_chunk_length * sizeof(int16_t)); | |
| 136 const size_t remaining_length = length - first_chunk_length; | |
| 137 if (remaining_length > 0) { | |
| 138 memcpy(array_.get(), &append_this[first_chunk_length], | |
| 139 remaining_length * sizeof(int16_t)); | |
| 140 } | |
| 141 end_index_ = (end_index_ + length) % capacity_; | |
| 71 } | 142 } |
| 72 | 143 |
| 73 void AudioVector::PopFront(size_t length) { | 144 void AudioVector::PopFront(size_t length) { |
| 74 if (length >= Size()) { | 145 if (length == 0) |
| 75 // Remove all elements. | 146 return; |
| 76 Clear(); | 147 length = std::min(length, Size()); |
| 77 } else { | 148 begin_index_ = (begin_index_ + length) % capacity_; |
| 78 size_t remaining_samples = Size() - length; | |
| 79 memmove(&array_[0], &array_[length], remaining_samples * sizeof(int16_t)); | |
| 80 first_free_ix_ -= length; | |
| 81 } | |
| 82 } | 149 } |
| 83 | 150 |
| 84 void AudioVector::PopBack(size_t length) { | 151 void AudioVector::PopBack(size_t length) { |
| 152 if (length == 0) | |
| 153 return; | |
| 85 // Never remove more than what is in the array. | 154 // Never remove more than what is in the array. |
| 86 length = std::min(length, Size()); | 155 length = std::min(length, Size()); |
| 87 first_free_ix_ -= length; | 156 end_index_ = (end_index_ + capacity_ - length) % capacity_; |
| 88 } | 157 } |
| 89 | 158 |
| 90 void AudioVector::Extend(size_t extra_length) { | 159 void AudioVector::Extend(size_t extra_length) { |
| 91 Reserve(Size() + extra_length); | 160 if (extra_length == 0) |
| 92 memset(&array_[first_free_ix_], 0, extra_length * sizeof(int16_t)); | 161 return; |
| 93 first_free_ix_ += extra_length; | 162 InsertZerosByPushBack(extra_length, Size()); |
| 94 } | 163 } |
| 95 | 164 |
| 96 void AudioVector::InsertAt(const int16_t* insert_this, | 165 void AudioVector::InsertAt(const int16_t* insert_this, |
| 97 size_t length, | 166 size_t length, |
| 98 size_t position) { | 167 size_t position) { |
| 99 Reserve(Size() + length); | 168 if (length == 0) |
| 100 // Cap the position at the current vector length, to be sure the iterator | 169 return; |
| 101 // does not extend beyond the end of the vector. | 170 // Cap the insert position at the current array length. |
| 102 position = std::min(Size(), position); | 171 position = std::min(Size(), position); |
| 103 int16_t* insert_position_ptr = &array_[position]; | 172 |
| 104 size_t samples_to_move = Size() - position; | 173 if (position <= Size() - position) { |
|
hlundin-webrtc
2016/05/10 07:53:18
Please, add a comment about what this if-statement
minyue-webrtc
2016/05/10 12:48:07
Done.
| |
| 105 memmove(insert_position_ptr + length, insert_position_ptr, | 174 InsertByPushFront(insert_this, length, position); |
| 106 samples_to_move * sizeof(int16_t)); | 175 } else { |
| 107 memcpy(insert_position_ptr, insert_this, length * sizeof(int16_t)); | 176 InsertByPushBack(insert_this, length, position); |
| 108 first_free_ix_ += length; | 177 } |
| 109 } | 178 } |
| 110 | 179 |
| 111 void AudioVector::InsertZerosAt(size_t length, | 180 void AudioVector::InsertZerosAt(size_t length, |
| 112 size_t position) { | 181 size_t position) { |
| 113 Reserve(Size() + length); | 182 if (length == 0) |
| 114 // Cap the position at the current vector length, to be sure the iterator | 183 return; |
| 115 // does not extend beyond the end of the vector. | 184 // Cap the insert position at the current array length. |
| 116 position = std::min(capacity_, position); | 185 position = std::min(Size(), position); |
| 117 int16_t* insert_position_ptr = &array_[position]; | 186 |
| 118 size_t samples_to_move = Size() - position; | 187 if (position <= Size() - position) { |
|
hlundin-webrtc
2016/05/10 07:53:18
Comment again.
minyue-webrtc
2016/05/10 12:48:07
Done.
| |
| 119 memmove(insert_position_ptr + length, insert_position_ptr, | 188 InsertZerosByPushFront(length, position); |
| 120 samples_to_move * sizeof(int16_t)); | 189 } else { |
| 121 memset(insert_position_ptr, 0, length * sizeof(int16_t)); | 190 InsertZerosByPushBack(length, position); |
| 122 first_free_ix_ += length; | 191 } |
| 192 } | |
| 193 | |
| 194 void AudioVector::OverwriteAt(const AudioVector& insert_this, | |
| 195 size_t length, | |
| 196 size_t position) { | |
| 197 length = std::min(length, insert_this.Size()); | |
| 198 if (length == 0) | |
| 199 return; | |
| 200 | |
| 201 position = std::min(Size(), position); | |
| 202 const size_t first_chunk_length = | |
| 203 std::min(length, insert_this.capacity_ - insert_this.begin_index_); | |
| 204 OverwriteAt(&insert_this.array_[insert_this.begin_index_], first_chunk_length, | |
| 205 position); | |
| 206 const size_t remaining_length = length - first_chunk_length; | |
| 207 if (remaining_length > 0) { | |
| 208 OverwriteAt(insert_this.array_.get(), remaining_length, | |
| 209 position + first_chunk_length); | |
|
hlundin-webrtc
2016/05/10 07:53:18
What if position + first_chunk_length > Size()? Th
minyue-webrtc
2016/05/10 12:48:07
OverwriteAt(const int16_t* insert_this will reserv
| |
| 210 } | |
| 123 } | 211 } |
| 124 | 212 |
| 125 void AudioVector::OverwriteAt(const int16_t* insert_this, | 213 void AudioVector::OverwriteAt(const int16_t* insert_this, |
| 126 size_t length, | 214 size_t length, |
| 127 size_t position) { | 215 size_t position) { |
| 216 if (length == 0) | |
| 217 return; | |
| 128 // Cap the insert position at the current array length. | 218 // Cap the insert position at the current array length. |
| 129 position = std::min(Size(), position); | 219 position = std::min(Size(), position); |
| 130 Reserve(position + length); | 220 |
| 131 memcpy(&array_[position], insert_this, length * sizeof(int16_t)); | 221 size_t new_size = std::max(Size(), position + length); |
| 132 if (position + length > Size()) { | 222 Reserve(new_size); |
| 133 // Array was expanded. | 223 |
| 134 first_free_ix_ += position + length - Size(); | 224 const size_t overwrite_index = (begin_index_ + position) % capacity_; |
| 135 } | 225 const size_t first_chunk_length = |
| 226 std::min(length, capacity_ - overwrite_index); | |
| 227 memcpy(&array_[overwrite_index], insert_this, | |
| 228 first_chunk_length * sizeof(int16_t)); | |
| 229 const size_t remaining_length = length - first_chunk_length; | |
| 230 if (remaining_length > 0) { | |
| 231 memcpy(array_.get(), &insert_this[first_chunk_length], | |
| 232 remaining_length * sizeof(int16_t)); | |
| 233 } | |
| 234 | |
| 235 end_index_ = (begin_index_ + new_size) % capacity_; | |
| 136 } | 236 } |
| 137 | 237 |
| 138 void AudioVector::CrossFade(const AudioVector& append_this, | 238 void AudioVector::CrossFade(const AudioVector& append_this, |
| 139 size_t fade_length) { | 239 size_t fade_length) { |
| 140 // Fade length cannot be longer than the current vector or |append_this|. | 240 // Fade length cannot be longer than the current vector or |append_this|. |
| 141 assert(fade_length <= Size()); | 241 assert(fade_length <= Size()); |
| 142 assert(fade_length <= append_this.Size()); | 242 assert(fade_length <= append_this.Size()); |
| 143 fade_length = std::min(fade_length, Size()); | 243 fade_length = std::min(fade_length, Size()); |
| 144 fade_length = std::min(fade_length, append_this.Size()); | 244 fade_length = std::min(fade_length, append_this.Size()); |
| 145 size_t position = Size() - fade_length; | 245 size_t position = Size() - fade_length + begin_index_; |
| 146 // Cross fade the overlapping regions. | 246 // Cross fade the overlapping regions. |
| 147 // |alpha| is the mixing factor in Q14. | 247 // |alpha| is the mixing factor in Q14. |
| 148 // TODO(hlundin): Consider skipping +1 in the denominator to produce a | 248 // TODO(hlundin): Consider skipping +1 in the denominator to produce a |
| 149 // smoother cross-fade, in particular at the end of the fade. | 249 // smoother cross-fade, in particular at the end of the fade. |
| 150 int alpha_step = 16384 / (static_cast<int>(fade_length) + 1); | 250 int alpha_step = 16384 / (static_cast<int>(fade_length) + 1); |
| 151 int alpha = 16384; | 251 int alpha = 16384; |
| 152 for (size_t i = 0; i < fade_length; ++i) { | 252 for (size_t i = 0; i < fade_length; ++i) { |
| 153 alpha -= alpha_step; | 253 alpha -= alpha_step; |
| 154 array_[position + i] = (alpha * array_[position + i] + | 254 array_[(position + i) % capacity_] = |
| 155 (16384 - alpha) * append_this[i] + 8192) >> 14; | 255 (alpha * array_[(position + i) % capacity_] + |
| 256 (16384 - alpha) * append_this[i] + 8192) >> 14; | |
| 156 } | 257 } |
| 157 assert(alpha >= 0); // Verify that the slope was correct. | 258 assert(alpha >= 0); // Verify that the slope was correct. |
| 158 // Append what is left of |append_this|. | 259 // Append what is left of |append_this|. |
| 159 size_t samples_to_push_back = append_this.Size() - fade_length; | 260 size_t samples_to_push_back = append_this.Size() - fade_length; |
| 160 if (samples_to_push_back > 0) | 261 if (samples_to_push_back > 0) |
| 161 PushBack(&append_this[fade_length], samples_to_push_back); | 262 PushBack(append_this, samples_to_push_back, fade_length); |
| 162 } | 263 } |
| 163 | 264 |
| 164 // Returns the number of elements in this AudioVector. | 265 // Returns the number of elements in this AudioVector. |
| 165 size_t AudioVector::Size() const { | 266 size_t AudioVector::Size() const { |
| 166 return first_free_ix_; | 267 return (end_index_ + capacity_ - begin_index_) % capacity_; |
| 167 } | 268 } |
| 168 | 269 |
| 169 // Returns true if this AudioVector is empty. | 270 // Returns true if this AudioVector is empty. |
| 170 bool AudioVector::Empty() const { | 271 bool AudioVector::Empty() const { |
| 171 return first_free_ix_ == 0; | 272 return begin_index_ == end_index_; |
| 172 } | 273 } |
| 173 | 274 |
| 174 const int16_t& AudioVector::operator[](size_t index) const { | 275 const int16_t& AudioVector::operator[](size_t index) const { |
| 175 return array_[index]; | 276 return array_[(begin_index_ + index) % capacity_]; |
| 176 } | 277 } |
| 177 | 278 |
| 178 int16_t& AudioVector::operator[](size_t index) { | 279 int16_t& AudioVector::operator[](size_t index) { |
| 179 return array_[index]; | 280 return array_[(begin_index_ + index) % capacity_]; |
| 180 } | 281 } |
| 181 | 282 |
| 182 void AudioVector::Reserve(size_t n) { | 283 void AudioVector::Reserve(size_t n) { |
| 183 if (capacity_ < n) { | 284 if (capacity_ > n) |
| 184 std::unique_ptr<int16_t[]> temp_array(new int16_t[n]); | 285 return; |
| 185 memcpy(temp_array.get(), array_.get(), Size() * sizeof(int16_t)); | 286 const size_t length = Size(); |
| 186 array_.swap(temp_array); | 287 // Reserve one more sample to remove the ambiguity between empty vector and |
| 187 capacity_ = n; | 288 // full vector. Therefore |begin_index_| == |end_index_| indicates empty |
| 289 // vector, and |begin_index_| == (|end_index_| + 1) % capacity indicates | |
| 290 // full vector. | |
| 291 std::unique_ptr<int16_t[]> temp_array(new int16_t[n + 1]); | |
| 292 const size_t first_chunk_length = | |
|
hlundin-webrtc
2016/05/10 07:53:18
Why not use the CopyTo method?
minyue-webrtc
2016/05/10 12:48:07
very good point, I should have used it. Thanks!
| |
| 293 std::min(length, capacity_ - begin_index_); | |
| 294 memcpy(temp_array.get(), &array_[begin_index_], | |
| 295 first_chunk_length * sizeof(int16_t)); | |
| 296 const size_t remaining_length = length - first_chunk_length; | |
| 297 if (remaining_length > 0) { | |
| 298 memcpy(&temp_array[first_chunk_length], array_.get(), | |
| 299 remaining_length * sizeof(int16_t)); | |
| 188 } | 300 } |
| 301 array_.swap(temp_array); | |
| 302 begin_index_ = 0; | |
| 303 end_index_ = length; | |
| 304 capacity_ = n + 1; | |
| 305 } | |
| 306 | |
| 307 void AudioVector::InsertByPushBack(const int16_t* insert_this, | |
| 308 size_t length, | |
| 309 size_t position) { | |
| 310 const size_t move_chunk_length = Size() - position; | |
| 311 std::unique_ptr<int16_t[]> temp_array(nullptr); | |
| 312 if (move_chunk_length > 0) { | |
| 313 temp_array.reset(new int16_t[move_chunk_length]); | |
|
hlundin-webrtc
2016/05/10 07:53:18
It seems inefficient to me to store the move-chunk
minyue-webrtc
2016/05/10 12:48:07
I thought about it, but it can be a bit complicate
| |
| 314 CopyTo(move_chunk_length, position, temp_array.get()); | |
| 315 PopBack(move_chunk_length); | |
| 316 } | |
| 317 | |
| 318 Reserve(Size() + length + move_chunk_length); | |
| 319 PushBack(insert_this, length); | |
| 320 if (move_chunk_length > 0) | |
| 321 PushBack(temp_array.get(), move_chunk_length); | |
| 322 } | |
| 323 | |
| 324 void AudioVector::InsertByPushFront(const int16_t* insert_this, | |
| 325 size_t length, | |
| 326 size_t position) { | |
| 327 std::unique_ptr<int16_t[]> temp_array(nullptr); | |
| 328 if (position > 0) { | |
| 329 temp_array.reset(new int16_t[position]); | |
| 330 CopyTo(position, 0, temp_array.get()); | |
| 331 PopFront(position); | |
| 332 } | |
| 333 | |
| 334 Reserve(Size() + length + position); | |
| 335 PushFront(insert_this, length); | |
| 336 if (position > 0) | |
| 337 PushFront(temp_array.get(), position); | |
| 338 } | |
| 339 | |
| 340 void AudioVector::InsertZerosByPushBack(size_t length, | |
| 341 size_t position) { | |
| 342 const size_t move_chunk_length = Size() - position; | |
| 343 std::unique_ptr<int16_t[]> temp_array(nullptr); | |
| 344 if (move_chunk_length > 0) { | |
| 345 temp_array.reset(new int16_t[move_chunk_length]); | |
| 346 CopyTo(move_chunk_length, position, temp_array.get()); | |
| 347 PopBack(move_chunk_length); | |
| 348 } | |
| 349 | |
| 350 Reserve(Size() + length + move_chunk_length); | |
| 351 | |
| 352 const size_t first_zero_chunk_length = | |
| 353 std::min(length, capacity_ - end_index_); | |
| 354 memset(&array_[end_index_], 0, first_zero_chunk_length * sizeof(int16_t)); | |
| 355 const size_t remaining_zero_length = length - first_zero_chunk_length; | |
| 356 if (remaining_zero_length > 0) | |
| 357 memset(array_.get(), 0, remaining_zero_length * sizeof(int16_t)); | |
| 358 end_index_ = (end_index_ + length) % capacity_; | |
| 359 | |
| 360 if (move_chunk_length > 0) | |
| 361 PushBack(temp_array.get(), move_chunk_length); | |
| 362 } | |
| 363 | |
| 364 void AudioVector::InsertZerosByPushFront(size_t length, | |
| 365 size_t position) { | |
| 366 std::unique_ptr<int16_t[]> temp_array(nullptr); | |
| 367 if (position > 0) { | |
| 368 temp_array.reset(new int16_t[position]); | |
| 369 CopyTo(position, 0, temp_array.get()); | |
| 370 PopFront(position); | |
| 371 } | |
| 372 | |
| 373 Reserve(Size() + length + position); | |
| 374 | |
| 375 const size_t first_zero_chunk_length = std::min(length, begin_index_); | |
| 376 memset(&array_[begin_index_ - first_zero_chunk_length], 0, | |
| 377 first_zero_chunk_length * sizeof(int16_t)); | |
| 378 const size_t remaining_zero_length = length - first_zero_chunk_length; | |
| 379 if (remaining_zero_length > 0) | |
| 380 memset(&array_[capacity_ - remaining_zero_length], 0, | |
| 381 remaining_zero_length * sizeof(int16_t)); | |
| 382 begin_index_ = (begin_index_ + capacity_ - length) % capacity_; | |
| 383 | |
| 384 if (position > 0) | |
| 385 PushFront(temp_array.get(), position); | |
| 189 } | 386 } |
| 190 | 387 |
| 191 } // namespace webrtc | 388 } // namespace webrtc |
| OLD | NEW |