echo_canceller3_config_json.cc (32819B)
1 /* 2 * Copyright (c) 2018 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 #include "modules/audio_processing/test/echo_canceller3_config_json.h" 11 12 #include <cstddef> 13 #include <memory> 14 #include <string> 15 #include <vector> 16 17 #include "absl/strings/string_view.h" 18 #include "api/audio/echo_canceller3_config.h" 19 #include "rtc_base/checks.h" 20 #include "rtc_base/logging.h" 21 #include "rtc_base/strings/json.h" 22 #include "rtc_base/strings/string_builder.h" 23 24 namespace webrtc { 25 namespace { 26 void ReadParam(const Json::Value& root, std::string param_name, bool* param) { 27 RTC_DCHECK(param); 28 bool v; 29 if (GetBoolFromJsonObject(root, param_name, &v)) { 30 *param = v; 31 } 32 } 33 34 void ReadParam(const Json::Value& root, std::string param_name, size_t* param) { 35 RTC_DCHECK(param); 36 int v; 37 if (GetIntFromJsonObject(root, param_name, &v) && v >= 0) { 38 *param = v; 39 } 40 } 41 42 void ReadParam(const Json::Value& root, std::string param_name, int* param) { 43 RTC_DCHECK(param); 44 int v; 45 if (GetIntFromJsonObject(root, param_name, &v)) { 46 *param = v; 47 } 48 } 49 50 void ReadParam(const Json::Value& root, std::string param_name, float* param) { 51 RTC_DCHECK(param); 52 double v; 53 if (GetDoubleFromJsonObject(root, param_name, &v)) { 54 *param = static_cast<float>(v); 55 } 56 } 57 58 void ReadParam(const Json::Value& root, 59 std::string param_name, 60 EchoCanceller3Config::Filter::RefinedConfiguration* param) { 61 RTC_DCHECK(param); 62 Json::Value json_array; 63 if (GetValueFromJsonObject(root, param_name, &json_array)) { 64 std::vector<double> v; 65 JsonArrayToDoubleVector(json_array, &v); 66 if (v.size() != 6) { 67 RTC_LOG(LS_ERROR) << "Incorrect array size for " << param_name; 68 return; 69 } 70 param->length_blocks = static_cast<size_t>(v[0]); 71 param->leakage_converged = static_cast<float>(v[1]); 72 param->leakage_diverged = static_cast<float>(v[2]); 73 param->error_floor = static_cast<float>(v[3]); 74 param->error_ceil = static_cast<float>(v[4]); 75 param->noise_gate = static_cast<float>(v[5]); 76 } 77 } 78 79 void ReadParam(const Json::Value& root, 80 std::string param_name, 81 EchoCanceller3Config::Filter::CoarseConfiguration* param) { 82 RTC_DCHECK(param); 83 Json::Value json_array; 84 if (GetValueFromJsonObject(root, param_name, &json_array)) { 85 std::vector<double> v; 86 JsonArrayToDoubleVector(json_array, &v); 87 if (v.size() != 3) { 88 RTC_LOG(LS_ERROR) << "Incorrect array size for " << param_name; 89 return; 90 } 91 param->length_blocks = static_cast<size_t>(v[0]); 92 param->rate = static_cast<float>(v[1]); 93 param->noise_gate = static_cast<float>(v[2]); 94 } 95 } 96 97 void ReadParam(const Json::Value& root, 98 std::string param_name, 99 EchoCanceller3Config::Delay::AlignmentMixing* param) { 100 RTC_DCHECK(param); 101 102 Json::Value subsection; 103 if (GetValueFromJsonObject(root, param_name, &subsection)) { 104 ReadParam(subsection, "downmix", ¶m->downmix); 105 ReadParam(subsection, "adaptive_selection", ¶m->adaptive_selection); 106 ReadParam(subsection, "activity_power_threshold", 107 ¶m->activity_power_threshold); 108 ReadParam(subsection, "prefer_first_two_channels", 109 ¶m->prefer_first_two_channels); 110 } 111 } 112 113 void ReadParam( 114 const Json::Value& root, 115 std::string param_name, 116 EchoCanceller3Config::Suppressor::SubbandNearendDetection::SubbandRegion* 117 param) { 118 RTC_DCHECK(param); 119 Json::Value json_array; 120 if (GetValueFromJsonObject(root, param_name, &json_array)) { 121 std::vector<int> v; 122 JsonArrayToIntVector(json_array, &v); 123 if (v.size() != 2) { 124 RTC_LOG(LS_ERROR) << "Incorrect array size for " << param_name; 125 return; 126 } 127 param->low = static_cast<size_t>(v[0]); 128 param->high = static_cast<size_t>(v[1]); 129 } 130 } 131 132 void ReadParam(const Json::Value& root, 133 std::string param_name, 134 EchoCanceller3Config::Suppressor::MaskingThresholds* param) { 135 RTC_DCHECK(param); 136 Json::Value json_array; 137 if (GetValueFromJsonObject(root, param_name, &json_array)) { 138 std::vector<double> v; 139 JsonArrayToDoubleVector(json_array, &v); 140 if (v.size() != 3) { 141 RTC_LOG(LS_ERROR) << "Incorrect array size for " << param_name; 142 return; 143 } 144 param->enr_transparent = static_cast<float>(v[0]); 145 param->enr_suppress = static_cast<float>(v[1]); 146 param->emr_transparent = static_cast<float>(v[2]); 147 } 148 } 149 } // namespace 150 151 void Aec3ConfigFromJsonString(absl::string_view json_string, 152 EchoCanceller3Config* config, 153 bool* parsing_successful) { 154 RTC_DCHECK(config); 155 RTC_DCHECK(parsing_successful); 156 EchoCanceller3Config& cfg = *config; 157 cfg = EchoCanceller3Config(); 158 *parsing_successful = true; 159 160 Json::Value root; 161 Json::CharReaderBuilder builder; 162 std::string error_message; 163 std::unique_ptr<Json::CharReader> reader(builder.newCharReader()); 164 bool success = 165 reader->parse(json_string.data(), json_string.data() + json_string.size(), 166 &root, &error_message); 167 if (!success) { 168 RTC_LOG(LS_ERROR) << "Incorrect JSON format: " << error_message; 169 *parsing_successful = false; 170 return; 171 } 172 173 Json::Value aec3_root; 174 success = GetValueFromJsonObject(root, "aec3", &aec3_root); 175 if (!success) { 176 RTC_LOG(LS_ERROR) << "Missing AEC3 config field: " << json_string; 177 *parsing_successful = false; 178 return; 179 } 180 181 Json::Value section; 182 if (GetValueFromJsonObject(aec3_root, "buffering", §ion)) { 183 ReadParam(section, "excess_render_detection_interval_blocks", 184 &cfg.buffering.excess_render_detection_interval_blocks); 185 ReadParam(section, "max_allowed_excess_render_blocks", 186 &cfg.buffering.max_allowed_excess_render_blocks); 187 } 188 189 if (GetValueFromJsonObject(aec3_root, "delay", §ion)) { 190 ReadParam(section, "default_delay", &cfg.delay.default_delay); 191 ReadParam(section, "down_sampling_factor", &cfg.delay.down_sampling_factor); 192 ReadParam(section, "num_filters", &cfg.delay.num_filters); 193 ReadParam(section, "delay_headroom_samples", 194 &cfg.delay.delay_headroom_samples); 195 ReadParam(section, "hysteresis_limit_blocks", 196 &cfg.delay.hysteresis_limit_blocks); 197 ReadParam(section, "fixed_capture_delay_samples", 198 &cfg.delay.fixed_capture_delay_samples); 199 ReadParam(section, "delay_estimate_smoothing", 200 &cfg.delay.delay_estimate_smoothing); 201 ReadParam(section, "delay_estimate_smoothing_delay_found", 202 &cfg.delay.delay_estimate_smoothing_delay_found); 203 ReadParam(section, "delay_candidate_detection_threshold", 204 &cfg.delay.delay_candidate_detection_threshold); 205 206 Json::Value subsection; 207 if (GetValueFromJsonObject(section, "delay_selection_thresholds", 208 &subsection)) { 209 ReadParam(subsection, "initial", 210 &cfg.delay.delay_selection_thresholds.initial); 211 ReadParam(subsection, "converged", 212 &cfg.delay.delay_selection_thresholds.converged); 213 } 214 215 ReadParam(section, "use_external_delay_estimator", 216 &cfg.delay.use_external_delay_estimator); 217 ReadParam(section, "log_warning_on_delay_changes", 218 &cfg.delay.log_warning_on_delay_changes); 219 220 ReadParam(section, "render_alignment_mixing", 221 &cfg.delay.render_alignment_mixing); 222 ReadParam(section, "capture_alignment_mixing", 223 &cfg.delay.capture_alignment_mixing); 224 ReadParam(section, "detect_pre_echo", &cfg.delay.detect_pre_echo); 225 } 226 227 if (GetValueFromJsonObject(aec3_root, "filter", §ion)) { 228 ReadParam(section, "refined", &cfg.filter.refined); 229 ReadParam(section, "coarse", &cfg.filter.coarse); 230 ReadParam(section, "refined_initial", &cfg.filter.refined_initial); 231 ReadParam(section, "coarse_initial", &cfg.filter.coarse_initial); 232 ReadParam(section, "config_change_duration_blocks", 233 &cfg.filter.config_change_duration_blocks); 234 ReadParam(section, "initial_state_seconds", 235 &cfg.filter.initial_state_seconds); 236 ReadParam(section, "coarse_reset_hangover_blocks", 237 &cfg.filter.coarse_reset_hangover_blocks); 238 ReadParam(section, "conservative_initial_phase", 239 &cfg.filter.conservative_initial_phase); 240 ReadParam(section, "enable_coarse_filter_output_usage", 241 &cfg.filter.enable_coarse_filter_output_usage); 242 ReadParam(section, "use_linear_filter", &cfg.filter.use_linear_filter); 243 ReadParam(section, "high_pass_filter_echo_reference", 244 &cfg.filter.high_pass_filter_echo_reference); 245 ReadParam(section, "export_linear_aec_output", 246 &cfg.filter.export_linear_aec_output); 247 } 248 249 if (GetValueFromJsonObject(aec3_root, "erle", §ion)) { 250 ReadParam(section, "min", &cfg.erle.min); 251 ReadParam(section, "max_l", &cfg.erle.max_l); 252 ReadParam(section, "max_h", &cfg.erle.max_h); 253 ReadParam(section, "onset_detection", &cfg.erle.onset_detection); 254 ReadParam(section, "num_sections", &cfg.erle.num_sections); 255 ReadParam(section, "clamp_quality_estimate_to_zero", 256 &cfg.erle.clamp_quality_estimate_to_zero); 257 ReadParam(section, "clamp_quality_estimate_to_one", 258 &cfg.erle.clamp_quality_estimate_to_one); 259 } 260 261 if (GetValueFromJsonObject(aec3_root, "ep_strength", §ion)) { 262 ReadParam(section, "default_gain", &cfg.ep_strength.default_gain); 263 ReadParam(section, "default_len", &cfg.ep_strength.default_len); 264 ReadParam(section, "nearend_len", &cfg.ep_strength.nearend_len); 265 ReadParam(section, "echo_can_saturate", &cfg.ep_strength.echo_can_saturate); 266 ReadParam(section, "bounded_erl", &cfg.ep_strength.bounded_erl); 267 ReadParam(section, "erle_onset_compensation_in_dominant_nearend", 268 &cfg.ep_strength.erle_onset_compensation_in_dominant_nearend); 269 ReadParam(section, "use_conservative_tail_frequency_response", 270 &cfg.ep_strength.use_conservative_tail_frequency_response); 271 } 272 273 if (GetValueFromJsonObject(aec3_root, "echo_audibility", §ion)) { 274 ReadParam(section, "low_render_limit", 275 &cfg.echo_audibility.low_render_limit); 276 ReadParam(section, "normal_render_limit", 277 &cfg.echo_audibility.normal_render_limit); 278 279 ReadParam(section, "floor_power", &cfg.echo_audibility.floor_power); 280 ReadParam(section, "audibility_threshold_lf", 281 &cfg.echo_audibility.audibility_threshold_lf); 282 ReadParam(section, "audibility_threshold_mf", 283 &cfg.echo_audibility.audibility_threshold_mf); 284 ReadParam(section, "audibility_threshold_hf", 285 &cfg.echo_audibility.audibility_threshold_hf); 286 ReadParam(section, "use_stationarity_properties", 287 &cfg.echo_audibility.use_stationarity_properties); 288 ReadParam(section, "use_stationarity_properties_at_init", 289 &cfg.echo_audibility.use_stationarity_properties_at_init); 290 } 291 292 if (GetValueFromJsonObject(aec3_root, "render_levels", §ion)) { 293 ReadParam(section, "active_render_limit", 294 &cfg.render_levels.active_render_limit); 295 ReadParam(section, "poor_excitation_render_limit", 296 &cfg.render_levels.poor_excitation_render_limit); 297 ReadParam(section, "poor_excitation_render_limit_ds8", 298 &cfg.render_levels.poor_excitation_render_limit_ds8); 299 ReadParam(section, "render_power_gain_db", 300 &cfg.render_levels.render_power_gain_db); 301 } 302 303 if (GetValueFromJsonObject(aec3_root, "echo_removal_control", §ion)) { 304 ReadParam(section, "has_clock_drift", 305 &cfg.echo_removal_control.has_clock_drift); 306 ReadParam(section, "linear_and_stable_echo_path", 307 &cfg.echo_removal_control.linear_and_stable_echo_path); 308 } 309 310 if (GetValueFromJsonObject(aec3_root, "echo_model", §ion)) { 311 Json::Value subsection; 312 ReadParam(section, "noise_floor_hold", &cfg.echo_model.noise_floor_hold); 313 ReadParam(section, "min_noise_floor_power", 314 &cfg.echo_model.min_noise_floor_power); 315 ReadParam(section, "stationary_gate_slope", 316 &cfg.echo_model.stationary_gate_slope); 317 ReadParam(section, "noise_gate_power", &cfg.echo_model.noise_gate_power); 318 ReadParam(section, "noise_gate_slope", &cfg.echo_model.noise_gate_slope); 319 ReadParam(section, "render_pre_window_size", 320 &cfg.echo_model.render_pre_window_size); 321 ReadParam(section, "render_post_window_size", 322 &cfg.echo_model.render_post_window_size); 323 ReadParam(section, "model_reverb_in_nonlinear_mode", 324 &cfg.echo_model.model_reverb_in_nonlinear_mode); 325 } 326 327 if (GetValueFromJsonObject(aec3_root, "comfort_noise", §ion)) { 328 ReadParam(section, "noise_floor_dbfs", &cfg.comfort_noise.noise_floor_dbfs); 329 } 330 331 Json::Value subsection; 332 if (GetValueFromJsonObject(aec3_root, "suppressor", §ion)) { 333 ReadParam(section, "nearend_average_blocks", 334 &cfg.suppressor.nearend_average_blocks); 335 336 if (GetValueFromJsonObject(section, "normal_tuning", &subsection)) { 337 ReadParam(subsection, "mask_lf", &cfg.suppressor.normal_tuning.mask_lf); 338 ReadParam(subsection, "mask_hf", &cfg.suppressor.normal_tuning.mask_hf); 339 ReadParam(subsection, "max_inc_factor", 340 &cfg.suppressor.normal_tuning.max_inc_factor); 341 ReadParam(subsection, "max_dec_factor_lf", 342 &cfg.suppressor.normal_tuning.max_dec_factor_lf); 343 } 344 345 if (GetValueFromJsonObject(section, "nearend_tuning", &subsection)) { 346 ReadParam(subsection, "mask_lf", &cfg.suppressor.nearend_tuning.mask_lf); 347 ReadParam(subsection, "mask_hf", &cfg.suppressor.nearend_tuning.mask_hf); 348 ReadParam(subsection, "max_inc_factor", 349 &cfg.suppressor.nearend_tuning.max_inc_factor); 350 ReadParam(subsection, "max_dec_factor_lf", 351 &cfg.suppressor.nearend_tuning.max_dec_factor_lf); 352 } 353 354 ReadParam(section, "lf_smoothing_during_initial_phase", 355 &cfg.suppressor.lf_smoothing_during_initial_phase); 356 ReadParam(section, "last_permanent_lf_smoothing_band", 357 &cfg.suppressor.last_permanent_lf_smoothing_band); 358 ReadParam(section, "last_lf_smoothing_band", 359 &cfg.suppressor.last_lf_smoothing_band); 360 ReadParam(section, "last_lf_band", &cfg.suppressor.last_lf_band); 361 ReadParam(section, "first_hf_band", &cfg.suppressor.first_hf_band); 362 363 if (GetValueFromJsonObject(section, "dominant_nearend_detection", 364 &subsection)) { 365 ReadParam(subsection, "enr_threshold", 366 &cfg.suppressor.dominant_nearend_detection.enr_threshold); 367 ReadParam(subsection, "enr_exit_threshold", 368 &cfg.suppressor.dominant_nearend_detection.enr_exit_threshold); 369 ReadParam(subsection, "snr_threshold", 370 &cfg.suppressor.dominant_nearend_detection.snr_threshold); 371 ReadParam(subsection, "hold_duration", 372 &cfg.suppressor.dominant_nearend_detection.hold_duration); 373 ReadParam(subsection, "trigger_threshold", 374 &cfg.suppressor.dominant_nearend_detection.trigger_threshold); 375 ReadParam( 376 subsection, "use_during_initial_phase", 377 &cfg.suppressor.dominant_nearend_detection.use_during_initial_phase); 378 ReadParam(subsection, "use_unbounded_echo_spectrum", 379 &cfg.suppressor.dominant_nearend_detection 380 .use_unbounded_echo_spectrum); 381 } 382 383 if (GetValueFromJsonObject(section, "subband_nearend_detection", 384 &subsection)) { 385 ReadParam( 386 subsection, "nearend_average_blocks", 387 &cfg.suppressor.subband_nearend_detection.nearend_average_blocks); 388 ReadParam(subsection, "subband1", 389 &cfg.suppressor.subband_nearend_detection.subband1); 390 ReadParam(subsection, "subband2", 391 &cfg.suppressor.subband_nearend_detection.subband2); 392 ReadParam(subsection, "nearend_threshold", 393 &cfg.suppressor.subband_nearend_detection.nearend_threshold); 394 ReadParam(subsection, "snr_threshold", 395 &cfg.suppressor.subband_nearend_detection.snr_threshold); 396 } 397 398 ReadParam(section, "use_subband_nearend_detection", 399 &cfg.suppressor.use_subband_nearend_detection); 400 401 if (GetValueFromJsonObject(section, "high_bands_suppression", 402 &subsection)) { 403 ReadParam(subsection, "enr_threshold", 404 &cfg.suppressor.high_bands_suppression.enr_threshold); 405 ReadParam(subsection, "max_gain_during_echo", 406 &cfg.suppressor.high_bands_suppression.max_gain_during_echo); 407 ReadParam(subsection, "anti_howling_activation_threshold", 408 &cfg.suppressor.high_bands_suppression 409 .anti_howling_activation_threshold); 410 ReadParam(subsection, "anti_howling_gain", 411 &cfg.suppressor.high_bands_suppression.anti_howling_gain); 412 } 413 414 ReadParam(section, "floor_first_increase", 415 &cfg.suppressor.floor_first_increase); 416 ReadParam(section, "conservative_hf_suppression", 417 &cfg.suppressor.conservative_hf_suppression); 418 } 419 420 if (GetValueFromJsonObject(aec3_root, "multi_channel", §ion)) { 421 ReadParam(section, "detect_stereo_content", 422 &cfg.multi_channel.detect_stereo_content); 423 ReadParam(section, "stereo_detection_threshold", 424 &cfg.multi_channel.stereo_detection_threshold); 425 ReadParam(section, "stereo_detection_timeout_threshold_seconds", 426 &cfg.multi_channel.stereo_detection_timeout_threshold_seconds); 427 ReadParam(section, "stereo_detection_hysteresis_seconds", 428 &cfg.multi_channel.stereo_detection_hysteresis_seconds); 429 } 430 } 431 432 std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) { 433 StringBuilder ost; 434 ost << "{"; 435 ost << "\"aec3\": {"; 436 ost << "\"buffering\": {"; 437 ost << "\"excess_render_detection_interval_blocks\": " 438 << config.buffering.excess_render_detection_interval_blocks << ","; 439 ost << "\"max_allowed_excess_render_blocks\": " 440 << config.buffering.max_allowed_excess_render_blocks; 441 ost << "},"; 442 443 ost << "\"delay\": {"; 444 ost << "\"default_delay\": " << config.delay.default_delay << ","; 445 ost << "\"down_sampling_factor\": " << config.delay.down_sampling_factor 446 << ","; 447 ost << "\"num_filters\": " << config.delay.num_filters << ","; 448 ost << "\"delay_headroom_samples\": " << config.delay.delay_headroom_samples 449 << ","; 450 ost << "\"hysteresis_limit_blocks\": " << config.delay.hysteresis_limit_blocks 451 << ","; 452 ost << "\"fixed_capture_delay_samples\": " 453 << config.delay.fixed_capture_delay_samples << ","; 454 ost << "\"delay_estimate_smoothing\": " 455 << config.delay.delay_estimate_smoothing << ","; 456 ost << "\"delay_estimate_smoothing_delay_found\": " 457 << config.delay.delay_estimate_smoothing_delay_found << ","; 458 ost << "\"delay_candidate_detection_threshold\": " 459 << config.delay.delay_candidate_detection_threshold << ","; 460 461 ost << "\"delay_selection_thresholds\": {"; 462 ost << "\"initial\": " << config.delay.delay_selection_thresholds.initial 463 << ","; 464 ost << "\"converged\": " << config.delay.delay_selection_thresholds.converged; 465 ost << "},"; 466 467 ost << "\"use_external_delay_estimator\": " 468 << (config.delay.use_external_delay_estimator ? "true" : "false") << ","; 469 ost << "\"log_warning_on_delay_changes\": " 470 << (config.delay.log_warning_on_delay_changes ? "true" : "false") << ","; 471 472 ost << "\"render_alignment_mixing\": {"; 473 ost << "\"downmix\": " 474 << (config.delay.render_alignment_mixing.downmix ? "true" : "false") 475 << ","; 476 ost << "\"adaptive_selection\": " 477 << (config.delay.render_alignment_mixing.adaptive_selection ? "true" 478 : "false") 479 << ","; 480 ost << "\"activity_power_threshold\": " 481 << config.delay.render_alignment_mixing.activity_power_threshold << ","; 482 ost << "\"prefer_first_two_channels\": " 483 << (config.delay.render_alignment_mixing.prefer_first_two_channels 484 ? "true" 485 : "false"); 486 ost << "},"; 487 488 ost << "\"capture_alignment_mixing\": {"; 489 ost << "\"downmix\": " 490 << (config.delay.capture_alignment_mixing.downmix ? "true" : "false") 491 << ","; 492 ost << "\"adaptive_selection\": " 493 << (config.delay.capture_alignment_mixing.adaptive_selection ? "true" 494 : "false") 495 << ","; 496 ost << "\"activity_power_threshold\": " 497 << config.delay.capture_alignment_mixing.activity_power_threshold << ","; 498 ost << "\"prefer_first_two_channels\": " 499 << (config.delay.capture_alignment_mixing.prefer_first_two_channels 500 ? "true" 501 : "false"); 502 ost << "},"; 503 ost << "\"detect_pre_echo\": " 504 << (config.delay.detect_pre_echo ? "true" : "false"); 505 ost << "},"; 506 507 ost << "\"filter\": {"; 508 509 ost << "\"refined\": ["; 510 ost << config.filter.refined.length_blocks << ","; 511 ost << config.filter.refined.leakage_converged << ","; 512 ost << config.filter.refined.leakage_diverged << ","; 513 ost << config.filter.refined.error_floor << ","; 514 ost << config.filter.refined.error_ceil << ","; 515 ost << config.filter.refined.noise_gate; 516 ost << "],"; 517 518 ost << "\"coarse\": ["; 519 ost << config.filter.coarse.length_blocks << ","; 520 ost << config.filter.coarse.rate << ","; 521 ost << config.filter.coarse.noise_gate; 522 ost << "],"; 523 524 ost << "\"refined_initial\": ["; 525 ost << config.filter.refined_initial.length_blocks << ","; 526 ost << config.filter.refined_initial.leakage_converged << ","; 527 ost << config.filter.refined_initial.leakage_diverged << ","; 528 ost << config.filter.refined_initial.error_floor << ","; 529 ost << config.filter.refined_initial.error_ceil << ","; 530 ost << config.filter.refined_initial.noise_gate; 531 ost << "],"; 532 533 ost << "\"coarse_initial\": ["; 534 ost << config.filter.coarse_initial.length_blocks << ","; 535 ost << config.filter.coarse_initial.rate << ","; 536 ost << config.filter.coarse_initial.noise_gate; 537 ost << "],"; 538 539 ost << "\"config_change_duration_blocks\": " 540 << config.filter.config_change_duration_blocks << ","; 541 ost << "\"initial_state_seconds\": " << config.filter.initial_state_seconds 542 << ","; 543 ost << "\"coarse_reset_hangover_blocks\": " 544 << config.filter.coarse_reset_hangover_blocks << ","; 545 ost << "\"conservative_initial_phase\": " 546 << (config.filter.conservative_initial_phase ? "true" : "false") << ","; 547 ost << "\"enable_coarse_filter_output_usage\": " 548 << (config.filter.enable_coarse_filter_output_usage ? "true" : "false") 549 << ","; 550 ost << "\"use_linear_filter\": " 551 << (config.filter.use_linear_filter ? "true" : "false") << ","; 552 ost << "\"high_pass_filter_echo_reference\": " 553 << (config.filter.high_pass_filter_echo_reference ? "true" : "false") 554 << ","; 555 ost << "\"export_linear_aec_output\": " 556 << (config.filter.export_linear_aec_output ? "true" : "false"); 557 558 ost << "},"; 559 560 ost << "\"erle\": {"; 561 ost << "\"min\": " << config.erle.min << ","; 562 ost << "\"max_l\": " << config.erle.max_l << ","; 563 ost << "\"max_h\": " << config.erle.max_h << ","; 564 ost << "\"onset_detection\": " 565 << (config.erle.onset_detection ? "true" : "false") << ","; 566 ost << "\"num_sections\": " << config.erle.num_sections << ","; 567 ost << "\"clamp_quality_estimate_to_zero\": " 568 << (config.erle.clamp_quality_estimate_to_zero ? "true" : "false") << ","; 569 ost << "\"clamp_quality_estimate_to_one\": " 570 << (config.erle.clamp_quality_estimate_to_one ? "true" : "false"); 571 ost << "},"; 572 573 ost << "\"ep_strength\": {"; 574 ost << "\"default_gain\": " << config.ep_strength.default_gain << ","; 575 ost << "\"default_len\": " << config.ep_strength.default_len << ","; 576 ost << "\"nearend_len\": " << config.ep_strength.nearend_len << ","; 577 ost << "\"echo_can_saturate\": " 578 << (config.ep_strength.echo_can_saturate ? "true" : "false") << ","; 579 ost << "\"bounded_erl\": " 580 << (config.ep_strength.bounded_erl ? "true" : "false") << ","; 581 ost << "\"erle_onset_compensation_in_dominant_nearend\": " 582 << (config.ep_strength.erle_onset_compensation_in_dominant_nearend 583 ? "true" 584 : "false") 585 << ","; 586 ost << "\"use_conservative_tail_frequency_response\": " 587 << (config.ep_strength.use_conservative_tail_frequency_response 588 ? "true" 589 : "false"); 590 ost << "},"; 591 592 ost << "\"echo_audibility\": {"; 593 ost << "\"low_render_limit\": " << config.echo_audibility.low_render_limit 594 << ","; 595 ost << "\"normal_render_limit\": " 596 << config.echo_audibility.normal_render_limit << ","; 597 ost << "\"floor_power\": " << config.echo_audibility.floor_power << ","; 598 ost << "\"audibility_threshold_lf\": " 599 << config.echo_audibility.audibility_threshold_lf << ","; 600 ost << "\"audibility_threshold_mf\": " 601 << config.echo_audibility.audibility_threshold_mf << ","; 602 ost << "\"audibility_threshold_hf\": " 603 << config.echo_audibility.audibility_threshold_hf << ","; 604 ost << "\"use_stationarity_properties\": " 605 << (config.echo_audibility.use_stationarity_properties ? "true" : "false") 606 << ","; 607 ost << "\"use_stationarity_properties_at_init\": " 608 << (config.echo_audibility.use_stationarity_properties_at_init ? "true" 609 : "false"); 610 ost << "},"; 611 612 ost << "\"render_levels\": {"; 613 ost << "\"active_render_limit\": " << config.render_levels.active_render_limit 614 << ","; 615 ost << "\"poor_excitation_render_limit\": " 616 << config.render_levels.poor_excitation_render_limit << ","; 617 ost << "\"poor_excitation_render_limit_ds8\": " 618 << config.render_levels.poor_excitation_render_limit_ds8 << ","; 619 ost << "\"render_power_gain_db\": " 620 << config.render_levels.render_power_gain_db; 621 ost << "},"; 622 623 ost << "\"echo_removal_control\": {"; 624 ost << "\"has_clock_drift\": " 625 << (config.echo_removal_control.has_clock_drift ? "true" : "false") 626 << ","; 627 ost << "\"linear_and_stable_echo_path\": " 628 << (config.echo_removal_control.linear_and_stable_echo_path ? "true" 629 : "false"); 630 631 ost << "},"; 632 633 ost << "\"echo_model\": {"; 634 ost << "\"noise_floor_hold\": " << config.echo_model.noise_floor_hold << ","; 635 ost << "\"min_noise_floor_power\": " 636 << config.echo_model.min_noise_floor_power << ","; 637 ost << "\"stationary_gate_slope\": " 638 << config.echo_model.stationary_gate_slope << ","; 639 ost << "\"noise_gate_power\": " << config.echo_model.noise_gate_power << ","; 640 ost << "\"noise_gate_slope\": " << config.echo_model.noise_gate_slope << ","; 641 ost << "\"render_pre_window_size\": " 642 << config.echo_model.render_pre_window_size << ","; 643 ost << "\"render_post_window_size\": " 644 << config.echo_model.render_post_window_size << ","; 645 ost << "\"model_reverb_in_nonlinear_mode\": " 646 << (config.echo_model.model_reverb_in_nonlinear_mode ? "true" : "false"); 647 ost << "},"; 648 649 ost << "\"comfort_noise\": {"; 650 ost << "\"noise_floor_dbfs\": " << config.comfort_noise.noise_floor_dbfs; 651 ost << "},"; 652 653 ost << "\"suppressor\": {"; 654 ost << "\"nearend_average_blocks\": " 655 << config.suppressor.nearend_average_blocks << ","; 656 ost << "\"normal_tuning\": {"; 657 ost << "\"mask_lf\": ["; 658 ost << config.suppressor.normal_tuning.mask_lf.enr_transparent << ","; 659 ost << config.suppressor.normal_tuning.mask_lf.enr_suppress << ","; 660 ost << config.suppressor.normal_tuning.mask_lf.emr_transparent; 661 ost << "],"; 662 ost << "\"mask_hf\": ["; 663 ost << config.suppressor.normal_tuning.mask_hf.enr_transparent << ","; 664 ost << config.suppressor.normal_tuning.mask_hf.enr_suppress << ","; 665 ost << config.suppressor.normal_tuning.mask_hf.emr_transparent; 666 ost << "],"; 667 ost << "\"max_inc_factor\": " 668 << config.suppressor.normal_tuning.max_inc_factor << ","; 669 ost << "\"max_dec_factor_lf\": " 670 << config.suppressor.normal_tuning.max_dec_factor_lf; 671 ost << "},"; 672 ost << "\"nearend_tuning\": {"; 673 ost << "\"mask_lf\": ["; 674 ost << config.suppressor.nearend_tuning.mask_lf.enr_transparent << ","; 675 ost << config.suppressor.nearend_tuning.mask_lf.enr_suppress << ","; 676 ost << config.suppressor.nearend_tuning.mask_lf.emr_transparent; 677 ost << "],"; 678 ost << "\"mask_hf\": ["; 679 ost << config.suppressor.nearend_tuning.mask_hf.enr_transparent << ","; 680 ost << config.suppressor.nearend_tuning.mask_hf.enr_suppress << ","; 681 ost << config.suppressor.nearend_tuning.mask_hf.emr_transparent; 682 ost << "],"; 683 ost << "\"max_inc_factor\": " 684 << config.suppressor.nearend_tuning.max_inc_factor << ","; 685 ost << "\"max_dec_factor_lf\": " 686 << config.suppressor.nearend_tuning.max_dec_factor_lf; 687 ost << "},"; 688 ost << "\"lf_smoothing_during_initial_phase\": " 689 << (config.suppressor.lf_smoothing_during_initial_phase ? "true" 690 : "false") 691 << ","; 692 ost << "\"last_permanent_lf_smoothing_band\": " 693 << config.suppressor.last_permanent_lf_smoothing_band << ","; 694 ost << "\"last_lf_smoothing_band\": " 695 << config.suppressor.last_lf_smoothing_band << ","; 696 ost << "\"last_lf_band\": " << config.suppressor.last_lf_band << ","; 697 ost << "\"first_hf_band\": " << config.suppressor.first_hf_band << ","; 698 { 699 const auto& dnd = config.suppressor.dominant_nearend_detection; 700 ost << "\"dominant_nearend_detection\": {"; 701 ost << "\"enr_threshold\": " << dnd.enr_threshold << ","; 702 ost << "\"enr_exit_threshold\": " << dnd.enr_exit_threshold << ","; 703 ost << "\"snr_threshold\": " << dnd.snr_threshold << ","; 704 ost << "\"hold_duration\": " << dnd.hold_duration << ","; 705 ost << "\"trigger_threshold\": " << dnd.trigger_threshold << ","; 706 ost << "\"use_during_initial_phase\": " << dnd.use_during_initial_phase 707 << ","; 708 ost << "\"use_unbounded_echo_spectrum\": " 709 << dnd.use_unbounded_echo_spectrum; 710 ost << "},"; 711 } 712 ost << "\"subband_nearend_detection\": {"; 713 ost << "\"nearend_average_blocks\": " 714 << config.suppressor.subband_nearend_detection.nearend_average_blocks 715 << ","; 716 ost << "\"subband1\": ["; 717 ost << config.suppressor.subband_nearend_detection.subband1.low << ","; 718 ost << config.suppressor.subband_nearend_detection.subband1.high; 719 ost << "],"; 720 ost << "\"subband2\": ["; 721 ost << config.suppressor.subband_nearend_detection.subband2.low << ","; 722 ost << config.suppressor.subband_nearend_detection.subband2.high; 723 ost << "],"; 724 ost << "\"nearend_threshold\": " 725 << config.suppressor.subband_nearend_detection.nearend_threshold << ","; 726 ost << "\"snr_threshold\": " 727 << config.suppressor.subband_nearend_detection.snr_threshold; 728 ost << "},"; 729 ost << "\"use_subband_nearend_detection\": " 730 << config.suppressor.use_subband_nearend_detection << ","; 731 ost << "\"high_bands_suppression\": {"; 732 ost << "\"enr_threshold\": " 733 << config.suppressor.high_bands_suppression.enr_threshold << ","; 734 ost << "\"max_gain_during_echo\": " 735 << config.suppressor.high_bands_suppression.max_gain_during_echo << ","; 736 ost << "\"anti_howling_activation_threshold\": " 737 << config.suppressor.high_bands_suppression 738 .anti_howling_activation_threshold 739 << ","; 740 ost << "\"anti_howling_gain\": " 741 << config.suppressor.high_bands_suppression.anti_howling_gain; 742 ost << "},"; 743 ost << "\"floor_first_increase\": " << config.suppressor.floor_first_increase 744 << ","; 745 ost << "\"conservative_hf_suppression\": " 746 << config.suppressor.conservative_hf_suppression; 747 ost << "},"; 748 749 ost << "\"multi_channel\": {"; 750 ost << "\"detect_stereo_content\": " 751 << (config.multi_channel.detect_stereo_content ? "true" : "false") << ","; 752 ost << "\"stereo_detection_threshold\": " 753 << config.multi_channel.stereo_detection_threshold << ","; 754 ost << "\"stereo_detection_timeout_threshold_seconds\": " 755 << config.multi_channel.stereo_detection_timeout_threshold_seconds << ","; 756 ost << "\"stereo_detection_hysteresis_seconds\": " 757 << config.multi_channel.stereo_detection_hysteresis_seconds; 758 ost << "}"; 759 760 ost << "}"; 761 ost << "}"; 762 763 return ost.Release(); 764 } 765 } // namespace webrtc