OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2017 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/aec3/render_delay_buffer.h" | 11 #include "webrtc/modules/audio_processing/aec3/render_delay_buffer.h" |
12 | 12 |
13 #include <string.h> | 13 #include <string.h> |
14 #include <algorithm> | 14 #include <algorithm> |
15 | 15 |
16 #include "webrtc/base/checks.h" | 16 #include "webrtc/base/checks.h" |
17 #include "webrtc/base/constructormagic.h" | 17 #include "webrtc/base/constructormagic.h" |
18 #include "webrtc/modules/audio_processing/aec3/aec3_common.h" | 18 #include "webrtc/modules/audio_processing/aec3/aec3_common.h" |
19 #include "webrtc/modules/audio_processing/aec3/block_processor.h" | |
20 #include "webrtc/modules/audio_processing/aec3/decimator_by_4.h" | |
21 #include "webrtc/modules/audio_processing/aec3/fft_data.h" | |
19 #include "webrtc/system_wrappers/include/logging.h" | 22 #include "webrtc/system_wrappers/include/logging.h" |
20 | 23 |
21 namespace webrtc { | 24 namespace webrtc { |
22 namespace { | 25 namespace { |
23 | 26 |
27 class ApiCallJitterBuffer { | |
28 public: | |
29 explicit ApiCallJitterBuffer(size_t num_bands) { | |
30 buffer_.fill(std::vector<std::vector<float>>( | |
31 num_bands, std::vector<float>(kBlockSize, 0.f))); | |
32 } | |
33 | |
34 ~ApiCallJitterBuffer() = default; | |
35 | |
36 void Reset() { | |
37 size_ = 0; | |
38 last_insert_index_ = 0; | |
39 } | |
40 | |
41 void Insert(const std::vector<std::vector<float>>& block) { | |
42 RTC_DCHECK_LT(size_, buffer_.size()); | |
43 last_insert_index_ = (last_insert_index_ + 1) % buffer_.size(); | |
44 RTC_DCHECK_EQ(buffer_[last_insert_index_].size(), block.size()); | |
45 RTC_DCHECK_EQ(buffer_[last_insert_index_][0].size(), block[0].size()); | |
46 for (size_t k = 0; k < block.size(); ++k) { | |
47 std::copy(block[k].begin(), block[k].end(), | |
48 buffer_[last_insert_index_][k].begin()); | |
49 } | |
50 | |
aleloi
2017/04/04 12:18:50
Unnecessary newline.
peah-webrtc
2017/04/04 13:57:11
Done.
| |
51 ++size_; | |
52 } | |
53 | |
54 void Remove(std::vector<std::vector<float>>* block) { | |
55 RTC_DCHECK_LT(0, size_); | |
56 --size_; | |
57 const size_t extract_index = | |
58 (last_insert_index_ - size_ + buffer_.size()) % buffer_.size(); | |
59 for (size_t k = 0; k < block->size(); ++k) { | |
60 std::copy(buffer_[extract_index][k].begin(), | |
61 buffer_[extract_index][k].end(), (*block)[k].begin()); | |
62 } | |
63 } | |
64 | |
65 size_t Size() const { return size_; } | |
66 bool Full() const { return size_ >= (buffer_.size()); } | |
67 bool Empty() const { return size_ == 0; } | |
68 | |
69 private: | |
70 std::array<std::vector<std::vector<float>>, kMaxApiCallsJitterBlocks> buffer_; | |
71 size_t size_ = 0; | |
72 int last_insert_index_ = 0; | |
73 }; | |
74 | |
24 class RenderDelayBufferImpl final : public RenderDelayBuffer { | 75 class RenderDelayBufferImpl final : public RenderDelayBuffer { |
25 public: | 76 public: |
26 RenderDelayBufferImpl(size_t size_blocks, | 77 RenderDelayBufferImpl(size_t num_bands); |
aleloi
2017/04/04 12:18:50
explicit
peah-webrtc
2017/04/04 13:57:11
Done.
| |
27 size_t num_bands, | |
28 size_t max_api_jitter_blocks); | |
29 ~RenderDelayBufferImpl() override; | 78 ~RenderDelayBufferImpl() override; |
30 | 79 |
80 void Reset() override; | |
31 bool Insert(std::vector<std::vector<float>>* block) override; | 81 bool Insert(std::vector<std::vector<float>>* block) override; |
32 const std::vector<std::vector<float>>& GetNext() override; | 82 bool UpdateBuffers() override; |
33 void SetDelay(size_t delay) override; | 83 void SetDelay(size_t delay) override; |
34 size_t Delay() const override { return delay_; } | 84 size_t Delay() const override { return delay_; } |
35 size_t MaxDelay() const override { | 85 |
36 return buffer_.size() - max_api_jitter_blocks_; | 86 const RenderBuffer& GetRenderBuffer() const override { return fft_buffer_; } |
87 | |
88 const DownsampledRenderBuffer& GetDownsampledRenderBuffer() const override { | |
89 return downsampled_render_buffer_; | |
37 } | 90 } |
38 bool IsBlockAvailable() const override { return insert_surplus_ > 0; } | |
39 size_t MaxApiJitter() const override { return max_api_jitter_blocks_; } | |
40 | 91 |
41 private: | 92 private: |
42 const size_t max_api_jitter_blocks_; | 93 const Aec3Optimization optimization_; |
43 std::vector<std::vector<std::vector<float>>> buffer_; | 94 std::array<std::vector<std::vector<float>>, kRenderDelayBufferSize> buffer_; |
95 size_t delay_ = 0; | |
44 size_t last_insert_index_ = 0; | 96 size_t last_insert_index_ = 0; |
45 size_t delay_ = 0; | 97 RenderBuffer fft_buffer_; |
46 size_t insert_surplus_ = 0; | 98 DownsampledRenderBuffer downsampled_render_buffer_; |
47 | 99 DecimatorBy4 render_decimator_; |
100 ApiCallJitterBuffer api_call_jitter_buffer_; | |
48 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderDelayBufferImpl); | 101 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderDelayBufferImpl); |
49 }; | 102 }; |
50 | 103 |
51 RenderDelayBufferImpl::RenderDelayBufferImpl(size_t size_blocks, | 104 RenderDelayBufferImpl::RenderDelayBufferImpl(size_t num_bands) |
52 size_t num_bands, | 105 : optimization_(DetectOptimization()), |
53 size_t max_api_jitter_blocks) | 106 fft_buffer_(optimization_, |
54 : max_api_jitter_blocks_(max_api_jitter_blocks), | |
55 buffer_(size_blocks + max_api_jitter_blocks_, | |
56 std::vector<std::vector<float>>( | |
57 num_bands, | 107 num_bands, |
58 std::vector<float>(kBlockSize, 0.f))) {} | 108 std::max(30, kAdaptiveFilterLength), |
109 std::vector<size_t>(1, kAdaptiveFilterLength)), | |
110 api_call_jitter_buffer_(num_bands) { | |
111 buffer_.fill(std::vector<std::vector<float>>( | |
112 num_bands, std::vector<float>(kBlockSize, 0.f))); | |
113 | |
114 RTC_DCHECK_LT(buffer_.size(), downsampled_render_buffer_.buffer.size()); | |
115 } | |
59 | 116 |
60 RenderDelayBufferImpl::~RenderDelayBufferImpl() = default; | 117 RenderDelayBufferImpl::~RenderDelayBufferImpl() = default; |
61 | 118 |
119 void RenderDelayBufferImpl::Reset() { | |
120 // Empty all data in the buffers. | |
121 delay_ = 0; | |
122 last_insert_index_ = 0; | |
123 downsampled_render_buffer_.position = 0; | |
124 downsampled_render_buffer_.buffer.fill(0.f); | |
125 fft_buffer_.Clear(); | |
126 api_call_jitter_buffer_.Reset(); | |
127 } | |
128 | |
62 bool RenderDelayBufferImpl::Insert(std::vector<std::vector<float>>* block) { | 129 bool RenderDelayBufferImpl::Insert(std::vector<std::vector<float>>* block) { |
aleloi
2017/04/04 12:18:50
This can take 'block' by const ref.
peah-webrtc
2017/04/04 13:57:11
Done.
| |
63 RTC_DCHECK_EQ(block->size(), buffer_[0].size()); | 130 RTC_DCHECK_EQ(block->size(), buffer_[0].size()); |
64 RTC_DCHECK_EQ((*block)[0].size(), buffer_[0][0].size()); | 131 RTC_DCHECK_EQ((*block)[0].size(), buffer_[0][0].size()); |
65 | 132 |
66 if (insert_surplus_ == max_api_jitter_blocks_) { | 133 if (api_call_jitter_buffer_.Full()) { |
134 // Report buffer overrun and let the caller handle the overrun. | |
67 return false; | 135 return false; |
68 } | 136 } |
69 last_insert_index_ = (last_insert_index_ + 1) % buffer_.size(); | 137 api_call_jitter_buffer_.Insert(*block); |
70 block->swap(buffer_[last_insert_index_]); | |
71 | |
72 ++insert_surplus_; | |
73 | 138 |
74 return true; | 139 return true; |
75 } | 140 } |
76 | 141 |
77 const std::vector<std::vector<float>>& RenderDelayBufferImpl::GetNext() { | 142 bool RenderDelayBufferImpl::UpdateBuffers() { |
78 RTC_DCHECK(IsBlockAvailable()); | 143 bool underrun = true; |
79 const size_t extract_index_ = | 144 // Update the buffers with a new block if such is available, otherwise repeat |
80 (last_insert_index_ - delay_ - insert_surplus_ + 1 + buffer_.size()) % | 145 // the previous block. |
81 buffer_.size(); | 146 if (api_call_jitter_buffer_.Size() > 0) { |
82 RTC_DCHECK_LE(0, extract_index_); | 147 last_insert_index_ = (last_insert_index_ + 1) % buffer_.size(); |
83 RTC_DCHECK_GT(buffer_.size(), extract_index_); | 148 api_call_jitter_buffer_.Remove(&buffer_[last_insert_index_]); |
84 | 149 |
85 RTC_DCHECK_LT(0, insert_surplus_); | 150 underrun = false; |
86 --insert_surplus_; | 151 } |
87 | 152 |
88 return buffer_[extract_index_]; | 153 downsampled_render_buffer_.position = |
154 (downsampled_render_buffer_.position - kSubBlockSize + | |
155 downsampled_render_buffer_.buffer.size()) % | |
156 downsampled_render_buffer_.buffer.size(); | |
157 | |
158 std::array<float, kSubBlockSize> render_downsampled; | |
159 render_decimator_.Decimate(buffer_[last_insert_index_][0], | |
160 render_downsampled); | |
161 std::copy(render_downsampled.rbegin(), render_downsampled.rend(), | |
162 downsampled_render_buffer_.buffer.begin() + | |
163 downsampled_render_buffer_.position); | |
164 | |
165 fft_buffer_.Insert( | |
166 buffer_[(last_insert_index_ - delay_ + buffer_.size()) % buffer_.size()]); | |
167 return !underrun; | |
89 } | 168 } |
90 | 169 |
91 void RenderDelayBufferImpl::SetDelay(size_t delay) { | 170 void RenderDelayBufferImpl::SetDelay(size_t delay) { |
92 RTC_DCHECK_GE(MaxDelay(), delay); | 171 if (delay_ == delay) { |
93 delay_ = delay; | 172 return; |
173 } | |
174 | |
175 // If there is a new delay set, clear the fft buffer. | |
176 fft_buffer_.Clear(); | |
177 | |
178 const size_t max_delay = buffer_.size() - 1; | |
179 if (max_delay < delay) { | |
180 // If the desired delay is larger than the delay buffer, shorten the delay | |
181 // buffer size to achieve the desired alignment with the available buffer | |
182 // size. | |
183 const size_t delay_decrease = delay - max_delay; | |
184 RTC_DCHECK_LT(delay_decrease, buffer_.size()); | |
185 | |
186 downsampled_render_buffer_.position = | |
187 (downsampled_render_buffer_.position + kSubBlockSize * delay_decrease) % | |
188 downsampled_render_buffer_.buffer.size(); | |
189 | |
190 last_insert_index_ = | |
191 (last_insert_index_ + buffer_.size() - delay_decrease) % buffer_.size(); | |
192 | |
193 RTC_DCHECK_EQ(max_delay, delay_ - delay_decrease); | |
194 delay_ = max_delay; | |
195 } else { | |
196 delay_ = delay; | |
197 } | |
94 } | 198 } |
95 | 199 |
96 } // namespace | 200 } // namespace |
97 | 201 |
98 RenderDelayBuffer* RenderDelayBuffer::Create(size_t size_blocks, | 202 RenderDelayBuffer* RenderDelayBuffer::Create(size_t num_bands) { |
99 size_t num_bands, | 203 return new RenderDelayBufferImpl(num_bands); |
100 size_t max_api_jitter_blocks) { | |
101 return new RenderDelayBufferImpl(size_blocks, num_bands, | |
102 max_api_jitter_blocks); | |
103 } | 204 } |
104 | 205 |
105 } // namespace webrtc | 206 } // namespace webrtc |
OLD | NEW |