Home | History | Annotate | Download | only in neteq
      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::CopyTo(AudioMultiVector* copy_to) const {
     61   if (copy_to) {
     62     for (size_t i = 0; i < num_channels_; ++i) {
     63       channels_[i]->CopyTo(&(*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::Channels() const {
    187   return num_channels_;
    188 }
    189 
    190 size_t AudioMultiVector::Size() const {
    191   assert(channels_[0]);
    192   return channels_[0]->Size();
    193 }
    194 
    195 void AudioMultiVector::AssertSize(size_t required_size) {
    196   if (Size() < required_size) {
    197     size_t extend_length = required_size - Size();
    198     for (size_t channel = 0; channel < num_channels_; ++channel) {
    199       channels_[channel]->Extend(extend_length);
    200     }
    201   }
    202 }
    203 
    204 bool AudioMultiVector::Empty() const {
    205   assert(channels_[0]);
    206   return channels_[0]->Empty();
    207 }
    208 
    209 void AudioMultiVector::CopyChannel(size_t from_channel, size_t to_channel) {
    210   assert(from_channel < num_channels_);
    211   assert(to_channel < num_channels_);
    212   channels_[from_channel]->CopyTo(channels_[to_channel]);
    213 }
    214 
    215 const AudioVector& AudioMultiVector::operator[](size_t index) const {
    216   return *(channels_[index]);
    217 }
    218 
    219 AudioVector& AudioMultiVector::operator[](size_t index) {
    220   return *(channels_[index]);
    221 }
    222 
    223 }  // namespace webrtc
    224