Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: webrtc/modules/audio_processing/high_pass_filter_impl.cc

Issue 1490333004: HighPassFilter not a ProcessingComponent anymore (bit exact). (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Less pessimistic locking Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/audio_processing/high_pass_filter_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/audio_processing/high_pass_filter_impl.h" 11 #include "webrtc/modules/audio_processing/high_pass_filter_impl.h"
12 12
13 #include <assert.h>
14
15 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" 13 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h"
16 #include "webrtc/modules/audio_processing/audio_buffer.h" 14 #include "webrtc/modules/audio_processing/audio_buffer.h"
17 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 15 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
18 #include "webrtc/typedefs.h"
19
20 16
21 namespace webrtc { 17 namespace webrtc {
22 namespace { 18 namespace {
23 const int16_t kFilterCoefficients8kHz[5] = 19 const int16_t kFilterCoefficients8kHz[5] = {3798, -7596, 3798, 7807, -3733};
24 {3798, -7596, 3798, 7807, -3733}; 20 const int16_t kFilterCoefficients[5] = {4012, -8024, 4012, 8002, -3913};
21 } // namespace
25 22
26 const int16_t kFilterCoefficients[5] = 23 class HighPassFilterImpl::MonoFilter {
peah-webrtc 2015/12/08 14:52:27 I think we should call this a MonoBiquadFilter, or
the sun 2015/12/08 15:08:06 Good idea. I changed it to BiquadFilter, and the p
27 {4012, -8024, 4012, 8002, -3913}; 24 public:
25 explicit MonoFilter(int sample_rate_hz) :
26 ba_(sample_rate_hz == AudioProcessing::kSampleRate8kHz ?
27 kFilterCoefficients8kHz : kFilterCoefficients)
28 {
29 std::memset(x_, 0, sizeof(x_));
30 std::memset(y_, 0, sizeof(y_));
31 }
28 32
29 struct FilterState { 33 void Filter(int16_t* data, size_t length) {
30 int16_t y[4]; 34 const int16_t* const ba = ba_;
31 int16_t x[2]; 35 int16_t* x = x_;
32 const int16_t* ba; 36 int16_t* y = y_;
37 int32_t tmp_int32 = 0;
38
39 for (size_t i = 0; i < length; i++) {
40 // y[i] = b[0] * x[i] + b[1] * x[i-1] + b[2] * x[i-2]
41 // + -a[1] * y[i-1] + -a[2] * y[i-2];
42
43 tmp_int32 = y[1] * ba[3]; // -a[1] * y[i-1] (low part)
44 tmp_int32 += y[3] * ba[4]; // -a[2] * y[i-2] (low part)
45 tmp_int32 = (tmp_int32 >> 15);
46 tmp_int32 += y[0] * ba[3]; // -a[1] * y[i-1] (high part)
47 tmp_int32 += y[2] * ba[4]; // -a[2] * y[i-2] (high part)
48 tmp_int32 = (tmp_int32 << 1);
49
50 tmp_int32 += data[i] * ba[0]; // b[0] * x[0]
51 tmp_int32 += x[0] * ba[1]; // b[1] * x[i-1]
52 tmp_int32 += x[1] * ba[2]; // b[2] * x[i-2]
53
54 // Update state (input part).
55 x[1] = x[0];
56 x[0] = data[i];
57
58 // Update state (filtered part).
59 y[2] = y[0];
60 y[3] = y[1];
61 y[0] = static_cast<int16_t>(tmp_int32 >> 13);
62 y[1] = static_cast<int16_t>(
63 (tmp_int32 - (static_cast<int32_t>(y[0]) << 13)) << 2);
64
65 // Rounding in Q12, i.e. add 2^11.
66 tmp_int32 += 2048;
67
68 // Saturate (to 2^27) so that the HP filtered signal does not overflow.
69 tmp_int32 = WEBRTC_SPL_SAT(static_cast<int32_t>(134217727),
70 tmp_int32,
71 static_cast<int32_t>(-134217728));
72
73 // Convert back to Q0 and use rounding.
74 data[i] = static_cast<int16_t>(tmp_int32 >> 12);
75 }
76 }
77
78 private:
79 const int16_t* const ba_ = nullptr;
80 int16_t x_[2];
81 int16_t y_[4];
33 }; 82 };
34 83
35 int InitializeFilter(FilterState* hpf, int sample_rate_hz) { 84 HighPassFilterImpl::HighPassFilterImpl(rtc::CriticalSection* crit)
36 assert(hpf != NULL); 85 : crit_(crit) {
37 86 RTC_DCHECK(crit_);
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, size_t 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 (size_t 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 = y[1] * ba[3]; // -a[1] * y[i-1] (low part)
63 tmp_int32 += y[3] * ba[4]; // -a[2] * y[i-2] (low part)
64 tmp_int32 = (tmp_int32 >> 15);
65 tmp_int32 += y[0] * ba[3]; // -a[1] * y[i-1] (high part)
66 tmp_int32 += y[2] * ba[4]; // -a[2] * y[i-2] (high part)
67 tmp_int32 = (tmp_int32 << 1);
68
69 tmp_int32 += data[i] * ba[0]; // b[0]*x[0]
70 tmp_int32 += x[0] * ba[1]; // b[1]*x[i-1]
71 tmp_int32 += x[1] * ba[2]; // b[2]*x[i-2]
72
73 // Update state (input part)
74 x[1] = x[0];
75 x[0] = data[i];
76
77 // Update state (filtered part)
78 y[2] = y[0];
79 y[3] = y[1];
80 y[0] = static_cast<int16_t>(tmp_int32 >> 13);
81 y[1] = static_cast<int16_t>(
82 (tmp_int32 - (static_cast<int32_t>(y[0]) << 13)) << 2);
83
84 // Rounding in Q12, i.e. add 2^11
85 tmp_int32 += 2048;
86
87 // Saturate (to 2^27) so that the HP filtered signal does not overflow
88 tmp_int32 = WEBRTC_SPL_SAT(static_cast<int32_t>(134217727),
89 tmp_int32,
90 static_cast<int32_t>(-134217728));
91
92 // Convert back to Q0 and use rounding.
93 data[i] = (int16_t)(tmp_int32 >> 12);
94 }
95
96 return AudioProcessing::kNoError;
97 }
98 } // namespace
99
100 typedef FilterState Handle;
101
102 HighPassFilterImpl::HighPassFilterImpl(const AudioProcessing* apm,
103 rtc::CriticalSection* crit)
104 : ProcessingComponent(), apm_(apm), crit_(crit) {
105 RTC_DCHECK(apm);
106 RTC_DCHECK(crit);
107 } 87 }
108 88
109 HighPassFilterImpl::~HighPassFilterImpl() {} 89 HighPassFilterImpl::~HighPassFilterImpl() {}
110 90
111 int HighPassFilterImpl::ProcessCaptureAudio(AudioBuffer* audio) { 91 void HighPassFilterImpl::Initialize(int channels, int sample_rate_hz) {
92 std::vector<rtc::scoped_ptr<MonoFilter>> new_filters(channels);
93 for (int i = 0; i < channels; i++) {
94 new_filters[i].reset(new MonoFilter(sample_rate_hz));
95 }
112 rtc::CritScope cs(crit_); 96 rtc::CritScope cs(crit_);
113 int err = AudioProcessing::kNoError; 97 filters_.swap(new_filters);
98 }
114 99
115 if (!is_component_enabled()) { 100 void HighPassFilterImpl::ProcessCaptureAudio(AudioBuffer* audio) {
116 return AudioProcessing::kNoError; 101 rtc::CritScope cs(crit_);
102 if (!enabled_) {
103 return;
117 } 104 }
118 105
119 assert(audio->num_frames_per_band() <= 160); 106 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
120 107 RTC_DCHECK_EQ(filters_.size(), static_cast<size_t>(audio->num_channels()));
121 for (int i = 0; i < num_handles(); i++) { 108 for (size_t i = 0; i < filters_.size(); i++) {
122 Handle* my_handle = static_cast<Handle*>(handle(i)); 109 filters_[i]->Filter(audio->split_bands(i)[kBand0To8kHz],
123 err = Filter(my_handle, 110 audio->num_frames_per_band());
124 audio->split_bands(i)[kBand0To8kHz],
125 audio->num_frames_per_band());
126
127 if (err != AudioProcessing::kNoError) {
128 return GetHandleError(my_handle);
129 }
130 } 111 }
131
132 return AudioProcessing::kNoError;
133 } 112 }
134 113
135 int HighPassFilterImpl::Enable(bool enable) { 114 int HighPassFilterImpl::Enable(bool enable) {
136 rtc::CritScope cs(crit_); 115 rtc::CritScope cs(crit_);
137 return EnableComponent(enable); 116 enabled_ = enable;
117 return AudioProcessing::kNoError;
138 } 118 }
139 119
140 bool HighPassFilterImpl::is_enabled() const { 120 bool HighPassFilterImpl::is_enabled() const {
141 rtc::CritScope cs(crit_); 121 rtc::CritScope cs(crit_);
142 return is_component_enabled(); 122 return enabled_;
143 }
144
145 void* HighPassFilterImpl::CreateHandle() const {
146 return new FilterState;
147 }
148
149 void HighPassFilterImpl::DestroyHandle(void* handle) const {
150 delete static_cast<Handle*>(handle);
151 }
152
153 int HighPassFilterImpl::InitializeHandle(void* handle) const {
154 // TODO(peah): Remove dependency on apm for the
155 // capture side sample rate.
156 rtc::CritScope cs(crit_);
157 return InitializeFilter(static_cast<Handle*>(handle),
158 apm_->proc_sample_rate_hz());
159 }
160
161 int HighPassFilterImpl::ConfigureHandle(void* /*handle*/) const {
162 return AudioProcessing::kNoError; // Not configurable.
163 }
164
165 int HighPassFilterImpl::num_handles_required() const {
166 return apm_->num_output_channels();
167 }
168
169 int HighPassFilterImpl::GetHandleError(void* handle) const {
170 // The component has no detailed errors.
171 assert(handle != NULL);
172 return AudioProcessing::kUnspecifiedError;
173 } 123 }
174 } // namespace webrtc 124 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/high_pass_filter_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698