| 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 | 83 |
| 84 private: | 84 private: |
| 85 Handle* state_; | 85 Handle* state_; |
| 86 // TODO(peah): Remove the optional once the initialization is moved into the | 86 // TODO(peah): Remove the optional once the initialization is moved into the |
| 87 // ctor. | 87 // ctor. |
| 88 rtc::Optional<int> capture_level_; | 88 rtc::Optional<int> capture_level_; |
| 89 | 89 |
| 90 RTC_DISALLOW_COPY_AND_ASSIGN(GainController); | 90 RTC_DISALLOW_COPY_AND_ASSIGN(GainController); |
| 91 }; | 91 }; |
| 92 | 92 |
| 93 GainControlImpl::GainControlImpl(const AudioProcessing* apm, | 93 GainControlImpl::GainControlImpl(rtc::CriticalSection* crit_render, |
| 94 rtc::CriticalSection* crit_render, | |
| 95 rtc::CriticalSection* crit_capture) | 94 rtc::CriticalSection* crit_capture) |
| 96 : apm_(apm), | 95 : crit_render_(crit_render), |
| 97 crit_render_(crit_render), | |
| 98 crit_capture_(crit_capture), | 96 crit_capture_(crit_capture), |
| 99 mode_(kAdaptiveAnalog), | 97 mode_(kAdaptiveAnalog), |
| 100 minimum_capture_level_(0), | 98 minimum_capture_level_(0), |
| 101 maximum_capture_level_(255), | 99 maximum_capture_level_(255), |
| 102 limiter_enabled_(true), | 100 limiter_enabled_(true), |
| 103 target_level_dbfs_(3), | 101 target_level_dbfs_(3), |
| 104 compression_gain_db_(9), | 102 compression_gain_db_(9), |
| 105 analog_capture_level_(0), | 103 analog_capture_level_(0), |
| 106 was_analog_level_set_(false), | 104 was_analog_level_set_(false), |
| 107 stream_is_saturated_(false), | 105 stream_is_saturated_(false), |
| 108 render_queue_element_max_size_(0) { | 106 render_queue_element_max_size_(0) { |
| 109 RTC_DCHECK(apm); | |
| 110 RTC_DCHECK(crit_render); | 107 RTC_DCHECK(crit_render); |
| 111 RTC_DCHECK(crit_capture); | 108 RTC_DCHECK(crit_capture); |
| 112 } | 109 } |
| 113 | 110 |
| 114 GainControlImpl::~GainControlImpl() {} | 111 GainControlImpl::~GainControlImpl() {} |
| 115 | 112 |
| 116 int GainControlImpl::ProcessRenderAudio(AudioBuffer* audio) { | 113 int GainControlImpl::ProcessRenderAudio(AudioBuffer* audio) { |
| 117 rtc::CritScope cs(crit_render_); | 114 rtc::CritScope cs(crit_render_); |
| 118 if (!enabled_) { | 115 if (!enabled_) { |
| 119 return AudioProcessing::kNoError; | 116 return AudioProcessing::kNoError; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 // a queue. All the data chunks are buffered into the farend signal of the AGC. | 149 // a queue. All the data chunks are buffered into the farend signal of the AGC. |
| 153 void GainControlImpl::ReadQueuedRenderData() { | 150 void GainControlImpl::ReadQueuedRenderData() { |
| 154 rtc::CritScope cs(crit_capture_); | 151 rtc::CritScope cs(crit_capture_); |
| 155 | 152 |
| 156 if (!enabled_) { | 153 if (!enabled_) { |
| 157 return; | 154 return; |
| 158 } | 155 } |
| 159 | 156 |
| 160 while (render_signal_queue_->Remove(&capture_queue_buffer_)) { | 157 while (render_signal_queue_->Remove(&capture_queue_buffer_)) { |
| 161 size_t buffer_index = 0; | 158 size_t buffer_index = 0; |
| 159 RTC_DCHECK(num_proc_channels_); |
| 160 RTC_DCHECK_LT(0ul, *num_proc_channels_); |
| 162 const size_t num_frames_per_band = | 161 const size_t num_frames_per_band = |
| 163 capture_queue_buffer_.size() / num_handles_required(); | 162 capture_queue_buffer_.size() / (*num_proc_channels_); |
| 164 for (auto& gain_controller : gain_controllers_) { | 163 for (auto& gain_controller : gain_controllers_) { |
| 165 WebRtcAgc_AddFarend(gain_controller->state(), | 164 WebRtcAgc_AddFarend(gain_controller->state(), |
| 166 &capture_queue_buffer_[buffer_index], | 165 &capture_queue_buffer_[buffer_index], |
| 167 num_frames_per_band); | 166 num_frames_per_band); |
| 168 | 167 |
| 169 buffer_index += num_frames_per_band; | 168 buffer_index += num_frames_per_band; |
| 170 } | 169 } |
| 171 } | 170 } |
| 172 } | 171 } |
| 173 | 172 |
| 174 int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) { | 173 int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) { |
| 175 rtc::CritScope cs(crit_capture_); | 174 rtc::CritScope cs(crit_capture_); |
| 176 | 175 |
| 177 if (!enabled_) { | 176 if (!enabled_) { |
| 178 return AudioProcessing::kNoError; | 177 return AudioProcessing::kNoError; |
| 179 } | 178 } |
| 180 | 179 |
| 180 RTC_DCHECK(num_proc_channels_); |
| 181 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); | 181 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); |
| 182 RTC_DCHECK_EQ(audio->num_channels(), num_handles_required()); | 182 RTC_DCHECK_EQ(audio->num_channels(), *num_proc_channels_); |
| 183 RTC_DCHECK_LE(num_handles_required(), gain_controllers_.size()); | 183 RTC_DCHECK_LE(*num_proc_channels_, gain_controllers_.size()); |
| 184 | 184 |
| 185 if (mode_ == kAdaptiveAnalog) { | 185 if (mode_ == kAdaptiveAnalog) { |
| 186 int capture_channel = 0; | 186 int capture_channel = 0; |
| 187 for (auto& gain_controller : gain_controllers_) { | 187 for (auto& gain_controller : gain_controllers_) { |
| 188 gain_controller->set_capture_level(analog_capture_level_); | 188 gain_controller->set_capture_level(analog_capture_level_); |
| 189 int err = WebRtcAgc_AddMic( | 189 int err = WebRtcAgc_AddMic( |
| 190 gain_controller->state(), audio->split_bands(capture_channel), | 190 gain_controller->state(), audio->split_bands(capture_channel), |
| 191 audio->num_bands(), audio->num_frames_per_band()); | 191 audio->num_bands(), audio->num_frames_per_band()); |
| 192 | 192 |
| 193 if (err != AudioProcessing::kNoError) { | 193 if (err != AudioProcessing::kNoError) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 209 if (err != AudioProcessing::kNoError) { | 209 if (err != AudioProcessing::kNoError) { |
| 210 return AudioProcessing::kUnspecifiedError; | 210 return AudioProcessing::kUnspecifiedError; |
| 211 } | 211 } |
| 212 ++capture_channel; | 212 ++capture_channel; |
| 213 } | 213 } |
| 214 } | 214 } |
| 215 | 215 |
| 216 return AudioProcessing::kNoError; | 216 return AudioProcessing::kNoError; |
| 217 } | 217 } |
| 218 | 218 |
| 219 int GainControlImpl::ProcessCaptureAudio(AudioBuffer* audio) { | 219 int GainControlImpl::ProcessCaptureAudio(AudioBuffer* audio, |
| 220 bool stream_has_echo) { |
| 220 rtc::CritScope cs(crit_capture_); | 221 rtc::CritScope cs(crit_capture_); |
| 221 | 222 |
| 222 if (!enabled_) { | 223 if (!enabled_) { |
| 223 return AudioProcessing::kNoError; | 224 return AudioProcessing::kNoError; |
| 224 } | 225 } |
| 225 | 226 |
| 226 if (mode_ == kAdaptiveAnalog && !was_analog_level_set_) { | 227 if (mode_ == kAdaptiveAnalog && !was_analog_level_set_) { |
| 227 return AudioProcessing::kStreamParameterNotSetError; | 228 return AudioProcessing::kStreamParameterNotSetError; |
| 228 } | 229 } |
| 229 | 230 |
| 231 RTC_DCHECK(num_proc_channels_); |
| 230 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); | 232 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); |
| 231 RTC_DCHECK_EQ(audio->num_channels(), num_handles_required()); | 233 RTC_DCHECK_EQ(audio->num_channels(), *num_proc_channels_); |
| 232 | 234 |
| 233 stream_is_saturated_ = false; | 235 stream_is_saturated_ = false; |
| 234 int capture_channel = 0; | 236 int capture_channel = 0; |
| 235 for (auto& gain_controller : gain_controllers_) { | 237 for (auto& gain_controller : gain_controllers_) { |
| 236 int32_t capture_level_out = 0; | 238 int32_t capture_level_out = 0; |
| 237 uint8_t saturation_warning = 0; | 239 uint8_t saturation_warning = 0; |
| 238 | 240 |
| 239 // The call to stream_has_echo() is ok from a deadlock perspective | 241 // The call to stream_has_echo() is ok from a deadlock perspective |
| 240 // as the capture lock is allready held. | 242 // as the capture lock is allready held. |
| 241 int err = WebRtcAgc_Process( | 243 int err = WebRtcAgc_Process( |
| 242 gain_controller->state(), audio->split_bands_const(capture_channel), | 244 gain_controller->state(), audio->split_bands_const(capture_channel), |
| 243 audio->num_bands(), audio->num_frames_per_band(), | 245 audio->num_bands(), audio->num_frames_per_band(), |
| 244 audio->split_bands(capture_channel), | 246 audio->split_bands(capture_channel), |
| 245 gain_controller->get_capture_level(), &capture_level_out, | 247 gain_controller->get_capture_level(), &capture_level_out, |
| 246 apm_->echo_cancellation()->stream_has_echo(), &saturation_warning); | 248 stream_has_echo, &saturation_warning); |
| 247 | 249 |
| 248 if (err != AudioProcessing::kNoError) { | 250 if (err != AudioProcessing::kNoError) { |
| 249 return AudioProcessing::kUnspecifiedError; | 251 return AudioProcessing::kUnspecifiedError; |
| 250 } | 252 } |
| 251 | 253 |
| 252 gain_controller->set_capture_level(capture_level_out); | 254 gain_controller->set_capture_level(capture_level_out); |
| 253 if (saturation_warning == 1) { | 255 if (saturation_warning == 1) { |
| 254 stream_is_saturated_ = true; | 256 stream_is_saturated_ = true; |
| 255 } | 257 } |
| 256 | 258 |
| 257 ++capture_channel; | 259 ++capture_channel; |
| 258 } | 260 } |
| 259 | 261 |
| 262 RTC_DCHECK_LT(0ul, *num_proc_channels_); |
| 260 if (mode_ == kAdaptiveAnalog) { | 263 if (mode_ == kAdaptiveAnalog) { |
| 261 // Take the analog level to be the average across the handles. | 264 // Take the analog level to be the average across the handles. |
| 262 analog_capture_level_ = 0; | 265 analog_capture_level_ = 0; |
| 263 for (auto& gain_controller : gain_controllers_) { | 266 for (auto& gain_controller : gain_controllers_) { |
| 264 analog_capture_level_ += gain_controller->get_capture_level(); | 267 analog_capture_level_ += gain_controller->get_capture_level(); |
| 265 } | 268 } |
| 266 | 269 |
| 267 analog_capture_level_ /= num_handles_required(); | 270 analog_capture_level_ /= (*num_proc_channels_); |
| 268 } | 271 } |
| 269 | 272 |
| 270 was_analog_level_set_ = false; | 273 was_analog_level_set_ = false; |
| 271 return AudioProcessing::kNoError; | 274 return AudioProcessing::kNoError; |
| 272 } | 275 } |
| 273 | 276 |
| 274 // TODO(ajm): ensure this is called under kAdaptiveAnalog. | 277 // TODO(ajm): ensure this is called under kAdaptiveAnalog. |
| 275 int GainControlImpl::set_stream_analog_level(int level) { | 278 int GainControlImpl::set_stream_analog_level(int level) { |
| 276 rtc::CritScope cs(crit_capture_); | 279 rtc::CritScope cs(crit_capture_); |
| 277 | 280 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 290 //assert(mode_ == kAdaptiveAnalog); | 293 //assert(mode_ == kAdaptiveAnalog); |
| 291 | 294 |
| 292 return analog_capture_level_; | 295 return analog_capture_level_; |
| 293 } | 296 } |
| 294 | 297 |
| 295 int GainControlImpl::Enable(bool enable) { | 298 int GainControlImpl::Enable(bool enable) { |
| 296 rtc::CritScope cs_render(crit_render_); | 299 rtc::CritScope cs_render(crit_render_); |
| 297 rtc::CritScope cs_capture(crit_capture_); | 300 rtc::CritScope cs_capture(crit_capture_); |
| 298 if (enable && !enabled_) { | 301 if (enable && !enabled_) { |
| 299 enabled_ = enable; // Must be set before Initialize() is called. | 302 enabled_ = enable; // Must be set before Initialize() is called. |
| 300 Initialize(); | 303 |
| 304 RTC_DCHECK(num_proc_channels_); |
| 305 RTC_DCHECK(sample_rate_hz_); |
| 306 Initialize(*num_proc_channels_, *sample_rate_hz_); |
| 301 } else { | 307 } else { |
| 302 enabled_ = enable; | 308 enabled_ = enable; |
| 303 } | 309 } |
| 304 return AudioProcessing::kNoError; | 310 return AudioProcessing::kNoError; |
| 305 } | 311 } |
| 306 | 312 |
| 307 bool GainControlImpl::is_enabled() const { | 313 bool GainControlImpl::is_enabled() const { |
| 308 rtc::CritScope cs(crit_capture_); | 314 rtc::CritScope cs(crit_capture_); |
| 309 return enabled_; | 315 return enabled_; |
| 310 } | 316 } |
| 311 | 317 |
| 312 int GainControlImpl::set_mode(Mode mode) { | 318 int GainControlImpl::set_mode(Mode mode) { |
| 313 rtc::CritScope cs_render(crit_render_); | 319 rtc::CritScope cs_render(crit_render_); |
| 314 rtc::CritScope cs_capture(crit_capture_); | 320 rtc::CritScope cs_capture(crit_capture_); |
| 315 if (MapSetting(mode) == -1) { | 321 if (MapSetting(mode) == -1) { |
| 316 return AudioProcessing::kBadParameterError; | 322 return AudioProcessing::kBadParameterError; |
| 317 } | 323 } |
| 318 | 324 |
| 319 mode_ = mode; | 325 mode_ = mode; |
| 320 Initialize(); | 326 RTC_DCHECK(num_proc_channels_); |
| 327 RTC_DCHECK(sample_rate_hz_); |
| 328 Initialize(*num_proc_channels_, *sample_rate_hz_); |
| 321 return AudioProcessing::kNoError; | 329 return AudioProcessing::kNoError; |
| 322 } | 330 } |
| 323 | 331 |
| 324 GainControl::Mode GainControlImpl::mode() const { | 332 GainControl::Mode GainControlImpl::mode() const { |
| 325 rtc::CritScope cs(crit_capture_); | 333 rtc::CritScope cs(crit_capture_); |
| 326 return mode_; | 334 return mode_; |
| 327 } | 335 } |
| 328 | 336 |
| 329 int GainControlImpl::set_analog_level_limits(int minimum, | 337 int GainControlImpl::set_analog_level_limits(int minimum, |
| 330 int maximum) { | 338 int maximum) { |
| 331 rtc::CritScope cs(crit_capture_); | 339 rtc::CritScope cs(crit_capture_); |
| 332 if (minimum < 0) { | 340 if (minimum < 0) { |
| 333 return AudioProcessing::kBadParameterError; | 341 return AudioProcessing::kBadParameterError; |
| 334 } | 342 } |
| 335 | 343 |
| 336 if (maximum > 65535) { | 344 if (maximum > 65535) { |
| 337 return AudioProcessing::kBadParameterError; | 345 return AudioProcessing::kBadParameterError; |
| 338 } | 346 } |
| 339 | 347 |
| 340 if (maximum < minimum) { | 348 if (maximum < minimum) { |
| 341 return AudioProcessing::kBadParameterError; | 349 return AudioProcessing::kBadParameterError; |
| 342 } | 350 } |
| 343 | 351 |
| 344 minimum_capture_level_ = minimum; | 352 minimum_capture_level_ = minimum; |
| 345 maximum_capture_level_ = maximum; | 353 maximum_capture_level_ = maximum; |
| 346 | 354 |
| 347 Initialize(); | 355 RTC_DCHECK(num_proc_channels_); |
| 356 RTC_DCHECK(sample_rate_hz_); |
| 357 Initialize(*num_proc_channels_, *sample_rate_hz_); |
| 348 return AudioProcessing::kNoError; | 358 return AudioProcessing::kNoError; |
| 349 } | 359 } |
| 350 | 360 |
| 351 int GainControlImpl::analog_level_minimum() const { | 361 int GainControlImpl::analog_level_minimum() const { |
| 352 rtc::CritScope cs(crit_capture_); | 362 rtc::CritScope cs(crit_capture_); |
| 353 return minimum_capture_level_; | 363 return minimum_capture_level_; |
| 354 } | 364 } |
| 355 | 365 |
| 356 int GainControlImpl::analog_level_maximum() const { | 366 int GainControlImpl::analog_level_maximum() const { |
| 357 rtc::CritScope cs(crit_capture_); | 367 rtc::CritScope cs(crit_capture_); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 limiter_enabled_ = enable; | 411 limiter_enabled_ = enable; |
| 402 } | 412 } |
| 403 return Configure(); | 413 return Configure(); |
| 404 } | 414 } |
| 405 | 415 |
| 406 bool GainControlImpl::is_limiter_enabled() const { | 416 bool GainControlImpl::is_limiter_enabled() const { |
| 407 rtc::CritScope cs(crit_capture_); | 417 rtc::CritScope cs(crit_capture_); |
| 408 return limiter_enabled_; | 418 return limiter_enabled_; |
| 409 } | 419 } |
| 410 | 420 |
| 411 void GainControlImpl::Initialize() { | 421 void GainControlImpl::Initialize(size_t num_proc_channels, int sample_rate_hz) { |
| 412 rtc::CritScope cs_render(crit_render_); | 422 rtc::CritScope cs_render(crit_render_); |
| 413 rtc::CritScope cs_capture(crit_capture_); | 423 rtc::CritScope cs_capture(crit_capture_); |
| 424 |
| 425 num_proc_channels_ = rtc::Optional<size_t>(num_proc_channels); |
| 426 sample_rate_hz_ = rtc::Optional<int>(sample_rate_hz); |
| 427 |
| 414 if (!enabled_) { | 428 if (!enabled_) { |
| 415 return; | 429 return; |
| 416 } | 430 } |
| 417 | 431 |
| 418 int sample_rate_hz = apm_->proc_sample_rate_hz(); | 432 gain_controllers_.resize(*num_proc_channels_); |
| 419 gain_controllers_.resize(num_handles_required()); | |
| 420 for (auto& gain_controller : gain_controllers_) { | 433 for (auto& gain_controller : gain_controllers_) { |
| 421 if (!gain_controller) { | 434 if (!gain_controller) { |
| 422 gain_controller.reset(new GainController()); | 435 gain_controller.reset(new GainController()); |
| 423 } | 436 } |
| 424 gain_controller->Initialize(minimum_capture_level_, maximum_capture_level_, | 437 gain_controller->Initialize(minimum_capture_level_, maximum_capture_level_, |
| 425 mode_, sample_rate_hz, analog_capture_level_); | 438 mode_, *sample_rate_hz_, analog_capture_level_); |
| 426 } | 439 } |
| 427 | 440 |
| 428 Configure(); | 441 Configure(); |
| 429 | 442 |
| 430 AllocateRenderQueue(); | 443 AllocateRenderQueue(); |
| 431 } | 444 } |
| 432 | 445 |
| 433 void GainControlImpl::AllocateRenderQueue() { | 446 void GainControlImpl::AllocateRenderQueue() { |
| 447 rtc::CritScope cs_render(crit_render_); |
| 448 rtc::CritScope cs_capture(crit_capture_); |
| 449 |
| 450 RTC_DCHECK(num_proc_channels_); |
| 434 const size_t new_render_queue_element_max_size = std::max<size_t>( | 451 const size_t new_render_queue_element_max_size = std::max<size_t>( |
| 435 static_cast<size_t>(1), | 452 static_cast<size_t>(1), |
| 436 kMaxAllowedValuesOfSamplesPerFrame * num_handles_required()); | 453 kMaxAllowedValuesOfSamplesPerFrame * (*num_proc_channels_)); |
| 437 | |
| 438 rtc::CritScope cs_render(crit_render_); | |
| 439 rtc::CritScope cs_capture(crit_capture_); | |
| 440 | 454 |
| 441 if (render_queue_element_max_size_ < new_render_queue_element_max_size) { | 455 if (render_queue_element_max_size_ < new_render_queue_element_max_size) { |
| 442 render_queue_element_max_size_ = new_render_queue_element_max_size; | 456 render_queue_element_max_size_ = new_render_queue_element_max_size; |
| 443 std::vector<int16_t> template_queue_element(render_queue_element_max_size_); | 457 std::vector<int16_t> template_queue_element(render_queue_element_max_size_); |
| 444 | 458 |
| 445 render_signal_queue_.reset( | 459 render_signal_queue_.reset( |
| 446 new SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>( | 460 new SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>( |
| 447 kMaxNumFramesToBuffer, template_queue_element, | 461 kMaxNumFramesToBuffer, template_queue_element, |
| 448 RenderQueueItemVerifier<int16_t>(render_queue_element_max_size_))); | 462 RenderQueueItemVerifier<int16_t>(render_queue_element_max_size_))); |
| 449 | 463 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 470 int error = AudioProcessing::kNoError; | 484 int error = AudioProcessing::kNoError; |
| 471 for (auto& gain_controller : gain_controllers_) { | 485 for (auto& gain_controller : gain_controllers_) { |
| 472 const int handle_error = | 486 const int handle_error = |
| 473 WebRtcAgc_set_config(gain_controller->state(), config); | 487 WebRtcAgc_set_config(gain_controller->state(), config); |
| 474 if (handle_error != AudioProcessing::kNoError) { | 488 if (handle_error != AudioProcessing::kNoError) { |
| 475 error = handle_error; | 489 error = handle_error; |
| 476 } | 490 } |
| 477 } | 491 } |
| 478 return error; | 492 return error; |
| 479 } | 493 } |
| 480 | |
| 481 size_t GainControlImpl::num_handles_required() const { | |
| 482 // Not locked as it only relies on APM public API which is threadsafe. | |
| 483 return apm_->num_proc_channels(); | |
| 484 } | |
| 485 } // namespace webrtc | 494 } // namespace webrtc |
| OLD | NEW |