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 WEBRTC_MODULES_AUDIO_PROCESSING_COMMON_H_ 12 #define WEBRTC_MODULES_AUDIO_PROCESSING_COMMON_H_ 13 14 #include <assert.h> 15 #include <string.h> 16 17 #include "webrtc/base/checks.h" 18 #include "webrtc/modules/audio_processing/include/audio_processing.h" 19 #include "webrtc/system_wrappers/interface/scoped_ptr.h" 20 21 namespace webrtc { 22 23 static inline int ChannelsFromLayout(AudioProcessing::ChannelLayout layout) { 24 switch (layout) { 25 case AudioProcessing::kMono: 26 case AudioProcessing::kMonoAndKeyboard: 27 return 1; 28 case AudioProcessing::kStereo: 29 case AudioProcessing::kStereoAndKeyboard: 30 return 2; 31 } 32 assert(false); 33 return -1; 34 } 35 36 // Helper to encapsulate a contiguous data buffer with access to a pointer 37 // array of the deinterleaved channels. 38 template <typename T> 39 class ChannelBuffer { 40 public: 41 ChannelBuffer(int samples_per_channel, int num_channels) 42 : data_(new T[samples_per_channel * num_channels]), 43 channels_(new T*[num_channels]), 44 samples_per_channel_(samples_per_channel), 45 num_channels_(num_channels) { 46 Initialize(); 47 } 48 49 ChannelBuffer(const T* data, int samples_per_channel, int num_channels) 50 : data_(new T[samples_per_channel * num_channels]), 51 channels_(new T*[num_channels]), 52 samples_per_channel_(samples_per_channel), 53 num_channels_(num_channels) { 54 Initialize(); 55 memcpy(data_.get(), data, length() * sizeof(T)); 56 } 57 58 ChannelBuffer(const T* const* channels, int samples_per_channel, 59 int num_channels) 60 : data_(new T[samples_per_channel * num_channels]), 61 channels_(new T*[num_channels]), 62 samples_per_channel_(samples_per_channel), 63 num_channels_(num_channels) { 64 Initialize(); 65 for (int i = 0; i < num_channels_; ++i) 66 CopyFrom(channels[i], i); 67 } 68 69 ~ChannelBuffer() {} 70 71 void CopyFrom(const void* channel_ptr, int i) { 72 DCHECK_LT(i, num_channels_); 73 memcpy(channels_[i], channel_ptr, samples_per_channel_ * sizeof(T)); 74 } 75 76 T* data() { return data_.get(); } 77 const T* data() const { return data_.get(); } 78 79 const T* channel(int i) const { 80 DCHECK_GE(i, 0); 81 DCHECK_LT(i, num_channels_); 82 return channels_[i]; 83 } 84 T* channel(int i) { 85 const ChannelBuffer<T>* t = this; 86 return const_cast<T*>(t->channel(i)); 87 } 88 89 T* const* channels() { return channels_.get(); } 90 const T* const* channels() const { return channels_.get(); } 91 92 int samples_per_channel() const { return samples_per_channel_; } 93 int num_channels() const { return num_channels_; } 94 int length() const { return samples_per_channel_ * num_channels_; } 95 96 private: 97 void Initialize() { 98 memset(data_.get(), 0, sizeof(T) * length()); 99 for (int i = 0; i < num_channels_; ++i) 100 channels_[i] = &data_[i * samples_per_channel_]; 101 } 102 103 scoped_ptr<T[]> data_; 104 scoped_ptr<T*[]> channels_; 105 const int samples_per_channel_; 106 const int num_channels_; 107 }; 108 109 } // namespace webrtc 110 111 #endif // WEBRTC_MODULES_AUDIO_PROCESSING_COMMON_H_ 112