Build libwebrtc unit tests executables
[WebKit-https.git] / Source / ThirdParty / libwebrtc / Source / webrtc / common_audio / resampler / push_resampler.cc
1 /*
2  *  Copyright (c) 2013 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/common_audio/resampler/include/push_resampler.h"
12
13 #include <string.h>
14
15 #include "webrtc/base/checks.h"
16 #include "webrtc/common_audio/include/audio_util.h"
17 #include "webrtc/common_audio/resampler/include/resampler.h"
18 #include "webrtc/common_audio/resampler/push_sinc_resampler.h"
19
20 namespace webrtc {
21 namespace {
22 // These checks were factored out into a non-templatized function
23 // due to problems with clang on Windows in debug builds.
24 // For some reason having the DCHECKs inline in the template code
25 // caused the compiler to generate code that threw off the linker.
26 // TODO(tommi): Re-enable when we've figured out what the problem is.
27 // http://crbug.com/615050
28 void CheckValidInitParams(int src_sample_rate_hz, int dst_sample_rate_hz,
29                           size_t num_channels) {
30 // The below checks are temporarily disabled on WEBRTC_WIN due to problems
31 // with clang debug builds.
32 #if !defined(WEBRTC_WIN) && defined(__clang__)
33   RTC_DCHECK_GT(src_sample_rate_hz, 0);
34   RTC_DCHECK_GT(dst_sample_rate_hz, 0);
35   RTC_DCHECK_GT(num_channels, 0);
36   RTC_DCHECK_LE(num_channels, 2);
37 #endif
38 }
39
40 void CheckExpectedBufferSizes(size_t src_length,
41                               size_t dst_capacity,
42                               size_t num_channels,
43                               int src_sample_rate,
44                               int dst_sample_rate) {
45 // The below checks are temporarily disabled on WEBRTC_WIN due to problems
46 // with clang debug builds.
47 // TODO(tommi): Re-enable when we've figured out what the problem is.
48 // http://crbug.com/615050
49 #if !defined(WEBRTC_WIN) && defined(__clang__)
50   const size_t src_size_10ms = src_sample_rate * num_channels / 100;
51   const size_t dst_size_10ms = dst_sample_rate * num_channels / 100;
52   RTC_DCHECK_EQ(src_length, src_size_10ms);
53   RTC_DCHECK_GE(dst_capacity, dst_size_10ms);
54 #endif
55 }
56 }  // namespace
57
58 template <typename T>
59 int PushResampler<T>::InitializeIfNeeded(int src_sample_rate_hz,
60                                          int dst_sample_rate_hz,
61                                          size_t num_channels) {
62   CheckValidInitParams(src_sample_rate_hz, dst_sample_rate_hz, num_channels);
63
64   if (src_sample_rate_hz == src_sample_rate_hz_ &&
65       dst_sample_rate_hz == dst_sample_rate_hz_ &&
66       num_channels == num_channels_) {
67     // No-op if settings haven't changed.
68     return 0;
69   }
70
71   if (src_sample_rate_hz <= 0 || dst_sample_rate_hz <= 0 || num_channels <= 0 ||
72       num_channels > 2) {
73     return -1;
74   }
75
76   src_sample_rate_hz_ = src_sample_rate_hz;
77   dst_sample_rate_hz_ = dst_sample_rate_hz;
78   num_channels_ = num_channels;
79
80   const size_t src_size_10ms_mono =
81       static_cast<size_t>(src_sample_rate_hz / 100);
82   const size_t dst_size_10ms_mono =
83       static_cast<size_t>(dst_sample_rate_hz / 100);
84   sinc_resampler_.reset(new PushSincResampler(src_size_10ms_mono,
85                                               dst_size_10ms_mono));
86   if (num_channels_ == 2) {
87     src_left_.reset(new T[src_size_10ms_mono]);
88     src_right_.reset(new T[src_size_10ms_mono]);
89     dst_left_.reset(new T[dst_size_10ms_mono]);
90     dst_right_.reset(new T[dst_size_10ms_mono]);
91     sinc_resampler_right_.reset(new PushSincResampler(src_size_10ms_mono,
92                                                       dst_size_10ms_mono));
93   }
94
95   return 0;
96 }
97
98 template <typename T>
99 int PushResampler<T>::Resample(const T* src, size_t src_length, T* dst,
100                                size_t dst_capacity) {
101   CheckExpectedBufferSizes(src_length, dst_capacity, num_channels_,
102                            src_sample_rate_hz_, dst_sample_rate_hz_);
103
104   if (src_sample_rate_hz_ == dst_sample_rate_hz_) {
105     // The old resampler provides this memcpy facility in the case of matching
106     // sample rates, so reproduce it here for the sinc resampler.
107     memcpy(dst, src, src_length * sizeof(T));
108     return static_cast<int>(src_length);
109   }
110   if (num_channels_ == 2) {
111     const size_t src_length_mono = src_length / num_channels_;
112     const size_t dst_capacity_mono = dst_capacity / num_channels_;
113     T* deinterleaved[] = {src_left_.get(), src_right_.get()};
114     Deinterleave(src, src_length_mono, num_channels_, deinterleaved);
115
116     size_t dst_length_mono =
117         sinc_resampler_->Resample(src_left_.get(), src_length_mono,
118                                   dst_left_.get(), dst_capacity_mono);
119     sinc_resampler_right_->Resample(src_right_.get(), src_length_mono,
120                                     dst_right_.get(), dst_capacity_mono);
121
122     deinterleaved[0] = dst_left_.get();
123     deinterleaved[1] = dst_right_.get();
124     Interleave(deinterleaved, dst_length_mono, num_channels_, dst);
125     return static_cast<int>(dst_length_mono * num_channels_);
126   } else {
127     return static_cast<int>(
128         sinc_resampler_->Resample(src, src_length, dst, dst_capacity));
129   }
130 }
131
132 // Explictly generate required instantiations.
133 template class PushResampler<int16_t>;
134 template class PushResampler<float>;
135
136 }  // namespace webrtc