• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef MODULES_AUDIO_CODING_NETEQ_AUDIO_VECTOR_H_
12 #define MODULES_AUDIO_CODING_NETEQ_AUDIO_VECTOR_H_
13 
14 #include <string.h>
15 
16 #include <cstdint>
17 #include <memory>
18 
19 #include "rtc_base/checks.h"
20 #include "rtc_base/constructor_magic.h"
21 
22 namespace webrtc {
23 
24 class AudioVector {
25  public:
26   // Creates an empty AudioVector.
27   AudioVector();
28 
29   // Creates an AudioVector with an initial size.
30   explicit AudioVector(size_t initial_size);
31 
32   virtual ~AudioVector();
33 
34   // Deletes all values and make the vector empty.
35   virtual void Clear();
36 
37   // Copies all values from this vector to |copy_to|. Any contents in |copy_to|
38   // are deleted before the copy operation. After the operation is done,
39   // |copy_to| will be an exact replica of this object.
40   virtual void CopyTo(AudioVector* copy_to) const;
41 
42   // Copies |length| values from |position| in this vector to |copy_to|.
43   virtual void CopyTo(size_t length, size_t position, int16_t* copy_to) const;
44 
45   // Prepends the contents of AudioVector |prepend_this| to this object. The
46   // length of this object is increased with the length of |prepend_this|.
47   virtual void PushFront(const AudioVector& prepend_this);
48 
49   // Same as above, but with an array |prepend_this| with |length| elements as
50   // source.
51   virtual void PushFront(const int16_t* prepend_this, size_t length);
52 
53   // Same as PushFront but will append to the end of this object.
54   virtual void PushBack(const AudioVector& append_this);
55 
56   // Appends a segment of |append_this| to the end of this object. The segment
57   // starts from |position| and has |length| samples.
58   virtual void PushBack(const AudioVector& append_this,
59                         size_t length,
60                         size_t position);
61 
62   // Same as PushFront but will append to the end of this object.
63   virtual void PushBack(const int16_t* append_this, size_t length);
64 
65   // Removes |length| elements from the beginning of this object.
66   virtual void PopFront(size_t length);
67 
68   // Removes |length| elements from the end of this object.
69   virtual void PopBack(size_t length);
70 
71   // Extends this object with |extra_length| elements at the end. The new
72   // elements are initialized to zero.
73   virtual void Extend(size_t extra_length);
74 
75   // Inserts |length| elements taken from the array |insert_this| and insert
76   // them at |position|. The length of the AudioVector is increased by |length|.
77   // |position| = 0 means that the new values are prepended to the vector.
78   // |position| = Size() means that the new values are appended to the vector.
79   virtual void InsertAt(const int16_t* insert_this,
80                         size_t length,
81                         size_t position);
82 
83   // Like InsertAt, but inserts |length| zero elements at |position|.
84   virtual void InsertZerosAt(size_t length, size_t position);
85 
86   // Overwrites |length| elements of this AudioVector starting from |position|
87   // with first values in |AudioVector|. The definition of |position|
88   // is the same as for InsertAt(). If |length| and |position| are selected
89   // such that the new data extends beyond the end of the current AudioVector,
90   // the vector is extended to accommodate the new data.
91   virtual void OverwriteAt(const AudioVector& insert_this,
92                            size_t length,
93                            size_t position);
94 
95   // Overwrites |length| elements of this AudioVector with values taken from the
96   // array |insert_this|, starting at |position|. The definition of |position|
97   // is the same as for InsertAt(). If |length| and |position| are selected
98   // such that the new data extends beyond the end of the current AudioVector,
99   // the vector is extended to accommodate the new data.
100   virtual void OverwriteAt(const int16_t* insert_this,
101                            size_t length,
102                            size_t position);
103 
104   // Appends |append_this| to the end of the current vector. Lets the two
105   // vectors overlap by |fade_length| samples, and cross-fade linearly in this
106   // region.
107   virtual void CrossFade(const AudioVector& append_this, size_t fade_length);
108 
109   // Returns the number of elements in this AudioVector.
110   virtual size_t Size() const;
111 
112   // Returns true if this AudioVector is empty.
113   virtual bool Empty() const;
114 
115   // Accesses and modifies an element of AudioVector.
116   inline const int16_t& operator[](size_t index) const {
117     return array_[WrapIndex(index, begin_index_, capacity_)];
118   }
119 
120   inline int16_t& operator[](size_t index) {
121     return array_[WrapIndex(index, begin_index_, capacity_)];
122   }
123 
124  private:
125   static const size_t kDefaultInitialSize = 10;
126 
127   // This method is used by the [] operators to calculate an index within the
128   // capacity of the array, but without using the modulo operation (%).
WrapIndex(size_t index,size_t begin_index,size_t capacity)129   static inline size_t WrapIndex(size_t index,
130                                  size_t begin_index,
131                                  size_t capacity) {
132     RTC_DCHECK_LT(index, capacity);
133     RTC_DCHECK_LT(begin_index, capacity);
134     size_t ix = begin_index + index;
135     RTC_DCHECK_GE(ix, index);  // Check for overflow.
136     if (ix >= capacity) {
137       ix -= capacity;
138     }
139     RTC_DCHECK_LT(ix, capacity);
140     return ix;
141   }
142 
143   void Reserve(size_t n);
144 
145   void InsertByPushBack(const int16_t* insert_this,
146                         size_t length,
147                         size_t position);
148 
149   void InsertByPushFront(const int16_t* insert_this,
150                          size_t length,
151                          size_t position);
152 
153   void InsertZerosByPushBack(size_t length, size_t position);
154 
155   void InsertZerosByPushFront(size_t length, size_t position);
156 
157   std::unique_ptr<int16_t[]> array_;
158 
159   size_t capacity_;  // Allocated number of samples in the array.
160 
161   // The index of the first sample in |array_|, except when
162   // |begin_index_ == end_index_|, which indicates an empty buffer.
163   size_t begin_index_;
164 
165   // The index of the sample after the last sample in |array_|.
166   size_t end_index_;
167 
168   RTC_DISALLOW_COPY_AND_ASSIGN(AudioVector);
169 };
170 
171 }  // namespace webrtc
172 #endif  // MODULES_AUDIO_CODING_NETEQ_AUDIO_VECTOR_H_
173