5a208a6972a35694db5977abd154f030d8364401
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq / audio_multi_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_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