1 /* 2 * Copyright (c) 2014 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 COMMON_AUDIO_CHANNEL_BUFFER_H_ 12 #define COMMON_AUDIO_CHANNEL_BUFFER_H_ 13 14 #include <string.h> 15 16 #include <memory> 17 #include <vector> 18 19 #include "api/array_view.h" 20 #include "common_audio/include/audio_util.h" 21 #include "rtc_base/checks.h" 22 #include "rtc_base/gtest_prod_util.h" 23 24 namespace webrtc { 25 26 // Helper to encapsulate a contiguous data buffer, full or split into frequency 27 // bands, with access to a pointer arrays of the deinterleaved channels and 28 // bands. The buffer is zero initialized at creation. 29 // 30 // The buffer structure is showed below for a 2 channel and 2 bands case: 31 // 32 // |data_|: 33 // { [ --- b1ch1 --- ] [ --- b2ch1 --- ] [ --- b1ch2 --- ] [ --- b2ch2 --- ] } 34 // 35 // The pointer arrays for the same example are as follows: 36 // 37 // |channels_|: 38 // { [ b1ch1* ] [ b1ch2* ] [ b2ch1* ] [ b2ch2* ] } 39 // 40 // |bands_|: 41 // { [ b1ch1* ] [ b2ch1* ] [ b1ch2* ] [ b2ch2* ] } 42 template <typename T> 43 class ChannelBuffer { 44 public: 45 ChannelBuffer(size_t num_frames, size_t num_channels, size_t num_bands = 1) data_(new T[num_frames * num_channels]())46 : data_(new T[num_frames * num_channels]()), 47 channels_(new T*[num_channels * num_bands]), 48 bands_(new T*[num_channels * num_bands]), 49 num_frames_(num_frames), 50 num_frames_per_band_(num_frames / num_bands), 51 num_allocated_channels_(num_channels), 52 num_channels_(num_channels), 53 num_bands_(num_bands), 54 bands_view_(num_allocated_channels_, 55 std::vector<rtc::ArrayView<T>>(num_bands_)), 56 channels_view_( 57 num_bands_, 58 std::vector<rtc::ArrayView<T>>(num_allocated_channels_)) { 59 // Temporarily cast away const_ness to allow populating the array views. 60 auto* bands_view = 61 const_cast<std::vector<std::vector<rtc::ArrayView<T>>>*>(&bands_view_); 62 auto* channels_view = 63 const_cast<std::vector<std::vector<rtc::ArrayView<T>>>*>( 64 &channels_view_); 65 66 for (size_t ch = 0; ch < num_allocated_channels_; ++ch) { 67 for (size_t band = 0; band < num_bands_; ++band) { 68 (*channels_view)[band][ch] = rtc::ArrayView<T>( 69 &data_[ch * num_frames_ + band * num_frames_per_band_], 70 num_frames_per_band_); 71 (*bands_view)[ch][band] = channels_view_[band][ch]; 72 channels_[band * num_allocated_channels_ + ch] = 73 channels_view_[band][ch].data(); 74 bands_[ch * num_bands_ + band] = 75 channels_[band * num_allocated_channels_ + ch]; 76 } 77 } 78 } 79 80 // Returns a pointer array to the channels. 81 // If band is explicitly specificed, the channels for a specific band are 82 // returned and the usage becomes: channels(band)[channel][sample]. 83 // Where: 84 // 0 <= band < |num_bands_| 85 // 0 <= channel < |num_allocated_channels_| 86 // 0 <= sample < |num_frames_per_band_| 87 88 // If band is not explicitly specified, the full-band channels (or lower band 89 // channels) are returned and the usage becomes: channels()[channel][sample]. 90 // Where: 91 // 0 <= channel < |num_allocated_channels_| 92 // 0 <= sample < |num_frames_| 93 const T* const* channels(size_t band = 0) const { 94 RTC_DCHECK_LT(band, num_bands_); 95 return &channels_[band * num_allocated_channels_]; 96 } 97 T* const* channels(size_t band = 0) { 98 const ChannelBuffer<T>* t = this; 99 return const_cast<T* const*>(t->channels(band)); 100 } 101 rtc::ArrayView<const rtc::ArrayView<T>> channels_view(size_t band = 0) { 102 return channels_view_[band]; 103 } 104 rtc::ArrayView<const rtc::ArrayView<T>> channels_view(size_t band = 0) const { 105 return channels_view_[band]; 106 } 107 108 // Returns a pointer array to the bands for a specific channel. 109 // Usage: 110 // bands(channel)[band][sample]. 111 // Where: 112 // 0 <= channel < |num_channels_| 113 // 0 <= band < |num_bands_| 114 // 0 <= sample < |num_frames_per_band_| bands(size_t channel)115 const T* const* bands(size_t channel) const { 116 RTC_DCHECK_LT(channel, num_channels_); 117 RTC_DCHECK_GE(channel, 0); 118 return &bands_[channel * num_bands_]; 119 } bands(size_t channel)120 T* const* bands(size_t channel) { 121 const ChannelBuffer<T>* t = this; 122 return const_cast<T* const*>(t->bands(channel)); 123 } 124 bands_view(size_t channel)125 rtc::ArrayView<const rtc::ArrayView<T>> bands_view(size_t channel) { 126 return bands_view_[channel]; 127 } bands_view(size_t channel)128 rtc::ArrayView<const rtc::ArrayView<T>> bands_view(size_t channel) const { 129 return bands_view_[channel]; 130 } 131 132 // Sets the |slice| pointers to the |start_frame| position for each channel. 133 // Returns |slice| for convenience. Slice(T ** slice,size_t start_frame)134 const T* const* Slice(T** slice, size_t start_frame) const { 135 RTC_DCHECK_LT(start_frame, num_frames_); 136 for (size_t i = 0; i < num_channels_; ++i) 137 slice[i] = &channels_[i][start_frame]; 138 return slice; 139 } Slice(T ** slice,size_t start_frame)140 T** Slice(T** slice, size_t start_frame) { 141 const ChannelBuffer<T>* t = this; 142 return const_cast<T**>(t->Slice(slice, start_frame)); 143 } 144 num_frames()145 size_t num_frames() const { return num_frames_; } num_frames_per_band()146 size_t num_frames_per_band() const { return num_frames_per_band_; } num_channels()147 size_t num_channels() const { return num_channels_; } num_bands()148 size_t num_bands() const { return num_bands_; } size()149 size_t size() const { return num_frames_ * num_allocated_channels_; } 150 set_num_channels(size_t num_channels)151 void set_num_channels(size_t num_channels) { 152 RTC_DCHECK_LE(num_channels, num_allocated_channels_); 153 num_channels_ = num_channels; 154 } 155 SetDataForTesting(const T * data,size_t size)156 void SetDataForTesting(const T* data, size_t size) { 157 RTC_CHECK_EQ(size, this->size()); 158 memcpy(data_.get(), data, size * sizeof(*data)); 159 } 160 161 private: 162 std::unique_ptr<T[]> data_; 163 std::unique_ptr<T*[]> channels_; 164 std::unique_ptr<T*[]> bands_; 165 const size_t num_frames_; 166 const size_t num_frames_per_band_; 167 // Number of channels the internal buffer holds. 168 const size_t num_allocated_channels_; 169 // Number of channels the user sees. 170 size_t num_channels_; 171 const size_t num_bands_; 172 const std::vector<std::vector<rtc::ArrayView<T>>> bands_view_; 173 const std::vector<std::vector<rtc::ArrayView<T>>> channels_view_; 174 }; 175 176 // One int16_t and one float ChannelBuffer that are kept in sync. The sync is 177 // broken when someone requests write access to either ChannelBuffer, and 178 // reestablished when someone requests the outdated ChannelBuffer. It is 179 // therefore safe to use the return value of ibuf_const() and fbuf_const() 180 // until the next call to ibuf() or fbuf(), and the return value of ibuf() and 181 // fbuf() until the next call to any of the other functions. 182 class IFChannelBuffer { 183 public: 184 IFChannelBuffer(size_t num_frames, size_t num_channels, size_t num_bands = 1); 185 ~IFChannelBuffer(); 186 187 ChannelBuffer<int16_t>* ibuf(); 188 ChannelBuffer<float>* fbuf(); 189 const ChannelBuffer<int16_t>* ibuf_const() const; 190 const ChannelBuffer<float>* fbuf_const() const; 191 num_frames()192 size_t num_frames() const { return ibuf_.num_frames(); } num_frames_per_band()193 size_t num_frames_per_band() const { return ibuf_.num_frames_per_band(); } num_channels()194 size_t num_channels() const { 195 return ivalid_ ? ibuf_.num_channels() : fbuf_.num_channels(); 196 } set_num_channels(size_t num_channels)197 void set_num_channels(size_t num_channels) { 198 ibuf_.set_num_channels(num_channels); 199 fbuf_.set_num_channels(num_channels); 200 } num_bands()201 size_t num_bands() const { return ibuf_.num_bands(); } 202 203 private: 204 void RefreshF() const; 205 void RefreshI() const; 206 207 mutable bool ivalid_; 208 mutable ChannelBuffer<int16_t> ibuf_; 209 mutable bool fvalid_; 210 mutable ChannelBuffer<float> fbuf_; 211 }; 212 213 } // namespace webrtc 214 215 #endif // COMMON_AUDIO_CHANNEL_BUFFER_H_ 216