OLD | NEW |
---|---|
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 |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 } | 207 } |
208 | 208 |
209 AudioProcessingImpl::AudioProcessingImpl(const Config& config) | 209 AudioProcessingImpl::AudioProcessingImpl(const Config& config) |
210 : AudioProcessingImpl(config, nullptr) {} | 210 : AudioProcessingImpl(config, nullptr) {} |
211 | 211 |
212 AudioProcessingImpl::AudioProcessingImpl(const Config& config, | 212 AudioProcessingImpl::AudioProcessingImpl(const Config& config, |
213 Beamformer<float>* beamformer) | 213 Beamformer<float>* beamformer) |
214 : public_submodules_(new ApmPublicSubmodules()), | 214 : public_submodules_(new ApmPublicSubmodules()), |
215 private_submodules_(new ApmPrivateSubmodules(beamformer)), | 215 private_submodules_(new ApmPrivateSubmodules(beamformer)), |
216 constants_(config.Get<ExperimentalAgc>().startup_min_volume, | 216 constants_(config.Get<ExperimentalAgc>().startup_min_volume, |
217 config.Get<Beamforming>().array_geometry, | |
218 config.Get<Beamforming>().target_direction, | |
219 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) | 217 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) |
220 false, | 218 false, |
221 #else | 219 #else |
222 config.Get<ExperimentalAgc>().enabled, | 220 config.Get<ExperimentalAgc>().enabled, |
223 #endif | 221 #endif |
224 config.Get<Intelligibility>().enabled, | 222 config.Get<Intelligibility>().enabled), |
225 config.Get<Beamforming>().enabled), | |
226 | 223 |
227 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) | 224 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) |
228 capture_(false) | 225 capture_(false, |
229 #else | 226 #else |
230 capture_(config.Get<ExperimentalNs>().enabled) | 227 capture_(config.Get<ExperimentalNs>().enabled, |
231 #endif | 228 #endif |
229 config.Get<Beamforming>().enabled, | |
230 config.Get<Beamforming>().array_geometry, | |
231 config.Get<Beamforming>().target_direction) | |
232 { | 232 { |
233 { | 233 { |
234 rtc::CritScope cs_render(&crit_render_); | 234 rtc::CritScope cs_render(&crit_render_); |
235 rtc::CritScope cs_capture(&crit_capture_); | 235 rtc::CritScope cs_capture(&crit_capture_); |
236 | 236 |
237 public_submodules_->echo_cancellation = | 237 public_submodules_->echo_cancellation = |
238 new EchoCancellationImpl(this, &crit_render_, &crit_capture_); | 238 new EchoCancellationImpl(this, &crit_render_, &crit_capture_); |
239 public_submodules_->echo_control_mobile = | 239 public_submodules_->echo_control_mobile = |
240 new EchoControlMobileImpl(this, &crit_render_, &crit_capture_); | 240 new EchoControlMobileImpl(this, &crit_render_, &crit_capture_); |
241 public_submodules_->gain_control = | 241 public_submodules_->gain_control = |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
338 if (processing_config == formats_.api_format) { | 338 if (processing_config == formats_.api_format) { |
339 return kNoError; | 339 return kNoError; |
340 } | 340 } |
341 | 341 |
342 rtc::CritScope cs_capture(&crit_capture_); | 342 rtc::CritScope cs_capture(&crit_capture_); |
343 return InitializeLocked(processing_config); | 343 return InitializeLocked(processing_config); |
344 } | 344 } |
345 | 345 |
346 int AudioProcessingImpl::InitializeLocked() { | 346 int AudioProcessingImpl::InitializeLocked() { |
347 const int fwd_audio_buffer_channels = | 347 const int fwd_audio_buffer_channels = |
348 constants_.beamformer_enabled | 348 capture_.beamformer_enabled |
349 ? formats_.api_format.input_stream().num_channels() | 349 ? formats_.api_format.input_stream().num_channels() |
350 : formats_.api_format.output_stream().num_channels(); | 350 : formats_.api_format.output_stream().num_channels(); |
351 const int rev_audio_buffer_out_num_frames = | 351 const int rev_audio_buffer_out_num_frames = |
352 formats_.api_format.reverse_output_stream().num_frames() == 0 | 352 formats_.api_format.reverse_output_stream().num_frames() == 0 |
353 ? formats_.rev_proc_format.num_frames() | 353 ? formats_.rev_proc_format.num_frames() |
354 : formats_.api_format.reverse_output_stream().num_frames(); | 354 : formats_.api_format.reverse_output_stream().num_frames(); |
355 if (formats_.api_format.reverse_input_stream().num_channels() > 0) { | 355 if (formats_.api_format.reverse_input_stream().num_channels() > 0) { |
356 render_.render_audio.reset(new AudioBuffer( | 356 render_.render_audio.reset(new AudioBuffer( |
357 formats_.api_format.reverse_input_stream().num_frames(), | 357 formats_.api_format.reverse_input_stream().num_frames(), |
358 formats_.api_format.reverse_input_stream().num_channels(), | 358 formats_.api_format.reverse_input_stream().num_channels(), |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 const int num_in_channels = config.input_stream().num_channels(); | 421 const int num_in_channels = config.input_stream().num_channels(); |
422 const int num_out_channels = config.output_stream().num_channels(); | 422 const int num_out_channels = config.output_stream().num_channels(); |
423 | 423 |
424 // Need at least one input channel. | 424 // Need at least one input channel. |
425 // Need either one output channel or as many outputs as there are inputs. | 425 // Need either one output channel or as many outputs as there are inputs. |
426 if (num_in_channels == 0 || | 426 if (num_in_channels == 0 || |
427 !(num_out_channels == 1 || num_out_channels == num_in_channels)) { | 427 !(num_out_channels == 1 || num_out_channels == num_in_channels)) { |
428 return kBadNumberChannelsError; | 428 return kBadNumberChannelsError; |
429 } | 429 } |
430 | 430 |
431 if (constants_.beamformer_enabled && (static_cast<size_t>(num_in_channels) != | 431 if (capture_.beamformer_enabled && |
432 constants_.array_geometry.size() || | 432 static_cast<size_t>(num_in_channels) != capture_.array_geometry.size()) { |
hlundin-webrtc
2016/01/08 12:38:38
What happened to num_out_channels > 1?
aluebs-webrtc
2016/01/08 17:59:17
I thought this was a fictitious restriction, since
| |
433 num_out_channels > 1)) { | |
434 return kBadNumberChannelsError; | 433 return kBadNumberChannelsError; |
435 } | 434 } |
436 | 435 |
437 formats_.api_format = config; | 436 formats_.api_format = config; |
438 | 437 |
439 // We process at the closest native rate >= min(input rate, output rate)... | 438 // We process at the closest native rate >= min(input rate, output rate)... |
440 const int min_proc_rate = | 439 const int min_proc_rate = |
441 std::min(formats_.api_format.input_stream().sample_rate_hz(), | 440 std::min(formats_.api_format.input_stream().sample_rate_hz(), |
442 formats_.api_format.output_stream().sample_rate_hz()); | 441 formats_.api_format.output_stream().sample_rate_hz()); |
443 int fwd_proc_rate; | 442 int fwd_proc_rate; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
491 for (auto item : private_submodules_->component_list) { | 490 for (auto item : private_submodules_->component_list) { |
492 item->SetExtraOptions(config); | 491 item->SetExtraOptions(config); |
493 } | 492 } |
494 | 493 |
495 if (capture_.transient_suppressor_enabled != | 494 if (capture_.transient_suppressor_enabled != |
496 config.Get<ExperimentalNs>().enabled) { | 495 config.Get<ExperimentalNs>().enabled) { |
497 capture_.transient_suppressor_enabled = | 496 capture_.transient_suppressor_enabled = |
498 config.Get<ExperimentalNs>().enabled; | 497 config.Get<ExperimentalNs>().enabled; |
499 InitializeTransient(); | 498 InitializeTransient(); |
500 } | 499 } |
500 | |
501 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD | |
hlundin-webrtc
2016/01/08 12:38:38
Why not WEBRTC_ANDROID?
aluebs-webrtc
2016/01/08 17:59:17
Because I want to be as restrictive as possible an
hlundin-webrtc
2016/01/11 16:00:42
Acknowledged.
| |
502 if (capture_.beamformer_enabled != config.Get<Beamforming>().enabled) { | |
503 capture_.beamformer_enabled = config.Get<Beamforming>().enabled; | |
504 if (config.Get<Beamforming>().array_geometry.size() > 1) { | |
505 capture_.array_geometry = config.Get<Beamforming>().array_geometry; | |
506 } | |
507 capture_.target_direction = config.Get<Beamforming>().target_direction; | |
508 InitializeBeamformer(); | |
509 } | |
510 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP | |
hlundin-webrtc
2016/01/08 12:38:38
Wrong comment.
aluebs-webrtc
2016/01/08 17:59:17
Done.
| |
501 } | 511 } |
502 | 512 |
503 int AudioProcessingImpl::input_sample_rate_hz() const { | 513 int AudioProcessingImpl::input_sample_rate_hz() const { |
504 // Accessed from outside APM, hence a lock is needed. | 514 // Accessed from outside APM, hence a lock is needed. |
505 rtc::CritScope cs(&crit_capture_); | 515 rtc::CritScope cs(&crit_capture_); |
506 return formats_.api_format.input_stream().sample_rate_hz(); | 516 return formats_.api_format.input_stream().sample_rate_hz(); |
507 } | 517 } |
508 | 518 |
509 int AudioProcessingImpl::proc_sample_rate_hz() const { | 519 int AudioProcessingImpl::proc_sample_rate_hz() const { |
510 // Used as callback from submodules, hence locking is not allowed. | 520 // Used as callback from submodules, hence locking is not allowed. |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
753 if (analysis_needed(data_processed)) { | 763 if (analysis_needed(data_processed)) { |
754 ca->SplitIntoFrequencyBands(); | 764 ca->SplitIntoFrequencyBands(); |
755 } | 765 } |
756 | 766 |
757 if (constants_.intelligibility_enabled) { | 767 if (constants_.intelligibility_enabled) { |
758 public_submodules_->intelligibility_enhancer->AnalyzeCaptureAudio( | 768 public_submodules_->intelligibility_enhancer->AnalyzeCaptureAudio( |
759 ca->split_channels_f(kBand0To8kHz), capture_nonlocked_.split_rate, | 769 ca->split_channels_f(kBand0To8kHz), capture_nonlocked_.split_rate, |
760 ca->num_channels()); | 770 ca->num_channels()); |
761 } | 771 } |
762 | 772 |
763 if (constants_.beamformer_enabled) { | 773 if (capture_.beamformer_enabled) { |
764 private_submodules_->beamformer->ProcessChunk(*ca->split_data_f(), | 774 private_submodules_->beamformer->ProcessChunk(*ca->split_data_f(), |
765 ca->split_data_f()); | 775 ca->split_data_f()); |
766 ca->set_num_channels(1); | 776 ca->set_num_channels(1); |
767 } | 777 } |
768 | 778 |
769 public_submodules_->high_pass_filter->ProcessCaptureAudio(ca); | 779 public_submodules_->high_pass_filter->ProcessCaptureAudio(ca); |
770 RETURN_ON_ERR(public_submodules_->gain_control->AnalyzeCaptureAudio(ca)); | 780 RETURN_ON_ERR(public_submodules_->gain_control->AnalyzeCaptureAudio(ca)); |
771 public_submodules_->noise_suppression->AnalyzeCaptureAudio(ca); | 781 public_submodules_->noise_suppression->AnalyzeCaptureAudio(ca); |
772 RETURN_ON_ERR(public_submodules_->echo_cancellation->ProcessCaptureAudio(ca)); | 782 RETURN_ON_ERR(public_submodules_->echo_cancellation->ProcessCaptureAudio(ca)); |
773 | 783 |
774 if (public_submodules_->echo_control_mobile->is_enabled() && | 784 if (public_submodules_->echo_control_mobile->is_enabled() && |
775 public_submodules_->noise_suppression->is_enabled()) { | 785 public_submodules_->noise_suppression->is_enabled()) { |
776 ca->CopyLowPassToReference(); | 786 ca->CopyLowPassToReference(); |
777 } | 787 } |
778 public_submodules_->noise_suppression->ProcessCaptureAudio(ca); | 788 public_submodules_->noise_suppression->ProcessCaptureAudio(ca); |
779 RETURN_ON_ERR( | 789 RETURN_ON_ERR( |
780 public_submodules_->echo_control_mobile->ProcessCaptureAudio(ca)); | 790 public_submodules_->echo_control_mobile->ProcessCaptureAudio(ca)); |
781 public_submodules_->voice_detection->ProcessCaptureAudio(ca); | 791 public_submodules_->voice_detection->ProcessCaptureAudio(ca); |
782 | 792 |
783 if (constants_.use_new_agc && | 793 if (constants_.use_new_agc && |
784 public_submodules_->gain_control->is_enabled() && | 794 public_submodules_->gain_control->is_enabled() && |
785 (!constants_.beamformer_enabled || | 795 (!capture_.beamformer_enabled || |
786 private_submodules_->beamformer->is_target_present())) { | 796 private_submodules_->beamformer->is_target_present())) { |
787 private_submodules_->agc_manager->Process( | 797 private_submodules_->agc_manager->Process( |
788 ca->split_bands_const(0)[kBand0To8kHz], ca->num_frames_per_band(), | 798 ca->split_bands_const(0)[kBand0To8kHz], ca->num_frames_per_band(), |
789 capture_nonlocked_.split_rate); | 799 capture_nonlocked_.split_rate); |
790 } | 800 } |
791 RETURN_ON_ERR(public_submodules_->gain_control->ProcessCaptureAudio(ca)); | 801 RETURN_ON_ERR(public_submodules_->gain_control->ProcessCaptureAudio(ca)); |
792 | 802 |
793 if (synthesis_needed(data_processed)) { | 803 if (synthesis_needed(data_processed)) { |
794 ca->MergeFrequencyBands(); | 804 ca->MergeFrequencyBands(); |
795 } | 805 } |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1165 return public_submodules_->noise_suppression.get(); | 1175 return public_submodules_->noise_suppression.get(); |
1166 } | 1176 } |
1167 | 1177 |
1168 VoiceDetection* AudioProcessingImpl::voice_detection() const { | 1178 VoiceDetection* AudioProcessingImpl::voice_detection() const { |
1169 // Adding a lock here has no effect as it allows any access to the submodule | 1179 // Adding a lock here has no effect as it allows any access to the submodule |
1170 // from the returned pointer. | 1180 // from the returned pointer. |
1171 return public_submodules_->voice_detection.get(); | 1181 return public_submodules_->voice_detection.get(); |
1172 } | 1182 } |
1173 | 1183 |
1174 bool AudioProcessingImpl::is_data_processed() const { | 1184 bool AudioProcessingImpl::is_data_processed() const { |
1175 if (constants_.beamformer_enabled) { | 1185 if (capture_.beamformer_enabled) { |
1176 return true; | 1186 return true; |
1177 } | 1187 } |
1178 | 1188 |
1179 int enabled_count = 0; | 1189 int enabled_count = 0; |
1180 for (auto item : private_submodules_->component_list) { | 1190 for (auto item : private_submodules_->component_list) { |
1181 if (item->is_component_enabled()) { | 1191 if (item->is_component_enabled()) { |
1182 enabled_count++; | 1192 enabled_count++; |
1183 } | 1193 } |
1184 } | 1194 } |
1185 if (public_submodules_->high_pass_filter->is_enabled()) { | 1195 if (public_submodules_->high_pass_filter->is_enabled()) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1280 public_submodules_->transient_suppressor.reset(new TransientSuppressor()); | 1290 public_submodules_->transient_suppressor.reset(new TransientSuppressor()); |
1281 } | 1291 } |
1282 public_submodules_->transient_suppressor->Initialize( | 1292 public_submodules_->transient_suppressor->Initialize( |
1283 capture_nonlocked_.fwd_proc_format.sample_rate_hz(), | 1293 capture_nonlocked_.fwd_proc_format.sample_rate_hz(), |
1284 capture_nonlocked_.split_rate, | 1294 capture_nonlocked_.split_rate, |
1285 formats_.api_format.output_stream().num_channels()); | 1295 formats_.api_format.output_stream().num_channels()); |
1286 } | 1296 } |
1287 } | 1297 } |
1288 | 1298 |
1289 void AudioProcessingImpl::InitializeBeamformer() { | 1299 void AudioProcessingImpl::InitializeBeamformer() { |
1290 if (constants_.beamformer_enabled) { | 1300 if (capture_.beamformer_enabled) { |
1291 if (!private_submodules_->beamformer) { | 1301 if (!private_submodules_->beamformer) { |
1292 private_submodules_->beamformer.reset(new NonlinearBeamformer( | 1302 private_submodules_->beamformer.reset(new NonlinearBeamformer( |
1293 constants_.array_geometry, constants_.target_direction)); | 1303 capture_.array_geometry, capture_.target_direction)); |
1294 } | 1304 } |
1295 private_submodules_->beamformer->Initialize(kChunkSizeMs, | 1305 private_submodules_->beamformer->Initialize(kChunkSizeMs, |
1296 capture_nonlocked_.split_rate); | 1306 capture_nonlocked_.split_rate); |
1297 } | 1307 } |
1298 } | 1308 } |
1299 | 1309 |
1300 void AudioProcessingImpl::InitializeIntelligibility() { | 1310 void AudioProcessingImpl::InitializeIntelligibility() { |
1301 if (constants_.intelligibility_enabled) { | 1311 if (constants_.intelligibility_enabled) { |
1302 IntelligibilityEnhancer::Config config; | 1312 IntelligibilityEnhancer::Config config; |
1303 config.sample_rate_hz = capture_nonlocked_.split_rate; | 1313 config.sample_rate_hz = capture_nonlocked_.split_rate; |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1504 debug_dump_.capture.event_msg->set_type(audioproc::Event::CONFIG); | 1514 debug_dump_.capture.event_msg->set_type(audioproc::Event::CONFIG); |
1505 debug_dump_.capture.event_msg->mutable_config()->CopyFrom(config); | 1515 debug_dump_.capture.event_msg->mutable_config()->CopyFrom(config); |
1506 | 1516 |
1507 RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), | 1517 RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), |
1508 &crit_debug_, &debug_dump_.capture)); | 1518 &crit_debug_, &debug_dump_.capture)); |
1509 return kNoError; | 1519 return kNoError; |
1510 } | 1520 } |
1511 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP | 1521 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP |
1512 | 1522 |
1513 } // namespace webrtc | 1523 } // namespace webrtc |
OLD | NEW |