Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq / audio_vector.cc
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_vector.h"
12
13 #include <assert.h>
14
15 #include <algorithm>
16
17 #include "webrtc/typedefs.h"
18
19 namespace webrtc {
20
21 void AudioVector::Clear() {
22   first_free_ix_ = 0;
23 }
24
25 void AudioVector::CopyTo(AudioVector* copy_to) const {
26   if (copy_to) {
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_;
31   }
32 }
33
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;
40 }
41
42 void AudioVector::PushFront(const int16_t* prepend_this, size_t length) {
43   // Same operation as InsertAt beginning.
44   InsertAt(prepend_this, length, 0);
45 }
46
47 void AudioVector::PushBack(const AudioVector& append_this) {
48   PushBack(append_this.array_.get(), append_this.Size());
49 }
50
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;
55 }
56
57 void AudioVector::PopFront(size_t length) {
58   if (length >= Size()) {
59     // Remove all elements.
60     Clear();
61   } else {
62     size_t remaining_samples = Size() - length;
63     memmove(&array_[0], &array_[length], remaining_samples * sizeof(int16_t));
64     first_free_ix_ -= length;
65   }
66 }
67
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;
72 }
73
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;
78 }
79
80 void AudioVector::InsertAt(const int16_t* insert_this,
81                            size_t length,
82                            size_t position) {
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;
93 }
94
95 void AudioVector::InsertZerosAt(size_t length,
96                                 size_t position) {
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;
107 }
108
109 void AudioVector::OverwriteAt(const int16_t* insert_this,
110                               size_t length,
111                               size_t position) {
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();
119   }
120 }
121
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);
135   int alpha = 16384;
136   for (size_t i = 0; i < fade_length; ++i) {
137     alpha -= alpha_step;
138     array_[position + i] = (alpha * array_[position + i] +
139         (16384 - alpha) * append_this[i] + 8192) >> 14;
140   }
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);
146 }
147
148 const int16_t& AudioVector::operator[](size_t index) const {
149   return array_[index];
150 }
151
152 int16_t& AudioVector::operator[](size_t index) {
153   return array_[index];
154 }
155
156 void AudioVector::Reserve(size_t n) {
157   if (capacity_ < 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);
161     capacity_ = n;
162   }
163 }
164
165 }  // namespace webrtc