clipping_predictor_unittest.cc (23055B)
1 /* 2 * Copyright (c) 2021 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 "modules/audio_processing/agc2/clipping_predictor.h" 12 13 #include <cstdint> 14 #include <limits> 15 #include <optional> 16 #include <tuple> 17 #include <vector> 18 19 #include "api/audio/audio_processing.h" 20 #include "modules/audio_processing/include/audio_frame_view.h" 21 #include "rtc_base/checks.h" 22 #include "test/gmock.h" 23 #include "test/gtest.h" 24 25 namespace webrtc { 26 namespace { 27 28 using ::testing::Eq; 29 using ::testing::Optional; 30 using ClippingPredictorConfig = AudioProcessing::Config::GainController1:: 31 AnalogGainController::ClippingPredictor; 32 using ClippingPredictorMode = AudioProcessing::Config::GainController1:: 33 AnalogGainController::ClippingPredictor::Mode; 34 35 constexpr int kSampleRateHz = 32000; 36 constexpr int kNumChannels = 1; 37 constexpr int kSamplesPerChannel = kSampleRateHz / 100; 38 constexpr int kMaxMicLevel = 255; 39 constexpr int kMinMicLevel = 12; 40 constexpr int kDefaultClippedLevelStep = 15; 41 constexpr float kMaxSampleS16 = 42 static_cast<float>(std::numeric_limits<int16_t>::max()); 43 44 // Threshold in dB corresponding to a signal with an amplitude equal to 99% of 45 // the dynamic range - i.e., computed as `20*log10(0.99)`. 46 constexpr float kClippingThresholdDb = -0.08729610804900176f; 47 48 void CallAnalyze(int num_calls, 49 const AudioFrameView<const float>& frame, 50 ClippingPredictor& predictor) { 51 for (int i = 0; i < num_calls; ++i) { 52 predictor.Analyze(frame); 53 } 54 } 55 56 // Creates and analyzes an audio frame with a non-zero (approx. 4.15dB) crest 57 // factor. 58 void AnalyzeNonZeroCrestFactorAudio(int num_calls, 59 int num_channels, 60 float peak_ratio, 61 ClippingPredictor& predictor) { 62 RTC_DCHECK_GT(num_calls, 0); 63 RTC_DCHECK_GT(num_channels, 0); 64 RTC_DCHECK_LE(peak_ratio, 1.0f); 65 std::vector<float*> audio(num_channels); 66 std::vector<float> audio_data(num_channels * kSamplesPerChannel, 0.0f); 67 for (int channel = 0; channel < num_channels; ++channel) { 68 audio[channel] = &audio_data[channel * kSamplesPerChannel]; 69 for (int sample = 0; sample < kSamplesPerChannel; sample += 10) { 70 audio[channel][sample] = 0.1f * peak_ratio * kMaxSampleS16; 71 audio[channel][sample + 1] = 0.2f * peak_ratio * kMaxSampleS16; 72 audio[channel][sample + 2] = 0.3f * peak_ratio * kMaxSampleS16; 73 audio[channel][sample + 3] = 0.4f * peak_ratio * kMaxSampleS16; 74 audio[channel][sample + 4] = 0.5f * peak_ratio * kMaxSampleS16; 75 audio[channel][sample + 5] = 0.6f * peak_ratio * kMaxSampleS16; 76 audio[channel][sample + 6] = 0.7f * peak_ratio * kMaxSampleS16; 77 audio[channel][sample + 7] = 0.8f * peak_ratio * kMaxSampleS16; 78 audio[channel][sample + 8] = 0.9f * peak_ratio * kMaxSampleS16; 79 audio[channel][sample + 9] = 1.0f * peak_ratio * kMaxSampleS16; 80 } 81 } 82 AudioFrameView<const float> frame(audio.data(), num_channels, 83 kSamplesPerChannel); 84 CallAnalyze(num_calls, frame, predictor); 85 } 86 87 void CheckChannelEstimatesWithValue(int num_channels, 88 int level, 89 int default_step, 90 int min_mic_level, 91 int max_mic_level, 92 const ClippingPredictor& predictor, 93 int expected) { 94 for (int i = 0; i < num_channels; ++i) { 95 SCOPED_TRACE(i); 96 EXPECT_THAT(predictor.EstimateClippedLevelStep( 97 i, level, default_step, min_mic_level, max_mic_level), 98 Optional(Eq(expected))); 99 } 100 } 101 102 void CheckChannelEstimatesWithoutValue(int num_channels, 103 int level, 104 int default_step, 105 int min_mic_level, 106 int max_mic_level, 107 const ClippingPredictor& predictor) { 108 for (int i = 0; i < num_channels; ++i) { 109 SCOPED_TRACE(i); 110 EXPECT_EQ(predictor.EstimateClippedLevelStep(i, level, default_step, 111 min_mic_level, max_mic_level), 112 std::nullopt); 113 } 114 } 115 116 // Creates and analyzes an audio frame with a zero crest factor. 117 void AnalyzeZeroCrestFactorAudio(int num_calls, 118 int num_channels, 119 float peak_ratio, 120 ClippingPredictor& predictor) { 121 RTC_DCHECK_GT(num_calls, 0); 122 RTC_DCHECK_GT(num_channels, 0); 123 RTC_DCHECK_LE(peak_ratio, 1.f); 124 std::vector<float*> audio(num_channels); 125 std::vector<float> audio_data(num_channels * kSamplesPerChannel, 0.f); 126 for (int channel = 0; channel < num_channels; ++channel) { 127 audio[channel] = &audio_data[channel * kSamplesPerChannel]; 128 for (int sample = 0; sample < kSamplesPerChannel; ++sample) { 129 audio[channel][sample] = peak_ratio * kMaxSampleS16; 130 } 131 } 132 auto frame = AudioFrameView<const float>(audio.data(), num_channels, 133 kSamplesPerChannel); 134 CallAnalyze(num_calls, frame, predictor); 135 } 136 137 TEST(ClippingPeakPredictorTest, NoPredictorCreated) { 138 auto predictor = 139 CreateClippingPredictor(kNumChannels, /*config=*/{.enabled = false}); 140 EXPECT_FALSE(predictor); 141 } 142 143 TEST(ClippingPeakPredictorTest, ClippingEventPredictionCreated) { 144 // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed. 145 auto predictor = CreateClippingPredictor( 146 kNumChannels, 147 /*config=*/{.enabled = true, 148 .mode = ClippingPredictorMode::kClippingEventPrediction}); 149 EXPECT_TRUE(predictor); 150 } 151 152 TEST(ClippingPeakPredictorTest, AdaptiveStepClippingPeakPredictionCreated) { 153 // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed. 154 auto predictor = CreateClippingPredictor( 155 kNumChannels, /*config=*/{ 156 .enabled = true, 157 .mode = ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction}); 158 EXPECT_TRUE(predictor); 159 } 160 161 TEST(ClippingPeakPredictorTest, FixedStepClippingPeakPredictionCreated) { 162 // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed. 163 auto predictor = CreateClippingPredictor( 164 kNumChannels, 165 /*config=*/{ 166 .enabled = true, 167 .mode = ClippingPredictorMode::kFixedStepClippingPeakPrediction}); 168 EXPECT_TRUE(predictor); 169 } 170 171 class ClippingPredictorParameterization 172 : public ::testing::TestWithParam<std::tuple<int, int, int, int>> { 173 protected: 174 int num_channels() const { return std::get<0>(GetParam()); } 175 ClippingPredictorConfig GetConfig(ClippingPredictorMode mode) const { 176 // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed. 177 return {/*enabled=*/true, 178 /*mode=*/mode, 179 /*window_length=*/std::get<1>(GetParam()), 180 /*reference_window_length=*/std::get<2>(GetParam()), 181 /*reference_window_delay=*/std::get<3>(GetParam()), 182 /*clipping_threshold=*/-1.0f, 183 /*crest_factor_margin=*/0.5f}; 184 } 185 }; 186 187 TEST_P(ClippingPredictorParameterization, 188 CheckClippingEventPredictorEstimateAfterCrestFactorDrop) { 189 const ClippingPredictorConfig config = 190 GetConfig(ClippingPredictorMode::kClippingEventPrediction); 191 if (config.reference_window_length + config.reference_window_delay <= 192 config.window_length) { 193 return; 194 } 195 auto predictor = CreateClippingPredictor(num_channels(), config); 196 AnalyzeNonZeroCrestFactorAudio( 197 /*num_calls=*/config.reference_window_length + 198 config.reference_window_delay - config.window_length, 199 num_channels(), /*peak_ratio=*/0.99f, *predictor); 200 CheckChannelEstimatesWithoutValue(num_channels(), /*level=*/255, 201 kDefaultClippedLevelStep, kMinMicLevel, 202 kMaxMicLevel, *predictor); 203 AnalyzeZeroCrestFactorAudio(config.window_length, num_channels(), 204 /*peak_ratio=*/0.99f, *predictor); 205 CheckChannelEstimatesWithValue( 206 num_channels(), /*level=*/255, kDefaultClippedLevelStep, kMinMicLevel, 207 kMaxMicLevel, *predictor, kDefaultClippedLevelStep); 208 } 209 210 TEST_P(ClippingPredictorParameterization, 211 CheckClippingEventPredictorNoEstimateAfterConstantCrestFactor) { 212 const ClippingPredictorConfig config = 213 GetConfig(ClippingPredictorMode::kClippingEventPrediction); 214 if (config.reference_window_length + config.reference_window_delay <= 215 config.window_length) { 216 return; 217 } 218 auto predictor = CreateClippingPredictor(num_channels(), config); 219 AnalyzeNonZeroCrestFactorAudio( 220 /*num_calls=*/config.reference_window_length + 221 config.reference_window_delay - config.window_length, 222 num_channels(), /*peak_ratio=*/0.99f, *predictor); 223 CheckChannelEstimatesWithoutValue(num_channels(), /*level=*/255, 224 kDefaultClippedLevelStep, kMinMicLevel, 225 kMaxMicLevel, *predictor); 226 AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/config.window_length, 227 num_channels(), 228 /*peak_ratio=*/0.99f, *predictor); 229 CheckChannelEstimatesWithoutValue(num_channels(), /*level=*/255, 230 kDefaultClippedLevelStep, kMinMicLevel, 231 kMaxMicLevel, *predictor); 232 } 233 234 TEST_P(ClippingPredictorParameterization, 235 CheckClippingPeakPredictorEstimateAfterHighCrestFactor) { 236 const ClippingPredictorConfig config = 237 GetConfig(ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction); 238 if (config.reference_window_length + config.reference_window_delay <= 239 config.window_length) { 240 return; 241 } 242 auto predictor = CreateClippingPredictor(num_channels(), config); 243 AnalyzeNonZeroCrestFactorAudio( 244 /*num_calls=*/config.reference_window_length + 245 config.reference_window_delay - config.window_length, 246 num_channels(), /*peak_ratio=*/0.99f, *predictor); 247 CheckChannelEstimatesWithoutValue(num_channels(), /*level=*/255, 248 kDefaultClippedLevelStep, kMinMicLevel, 249 kMaxMicLevel, *predictor); 250 AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/config.window_length, 251 num_channels(), 252 /*peak_ratio=*/0.99f, *predictor); 253 CheckChannelEstimatesWithValue( 254 num_channels(), /*level=*/255, kDefaultClippedLevelStep, kMinMicLevel, 255 kMaxMicLevel, *predictor, kDefaultClippedLevelStep); 256 } 257 258 TEST_P(ClippingPredictorParameterization, 259 CheckClippingPeakPredictorNoEstimateAfterLowCrestFactor) { 260 const ClippingPredictorConfig config = 261 GetConfig(ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction); 262 if (config.reference_window_length + config.reference_window_delay <= 263 config.window_length) { 264 return; 265 } 266 auto predictor = CreateClippingPredictor(num_channels(), config); 267 AnalyzeZeroCrestFactorAudio( 268 /*num_calls=*/config.reference_window_length + 269 config.reference_window_delay - config.window_length, 270 num_channels(), /*peak_ratio=*/0.99f, *predictor); 271 CheckChannelEstimatesWithoutValue(num_channels(), /*level=*/255, 272 kDefaultClippedLevelStep, kMinMicLevel, 273 kMaxMicLevel, *predictor); 274 AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/config.window_length, 275 num_channels(), 276 /*peak_ratio=*/0.99f, *predictor); 277 CheckChannelEstimatesWithoutValue(num_channels(), /*level=*/255, 278 kDefaultClippedLevelStep, kMinMicLevel, 279 kMaxMicLevel, *predictor); 280 } 281 282 INSTANTIATE_TEST_SUITE_P(GainController1ClippingPredictor, 283 ClippingPredictorParameterization, 284 ::testing::Combine(::testing::Values(1, 5), 285 ::testing::Values(1, 5, 10), 286 ::testing::Values(1, 5), 287 ::testing::Values(0, 1, 5))); 288 289 class ClippingEventPredictorParameterization 290 : public ::testing::TestWithParam<std::tuple<float, float>> { 291 protected: 292 ClippingPredictorConfig GetConfig() const { 293 // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed. 294 return {/*enabled=*/true, 295 /*mode=*/ClippingPredictorMode::kClippingEventPrediction, 296 /*window_length=*/5, 297 /*reference_window_length=*/5, 298 /*reference_window_delay=*/5, 299 /*clipping_threshold=*/std::get<0>(GetParam()), 300 /*crest_factor_margin=*/std::get<1>(GetParam())}; 301 } 302 }; 303 304 TEST_P(ClippingEventPredictorParameterization, 305 CheckEstimateAfterCrestFactorDrop) { 306 const ClippingPredictorConfig config = GetConfig(); 307 auto predictor = CreateClippingPredictor(kNumChannels, config); 308 AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/config.reference_window_length, 309 kNumChannels, /*peak_ratio=*/0.99f, 310 *predictor); 311 CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255, 312 kDefaultClippedLevelStep, kMinMicLevel, 313 kMaxMicLevel, *predictor); 314 AnalyzeZeroCrestFactorAudio(config.window_length, kNumChannels, 315 /*peak_ratio=*/0.99f, *predictor); 316 // TODO(bugs.webrtc.org/12774): Add clarifying comment. 317 // TODO(bugs.webrtc.org/12774): Remove 4.15f threshold and split tests. 318 if (config.clipping_threshold < kClippingThresholdDb && 319 config.crest_factor_margin < 4.15f) { 320 CheckChannelEstimatesWithValue( 321 kNumChannels, /*level=*/255, kDefaultClippedLevelStep, kMinMicLevel, 322 kMaxMicLevel, *predictor, kDefaultClippedLevelStep); 323 } else { 324 CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255, 325 kDefaultClippedLevelStep, kMinMicLevel, 326 kMaxMicLevel, *predictor); 327 } 328 } 329 330 INSTANTIATE_TEST_SUITE_P(GainController1ClippingPredictor, 331 ClippingEventPredictorParameterization, 332 ::testing::Combine(::testing::Values(-1.0f, 0.0f), 333 ::testing::Values(3.0f, 4.16f))); 334 335 class ClippingPredictorModeParameterization 336 : public ::testing::TestWithParam<ClippingPredictorMode> { 337 protected: 338 ClippingPredictorConfig GetConfig(float clipping_threshold_dbfs) const { 339 // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed. 340 return {/*enabled=*/true, 341 /*mode=*/GetParam(), 342 /*window_length=*/5, 343 /*reference_window_length=*/5, 344 /*reference_window_delay=*/5, 345 /*clipping_threshold=*/clipping_threshold_dbfs, 346 /*crest_factor_margin=*/3.0f}; 347 } 348 }; 349 350 TEST_P(ClippingPredictorModeParameterization, 351 CheckEstimateAfterHighCrestFactorWithNoClippingMargin) { 352 const ClippingPredictorConfig config = GetConfig( 353 /*clipping_threshold_dbfs=*/0.0f); 354 auto predictor = CreateClippingPredictor(kNumChannels, config); 355 AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/config.reference_window_length, 356 kNumChannels, /*peak_ratio=*/0.99f, 357 *predictor); 358 CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255, 359 kDefaultClippedLevelStep, kMinMicLevel, 360 kMaxMicLevel, *predictor); 361 AnalyzeZeroCrestFactorAudio(config.window_length, kNumChannels, 362 /*peak_ratio=*/0.99f, *predictor); 363 // Since the clipping threshold is set to 0 dBFS, `EstimateClippedLevelStep()` 364 // is expected to return an unavailable value. 365 CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255, 366 kDefaultClippedLevelStep, kMinMicLevel, 367 kMaxMicLevel, *predictor); 368 } 369 370 TEST_P(ClippingPredictorModeParameterization, 371 CheckEstimateAfterHighCrestFactorWithClippingMargin) { 372 const ClippingPredictorConfig config = 373 GetConfig(/*clipping_threshold_dbfs=*/-1.0f); 374 auto predictor = CreateClippingPredictor(kNumChannels, config); 375 AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/config.reference_window_length, 376 kNumChannels, 377 /*peak_ratio=*/0.99f, *predictor); 378 CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255, 379 kDefaultClippedLevelStep, kMinMicLevel, 380 kMaxMicLevel, *predictor); 381 AnalyzeZeroCrestFactorAudio(config.window_length, kNumChannels, 382 /*peak_ratio=*/0.99f, *predictor); 383 // TODO(bugs.webrtc.org/12774): Add clarifying comment. 384 const float expected_step = 385 config.mode == ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction 386 ? 17 387 : kDefaultClippedLevelStep; 388 CheckChannelEstimatesWithValue(kNumChannels, /*level=*/255, 389 kDefaultClippedLevelStep, kMinMicLevel, 390 kMaxMicLevel, *predictor, expected_step); 391 } 392 393 INSTANTIATE_TEST_SUITE_P( 394 GainController1ClippingPredictor, 395 ClippingPredictorModeParameterization, 396 ::testing::Values( 397 ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction, 398 ClippingPredictorMode::kFixedStepClippingPeakPrediction)); 399 400 TEST(ClippingEventPredictorTest, CheckEstimateAfterReset) { 401 // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed. 402 constexpr ClippingPredictorConfig kConfig{ 403 /*enabled=*/true, 404 /*mode=*/ClippingPredictorMode::kClippingEventPrediction, 405 /*window_length=*/5, 406 /*reference_window_length=*/5, 407 /*reference_window_delay=*/5, 408 /*clipping_threshold=*/-1.0f, 409 /*crest_factor_margin=*/3.0f}; 410 auto predictor = CreateClippingPredictor(kNumChannels, kConfig); 411 AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/kConfig.reference_window_length, 412 kNumChannels, 413 /*peak_ratio=*/0.99f, *predictor); 414 CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255, 415 kDefaultClippedLevelStep, kMinMicLevel, 416 kMaxMicLevel, *predictor); 417 predictor->Reset(); 418 AnalyzeZeroCrestFactorAudio(kConfig.window_length, kNumChannels, 419 /*peak_ratio=*/0.99f, *predictor); 420 CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255, 421 kDefaultClippedLevelStep, kMinMicLevel, 422 kMaxMicLevel, *predictor); 423 } 424 425 TEST(ClippingPeakPredictorTest, CheckNoEstimateAfterReset) { 426 // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed. 427 constexpr ClippingPredictorConfig kConfig{ 428 /*enabled=*/true, 429 /*mode=*/ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction, 430 /*window_length=*/5, 431 /*reference_window_length=*/5, 432 /*reference_window_delay=*/5, 433 /*clipping_threshold=*/-1.0f}; 434 auto predictor = CreateClippingPredictor(kNumChannels, kConfig); 435 AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/kConfig.reference_window_length, 436 kNumChannels, 437 /*peak_ratio=*/0.99f, *predictor); 438 CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255, 439 kDefaultClippedLevelStep, kMinMicLevel, 440 kMaxMicLevel, *predictor); 441 predictor->Reset(); 442 AnalyzeZeroCrestFactorAudio(kConfig.window_length, kNumChannels, 443 /*peak_ratio=*/0.99f, *predictor); 444 CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255, 445 kDefaultClippedLevelStep, kMinMicLevel, 446 kMaxMicLevel, *predictor); 447 } 448 449 TEST(ClippingPeakPredictorTest, CheckAdaptiveStepEstimate) { 450 // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed. 451 constexpr ClippingPredictorConfig kConfig{ 452 /*enabled=*/true, 453 /*mode=*/ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction, 454 /*window_length=*/5, 455 /*reference_window_length=*/5, 456 /*reference_window_delay=*/5, 457 /*clipping_threshold=*/-1.0f}; 458 auto predictor = CreateClippingPredictor(kNumChannels, kConfig); 459 AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/kConfig.reference_window_length, 460 kNumChannels, /*peak_ratio=*/0.99f, 461 *predictor); 462 CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255, 463 kDefaultClippedLevelStep, kMinMicLevel, 464 kMaxMicLevel, *predictor); 465 AnalyzeZeroCrestFactorAudio(kConfig.window_length, kNumChannels, 466 /*peak_ratio=*/0.99f, *predictor); 467 CheckChannelEstimatesWithValue(kNumChannels, /*level=*/255, 468 kDefaultClippedLevelStep, kMinMicLevel, 469 kMaxMicLevel, *predictor, /*expected=*/17); 470 } 471 472 TEST(ClippingPeakPredictorTest, CheckFixedStepEstimate) { 473 // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed. 474 constexpr ClippingPredictorConfig kConfig{ 475 /*enabled=*/true, 476 /*mode=*/ClippingPredictorMode::kFixedStepClippingPeakPrediction, 477 /*window_length=*/5, 478 /*reference_window_length=*/5, 479 /*reference_window_delay=*/5, 480 /*clipping_threshold=*/-1.0f}; 481 auto predictor = CreateClippingPredictor(kNumChannels, kConfig); 482 AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/kConfig.reference_window_length, 483 kNumChannels, /*peak_ratio=*/0.99f, 484 *predictor); 485 CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255, 486 kDefaultClippedLevelStep, kMinMicLevel, 487 kMaxMicLevel, *predictor); 488 AnalyzeZeroCrestFactorAudio(kConfig.window_length, kNumChannels, 489 /*peak_ratio=*/0.99f, *predictor); 490 CheckChannelEstimatesWithValue( 491 kNumChannels, /*level=*/255, kDefaultClippedLevelStep, kMinMicLevel, 492 kMaxMicLevel, *predictor, kDefaultClippedLevelStep); 493 } 494 495 } // namespace 496 } // namespace webrtc