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
21namespace webrtc {
22
23static 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.
38template <typename T>
39class 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