Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_processing / high_pass_filter_impl.cc
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 #include "webrtc/modules/audio_processing/high_pass_filter_impl.h"
12
13 #include <assert.h>
14
15 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
16 #include "webrtc/modules/audio_processing/audio_buffer.h"
17 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
18 #include "webrtc/typedefs.h"
19
20
21 namespace webrtc {
22 namespace {
23 const int16_t kFilterCoefficients8kHz[5] =
24     {3798, -7596, 3798, 7807, -3733};
25
26 const int16_t kFilterCoefficients[5] =
27     {4012, -8024, 4012, 8002, -3913};
28
29 struct FilterState {
30   int16_t y[4];
31   int16_t x[2];
32   const int16_t* ba;
33 };
34
35 int InitializeFilter(FilterState* hpf, int sample_rate_hz) {
36   assert(hpf != NULL);
37
38   if (sample_rate_hz == AudioProcessing::kSampleRate8kHz) {
39     hpf->ba = kFilterCoefficients8kHz;
40   } else {
41     hpf->ba = kFilterCoefficients;
42   }
43
44   WebRtcSpl_MemSetW16(hpf->x, 0, 2);
45   WebRtcSpl_MemSetW16(hpf->y, 0, 4);
46
47   return AudioProcessing::kNoError;
48 }
49
50 int Filter(FilterState* hpf, int16_t* data, int length) {
51   assert(hpf != NULL);
52
53   int32_t tmp_int32 = 0;
54   int16_t* y = hpf->y;
55   int16_t* x = hpf->x;
56   const int16_t* ba = hpf->ba;
57
58   for (int i = 0; i < length; i++) {
59     //  y[i] = b[0] * x[i] + b[1] * x[i-1] + b[2] * x[i-2]
60     //         + -a[1] * y[i-1] + -a[2] * y[i-2];
61
62     tmp_int32 =
63         WEBRTC_SPL_MUL_16_16(y[1], ba[3]); // -a[1] * y[i-1] (low part)
64     tmp_int32 +=
65         WEBRTC_SPL_MUL_16_16(y[3], ba[4]); // -a[2] * y[i-2] (low part)
66     tmp_int32 = (tmp_int32 >> 15);
67     tmp_int32 +=
68         WEBRTC_SPL_MUL_16_16(y[0], ba[3]); // -a[1] * y[i-1] (high part)
69     tmp_int32 +=
70         WEBRTC_SPL_MUL_16_16(y[2], ba[4]); // -a[2] * y[i-2] (high part)
71     tmp_int32 = (tmp_int32 << 1);
72
73     tmp_int32 += WEBRTC_SPL_MUL_16_16(data[i], ba[0]); // b[0]*x[0]
74     tmp_int32 += WEBRTC_SPL_MUL_16_16(x[0], ba[1]);    // b[1]*x[i-1]
75     tmp_int32 += WEBRTC_SPL_MUL_16_16(x[1], ba[2]);    // b[2]*x[i-2]
76
77     // Update state (input part)
78     x[1] = x[0];
79     x[0] = data[i];
80
81     // Update state (filtered part)
82     y[2] = y[0];
83     y[3] = y[1];
84     y[0] = static_cast<int16_t>(tmp_int32 >> 13);
85     y[1] = static_cast<int16_t>((tmp_int32 -
86         WEBRTC_SPL_LSHIFT_W32(static_cast<int32_t>(y[0]), 13)) << 2);
87
88     // Rounding in Q12, i.e. add 2^11
89     tmp_int32 += 2048;
90
91     // Saturate (to 2^27) so that the HP filtered signal does not overflow
92     tmp_int32 = WEBRTC_SPL_SAT(static_cast<int32_t>(134217727),
93                                tmp_int32,
94                                static_cast<int32_t>(-134217728));
95
96     // Convert back to Q0 and use rounding
97     data[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp_int32, 12);
98
99   }
100
101   return AudioProcessing::kNoError;
102 }
103 }  // namespace
104
105 typedef FilterState Handle;
106
107 HighPassFilterImpl::HighPassFilterImpl(const AudioProcessing* apm,
108                                        CriticalSectionWrapper* crit)
109   : ProcessingComponent(),
110     apm_(apm),
111     crit_(crit) {}
112
113 HighPassFilterImpl::~HighPassFilterImpl() {}
114
115 int HighPassFilterImpl::ProcessCaptureAudio(AudioBuffer* audio) {
116   int err = apm_->kNoError;
117
118   if (!is_component_enabled()) {
119     return apm_->kNoError;
120   }
121
122   assert(audio->samples_per_split_channel() <= 160);
123
124   for (int i = 0; i < num_handles(); i++) {
125     Handle* my_handle = static_cast<Handle*>(handle(i));
126     err = Filter(my_handle,
127                  audio->low_pass_split_data(i),
128                  audio->samples_per_split_channel());
129
130     if (err != apm_->kNoError) {
131       return GetHandleError(my_handle);
132     }
133   }
134
135   return apm_->kNoError;
136 }
137
138 int HighPassFilterImpl::Enable(bool enable) {
139   CriticalSectionScoped crit_scoped(crit_);
140   return EnableComponent(enable);
141 }
142
143 bool HighPassFilterImpl::is_enabled() const {
144   return is_component_enabled();
145 }
146
147 void* HighPassFilterImpl::CreateHandle() const {
148   return new FilterState;
149 }
150
151 void HighPassFilterImpl::DestroyHandle(void* handle) const {
152   delete static_cast<Handle*>(handle);
153 }
154
155 int HighPassFilterImpl::InitializeHandle(void* handle) const {
156   return InitializeFilter(static_cast<Handle*>(handle),
157                           apm_->proc_sample_rate_hz());
158 }
159
160 int HighPassFilterImpl::ConfigureHandle(void* /*handle*/) const {
161   return apm_->kNoError; // Not configurable.
162 }
163
164 int HighPassFilterImpl::num_handles_required() const {
165   return apm_->num_output_channels();
166 }
167
168 int HighPassFilterImpl::GetHandleError(void* handle) const {
169   // The component has no detailed errors.
170   assert(handle != NULL);
171   return apm_->kUnspecifiedError;
172 }
173 }  // namespace webrtc