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_vector.h"
17 #include "webrtc/typedefs.h"
21 void AudioVector::Clear() {
25 void AudioVector::CopyTo(AudioVector* copy_to) const {
27 copy_to->Reserve(Size());
28 assert(copy_to->capacity_ >= Size());
29 memcpy(copy_to->array_.get(), array_.get(), Size() * sizeof(int16_t));
30 copy_to->first_free_ix_ = first_free_ix_;
34 void AudioVector::PushFront(const AudioVector& prepend_this) {
35 size_t insert_length = prepend_this.Size();
36 Reserve(Size() + insert_length);
37 memmove(&array_[insert_length], &array_[0], Size() * sizeof(int16_t));
38 memcpy(&array_[0], &prepend_this.array_[0], insert_length * sizeof(int16_t));
39 first_free_ix_ += insert_length;
42 void AudioVector::PushFront(const int16_t* prepend_this, size_t length) {
43 // Same operation as InsertAt beginning.
44 InsertAt(prepend_this, length, 0);
47 void AudioVector::PushBack(const AudioVector& append_this) {
48 PushBack(append_this.array_.get(), append_this.Size());
51 void AudioVector::PushBack(const int16_t* append_this, size_t length) {
52 Reserve(Size() + length);
53 memcpy(&array_[first_free_ix_], append_this, length * sizeof(int16_t));
54 first_free_ix_ += length;
57 void AudioVector::PopFront(size_t length) {
58 if (length >= Size()) {
59 // Remove all elements.
62 size_t remaining_samples = Size() - length;
63 memmove(&array_[0], &array_[length], remaining_samples * sizeof(int16_t));
64 first_free_ix_ -= length;
68 void AudioVector::PopBack(size_t length) {
69 // Never remove more than what is in the array.
70 length = std::min(length, Size());
71 first_free_ix_ -= length;
74 void AudioVector::Extend(size_t extra_length) {
75 Reserve(Size() + extra_length);
76 memset(&array_[first_free_ix_], 0, extra_length * sizeof(int16_t));
77 first_free_ix_ += extra_length;
80 void AudioVector::InsertAt(const int16_t* insert_this,
83 Reserve(Size() + length);
84 // Cap the position at the current vector length, to be sure the iterator
85 // does not extend beyond the end of the vector.
86 position = std::min(Size(), position);
87 int16_t* insert_position_ptr = &array_[position];
88 size_t samples_to_move = Size() - position;
89 memmove(insert_position_ptr + length, insert_position_ptr,
90 samples_to_move * sizeof(int16_t));
91 memcpy(insert_position_ptr, insert_this, length * sizeof(int16_t));
92 first_free_ix_ += length;
95 void AudioVector::InsertZerosAt(size_t length,
97 Reserve(Size() + length);
98 // Cap the position at the current vector length, to be sure the iterator
99 // does not extend beyond the end of the vector.
100 position = std::min(capacity_, position);
101 int16_t* insert_position_ptr = &array_[position];
102 size_t samples_to_move = Size() - position;
103 memmove(insert_position_ptr + length, insert_position_ptr,
104 samples_to_move * sizeof(int16_t));
105 memset(insert_position_ptr, 0, length * sizeof(int16_t));
106 first_free_ix_ += length;
109 void AudioVector::OverwriteAt(const int16_t* insert_this,
112 // Cap the insert position at the current array length.
113 position = std::min(Size(), position);
114 Reserve(position + length);
115 memcpy(&array_[position], insert_this, length * sizeof(int16_t));
116 if (position + length > Size()) {
117 // Array was expanded.
118 first_free_ix_ += position + length - Size();
122 void AudioVector::CrossFade(const AudioVector& append_this,
123 size_t fade_length) {
124 // Fade length cannot be longer than the current vector or |append_this|.
125 assert(fade_length <= Size());
126 assert(fade_length <= append_this.Size());
127 fade_length = std::min(fade_length, Size());
128 fade_length = std::min(fade_length, append_this.Size());
129 size_t position = Size() - fade_length;
130 // Cross fade the overlapping regions.
131 // |alpha| is the mixing factor in Q14.
132 // TODO(hlundin): Consider skipping +1 in the denominator to produce a
133 // smoother cross-fade, in particular at the end of the fade.
134 int alpha_step = 16384 / (static_cast<int>(fade_length) + 1);
136 for (size_t i = 0; i < fade_length; ++i) {
138 array_[position + i] = (alpha * array_[position + i] +
139 (16384 - alpha) * append_this[i] + 8192) >> 14;
141 assert(alpha >= 0); // Verify that the slope was correct.
142 // Append what is left of |append_this|.
143 size_t samples_to_push_back = append_this.Size() - fade_length;
144 if (samples_to_push_back > 0)
145 PushBack(&append_this[fade_length], samples_to_push_back);
148 const int16_t& AudioVector::operator[](size_t index) const {
149 return array_[index];
152 int16_t& AudioVector::operator[](size_t index) {
153 return array_[index];
156 void AudioVector::Reserve(size_t n) {
158 scoped_ptr<int16_t[]> temp_array(new int16_t[n]);
159 memcpy(temp_array.get(), array_.get(), Size() * sizeof(int16_t));
160 array_.swap(temp_array);
165 } // namespace webrtc