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 #include "webrtc/modules/audio_processing/splitting_filter.h"
12
13 #include "webrtc/base/checks.h"
14 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
15 #include "webrtc/common_audio/channel_buffer.h"
16
17 namespace webrtc {
18
SplittingFilter(int num_channels,size_t num_bands,size_t num_frames)19 SplittingFilter::SplittingFilter(int num_channels,
20 size_t num_bands,
21 size_t num_frames)
22 : num_bands_(num_bands) {
23 RTC_CHECK(num_bands_ == 2 || num_bands_ == 3);
24 if (num_bands_ == 2) {
25 two_bands_states_.resize(num_channels);
26 } else if (num_bands_ == 3) {
27 for (int i = 0; i < num_channels; ++i) {
28 three_band_filter_banks_.push_back(new ThreeBandFilterBank(num_frames));
29 }
30 }
31 }
32
Analysis(const IFChannelBuffer * data,IFChannelBuffer * bands)33 void SplittingFilter::Analysis(const IFChannelBuffer* data,
34 IFChannelBuffer* bands) {
35 RTC_DCHECK_EQ(num_bands_, bands->num_bands());
36 RTC_DCHECK_EQ(data->num_channels(), bands->num_channels());
37 RTC_DCHECK_EQ(data->num_frames(),
38 bands->num_frames_per_band() * bands->num_bands());
39 if (bands->num_bands() == 2) {
40 TwoBandsAnalysis(data, bands);
41 } else if (bands->num_bands() == 3) {
42 ThreeBandsAnalysis(data, bands);
43 }
44 }
45
Synthesis(const IFChannelBuffer * bands,IFChannelBuffer * data)46 void SplittingFilter::Synthesis(const IFChannelBuffer* bands,
47 IFChannelBuffer* data) {
48 RTC_DCHECK_EQ(num_bands_, bands->num_bands());
49 RTC_DCHECK_EQ(data->num_channels(), bands->num_channels());
50 RTC_DCHECK_EQ(data->num_frames(),
51 bands->num_frames_per_band() * bands->num_bands());
52 if (bands->num_bands() == 2) {
53 TwoBandsSynthesis(bands, data);
54 } else if (bands->num_bands() == 3) {
55 ThreeBandsSynthesis(bands, data);
56 }
57 }
58
TwoBandsAnalysis(const IFChannelBuffer * data,IFChannelBuffer * bands)59 void SplittingFilter::TwoBandsAnalysis(const IFChannelBuffer* data,
60 IFChannelBuffer* bands) {
61 RTC_DCHECK_EQ(static_cast<int>(two_bands_states_.size()),
62 data->num_channels());
63 for (size_t i = 0; i < two_bands_states_.size(); ++i) {
64 WebRtcSpl_AnalysisQMF(data->ibuf_const()->channels()[i],
65 data->num_frames(),
66 bands->ibuf()->channels(0)[i],
67 bands->ibuf()->channels(1)[i],
68 two_bands_states_[i].analysis_state1,
69 two_bands_states_[i].analysis_state2);
70 }
71 }
72
TwoBandsSynthesis(const IFChannelBuffer * bands,IFChannelBuffer * data)73 void SplittingFilter::TwoBandsSynthesis(const IFChannelBuffer* bands,
74 IFChannelBuffer* data) {
75 RTC_DCHECK_EQ(static_cast<int>(two_bands_states_.size()),
76 data->num_channels());
77 for (size_t i = 0; i < two_bands_states_.size(); ++i) {
78 WebRtcSpl_SynthesisQMF(bands->ibuf_const()->channels(0)[i],
79 bands->ibuf_const()->channels(1)[i],
80 bands->num_frames_per_band(),
81 data->ibuf()->channels()[i],
82 two_bands_states_[i].synthesis_state1,
83 two_bands_states_[i].synthesis_state2);
84 }
85 }
86
ThreeBandsAnalysis(const IFChannelBuffer * data,IFChannelBuffer * bands)87 void SplittingFilter::ThreeBandsAnalysis(const IFChannelBuffer* data,
88 IFChannelBuffer* bands) {
89 RTC_DCHECK_EQ(static_cast<int>(three_band_filter_banks_.size()),
90 data->num_channels());
91 for (size_t i = 0; i < three_band_filter_banks_.size(); ++i) {
92 three_band_filter_banks_[i]->Analysis(data->fbuf_const()->channels()[i],
93 data->num_frames(),
94 bands->fbuf()->bands(i));
95 }
96 }
97
ThreeBandsSynthesis(const IFChannelBuffer * bands,IFChannelBuffer * data)98 void SplittingFilter::ThreeBandsSynthesis(const IFChannelBuffer* bands,
99 IFChannelBuffer* data) {
100 RTC_DCHECK_EQ(static_cast<int>(three_band_filter_banks_.size()),
101 data->num_channels());
102 for (size_t i = 0; i < three_band_filter_banks_.size(); ++i) {
103 three_band_filter_banks_[i]->Synthesis(bands->fbuf_const()->bands(i),
104 bands->num_frames_per_band(),
105 data->fbuf()->channels()[i]);
106 }
107 }
108
109 } // namespace webrtc
110