tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

audio_processing_unittest.cc (137392B)


      1 /*
      2 *  Copyright (c) 2012 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 "api/audio/audio_processing.h"
     11 
     12 #include <stdio.h>
     13 
     14 #include <algorithm>
     15 #include <array>
     16 #include <cmath>
     17 #include <cstdint>
     18 #include <cstdio>
     19 #include <cstring>
     20 #include <iostream>
     21 #include <limits>
     22 #include <map>
     23 #include <memory>
     24 #include <numeric>
     25 #include <ostream>
     26 #include <queue>
     27 #include <string>
     28 #include <tuple>
     29 #include <utility>
     30 #include <vector>
     31 
     32 #include "absl/flags/flag.h"
     33 #include "absl/strings/string_view.h"
     34 #include "api/array_view.h"
     35 #include "api/audio/audio_processing_statistics.h"
     36 #include "api/audio/audio_view.h"
     37 #include "api/audio/builtin_audio_processing_builder.h"
     38 #include "api/audio/echo_control.h"
     39 #include "api/audio/echo_detector_creator.h"
     40 #include "api/audio/neural_residual_echo_estimator.h"
     41 #include "api/environment/environment.h"
     42 #include "api/environment/environment_factory.h"
     43 #include "api/make_ref_counted.h"
     44 #include "api/scoped_refptr.h"
     45 #include "common_audio/channel_buffer.h"
     46 #include "common_audio/include/audio_util.h"
     47 #include "common_audio/resampler/include/push_resampler.h"
     48 #include "common_audio/resampler/push_sinc_resampler.h"
     49 #include "modules/audio_processing/aec_dump/aec_dump_factory.h"
     50 #include "modules/audio_processing/include/mock_audio_processing.h"
     51 #include "modules/audio_processing/test/protobuf_utils.h"
     52 #include "modules/audio_processing/test/test_utils.h"
     53 #include "rtc_base/checks.h"
     54 #include "rtc_base/cpu_info.h"
     55 #include "rtc_base/fake_clock.h"
     56 #include "rtc_base/numerics/safe_conversions.h"
     57 #include "rtc_base/numerics/safe_minmax.h"
     58 #include "rtc_base/protobuf_utils.h"
     59 #include "rtc_base/strings/string_builder.h"
     60 #include "rtc_base/swap_queue.h"
     61 #include "rtc_base/system/file_wrapper.h"
     62 #include "rtc_base/task_queue_for_test.h"
     63 #include "test/gmock.h"
     64 #include "test/gtest.h"
     65 #include "test/testsupport/file_utils.h"
     66 
     67 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD
     68 #include "external/webrtc/webrtc/modules/audio_processing/debug.pb.h"
     69 #include "external/webrtc/webrtc/modules/audio_processing/test/unittest.pb.h"
     70 #else
     71 #include "modules/audio_processing/debug.pb.h"
     72 #include "modules/audio_processing/test/unittest.pb.h"
     73 #endif
     74 
     75 ABSL_FLAG(bool,
     76          write_apm_ref_data,
     77          false,
     78          "Write ApmTest.Process results to file, instead of comparing results "
     79          "to the existing reference data file.");
     80 
     81 namespace webrtc {
     82 namespace {
     83 
     84 using ::testing::_;
     85 using ::testing::WithoutArgs;
     86 
     87 // All sample rates used by APM internally during processing. Other input /
     88 // output rates are resampled to / from one of these.
     89 constexpr int kProcessSampleRates[] = {16000, 32000, 48000};
     90 
     91 enum StreamDirection { kForward = 0, kReverse };
     92 
     93 void ConvertToFloat(const int16_t* int_data, ChannelBuffer<float>* cb) {
     94  ChannelBuffer<int16_t> cb_int(cb->num_frames(), cb->num_channels());
     95  Deinterleave(int_data, cb->num_frames(), cb->num_channels(),
     96               cb_int.channels());
     97  for (size_t i = 0; i < cb->num_channels(); ++i) {
     98    S16ToFloat(cb_int.channels()[i], cb->num_frames(), cb->channels()[i]);
     99  }
    100 }
    101 
    102 void ConvertToFloat(const Int16FrameData& frame, ChannelBuffer<float>* cb) {
    103  ConvertToFloat(frame.data.data(), cb);
    104 }
    105 
    106 void MixStereoToMono(const float* stereo,
    107                     float* mono,
    108                     size_t samples_per_channel) {
    109  for (size_t i = 0; i < samples_per_channel; ++i)
    110    mono[i] = (stereo[i * 2] + stereo[i * 2 + 1]) / 2;
    111 }
    112 
    113 void MixStereoToMono(const int16_t* stereo,
    114                     int16_t* mono,
    115                     size_t samples_per_channel) {
    116  for (size_t i = 0; i < samples_per_channel; ++i)
    117    mono[i] = (stereo[i * 2] + stereo[i * 2 + 1]) >> 1;
    118 }
    119 
    120 void CopyLeftToRightChannel(int16_t* stereo, size_t samples_per_channel) {
    121  for (size_t i = 0; i < samples_per_channel; i++) {
    122    stereo[i * 2 + 1] = stereo[i * 2];
    123  }
    124 }
    125 
    126 void VerifyChannelsAreEqual(const int16_t* stereo, size_t samples_per_channel) {
    127  for (size_t i = 0; i < samples_per_channel; i++) {
    128    EXPECT_EQ(stereo[i * 2 + 1], stereo[i * 2]);
    129  }
    130 }
    131 
    132 void EnableAllAPComponents(AudioProcessing* ap) {
    133  AudioProcessing::Config apm_config = ap->GetConfig();
    134  apm_config.echo_canceller.enabled = true;
    135 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
    136  apm_config.echo_canceller.mobile_mode = true;
    137 
    138  apm_config.gain_controller1.enabled = true;
    139  apm_config.gain_controller1.mode =
    140      AudioProcessing::Config::GainController1::kAdaptiveDigital;
    141 #elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
    142  apm_config.echo_canceller.mobile_mode = false;
    143 
    144  apm_config.gain_controller1.enabled = true;
    145  apm_config.gain_controller1.mode =
    146      AudioProcessing::Config::GainController1::kAdaptiveAnalog;
    147 #endif
    148 
    149  apm_config.noise_suppression.enabled = true;
    150 
    151  apm_config.high_pass_filter.enabled = true;
    152  apm_config.pipeline.maximum_internal_processing_rate = 48000;
    153  ap->ApplyConfig(apm_config);
    154 }
    155 
    156 // These functions are only used by ApmTest.Process.
    157 template <class T>
    158 T AbsValue(T a) {
    159  return a > 0 ? a : -a;
    160 }
    161 
    162 int16_t MaxAudioFrame(const Int16FrameData& frame) {
    163  int16_t max_data = AbsValue(frame.data[0]);
    164  for (size_t i = 1; i < frame.size(); i++) {
    165    max_data = std::max(max_data, AbsValue(frame.data[i]));
    166  }
    167 
    168  return max_data;
    169 }
    170 
    171 void OpenFileAndWriteMessage(absl::string_view filename,
    172                             const MessageLite& msg) {
    173  FILE* file = fopen(std::string(filename).c_str(), "wb");
    174  ASSERT_TRUE(file != nullptr);
    175 
    176  int32_t size = checked_cast<int32_t>(msg.ByteSizeLong());
    177  ASSERT_GT(size, 0);
    178  std::unique_ptr<uint8_t[]> array(new uint8_t[size]);
    179  ASSERT_TRUE(msg.SerializeToArray(array.get(), size));
    180 
    181  ASSERT_EQ(1u, fwrite(&size, sizeof(size), 1, file));
    182  ASSERT_EQ(static_cast<size_t>(size),
    183            fwrite(array.get(), sizeof(array[0]), size, file));
    184  fclose(file);
    185 }
    186 
    187 std::string ResourceFilePath(absl::string_view name, int sample_rate_hz) {
    188  StringBuilder ss;
    189  // Resource files are all stereo.
    190  ss << name << sample_rate_hz / 1000 << "_stereo";
    191  return test::ResourcePath(ss.str(), "pcm");
    192 }
    193 
    194 // Temporary filenames unique to this process. Used to be able to run these
    195 // tests in parallel as each process needs to be running in isolation they can't
    196 // have competing filenames.
    197 std::map<std::string, std::string> temp_filenames;
    198 
    199 std::string OutputFilePath(absl::string_view name,
    200                           int input_rate,
    201                           int output_rate,
    202                           int reverse_input_rate,
    203                           int reverse_output_rate,
    204                           size_t num_input_channels,
    205                           size_t num_output_channels,
    206                           size_t num_reverse_input_channels,
    207                           size_t num_reverse_output_channels,
    208                           StreamDirection file_direction) {
    209  StringBuilder ss;
    210  ss << name << "_i" << num_input_channels << "_" << input_rate / 1000 << "_ir"
    211     << num_reverse_input_channels << "_" << reverse_input_rate / 1000 << "_";
    212  if (num_output_channels == 1) {
    213    ss << "mono";
    214  } else if (num_output_channels == 2) {
    215    ss << "stereo";
    216  } else {
    217    RTC_DCHECK_NOTREACHED();
    218  }
    219  ss << output_rate / 1000;
    220  if (num_reverse_output_channels == 1) {
    221    ss << "_rmono";
    222  } else if (num_reverse_output_channels == 2) {
    223    ss << "_rstereo";
    224  } else {
    225    RTC_DCHECK_NOTREACHED();
    226  }
    227  ss << reverse_output_rate / 1000;
    228  ss << "_d" << file_direction << "_pcm";
    229 
    230  std::string filename = ss.str();
    231  if (temp_filenames[filename].empty())
    232    temp_filenames[filename] = test::TempFilename(test::OutputPath(), filename);
    233  return temp_filenames[filename];
    234 }
    235 
    236 void ClearTempFiles() {
    237  for (auto& kv : temp_filenames)
    238    remove(kv.second.c_str());
    239 }
    240 
    241 // Only remove "out" files. Keep "ref" files.
    242 void ClearTempOutFiles() {
    243  for (auto it = temp_filenames.begin(); it != temp_filenames.end();) {
    244    const std::string& filename = it->first;
    245    if (filename.substr(0, 3).compare("out") == 0) {
    246      remove(it->second.c_str());
    247      temp_filenames.erase(it++);
    248    } else {
    249      it++;
    250    }
    251  }
    252 }
    253 
    254 void OpenFileAndReadMessage(absl::string_view filename, MessageLite* msg) {
    255  FILE* file = fopen(std::string(filename).c_str(), "rb");
    256  ASSERT_TRUE(file != nullptr);
    257  ReadMessageFromFile(file, msg);
    258  fclose(file);
    259 }
    260 
    261 // Reads a 10 ms chunk (actually AudioProcessing::GetFrameSize() samples per
    262 // channel) of int16 interleaved audio from the given (assumed stereo) file,
    263 // converts to deinterleaved float (optionally downmixing) and returns the
    264 // result in `cb`. Returns false if the file ended (or on error) and true
    265 // otherwise.
    266 //
    267 // `int_data` and `float_data` are just temporary space that must be
    268 // sufficiently large to hold the 10 ms chunk.
    269 bool ReadChunk(FILE* file,
    270               int16_t* int_data,
    271               float* float_data,
    272               ChannelBuffer<float>* cb) {
    273  // The files always contain stereo audio.
    274  size_t frame_size = cb->num_frames() * 2;
    275  size_t read_count = fread(int_data, sizeof(int16_t), frame_size, file);
    276  if (read_count != frame_size) {
    277    // Check that the file really ended.
    278    RTC_DCHECK(feof(file));
    279    return false;  // This is expected.
    280  }
    281 
    282  S16ToFloat(int_data, frame_size, float_data);
    283  if (cb->num_channels() == 1) {
    284    MixStereoToMono(float_data, cb->channels()[0], cb->num_frames());
    285  } else {
    286    Deinterleave(float_data, cb->num_frames(), 2, cb->channels());
    287  }
    288 
    289  return true;
    290 }
    291 
    292 // Returns the reference file name that matches the current CPU
    293 // architecture/optimizations.
    294 std::string GetReferenceFilename() {
    295 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
    296  return test::ResourcePath("audio_processing/output_data_fixed", "pb");
    297 #elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
    298  if (cpu_info::Supports(cpu_info::ISA::kAVX2)) {
    299    return test::ResourcePath("audio_processing/output_data_float_avx2", "pb");
    300  }
    301  return test::ResourcePath("audio_processing/output_data_float", "pb");
    302 #endif
    303 }
    304 
    305 // Flag that can temporarily be enabled for local debugging to inspect
    306 // `ApmTest.VerifyDebugDump(Int|Float)` failures. Do not upload code changes
    307 // with this flag set to true.
    308 constexpr bool kDumpWhenExpectMessageEqFails = false;
    309 
    310 // Checks the debug constants values used in this file so that no code change is
    311 // submitted with values temporarily used for local debugging.
    312 TEST(ApmUnitTests, CheckDebugConstants) {
    313  ASSERT_FALSE(kDumpWhenExpectMessageEqFails);
    314 }
    315 
    316 // Expects the equality of `actual` and `expected` by inspecting a hard-coded
    317 // subset of `audioproc::Stream` fields.
    318 void ExpectStreamFieldsEq(const audioproc::Stream& actual,
    319                          const audioproc::Stream& expected) {
    320  EXPECT_EQ(actual.input_data(), expected.input_data());
    321  EXPECT_EQ(actual.output_data(), expected.output_data());
    322  EXPECT_EQ(actual.delay(), expected.delay());
    323  EXPECT_EQ(actual.drift(), expected.drift());
    324  EXPECT_EQ(actual.applied_input_volume(), expected.applied_input_volume());
    325  EXPECT_EQ(actual.keypress(), expected.keypress());
    326 }
    327 
    328 // Expects the equality of `actual` and `expected` by inspecting a hard-coded
    329 // subset of `audioproc::Event` fields.
    330 void ExpectEventFieldsEq(const audioproc::Event& actual,
    331                         const audioproc::Event& expected) {
    332  EXPECT_EQ(actual.type(), expected.type());
    333  if (actual.type() != expected.type()) {
    334    return;
    335  }
    336  switch (actual.type()) {
    337    case audioproc::Event::STREAM:
    338      ExpectStreamFieldsEq(actual.stream(), expected.stream());
    339      break;
    340    default:
    341      // Not implemented.
    342      break;
    343  }
    344 }
    345 
    346 // Returns true if the `actual` and `expected` byte streams share the same size
    347 // and contain the same data. If they differ and `kDumpWhenExpectMessageEqFails`
    348 // is true, checks the equality of a subset of `audioproc::Event` (nested)
    349 // fields.
    350 bool ExpectMessageEq(ArrayView<const uint8_t> actual,
    351                     ArrayView<const uint8_t> expected) {
    352  EXPECT_EQ(actual.size(), expected.size());
    353  if (actual.size() != expected.size()) {
    354    return false;
    355  }
    356  if (memcmp(actual.data(), expected.data(), actual.size()) == 0) {
    357    // Same message. No need to parse.
    358    return true;
    359  }
    360  if (kDumpWhenExpectMessageEqFails) {
    361    // Parse differing messages and expect equality to produce detailed error
    362    // messages.
    363    audioproc::Event event_actual, event_expected;
    364    RTC_DCHECK(event_actual.ParseFromArray(actual.data(), actual.size()));
    365    RTC_DCHECK(event_expected.ParseFromArray(expected.data(), expected.size()));
    366    ExpectEventFieldsEq(event_actual, event_expected);
    367  }
    368  return false;
    369 }
    370 
    371 class ApmTest : public ::testing::Test {
    372 protected:
    373  ApmTest();
    374  void SetUp() override;
    375  void TearDown() override;
    376 
    377  static void SetUpTestSuite() {}
    378 
    379  static void TearDownTestSuite() { ClearTempFiles(); }
    380 
    381  // Used to select between int and float interface tests.
    382  enum Format { kIntFormat, kFloatFormat };
    383 
    384  void Init(int sample_rate_hz,
    385            int output_sample_rate_hz,
    386            int reverse_sample_rate_hz,
    387            size_t num_input_channels,
    388            size_t num_output_channels,
    389            size_t num_reverse_channels,
    390            bool open_output_file);
    391  void Init(AudioProcessing* ap);
    392  void EnableAllComponents();
    393  bool ReadFrame(FILE* file, Int16FrameData* frame);
    394  bool ReadFrame(FILE* file, Int16FrameData* frame, ChannelBuffer<float>* cb);
    395  void ReadFrameWithRewind(FILE* file, Int16FrameData* frame);
    396  void ReadFrameWithRewind(FILE* file,
    397                           Int16FrameData* frame,
    398                           ChannelBuffer<float>* cb);
    399  void ProcessDelayVerificationTest(int delay_ms,
    400                                    int system_delay_ms,
    401                                    int delay_min,
    402                                    int delay_max);
    403  void TestChangingChannelsInt16Interface(
    404      size_t num_channels,
    405      AudioProcessing::Error expected_return);
    406  void TestChangingForwardChannels(size_t num_in_channels,
    407                                   size_t num_out_channels,
    408                                   AudioProcessing::Error expected_return);
    409  void TestChangingReverseChannels(size_t num_rev_channels,
    410                                   AudioProcessing::Error expected_return);
    411  void RunQuantizedVolumeDoesNotGetStuckTest(int sample_rate);
    412  void RunManualVolumeChangeIsPossibleTest(int sample_rate);
    413  void StreamParametersTest(Format format);
    414  int ProcessStreamChooser(Format format);
    415  int AnalyzeReverseStreamChooser(Format format);
    416  void ProcessDebugDump(absl::string_view in_filename,
    417                        absl::string_view out_filename,
    418                        Format format,
    419                        int max_size_bytes);
    420  void VerifyDebugDumpTest(Format format);
    421 
    422  const std::string output_path_;
    423  const std::string ref_filename_;
    424  scoped_refptr<AudioProcessing> apm_;
    425  Int16FrameData frame_;
    426  Int16FrameData revframe_;
    427  std::unique_ptr<ChannelBuffer<float>> float_cb_;
    428  std::unique_ptr<ChannelBuffer<float>> revfloat_cb_;
    429  int output_sample_rate_hz_;
    430  size_t num_output_channels_;
    431  FILE* far_file_;
    432  FILE* near_file_;
    433  FILE* out_file_;
    434 };
    435 
    436 ApmTest::ApmTest()
    437    : output_path_(test::OutputPath()),
    438      ref_filename_(GetReferenceFilename()),
    439      output_sample_rate_hz_(0),
    440      num_output_channels_(0),
    441      far_file_(nullptr),
    442      near_file_(nullptr),
    443      out_file_(nullptr) {
    444  apm_ = BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
    445  AudioProcessing::Config apm_config = apm_->GetConfig();
    446  apm_config.gain_controller1.analog_gain_controller.enabled = false;
    447  apm_config.pipeline.maximum_internal_processing_rate = 48000;
    448  apm_->ApplyConfig(apm_config);
    449 }
    450 
    451 void ApmTest::SetUp() {
    452  ASSERT_TRUE(apm_.get() != nullptr);
    453 
    454  Init(32000, 32000, 32000, 2, 2, 2, false);
    455 }
    456 
    457 void ApmTest::TearDown() {
    458  if (far_file_) {
    459    ASSERT_EQ(0, fclose(far_file_));
    460  }
    461  far_file_ = nullptr;
    462 
    463  if (near_file_) {
    464    ASSERT_EQ(0, fclose(near_file_));
    465  }
    466  near_file_ = nullptr;
    467 
    468  if (out_file_) {
    469    ASSERT_EQ(0, fclose(out_file_));
    470  }
    471  out_file_ = nullptr;
    472 }
    473 
    474 void ApmTest::Init(AudioProcessing* ap) {
    475  ASSERT_EQ(
    476      AudioProcessing::kNoError,
    477      ap->Initialize({{{frame_.sample_rate_hz, frame_.num_channels()},
    478                       {output_sample_rate_hz_, num_output_channels_},
    479                       {revframe_.sample_rate_hz, revframe_.num_channels()},
    480                       {revframe_.sample_rate_hz, revframe_.num_channels()}}}));
    481 }
    482 
    483 void ApmTest::Init(int sample_rate_hz,
    484                   int output_sample_rate_hz,
    485                   int reverse_sample_rate_hz,
    486                   size_t num_input_channels,
    487                   size_t num_output_channels,
    488                   size_t num_reverse_channels,
    489                   bool open_output_file) {
    490  SetContainerFormat(sample_rate_hz, num_input_channels, &frame_, &float_cb_);
    491  output_sample_rate_hz_ = output_sample_rate_hz;
    492  num_output_channels_ = num_output_channels;
    493 
    494  SetContainerFormat(reverse_sample_rate_hz, num_reverse_channels, &revframe_,
    495                     &revfloat_cb_);
    496  Init(apm_.get());
    497 
    498  if (far_file_) {
    499    ASSERT_EQ(0, fclose(far_file_));
    500  }
    501  std::string filename = ResourceFilePath("far", sample_rate_hz);
    502  far_file_ = fopen(filename.c_str(), "rb");
    503  ASSERT_TRUE(far_file_ != nullptr)
    504      << "Could not open file " << filename << "\n";
    505 
    506  if (near_file_) {
    507    ASSERT_EQ(0, fclose(near_file_));
    508  }
    509  filename = ResourceFilePath("near", sample_rate_hz);
    510  near_file_ = fopen(filename.c_str(), "rb");
    511  ASSERT_TRUE(near_file_ != nullptr)
    512      << "Could not open file " << filename << "\n";
    513 
    514  if (open_output_file) {
    515    if (out_file_) {
    516      ASSERT_EQ(0, fclose(out_file_));
    517    }
    518    filename = OutputFilePath(
    519        "out", sample_rate_hz, output_sample_rate_hz, reverse_sample_rate_hz,
    520        reverse_sample_rate_hz, num_input_channels, num_output_channels,
    521        num_reverse_channels, num_reverse_channels, kForward);
    522    out_file_ = fopen(filename.c_str(), "wb");
    523    ASSERT_TRUE(out_file_ != nullptr)
    524        << "Could not open file " << filename << "\n";
    525  }
    526 }
    527 
    528 void ApmTest::EnableAllComponents() {
    529  EnableAllAPComponents(apm_.get());
    530 }
    531 
    532 bool ApmTest::ReadFrame(FILE* file,
    533                        Int16FrameData* frame,
    534                        ChannelBuffer<float>* cb) {
    535  // The files always contain stereo audio.
    536  size_t frame_size = frame->samples_per_channel() * 2;
    537  size_t read_count =
    538      fread(frame->data.data(), sizeof(int16_t), frame_size, file);
    539  if (read_count != frame_size) {
    540    // Check that the file really ended.
    541    EXPECT_NE(0, feof(file));
    542    return false;  // This is expected.
    543  }
    544 
    545  if (frame->num_channels() == 1) {
    546    MixStereoToMono(frame->data.data(), frame->data.data(),
    547                    frame->samples_per_channel());
    548  }
    549 
    550  if (cb) {
    551    ConvertToFloat(*frame, cb);
    552  }
    553  return true;
    554 }
    555 
    556 bool ApmTest::ReadFrame(FILE* file, Int16FrameData* frame) {
    557  return ReadFrame(file, frame, nullptr);
    558 }
    559 
    560 // If the end of the file has been reached, rewind it and attempt to read the
    561 // frame again.
    562 void ApmTest::ReadFrameWithRewind(FILE* /* file */,
    563                                  Int16FrameData* /* frame */,
    564                                  ChannelBuffer<float>* cb) {
    565  if (!ReadFrame(near_file_, &frame_, cb)) {
    566    rewind(near_file_);
    567    ASSERT_TRUE(ReadFrame(near_file_, &frame_, cb));
    568  }
    569 }
    570 
    571 void ApmTest::ReadFrameWithRewind(FILE* file, Int16FrameData* frame) {
    572  ReadFrameWithRewind(file, frame, nullptr);
    573 }
    574 
    575 int ApmTest::ProcessStreamChooser(Format format) {
    576  if (format == kIntFormat) {
    577    return apm_->ProcessStream(
    578        frame_.data.data(),
    579        StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
    580        StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
    581        frame_.data.data());
    582  }
    583  return apm_->ProcessStream(
    584      float_cb_->channels(),
    585      StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
    586      StreamConfig(output_sample_rate_hz_, num_output_channels_),
    587      float_cb_->channels());
    588 }
    589 
    590 int ApmTest::AnalyzeReverseStreamChooser(Format format) {
    591  if (format == kIntFormat) {
    592    return apm_->ProcessReverseStream(
    593        revframe_.data.data(),
    594        StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
    595        StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
    596        revframe_.data.data());
    597  }
    598  return apm_->AnalyzeReverseStream(
    599      revfloat_cb_->channels(),
    600      StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()));
    601 }
    602 
    603 void ApmTest::ProcessDelayVerificationTest(int delay_ms,
    604                                           int system_delay_ms,
    605                                           int delay_min,
    606                                           int delay_max) {
    607  // The `revframe_` and `frame_` should include the proper frame information,
    608  // hence can be used for extracting information.
    609  Int16FrameData tmp_frame;
    610  std::queue<Int16FrameData*> frame_queue;
    611  bool causal = true;
    612 
    613  tmp_frame.CopyFrom(revframe_);
    614  tmp_frame.FillData(0);
    615 
    616  EXPECT_EQ(AudioProcessing::kNoError, apm_->Initialize());
    617  // Initialize the `frame_queue` with empty frames.
    618  int frame_delay = delay_ms / 10;
    619  while (frame_delay < 0) {
    620    Int16FrameData* frame = new Int16FrameData();
    621    frame->CopyFrom(tmp_frame);
    622    frame_queue.push(frame);
    623    frame_delay++;
    624    causal = false;
    625  }
    626  while (frame_delay > 0) {
    627    Int16FrameData* frame = new Int16FrameData();
    628    frame->CopyFrom(tmp_frame);
    629    frame_queue.push(frame);
    630    frame_delay--;
    631  }
    632  // Run for 4.5 seconds, skipping statistics from the first 2.5 seconds.  We
    633  // need enough frames with audio to have reliable estimates, but as few as
    634  // possible to keep processing time down.  4.5 seconds seemed to be a good
    635  // compromise for this recording.
    636  for (int frame_count = 0; frame_count < 450; ++frame_count) {
    637    Int16FrameData* frame = new Int16FrameData();
    638    frame->CopyFrom(tmp_frame);
    639    // Use the near end recording, since that has more speech in it.
    640    ASSERT_TRUE(ReadFrame(near_file_, frame));
    641    frame_queue.push(frame);
    642    Int16FrameData* reverse_frame = frame;
    643    Int16FrameData* process_frame = frame_queue.front();
    644    if (!causal) {
    645      reverse_frame = frame_queue.front();
    646      // When we call ProcessStream() the frame is modified, so we can't use the
    647      // pointer directly when things are non-causal. Use an intermediate frame
    648      // and copy the data.
    649      process_frame = &tmp_frame;
    650      process_frame->CopyFrom(*frame);
    651    }
    652    EXPECT_EQ(
    653        AudioProcessing::kNoError,
    654        apm_->ProcessReverseStream(reverse_frame->data.data(),
    655                                   StreamConfig(reverse_frame->sample_rate_hz,
    656                                                reverse_frame->num_channels()),
    657                                   StreamConfig(reverse_frame->sample_rate_hz,
    658                                                reverse_frame->num_channels()),
    659                                   reverse_frame->data.data()));
    660    EXPECT_EQ(AudioProcessing::kNoError,
    661              apm_->set_stream_delay_ms(system_delay_ms));
    662    EXPECT_EQ(AudioProcessing::kNoError,
    663              apm_->ProcessStream(process_frame->data.data(),
    664                                  StreamConfig(process_frame->sample_rate_hz,
    665                                               process_frame->num_channels()),
    666                                  StreamConfig(process_frame->sample_rate_hz,
    667                                               process_frame->num_channels()),
    668                                  process_frame->data.data()));
    669    frame = frame_queue.front();
    670    frame_queue.pop();
    671    delete frame;
    672 
    673    if (frame_count == 250) {
    674      // Discard the first delay metrics to avoid convergence effects.
    675      static_cast<void>(apm_->GetStatistics());
    676    }
    677  }
    678 
    679  rewind(near_file_);
    680  while (!frame_queue.empty()) {
    681    Int16FrameData* frame = frame_queue.front();
    682    frame_queue.pop();
    683    delete frame;
    684  }
    685  // Calculate expected delay estimate and acceptable regions. Further,
    686  // limit them w.r.t. AEC delay estimation support.
    687  const size_t samples_per_ms =
    688      SafeMin<size_t>(16u, frame_.samples_per_channel() / 10);
    689  const int expected_median =
    690      SafeClamp<int>(delay_ms - system_delay_ms, delay_min, delay_max);
    691  const int expected_median_high =
    692      SafeClamp<int>(expected_median + dchecked_cast<int>(96 / samples_per_ms),
    693                     delay_min, delay_max);
    694  const int expected_median_low =
    695      SafeClamp<int>(expected_median - dchecked_cast<int>(96 / samples_per_ms),
    696                     delay_min, delay_max);
    697  // Verify delay metrics.
    698  AudioProcessingStats stats = apm_->GetStatistics();
    699  ASSERT_TRUE(stats.delay_median_ms.has_value());
    700  int32_t median = *stats.delay_median_ms;
    701  EXPECT_GE(expected_median_high, median);
    702  EXPECT_LE(expected_median_low, median);
    703 }
    704 
    705 void ApmTest::StreamParametersTest(Format format) {
    706  // No errors when the components are disabled.
    707  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
    708 
    709  // -- Missing AGC level --
    710  AudioProcessing::Config apm_config = apm_->GetConfig();
    711  apm_config.gain_controller1.enabled = true;
    712  apm_->ApplyConfig(apm_config);
    713  EXPECT_EQ(apm_->kStreamParameterNotSetError, ProcessStreamChooser(format));
    714 
    715  // Resets after successful ProcessStream().
    716  apm_->set_stream_analog_level(127);
    717  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
    718  EXPECT_EQ(apm_->kStreamParameterNotSetError, ProcessStreamChooser(format));
    719 
    720  // Other stream parameters set correctly.
    721  apm_config.echo_canceller.enabled = true;
    722  apm_config.echo_canceller.mobile_mode = false;
    723  apm_->ApplyConfig(apm_config);
    724  EXPECT_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(100));
    725  EXPECT_EQ(apm_->kStreamParameterNotSetError, ProcessStreamChooser(format));
    726  apm_config.gain_controller1.enabled = false;
    727  apm_->ApplyConfig(apm_config);
    728 
    729  // -- Missing delay --
    730  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
    731  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
    732 
    733  // Resets after successful ProcessStream().
    734  EXPECT_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(100));
    735  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
    736  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
    737 
    738  // Other stream parameters set correctly.
    739  apm_config.gain_controller1.enabled = true;
    740  apm_->ApplyConfig(apm_config);
    741  apm_->set_stream_analog_level(127);
    742  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
    743  apm_config.gain_controller1.enabled = false;
    744  apm_->ApplyConfig(apm_config);
    745 
    746  // -- No stream parameters --
    747  EXPECT_EQ(AudioProcessing::kNoError, AnalyzeReverseStreamChooser(format));
    748  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
    749 
    750  // -- All there --
    751  EXPECT_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(100));
    752  apm_->set_stream_analog_level(127);
    753  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
    754 }
    755 
    756 TEST_F(ApmTest, StreamParametersInt) {
    757  StreamParametersTest(kIntFormat);
    758 }
    759 
    760 TEST_F(ApmTest, StreamParametersFloat) {
    761  StreamParametersTest(kFloatFormat);
    762 }
    763 
    764 void ApmTest::TestChangingChannelsInt16Interface(
    765    size_t num_channels,
    766    AudioProcessing::Error expected_return) {
    767  frame_.set_num_channels(num_channels);
    768 
    769  EXPECT_EQ(expected_return,
    770            apm_->ProcessStream(
    771                frame_.data.data(),
    772                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
    773                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
    774                frame_.data.data()));
    775  EXPECT_EQ(expected_return,
    776            apm_->ProcessReverseStream(
    777                frame_.data.data(),
    778                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
    779                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
    780                frame_.data.data()));
    781 }
    782 
    783 void ApmTest::TestChangingForwardChannels(
    784    size_t num_in_channels,
    785    size_t num_out_channels,
    786    AudioProcessing::Error expected_return) {
    787  const StreamConfig input_stream = {frame_.sample_rate_hz, num_in_channels};
    788  const StreamConfig output_stream = {output_sample_rate_hz_, num_out_channels};
    789 
    790  EXPECT_EQ(expected_return,
    791            apm_->ProcessStream(float_cb_->channels(), input_stream,
    792                                output_stream, float_cb_->channels()));
    793 }
    794 
    795 void ApmTest::TestChangingReverseChannels(
    796    size_t num_rev_channels,
    797    AudioProcessing::Error expected_return) {
    798  const ProcessingConfig processing_config = {
    799      {{frame_.sample_rate_hz, apm_->num_input_channels()},
    800       {output_sample_rate_hz_, apm_->num_output_channels()},
    801       {frame_.sample_rate_hz, num_rev_channels},
    802       {frame_.sample_rate_hz, num_rev_channels}}};
    803 
    804  EXPECT_EQ(
    805      expected_return,
    806      apm_->ProcessReverseStream(
    807          float_cb_->channels(), processing_config.reverse_input_stream(),
    808          processing_config.reverse_output_stream(), float_cb_->channels()));
    809 }
    810 
    811 TEST_F(ApmTest, ChannelsInt16Interface) {
    812  // Testing number of invalid and valid channels.
    813  Init(16000, 16000, 16000, 4, 4, 4, false);
    814 
    815  TestChangingChannelsInt16Interface(0,
    816                                     AudioProcessing::kBadNumberChannelsError);
    817 
    818  for (size_t i = 1; i < 4; i++) {
    819    TestChangingChannelsInt16Interface(i, AudioProcessing::kNoError);
    820    EXPECT_EQ(i, apm_->num_input_channels());
    821  }
    822 }
    823 
    824 TEST_F(ApmTest, Channels) {
    825  // Testing number of invalid and valid channels.
    826  Init(16000, 16000, 16000, 4, 4, 4, false);
    827 
    828  TestChangingForwardChannels(0, 1, AudioProcessing::kBadNumberChannelsError);
    829  TestChangingReverseChannels(0, AudioProcessing::kBadNumberChannelsError);
    830 
    831  for (size_t i = 1; i < 4; ++i) {
    832    for (size_t j = 0; j < 1; ++j) {
    833      // Output channels much be one or match input channels.
    834      if (j == 1 || i == j) {
    835        TestChangingForwardChannels(i, j, AudioProcessing::kNoError);
    836        TestChangingReverseChannels(i, AudioProcessing::kNoError);
    837 
    838        EXPECT_EQ(i, apm_->num_input_channels());
    839        EXPECT_EQ(j, apm_->num_output_channels());
    840        // The number of reverse channels used for processing to is always 1.
    841        EXPECT_EQ(1u, apm_->num_reverse_channels());
    842      } else {
    843        TestChangingForwardChannels(i, j,
    844                                    AudioProcessing::kBadNumberChannelsError);
    845      }
    846    }
    847  }
    848 }
    849 
    850 TEST_F(ApmTest, SampleRatesInt) {
    851  // Testing some valid sample rates.
    852  for (int sample_rate : {8000, 12000, 16000, 32000, 44100, 48000, 96000}) {
    853    SetContainerFormat(sample_rate, 2, &frame_, &float_cb_);
    854    EXPECT_NOERR(ProcessStreamChooser(kIntFormat));
    855  }
    856 }
    857 
    858 // This test repeatedly reconfigures the pre-amplifier in APM, processes a
    859 // number of frames, and checks that output signal has the right level.
    860 TEST_F(ApmTest, PreAmplifier) {
    861  // Fill the audio frame with a sawtooth pattern.
    862  InterleavedView<int16_t> frame_data = frame_.view();
    863  const size_t samples_per_channel = frame_.samples_per_channel();
    864  for (size_t i = 0; i < samples_per_channel; i++) {
    865    for (size_t ch = 0; ch < frame_.num_channels(); ++ch) {
    866      frame_data[i + ch * samples_per_channel] = 10000 * ((i % 3) - 1);
    867    }
    868  }
    869  // Cache the frame in tmp_frame.
    870  Int16FrameData tmp_frame;
    871  tmp_frame.CopyFrom(frame_);
    872 
    873  auto compute_power = [](const Int16FrameData& frame) {
    874    ArrayView<const int16_t> data = frame.view().data();
    875    return std::accumulate(data.begin(), data.end(), 0.0f,
    876                           [](float a, float b) { return a + b * b; }) /
    877           data.size() / 32768 / 32768;
    878  };
    879 
    880  const float input_power = compute_power(tmp_frame);
    881  // Double-check that the input data is large compared to the error kEpsilon.
    882  constexpr float kEpsilon = 1e-4f;
    883  RTC_DCHECK_GE(input_power, 10 * kEpsilon);
    884 
    885  // 1. Enable pre-amp with 0 dB gain.
    886  AudioProcessing::Config config = apm_->GetConfig();
    887  config.pre_amplifier.enabled = true;
    888  config.pre_amplifier.fixed_gain_factor = 1.0f;
    889  apm_->ApplyConfig(config);
    890 
    891  for (int i = 0; i < 20; ++i) {
    892    frame_.CopyFrom(tmp_frame);
    893    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
    894  }
    895  float output_power = compute_power(frame_);
    896  EXPECT_NEAR(output_power, input_power, kEpsilon);
    897  config = apm_->GetConfig();
    898  EXPECT_EQ(config.pre_amplifier.fixed_gain_factor, 1.0f);
    899 
    900  // 2. Change pre-amp gain via ApplyConfig.
    901  config.pre_amplifier.fixed_gain_factor = 2.0f;
    902  apm_->ApplyConfig(config);
    903 
    904  for (int i = 0; i < 20; ++i) {
    905    frame_.CopyFrom(tmp_frame);
    906    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
    907  }
    908  output_power = compute_power(frame_);
    909  EXPECT_NEAR(output_power, 4 * input_power, kEpsilon);
    910  config = apm_->GetConfig();
    911  EXPECT_EQ(config.pre_amplifier.fixed_gain_factor, 2.0f);
    912 
    913  // 3. Change pre-amp gain via a RuntimeSetting.
    914  apm_->SetRuntimeSetting(
    915      AudioProcessing::RuntimeSetting::CreateCapturePreGain(1.5f));
    916 
    917  for (int i = 0; i < 20; ++i) {
    918    frame_.CopyFrom(tmp_frame);
    919    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
    920  }
    921  output_power = compute_power(frame_);
    922  EXPECT_NEAR(output_power, 2.25 * input_power, kEpsilon);
    923  config = apm_->GetConfig();
    924  EXPECT_EQ(config.pre_amplifier.fixed_gain_factor, 1.5f);
    925 }
    926 
    927 // Ensures that the emulated analog mic gain functionality runs without
    928 // crashing.
    929 TEST_F(ApmTest, AnalogMicGainEmulation) {
    930  // Fill the audio frame with a sawtooth pattern.
    931  InterleavedView<int16_t> frame_data = frame_.view();
    932  const size_t samples_per_channel = frame_.samples_per_channel();
    933  for (size_t i = 0; i < samples_per_channel; i++) {
    934    for (size_t ch = 0; ch < frame_.num_channels(); ++ch) {
    935      frame_data[i + ch * samples_per_channel] = 100 * ((i % 3) - 1);
    936    }
    937  }
    938  // Cache the frame in tmp_frame.
    939  Int16FrameData tmp_frame;
    940  tmp_frame.CopyFrom(frame_);
    941 
    942  // Enable the analog gain emulation.
    943  AudioProcessing::Config config = apm_->GetConfig();
    944  config.capture_level_adjustment.enabled = true;
    945  config.capture_level_adjustment.analog_mic_gain_emulation.enabled = true;
    946  config.capture_level_adjustment.analog_mic_gain_emulation.initial_level = 21;
    947  config.gain_controller1.enabled = true;
    948  config.gain_controller1.mode =
    949      AudioProcessing::Config::GainController1::Mode::kAdaptiveAnalog;
    950  config.gain_controller1.analog_gain_controller.enabled = true;
    951  apm_->ApplyConfig(config);
    952 
    953  // Process a number of frames to ensure that the code runs without crashes.
    954  for (int i = 0; i < 20; ++i) {
    955    frame_.CopyFrom(tmp_frame);
    956    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
    957  }
    958 }
    959 
    960 // This test repeatedly reconfigures the capture level adjustment functionality
    961 // in APM, processes a number of frames, and checks that output signal has the
    962 // right level.
    963 TEST_F(ApmTest, CaptureLevelAdjustment) {
    964  // Fill the audio frame with a sawtooth pattern.
    965  InterleavedView<int16_t> frame_data = frame_.view();
    966  const size_t samples_per_channel = frame_.samples_per_channel();
    967  for (size_t i = 0; i < samples_per_channel; i++) {
    968    for (size_t ch = 0; ch < frame_.num_channels(); ++ch) {
    969      frame_data[i + ch * samples_per_channel] = 100 * ((i % 3) - 1);
    970    }
    971  }
    972  // Cache the frame in tmp_frame.
    973  Int16FrameData tmp_frame;
    974  tmp_frame.CopyFrom(frame_);
    975 
    976  auto compute_power = [](const Int16FrameData& frame) {
    977    ArrayView<const int16_t> data = frame.view().data();
    978    return std::accumulate(data.begin(), data.end(), 0.0f,
    979                           [](float a, float b) { return a + b * b; }) /
    980           data.size() / 32768 / 32768;
    981  };
    982 
    983  const float input_power = compute_power(tmp_frame);
    984  // Double-check that the input data is large compared to the error kEpsilon.
    985  constexpr float kEpsilon = 1e-20f;
    986  RTC_DCHECK_GE(input_power, 10 * kEpsilon);
    987 
    988  // 1. Enable pre-amp with 0 dB gain.
    989  AudioProcessing::Config config = apm_->GetConfig();
    990  config.capture_level_adjustment.enabled = true;
    991  config.capture_level_adjustment.pre_gain_factor = 0.5f;
    992  config.capture_level_adjustment.post_gain_factor = 4.f;
    993  const float expected_output_power1 =
    994      config.capture_level_adjustment.pre_gain_factor *
    995      config.capture_level_adjustment.pre_gain_factor *
    996      config.capture_level_adjustment.post_gain_factor *
    997      config.capture_level_adjustment.post_gain_factor * input_power;
    998  apm_->ApplyConfig(config);
    999 
   1000  for (int i = 0; i < 20; ++i) {
   1001    frame_.CopyFrom(tmp_frame);
   1002    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
   1003  }
   1004  float output_power = compute_power(frame_);
   1005  EXPECT_NEAR(output_power, expected_output_power1, kEpsilon);
   1006  config = apm_->GetConfig();
   1007  EXPECT_EQ(config.capture_level_adjustment.pre_gain_factor, 0.5f);
   1008  EXPECT_EQ(config.capture_level_adjustment.post_gain_factor, 4.f);
   1009 
   1010  // 2. Change pre-amp gain via ApplyConfig.
   1011  config.capture_level_adjustment.pre_gain_factor = 1.0f;
   1012  config.capture_level_adjustment.post_gain_factor = 2.f;
   1013  const float expected_output_power2 =
   1014      config.capture_level_adjustment.pre_gain_factor *
   1015      config.capture_level_adjustment.pre_gain_factor *
   1016      config.capture_level_adjustment.post_gain_factor *
   1017      config.capture_level_adjustment.post_gain_factor * input_power;
   1018  apm_->ApplyConfig(config);
   1019 
   1020  for (int i = 0; i < 20; ++i) {
   1021    frame_.CopyFrom(tmp_frame);
   1022    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
   1023  }
   1024  output_power = compute_power(frame_);
   1025  EXPECT_NEAR(output_power, expected_output_power2, kEpsilon);
   1026  config = apm_->GetConfig();
   1027  EXPECT_EQ(config.capture_level_adjustment.pre_gain_factor, 1.0f);
   1028  EXPECT_EQ(config.capture_level_adjustment.post_gain_factor, 2.f);
   1029 
   1030  // 3. Change pre-amp gain via a RuntimeSetting.
   1031  constexpr float kPreGain3 = 0.5f;
   1032  constexpr float kPostGain3 = 3.f;
   1033  const float expected_output_power3 =
   1034      kPreGain3 * kPreGain3 * kPostGain3 * kPostGain3 * input_power;
   1035 
   1036  apm_->SetRuntimeSetting(
   1037      AudioProcessing::RuntimeSetting::CreateCapturePreGain(kPreGain3));
   1038  apm_->SetRuntimeSetting(
   1039      AudioProcessing::RuntimeSetting::CreateCapturePostGain(kPostGain3));
   1040 
   1041  for (int i = 0; i < 20; ++i) {
   1042    frame_.CopyFrom(tmp_frame);
   1043    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
   1044  }
   1045  output_power = compute_power(frame_);
   1046  EXPECT_NEAR(output_power, expected_output_power3, kEpsilon);
   1047  config = apm_->GetConfig();
   1048  EXPECT_EQ(config.capture_level_adjustment.pre_gain_factor, 0.5f);
   1049  EXPECT_EQ(config.capture_level_adjustment.post_gain_factor, 3.f);
   1050 }
   1051 
   1052 TEST_F(ApmTest, GainControl) {
   1053  AudioProcessing::Config config = apm_->GetConfig();
   1054  config.gain_controller1.enabled = false;
   1055  apm_->ApplyConfig(config);
   1056  config.gain_controller1.enabled = true;
   1057  apm_->ApplyConfig(config);
   1058 
   1059  // Testing gain modes
   1060  for (auto mode :
   1061       {AudioProcessing::Config::GainController1::kAdaptiveDigital,
   1062        AudioProcessing::Config::GainController1::kFixedDigital,
   1063        AudioProcessing::Config::GainController1::kAdaptiveAnalog}) {
   1064    config.gain_controller1.mode = mode;
   1065    apm_->ApplyConfig(config);
   1066    apm_->set_stream_analog_level(100);
   1067    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
   1068  }
   1069 
   1070  // Testing target levels
   1071  for (int target_level_dbfs : {0, 15, 31}) {
   1072    config.gain_controller1.target_level_dbfs = target_level_dbfs;
   1073    apm_->ApplyConfig(config);
   1074    apm_->set_stream_analog_level(100);
   1075    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
   1076  }
   1077 
   1078  // Testing compression gains
   1079  for (int compression_gain_db : {0, 10, 90}) {
   1080    config.gain_controller1.compression_gain_db = compression_gain_db;
   1081    apm_->ApplyConfig(config);
   1082    apm_->set_stream_analog_level(100);
   1083    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
   1084  }
   1085 
   1086  // Testing limiter off/on
   1087  for (bool enable : {false, true}) {
   1088    config.gain_controller1.enable_limiter = enable;
   1089    apm_->ApplyConfig(config);
   1090    apm_->set_stream_analog_level(100);
   1091    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
   1092  }
   1093 
   1094  // Testing level limits.
   1095  constexpr int kMinLevel = 0;
   1096  constexpr int kMaxLevel = 255;
   1097  apm_->set_stream_analog_level(kMinLevel);
   1098  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
   1099  apm_->set_stream_analog_level((kMinLevel + kMaxLevel) / 2);
   1100  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
   1101  apm_->set_stream_analog_level(kMaxLevel);
   1102  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
   1103 }
   1104 
   1105 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
   1106 using ApmDeathTest = ApmTest;
   1107 
   1108 TEST_F(ApmDeathTest, GainControlDiesOnTooLowTargetLevelDbfs) {
   1109  auto config = apm_->GetConfig();
   1110  config.gain_controller1.enabled = true;
   1111  config.gain_controller1.target_level_dbfs = -1;
   1112  EXPECT_DEATH(apm_->ApplyConfig(config), "");
   1113 }
   1114 
   1115 TEST_F(ApmDeathTest, GainControlDiesOnTooHighTargetLevelDbfs) {
   1116  auto config = apm_->GetConfig();
   1117  config.gain_controller1.enabled = true;
   1118  config.gain_controller1.target_level_dbfs = 32;
   1119  EXPECT_DEATH(apm_->ApplyConfig(config), "");
   1120 }
   1121 
   1122 TEST_F(ApmDeathTest, GainControlDiesOnTooLowCompressionGainDb) {
   1123  auto config = apm_->GetConfig();
   1124  config.gain_controller1.enabled = true;
   1125  config.gain_controller1.compression_gain_db = -1;
   1126  EXPECT_DEATH(apm_->ApplyConfig(config), "");
   1127 }
   1128 
   1129 TEST_F(ApmDeathTest, GainControlDiesOnTooHighCompressionGainDb) {
   1130  auto config = apm_->GetConfig();
   1131  config.gain_controller1.enabled = true;
   1132  config.gain_controller1.compression_gain_db = 91;
   1133  EXPECT_DEATH(apm_->ApplyConfig(config), "");
   1134 }
   1135 
   1136 TEST_F(ApmDeathTest, ApmDiesOnTooLowAnalogLevel) {
   1137  auto config = apm_->GetConfig();
   1138  config.gain_controller1.enabled = true;
   1139  apm_->ApplyConfig(config);
   1140  EXPECT_DEATH(apm_->set_stream_analog_level(-1), "");
   1141 }
   1142 
   1143 TEST_F(ApmDeathTest, ApmDiesOnTooHighAnalogLevel) {
   1144  auto config = apm_->GetConfig();
   1145  config.gain_controller1.enabled = true;
   1146  apm_->ApplyConfig(config);
   1147  EXPECT_DEATH(apm_->set_stream_analog_level(256), "");
   1148 }
   1149 #endif
   1150 
   1151 void ApmTest::RunQuantizedVolumeDoesNotGetStuckTest(int sample_rate) {
   1152  Init(sample_rate, sample_rate, sample_rate, 2, 2, 2, false);
   1153  auto config = apm_->GetConfig();
   1154  config.gain_controller1.enabled = true;
   1155  config.gain_controller1.mode =
   1156      AudioProcessing::Config::GainController1::kAdaptiveAnalog;
   1157  apm_->ApplyConfig(config);
   1158 
   1159  int out_analog_level = 0;
   1160  for (int i = 0; i < 2000; ++i) {
   1161    ReadFrameWithRewind(near_file_, &frame_);
   1162    // Ensure the audio is at a low level, so the AGC will try to increase it.
   1163    frame_.Scale(0.25f);
   1164 
   1165    // Always pass in the same volume.
   1166    apm_->set_stream_analog_level(100);
   1167    EXPECT_EQ(AudioProcessing::kNoError,
   1168              apm_->ProcessStream(
   1169                  frame_.data.data(),
   1170                  StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1171                  StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1172                  frame_.data.data()));
   1173    out_analog_level = apm_->recommended_stream_analog_level();
   1174  }
   1175 
   1176  // Ensure the AGC is still able to reach the maximum.
   1177  EXPECT_EQ(255, out_analog_level);
   1178 }
   1179 
   1180 // Verifies that despite volume slider quantization, the AGC can continue to
   1181 // increase its volume.
   1182 TEST_F(ApmTest, QuantizedVolumeDoesNotGetStuck) {
   1183  for (size_t sample_rate_hz : kProcessSampleRates) {
   1184    SCOPED_TRACE(::testing::Message() << "sample_rate_hz=" << sample_rate_hz);
   1185    RunQuantizedVolumeDoesNotGetStuckTest(sample_rate_hz);
   1186  }
   1187 }
   1188 
   1189 void ApmTest::RunManualVolumeChangeIsPossibleTest(int sample_rate) {
   1190  Init(sample_rate, sample_rate, sample_rate, 2, 2, 2, false);
   1191  auto config = apm_->GetConfig();
   1192  config.gain_controller1.enabled = true;
   1193  config.gain_controller1.mode =
   1194      AudioProcessing::Config::GainController1::kAdaptiveAnalog;
   1195  apm_->ApplyConfig(config);
   1196 
   1197  int out_analog_level = 100;
   1198  for (int i = 0; i < 1000; ++i) {
   1199    ReadFrameWithRewind(near_file_, &frame_);
   1200    // Ensure the audio is at a low level, so the AGC will try to increase it.
   1201    frame_.Scale(0.25f);
   1202 
   1203    apm_->set_stream_analog_level(out_analog_level);
   1204    EXPECT_EQ(AudioProcessing::kNoError,
   1205              apm_->ProcessStream(
   1206                  frame_.data.data(),
   1207                  StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1208                  StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1209                  frame_.data.data()));
   1210    out_analog_level = apm_->recommended_stream_analog_level();
   1211  }
   1212 
   1213  // Ensure the volume was raised.
   1214  EXPECT_GT(out_analog_level, 100);
   1215  int highest_level_reached = out_analog_level;
   1216  // Simulate a user manual volume change.
   1217  out_analog_level = 100;
   1218 
   1219  for (int i = 0; i < 300; ++i) {
   1220    ReadFrameWithRewind(near_file_, &frame_);
   1221    frame_.Scale(0.25f);
   1222 
   1223    apm_->set_stream_analog_level(out_analog_level);
   1224    EXPECT_EQ(AudioProcessing::kNoError,
   1225              apm_->ProcessStream(
   1226                  frame_.data.data(),
   1227                  StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1228                  StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1229                  frame_.data.data()));
   1230    out_analog_level = apm_->recommended_stream_analog_level();
   1231    // Check that AGC respected the manually adjusted volume.
   1232    EXPECT_LT(out_analog_level, highest_level_reached);
   1233  }
   1234  // Check that the volume was still raised.
   1235  EXPECT_GT(out_analog_level, 100);
   1236 }
   1237 
   1238 TEST_F(ApmTest, ManualVolumeChangeIsPossible) {
   1239  for (size_t sample_rate_hz : kProcessSampleRates) {
   1240    SCOPED_TRACE(::testing::Message() << "sample_rate_hz=" << sample_rate_hz);
   1241    RunManualVolumeChangeIsPossibleTest(sample_rate_hz);
   1242  }
   1243 }
   1244 
   1245 TEST_F(ApmTest, HighPassFilter) {
   1246  // Turn HP filter on/off
   1247  AudioProcessing::Config apm_config;
   1248  apm_config.high_pass_filter.enabled = true;
   1249  apm_->ApplyConfig(apm_config);
   1250  apm_config.high_pass_filter.enabled = false;
   1251  apm_->ApplyConfig(apm_config);
   1252 }
   1253 
   1254 TEST_F(ApmTest, AllProcessingDisabledByDefault) {
   1255  AudioProcessing::Config config = apm_->GetConfig();
   1256  EXPECT_FALSE(config.echo_canceller.enabled);
   1257  EXPECT_FALSE(config.high_pass_filter.enabled);
   1258  EXPECT_FALSE(config.gain_controller1.enabled);
   1259  EXPECT_FALSE(config.noise_suppression.enabled);
   1260 }
   1261 
   1262 TEST_F(ApmTest, NoProcessingWhenAllComponentsDisabledInt) {
   1263  // Test that ProcessStream simply copies input to output when all components
   1264  // are disabled.
   1265  // Runs over all processing rates, and some particularly common or special
   1266  // rates.
   1267  // - 8000 Hz: lowest sample rate seen in Chrome metrics,
   1268  // - 22050 Hz: APM input/output frames are not exactly 10 ms,
   1269  // - 44100 Hz: very common desktop sample rate.
   1270  constexpr int kSampleRatesHz[] = {8000, 16000, 22050, 32000, 44100, 48000};
   1271  for (size_t sample_rate_hz : kSampleRatesHz) {
   1272    SCOPED_TRACE(::testing::Message() << "sample_rate_hz=" << sample_rate_hz);
   1273    Init(sample_rate_hz, sample_rate_hz, sample_rate_hz, 2, 2, 2, false);
   1274    frame_.FillStereoData(1000, 2000);
   1275    Int16FrameData frame_copy;
   1276    frame_copy.CopyFrom(frame_);
   1277    for (int j = 0; j < 1000; j++) {
   1278      EXPECT_EQ(AudioProcessing::kNoError,
   1279                apm_->ProcessStream(
   1280                    frame_.data.data(),
   1281                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1282                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1283                    frame_.data.data()));
   1284      EXPECT_TRUE(frame_.IsEqual(frame_copy));
   1285      EXPECT_EQ(AudioProcessing::kNoError,
   1286                apm_->ProcessReverseStream(
   1287                    frame_.data.data(),
   1288                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1289                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1290                    frame_.data.data()));
   1291      EXPECT_TRUE(frame_.IsEqual(frame_copy));
   1292    }
   1293  }
   1294 }
   1295 
   1296 TEST_F(ApmTest, NoProcessingWhenAllComponentsDisabledFloat) {
   1297  // Test that ProcessStream simply copies input to output when all components
   1298  // are disabled.
   1299  const size_t kSamples = 160;
   1300  const int sample_rate = 16000;
   1301  const float src[kSamples] = {-1.0f, 0.0f, 1.0f};
   1302  float dest[kSamples] = {};
   1303 
   1304  auto src_channels = &src[0];
   1305  auto dest_channels = &dest[0];
   1306 
   1307  apm_ = BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
   1308  EXPECT_NOERR(apm_->ProcessStream(&src_channels, StreamConfig(sample_rate, 1),
   1309                                   StreamConfig(sample_rate, 1),
   1310                                   &dest_channels));
   1311 
   1312  for (size_t i = 0; i < kSamples; ++i) {
   1313    EXPECT_EQ(src[i], dest[i]);
   1314  }
   1315 
   1316  // Same for ProcessReverseStream.
   1317  float rev_dest[kSamples] = {};
   1318  auto rev_dest_channels = &rev_dest[0];
   1319 
   1320  StreamConfig input_stream = {sample_rate, 1};
   1321  StreamConfig output_stream = {sample_rate, 1};
   1322  EXPECT_NOERR(apm_->ProcessReverseStream(&src_channels, input_stream,
   1323                                          output_stream, &rev_dest_channels));
   1324 
   1325  for (size_t i = 0; i < kSamples; ++i) {
   1326    EXPECT_EQ(src[i], rev_dest[i]);
   1327  }
   1328 }
   1329 
   1330 TEST_F(ApmTest, IdenticalInputChannelsResultInIdenticalOutputChannels) {
   1331  EnableAllComponents();
   1332 
   1333  for (int sample_rate_hz : kProcessSampleRates) {
   1334    Init(sample_rate_hz, sample_rate_hz, sample_rate_hz, 2, 2, 2, false);
   1335    int analog_level = 127;
   1336    ASSERT_EQ(0, feof(far_file_));
   1337    ASSERT_EQ(0, feof(near_file_));
   1338    while (ReadFrame(far_file_, &revframe_) && ReadFrame(near_file_, &frame_)) {
   1339      CopyLeftToRightChannel(revframe_.data.data(),
   1340                             revframe_.samples_per_channel());
   1341 
   1342      ASSERT_EQ(
   1343          AudioProcessing::kNoError,
   1344          apm_->ProcessReverseStream(
   1345              revframe_.data.data(),
   1346              StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
   1347              StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
   1348              revframe_.data.data()));
   1349 
   1350      CopyLeftToRightChannel(frame_.data.data(), frame_.samples_per_channel());
   1351 
   1352      ASSERT_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(0));
   1353      apm_->set_stream_analog_level(analog_level);
   1354      ASSERT_EQ(AudioProcessing::kNoError,
   1355                apm_->ProcessStream(
   1356                    frame_.data.data(),
   1357                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1358                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1359                    frame_.data.data()));
   1360      analog_level = apm_->recommended_stream_analog_level();
   1361 
   1362      VerifyChannelsAreEqual(frame_.data.data(), frame_.samples_per_channel());
   1363    }
   1364    rewind(far_file_);
   1365    rewind(near_file_);
   1366  }
   1367 }
   1368 
   1369 TEST_F(ApmTest, SplittingFilter) {
   1370  // Verify the filter is not active through undistorted audio when:
   1371  // 1. No components are enabled...
   1372  frame_.FillData(1000);
   1373  Int16FrameData frame_copy;
   1374  frame_copy.CopyFrom(frame_);
   1375  EXPECT_EQ(AudioProcessing::kNoError,
   1376            apm_->ProcessStream(
   1377                frame_.data.data(),
   1378                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1379                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1380                frame_.data.data()));
   1381  EXPECT_EQ(AudioProcessing::kNoError,
   1382            apm_->ProcessStream(
   1383                frame_.data.data(),
   1384                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1385                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1386                frame_.data.data()));
   1387  EXPECT_TRUE(frame_.IsEqual(frame_copy));
   1388 
   1389  // 2. Only the level estimator is enabled...
   1390  auto apm_config = apm_->GetConfig();
   1391  frame_.FillData(1000);
   1392  frame_copy.CopyFrom(frame_);
   1393  apm_->ApplyConfig(apm_config);
   1394  EXPECT_EQ(AudioProcessing::kNoError,
   1395            apm_->ProcessStream(
   1396                frame_.data.data(),
   1397                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1398                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1399                frame_.data.data()));
   1400  EXPECT_EQ(AudioProcessing::kNoError,
   1401            apm_->ProcessStream(
   1402                frame_.data.data(),
   1403                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1404                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1405                frame_.data.data()));
   1406  EXPECT_TRUE(frame_.IsEqual(frame_copy));
   1407  apm_->ApplyConfig(apm_config);
   1408 
   1409  // Check the test is valid. We should have distortion from the filter
   1410  // when AEC is enabled (which won't affect the audio).
   1411  apm_config.echo_canceller.enabled = true;
   1412  apm_config.echo_canceller.mobile_mode = false;
   1413  apm_->ApplyConfig(apm_config);
   1414  frame_.SetProperties(/* samples_per_channel=*/320, /* num_channels=*/2);
   1415  frame_.FillData(1000);
   1416  frame_copy.CopyFrom(frame_);
   1417  EXPECT_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(0));
   1418  EXPECT_EQ(AudioProcessing::kNoError,
   1419            apm_->ProcessStream(
   1420                frame_.data.data(),
   1421                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1422                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1423                frame_.data.data()));
   1424  EXPECT_FALSE(frame_.IsEqual(frame_copy));
   1425 }
   1426 
   1427 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
   1428 void ApmTest::ProcessDebugDump(absl::string_view in_filename,
   1429                               absl::string_view out_filename,
   1430                               Format format,
   1431                               int max_size_bytes) {
   1432  TaskQueueForTest worker_queue("ApmTest_worker_queue");
   1433  FILE* in_file = fopen(std::string(in_filename).c_str(), "rb");
   1434  ASSERT_TRUE(in_file != nullptr);
   1435  audioproc::Event event_msg;
   1436  bool first_init = true;
   1437 
   1438  while (ReadMessageFromFile(in_file, &event_msg)) {
   1439    if (event_msg.type() == audioproc::Event::INIT) {
   1440      const audioproc::Init msg = event_msg.init();
   1441      int reverse_sample_rate = msg.sample_rate();
   1442      if (msg.has_reverse_sample_rate()) {
   1443        reverse_sample_rate = msg.reverse_sample_rate();
   1444      }
   1445      int output_sample_rate = msg.sample_rate();
   1446      if (msg.has_output_sample_rate()) {
   1447        output_sample_rate = msg.output_sample_rate();
   1448      }
   1449 
   1450      Init(msg.sample_rate(), output_sample_rate, reverse_sample_rate,
   1451           msg.num_input_channels(), msg.num_output_channels(),
   1452           msg.num_reverse_channels(), false);
   1453      if (first_init) {
   1454        // AttachAecDump() writes an additional init message. Don't start
   1455        // recording until after the first init to avoid the extra message.
   1456        auto aec_dump = AecDumpFactory::Create(out_filename, max_size_bytes,
   1457                                               worker_queue.Get());
   1458        EXPECT_TRUE(aec_dump);
   1459        apm_->AttachAecDump(std::move(aec_dump));
   1460        first_init = false;
   1461      }
   1462 
   1463    } else if (event_msg.type() == audioproc::Event::REVERSE_STREAM) {
   1464      const audioproc::ReverseStream msg = event_msg.reverse_stream();
   1465 
   1466      if (msg.channel_size() > 0) {
   1467        ASSERT_EQ(revframe_.num_channels(),
   1468                  static_cast<size_t>(msg.channel_size()));
   1469        for (int i = 0; i < msg.channel_size(); ++i) {
   1470          memcpy(revfloat_cb_->channels()[i], msg.channel(i).data(),
   1471                 msg.channel(i).size());
   1472        }
   1473      } else {
   1474        memcpy(revframe_.data.data(), msg.data().data(), msg.data().size());
   1475        if (format == kFloatFormat) {
   1476          // We're using an int16 input file; convert to float.
   1477          ConvertToFloat(revframe_, revfloat_cb_.get());
   1478        }
   1479      }
   1480      AnalyzeReverseStreamChooser(format);
   1481 
   1482    } else if (event_msg.type() == audioproc::Event::STREAM) {
   1483      const audioproc::Stream msg = event_msg.stream();
   1484      // ProcessStream could have changed this for the output frame.
   1485      frame_.set_num_channels(apm_->num_input_channels());
   1486 
   1487      apm_->set_stream_analog_level(msg.applied_input_volume());
   1488      EXPECT_NOERR(apm_->set_stream_delay_ms(msg.delay()));
   1489      if (msg.has_keypress()) {
   1490        apm_->set_stream_key_pressed(msg.keypress());
   1491      } else {
   1492        apm_->set_stream_key_pressed(true);
   1493      }
   1494 
   1495      if (msg.input_channel_size() > 0) {
   1496        ASSERT_EQ(frame_.num_channels(),
   1497                  static_cast<size_t>(msg.input_channel_size()));
   1498        for (int i = 0; i < msg.input_channel_size(); ++i) {
   1499          memcpy(float_cb_->channels()[i], msg.input_channel(i).data(),
   1500                 msg.input_channel(i).size());
   1501        }
   1502      } else {
   1503        memcpy(frame_.data.data(), msg.input_data().data(),
   1504               msg.input_data().size());
   1505        if (format == kFloatFormat) {
   1506          // We're using an int16 input file; convert to float.
   1507          ConvertToFloat(frame_, float_cb_.get());
   1508        }
   1509      }
   1510      ProcessStreamChooser(format);
   1511    }
   1512  }
   1513  apm_->DetachAecDump();
   1514  fclose(in_file);
   1515 }
   1516 
   1517 void ApmTest::VerifyDebugDumpTest(Format format) {
   1518  ScopedFakeClock fake_clock;
   1519  const std::string in_filename = test::ResourcePath("ref03", "aecdump");
   1520  std::string format_string;
   1521  switch (format) {
   1522    case kIntFormat:
   1523      format_string = "_int";
   1524      break;
   1525    case kFloatFormat:
   1526      format_string = "_float";
   1527      break;
   1528  }
   1529  const std::string ref_filename = test::TempFilename(
   1530      test::OutputPath(), std::string("ref") + format_string + "_aecdump");
   1531  const std::string out_filename = test::TempFilename(
   1532      test::OutputPath(), std::string("out") + format_string + "_aecdump");
   1533  const std::string limited_filename = test::TempFilename(
   1534      test::OutputPath(), std::string("limited") + format_string + "_aecdump");
   1535  const size_t logging_limit_bytes = 100000;
   1536  // We expect at least this many bytes in the created logfile.
   1537  const size_t logging_expected_bytes = 95000;
   1538  EnableAllComponents();
   1539  ProcessDebugDump(in_filename, ref_filename, format, -1);
   1540  ProcessDebugDump(ref_filename, out_filename, format, -1);
   1541  ProcessDebugDump(ref_filename, limited_filename, format, logging_limit_bytes);
   1542 
   1543  FILE* ref_file = fopen(ref_filename.c_str(), "rb");
   1544  FILE* out_file = fopen(out_filename.c_str(), "rb");
   1545  FILE* limited_file = fopen(limited_filename.c_str(), "rb");
   1546  ASSERT_TRUE(ref_file != nullptr);
   1547  ASSERT_TRUE(out_file != nullptr);
   1548  ASSERT_TRUE(limited_file != nullptr);
   1549  std::unique_ptr<uint8_t[]> ref_bytes;
   1550  std::unique_ptr<uint8_t[]> out_bytes;
   1551  std::unique_ptr<uint8_t[]> limited_bytes;
   1552 
   1553  size_t ref_size = ReadMessageBytesFromFile(ref_file, &ref_bytes);
   1554  size_t out_size = ReadMessageBytesFromFile(out_file, &out_bytes);
   1555  size_t limited_size = ReadMessageBytesFromFile(limited_file, &limited_bytes);
   1556  size_t bytes_read = 0;
   1557  size_t bytes_read_limited = 0;
   1558  while (ref_size > 0 && out_size > 0) {
   1559    bytes_read += ref_size;
   1560    bytes_read_limited += limited_size;
   1561    EXPECT_EQ(ref_size, out_size);
   1562    EXPECT_GE(ref_size, limited_size);
   1563    EXPECT_TRUE(ExpectMessageEq(/*actual=*/{out_bytes.get(), out_size},
   1564                                /*expected=*/{ref_bytes.get(), ref_size}));
   1565    if (limited_size > 0) {
   1566      EXPECT_TRUE(
   1567          ExpectMessageEq(/*actual=*/{limited_bytes.get(), limited_size},
   1568                          /*expected=*/{ref_bytes.get(), ref_size}));
   1569    }
   1570    ref_size = ReadMessageBytesFromFile(ref_file, &ref_bytes);
   1571    out_size = ReadMessageBytesFromFile(out_file, &out_bytes);
   1572    limited_size = ReadMessageBytesFromFile(limited_file, &limited_bytes);
   1573  }
   1574  EXPECT_GT(bytes_read, 0u);
   1575  EXPECT_GT(bytes_read_limited, logging_expected_bytes);
   1576  EXPECT_LE(bytes_read_limited, logging_limit_bytes);
   1577  EXPECT_NE(0, feof(ref_file));
   1578  EXPECT_NE(0, feof(out_file));
   1579  EXPECT_NE(0, feof(limited_file));
   1580  ASSERT_EQ(0, fclose(ref_file));
   1581  ASSERT_EQ(0, fclose(out_file));
   1582  ASSERT_EQ(0, fclose(limited_file));
   1583  remove(ref_filename.c_str());
   1584  remove(out_filename.c_str());
   1585  remove(limited_filename.c_str());
   1586 }
   1587 
   1588 TEST_F(ApmTest, VerifyDebugDumpInt) {
   1589  VerifyDebugDumpTest(kIntFormat);
   1590 }
   1591 
   1592 TEST_F(ApmTest, VerifyDebugDumpFloat) {
   1593  VerifyDebugDumpTest(kFloatFormat);
   1594 }
   1595 #endif
   1596 
   1597 // TODO(andrew): expand test to verify output.
   1598 TEST_F(ApmTest, DebugDump) {
   1599  TaskQueueForTest worker_queue("ApmTest_worker_queue");
   1600  const std::string filename =
   1601      test::TempFilename(test::OutputPath(), "debug_aec");
   1602  {
   1603    auto aec_dump = AecDumpFactory::Create("", -1, worker_queue.Get());
   1604    EXPECT_FALSE(aec_dump);
   1605  }
   1606 
   1607 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
   1608  // Stopping without having started should be OK.
   1609  apm_->DetachAecDump();
   1610 
   1611  auto aec_dump = AecDumpFactory::Create(filename, -1, worker_queue.Get());
   1612  EXPECT_TRUE(aec_dump);
   1613  apm_->AttachAecDump(std::move(aec_dump));
   1614  EXPECT_EQ(AudioProcessing::kNoError,
   1615            apm_->ProcessStream(
   1616                frame_.data.data(),
   1617                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1618                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1619                frame_.data.data()));
   1620  EXPECT_EQ(
   1621      AudioProcessing::kNoError,
   1622      apm_->ProcessReverseStream(
   1623          revframe_.data.data(),
   1624          StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
   1625          StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
   1626          revframe_.data.data()));
   1627  apm_->DetachAecDump();
   1628 
   1629  // Verify the file has been written.
   1630  FILE* fid = fopen(filename.c_str(), "r");
   1631  ASSERT_TRUE(fid != nullptr);
   1632 
   1633  // Clean it up.
   1634  ASSERT_EQ(0, fclose(fid));
   1635  ASSERT_EQ(0, remove(filename.c_str()));
   1636 #else
   1637  // Verify the file has NOT been written.
   1638  ASSERT_TRUE(fopen(filename.c_str(), "r") == NULL);
   1639 #endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
   1640 }
   1641 
   1642 // TODO(andrew): expand test to verify output.
   1643 TEST_F(ApmTest, DebugDumpFromFileHandle) {
   1644  TaskQueueForTest worker_queue("ApmTest_worker_queue");
   1645 
   1646  const std::string filename =
   1647      test::TempFilename(test::OutputPath(), "debug_aec");
   1648  FileWrapper f = FileWrapper::OpenWriteOnly(filename);
   1649  ASSERT_TRUE(f.is_open());
   1650 
   1651 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
   1652  // Stopping without having started should be OK.
   1653  apm_->DetachAecDump();
   1654 
   1655  auto aec_dump = AecDumpFactory::Create(std::move(f), -1, worker_queue.Get());
   1656  EXPECT_TRUE(aec_dump);
   1657  apm_->AttachAecDump(std::move(aec_dump));
   1658  EXPECT_EQ(
   1659      AudioProcessing::kNoError,
   1660      apm_->ProcessReverseStream(
   1661          revframe_.data.data(),
   1662          StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
   1663          StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
   1664          revframe_.data.data()));
   1665  EXPECT_EQ(AudioProcessing::kNoError,
   1666            apm_->ProcessStream(
   1667                frame_.data.data(),
   1668                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1669                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1670                frame_.data.data()));
   1671  apm_->DetachAecDump();
   1672 
   1673  // Verify the file has been written.
   1674  FILE* fid = fopen(filename.c_str(), "r");
   1675  ASSERT_TRUE(fid != nullptr);
   1676 
   1677  // Clean it up.
   1678  ASSERT_EQ(0, fclose(fid));
   1679  ASSERT_EQ(0, remove(filename.c_str()));
   1680 #endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
   1681 }
   1682 
   1683 // TODO(andrew): Add a test to process a few frames with different combinations
   1684 // of enabled components.
   1685 
   1686 TEST_F(ApmTest, Process) {
   1687  audioproc::OutputData ref_data;
   1688 
   1689  if (!absl::GetFlag(FLAGS_write_apm_ref_data)) {
   1690    OpenFileAndReadMessage(ref_filename_, &ref_data);
   1691  } else {
   1692    const int kChannels[] = {1, 2};
   1693    // Write the desired tests to the protobuf reference file.
   1694    for (int num_reverse_channels : kChannels) {
   1695      for (int num_channels : kChannels) {
   1696        for (int sample_rate_hz : AudioProcessing::kNativeSampleRatesHz) {
   1697          audioproc::Test* test = ref_data.add_test();
   1698          test->set_num_reverse_channels(num_reverse_channels);
   1699          test->set_num_input_channels(num_channels);
   1700          test->set_num_output_channels(num_channels);
   1701          test->set_sample_rate(sample_rate_hz);
   1702          test->set_use_aec_extended_filter(false);
   1703        }
   1704      }
   1705    }
   1706 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
   1707    // To test the extended filter mode.
   1708    audioproc::Test* test = ref_data.add_test();
   1709    test->set_num_reverse_channels(2);
   1710    test->set_num_input_channels(2);
   1711    test->set_num_output_channels(2);
   1712    test->set_sample_rate(AudioProcessing::kSampleRate32kHz);
   1713    test->set_use_aec_extended_filter(true);
   1714 #endif
   1715  }
   1716 
   1717  for (int i = 0; i < ref_data.test_size(); i++) {
   1718    printf("Running test %d of %d...\n", i + 1, ref_data.test_size());
   1719 
   1720    audioproc::Test* test = ref_data.mutable_test(i);
   1721    // TODO(ajm): We no longer allow different input and output channels. Skip
   1722    // these tests for now, but they should be removed from the set.
   1723    if (test->num_input_channels() != test->num_output_channels())
   1724      continue;
   1725 
   1726    apm_ = BuiltinAudioProcessingBuilder()
   1727               .SetEchoDetector(CreateEchoDetector())
   1728               .Build(CreateEnvironment());
   1729    AudioProcessing::Config apm_config = apm_->GetConfig();
   1730    apm_config.gain_controller1.analog_gain_controller.enabled = false;
   1731    apm_->ApplyConfig(apm_config);
   1732 
   1733    EnableAllComponents();
   1734 
   1735    Init(test->sample_rate(), test->sample_rate(), test->sample_rate(),
   1736         static_cast<size_t>(test->num_input_channels()),
   1737         static_cast<size_t>(test->num_output_channels()),
   1738         static_cast<size_t>(test->num_reverse_channels()), true);
   1739 
   1740    int frame_count = 0;
   1741    int analog_level = 127;
   1742    int analog_level_average = 0;
   1743    int max_output_average = 0;
   1744 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
   1745    int stats_index = 0;
   1746 #endif
   1747 
   1748    while (ReadFrame(far_file_, &revframe_) && ReadFrame(near_file_, &frame_)) {
   1749      EXPECT_EQ(
   1750          AudioProcessing::kNoError,
   1751          apm_->ProcessReverseStream(
   1752              revframe_.data.data(),
   1753              StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
   1754              StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
   1755              revframe_.data.data()));
   1756 
   1757      EXPECT_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(0));
   1758      apm_->set_stream_analog_level(analog_level);
   1759 
   1760      EXPECT_EQ(AudioProcessing::kNoError,
   1761                apm_->ProcessStream(
   1762                    frame_.data.data(),
   1763                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1764                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
   1765                    frame_.data.data()));
   1766 
   1767      // Ensure the frame was downmixed properly.
   1768      EXPECT_EQ(static_cast<size_t>(test->num_output_channels()),
   1769                frame_.num_channels());
   1770 
   1771      max_output_average += MaxAudioFrame(frame_);
   1772 
   1773      analog_level = apm_->recommended_stream_analog_level();
   1774      analog_level_average += analog_level;
   1775      AudioProcessingStats stats = apm_->GetStatistics();
   1776 
   1777      size_t write_count =
   1778          fwrite(frame_.data.data(), sizeof(int16_t), frame_.size(), out_file_);
   1779      ASSERT_EQ(frame_.size(), write_count);
   1780 
   1781      // Reset in case of downmixing.
   1782      frame_.set_num_channels(static_cast<size_t>(test->num_input_channels()));
   1783      frame_count++;
   1784 
   1785 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
   1786      const int kStatsAggregationFrameNum = 100;  // 1 second.
   1787      if (frame_count % kStatsAggregationFrameNum == 0) {
   1788        // Get echo and delay metrics.
   1789        AudioProcessingStats stats2 = apm_->GetStatistics();
   1790 
   1791        // Echo metrics.
   1792        const float echo_return_loss = stats2.echo_return_loss.value_or(-1.0f);
   1793        const float echo_return_loss_enhancement =
   1794            stats2.echo_return_loss_enhancement.value_or(-1.0f);
   1795        const float residual_echo_likelihood =
   1796            stats2.residual_echo_likelihood.value_or(-1.0f);
   1797        const float residual_echo_likelihood_recent_max =
   1798            stats2.residual_echo_likelihood_recent_max.value_or(-1.0f);
   1799 
   1800        if (!absl::GetFlag(FLAGS_write_apm_ref_data)) {
   1801          const audioproc::Test::EchoMetrics& reference =
   1802              test->echo_metrics(stats_index);
   1803          constexpr float kEpsilon = 0.01;
   1804          EXPECT_NEAR(echo_return_loss, reference.echo_return_loss(), kEpsilon);
   1805          EXPECT_NEAR(echo_return_loss_enhancement,
   1806                      reference.echo_return_loss_enhancement(), kEpsilon);
   1807          EXPECT_NEAR(residual_echo_likelihood,
   1808                      reference.residual_echo_likelihood(), kEpsilon);
   1809          EXPECT_NEAR(residual_echo_likelihood_recent_max,
   1810                      reference.residual_echo_likelihood_recent_max(),
   1811                      kEpsilon);
   1812          ++stats_index;
   1813        } else {
   1814          audioproc::Test::EchoMetrics* message_echo = test->add_echo_metrics();
   1815          message_echo->set_echo_return_loss(echo_return_loss);
   1816          message_echo->set_echo_return_loss_enhancement(
   1817              echo_return_loss_enhancement);
   1818          message_echo->set_residual_echo_likelihood(residual_echo_likelihood);
   1819          message_echo->set_residual_echo_likelihood_recent_max(
   1820              residual_echo_likelihood_recent_max);
   1821        }
   1822      }
   1823 #endif  // defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE).
   1824    }
   1825    max_output_average /= frame_count;
   1826    analog_level_average /= frame_count;
   1827 
   1828    if (!absl::GetFlag(FLAGS_write_apm_ref_data)) {
   1829      const int kIntNear = 1;
   1830      // All numbers being consistently higher on N7 compare to the reference
   1831      // data.
   1832      // TODO(bjornv): If we start getting more of these offsets on Android we
   1833      // should consider a different approach. Either using one slack for all,
   1834      // or generate a separate android reference.
   1835 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
   1836      const int kMaxOutputAverageOffset = 9;
   1837      const int kMaxOutputAverageNear = 26;
   1838 #else
   1839      const int kMaxOutputAverageOffset = 0;
   1840      const int kMaxOutputAverageNear = 7;
   1841 #endif
   1842      EXPECT_NEAR(test->analog_level_average(), analog_level_average, kIntNear);
   1843      EXPECT_NEAR(test->max_output_average(),
   1844                  max_output_average - kMaxOutputAverageOffset,
   1845                  kMaxOutputAverageNear);
   1846    } else {
   1847      test->set_analog_level_average(analog_level_average);
   1848      test->set_max_output_average(max_output_average);
   1849    }
   1850 
   1851    rewind(far_file_);
   1852    rewind(near_file_);
   1853  }
   1854 
   1855  if (absl::GetFlag(FLAGS_write_apm_ref_data)) {
   1856    OpenFileAndWriteMessage(ref_filename_, ref_data);
   1857  }
   1858 }
   1859 
   1860 // Compares the reference and test arrays over a region around the expected
   1861 // delay. Finds the highest SNR in that region and adds the variance and squared
   1862 // error results to the supplied accumulators.
   1863 void UpdateBestSNR(const float* ref,
   1864                   const float* test,
   1865                   size_t length,
   1866                   int expected_delay,
   1867                   double* variance_acc,
   1868                   double* sq_error_acc) {
   1869  RTC_CHECK_LT(expected_delay, length)
   1870      << "delay greater than signal length, cannot compute SNR";
   1871  double best_snr = std::numeric_limits<double>::min();
   1872  double best_variance = 0;
   1873  double best_sq_error = 0;
   1874  // Search over a region of nine samples around the expected delay.
   1875  for (int delay = std::max(expected_delay - 4, 0); delay <= expected_delay + 4;
   1876       ++delay) {
   1877    double sq_error = 0;
   1878    double variance = 0;
   1879    for (size_t i = 0; i < length - delay; ++i) {
   1880      double error = test[i + delay] - ref[i];
   1881      sq_error += error * error;
   1882      variance += ref[i] * ref[i];
   1883    }
   1884 
   1885    if (sq_error == 0) {
   1886      *variance_acc += variance;
   1887      return;
   1888    }
   1889    double snr = variance / sq_error;
   1890    if (snr > best_snr) {
   1891      best_snr = snr;
   1892      best_variance = variance;
   1893      best_sq_error = sq_error;
   1894    }
   1895  }
   1896 
   1897  *variance_acc += best_variance;
   1898  *sq_error_acc += best_sq_error;
   1899 }
   1900 
   1901 // Used to test a multitude of sample rate and channel combinations. It works
   1902 // by first producing a set of reference files (in SetUpTestCase) that are
   1903 // assumed to be correct, as the used parameters are verified by other tests
   1904 // in this collection. Primarily the reference files are all produced at
   1905 // "native" rates which do not involve any resampling.
   1906 
   1907 // Each test pass produces an output file with a particular format. The output
   1908 // is matched against the reference file closest to its internal processing
   1909 // format. If necessary the output is resampled back to its process format.
   1910 // Due to the resampling distortion, we don't expect identical results, but
   1911 // enforce SNR thresholds which vary depending on the format. 0 is a special
   1912 // case SNR which corresponds to inf, or zero error.
   1913 typedef std::tuple<int, int, int, int, double, double> AudioProcessingTestData;
   1914 class AudioProcessingTest
   1915    : public ::testing::TestWithParam<AudioProcessingTestData> {
   1916 public:
   1917  AudioProcessingTest()
   1918      : input_rate_(std::get<0>(GetParam())),
   1919        output_rate_(std::get<1>(GetParam())),
   1920        reverse_input_rate_(std::get<2>(GetParam())),
   1921        reverse_output_rate_(std::get<3>(GetParam())),
   1922        expected_snr_(std::get<4>(GetParam())),
   1923        expected_reverse_snr_(std::get<5>(GetParam())) {}
   1924 
   1925  ~AudioProcessingTest() override {}
   1926 
   1927  static void SetUpTestSuite() {
   1928    // Create all needed output reference files.
   1929    const size_t kNumChannels[] = {1, 2};
   1930    for (int sample_rate_hz : kProcessSampleRates) {
   1931      for (int num_channels : kNumChannels) {
   1932        for (int num_reverse_channels : kNumChannels) {
   1933          // The reference files always have matching input and output channels.
   1934          ProcessFormat(sample_rate_hz, sample_rate_hz, sample_rate_hz,
   1935                        sample_rate_hz, num_channels, num_channels,
   1936                        num_reverse_channels, num_reverse_channels, "ref");
   1937        }
   1938      }
   1939    }
   1940  }
   1941 
   1942  void TearDown() override {
   1943    // Remove "out" files after each test.
   1944    ClearTempOutFiles();
   1945  }
   1946 
   1947  static void TearDownTestSuite() { ClearTempFiles(); }
   1948 
   1949  // Runs a process pass on files with the given parameters and dumps the output
   1950  // to a file specified with `output_file_prefix`. Both forward and reverse
   1951  // output streams are dumped.
   1952  static void ProcessFormat(int input_rate,
   1953                            int output_rate,
   1954                            int reverse_input_rate,
   1955                            int reverse_output_rate,
   1956                            size_t num_input_channels,
   1957                            size_t num_output_channels,
   1958                            size_t num_reverse_input_channels,
   1959                            size_t num_reverse_output_channels,
   1960                            absl::string_view output_file_prefix) {
   1961    AudioProcessing::Config apm_config;
   1962    apm_config.gain_controller1.analog_gain_controller.enabled = false;
   1963    scoped_refptr<AudioProcessing> ap = BuiltinAudioProcessingBuilder()
   1964                                            .SetConfig(apm_config)
   1965                                            .Build(CreateEnvironment());
   1966 
   1967    EnableAllAPComponents(ap.get());
   1968 
   1969    ProcessingConfig processing_config = {
   1970        {{input_rate, num_input_channels},
   1971         {output_rate, num_output_channels},
   1972         {reverse_input_rate, num_reverse_input_channels},
   1973         {reverse_output_rate, num_reverse_output_channels}}};
   1974    ap->Initialize(processing_config);
   1975 
   1976    FILE* far_file =
   1977        fopen(ResourceFilePath("far", reverse_input_rate).c_str(), "rb");
   1978    FILE* near_file = fopen(ResourceFilePath("near", input_rate).c_str(), "rb");
   1979    FILE* out_file = fopen(
   1980        OutputFilePath(
   1981            output_file_prefix, input_rate, output_rate, reverse_input_rate,
   1982            reverse_output_rate, num_input_channels, num_output_channels,
   1983            num_reverse_input_channels, num_reverse_output_channels, kForward)
   1984            .c_str(),
   1985        "wb");
   1986    FILE* rev_out_file = fopen(
   1987        OutputFilePath(
   1988            output_file_prefix, input_rate, output_rate, reverse_input_rate,
   1989            reverse_output_rate, num_input_channels, num_output_channels,
   1990            num_reverse_input_channels, num_reverse_output_channels, kReverse)
   1991            .c_str(),
   1992        "wb");
   1993    ASSERT_TRUE(far_file != nullptr);
   1994    ASSERT_TRUE(near_file != nullptr);
   1995    ASSERT_TRUE(out_file != nullptr);
   1996    ASSERT_TRUE(rev_out_file != nullptr);
   1997 
   1998    ChannelBuffer<float> fwd_cb(AudioProcessing::GetFrameSize(input_rate),
   1999                                num_input_channels);
   2000    ChannelBuffer<float> rev_cb(
   2001        AudioProcessing::GetFrameSize(reverse_input_rate),
   2002        num_reverse_input_channels);
   2003    ChannelBuffer<float> out_cb(AudioProcessing::GetFrameSize(output_rate),
   2004                                num_output_channels);
   2005    ChannelBuffer<float> rev_out_cb(
   2006        AudioProcessing::GetFrameSize(reverse_output_rate),
   2007        num_reverse_output_channels);
   2008 
   2009    // Temporary buffers.
   2010    const int max_length =
   2011        2 * std::max(std::max(out_cb.num_frames(), rev_out_cb.num_frames()),
   2012                     std::max(fwd_cb.num_frames(), rev_cb.num_frames()));
   2013    std::unique_ptr<float[]> float_data(new float[max_length]);
   2014    std::unique_ptr<int16_t[]> int_data(new int16_t[max_length]);
   2015 
   2016    int analog_level = 127;
   2017    while (ReadChunk(far_file, int_data.get(), float_data.get(), &rev_cb) &&
   2018           ReadChunk(near_file, int_data.get(), float_data.get(), &fwd_cb)) {
   2019      EXPECT_NOERR(ap->ProcessReverseStream(
   2020          rev_cb.channels(), processing_config.reverse_input_stream(),
   2021          processing_config.reverse_output_stream(), rev_out_cb.channels()));
   2022 
   2023      EXPECT_NOERR(ap->set_stream_delay_ms(0));
   2024      ap->set_stream_analog_level(analog_level);
   2025 
   2026      EXPECT_NOERR(ap->ProcessStream(
   2027          fwd_cb.channels(), StreamConfig(input_rate, num_input_channels),
   2028          StreamConfig(output_rate, num_output_channels), out_cb.channels()));
   2029 
   2030      // Dump forward output to file.
   2031      RTC_DCHECK_EQ(out_cb.num_bands(), 1u);  // Assumes full frequency band.
   2032      DeinterleavedView<const float> deinterleaved_src(
   2033          out_cb.channels(), out_cb.num_frames(), out_cb.num_channels());
   2034      InterleavedView<float> interleaved_dst(
   2035          float_data.get(), out_cb.num_frames(), out_cb.num_channels());
   2036      Interleave(deinterleaved_src, interleaved_dst);
   2037      size_t out_length = out_cb.num_channels() * out_cb.num_frames();
   2038 
   2039      ASSERT_EQ(out_length, fwrite(float_data.get(), sizeof(float_data[0]),
   2040                                   out_length, out_file));
   2041 
   2042      // Dump reverse output to file.
   2043      RTC_DCHECK_EQ(rev_out_cb.num_bands(), 1u);
   2044      deinterleaved_src = DeinterleavedView<const float>(
   2045          rev_out_cb.channels(), rev_out_cb.num_frames(),
   2046          rev_out_cb.num_channels());
   2047      interleaved_dst = InterleavedView<float>(
   2048          float_data.get(), rev_out_cb.num_frames(), rev_out_cb.num_channels());
   2049      Interleave(deinterleaved_src, interleaved_dst);
   2050      size_t rev_out_length =
   2051          rev_out_cb.num_channels() * rev_out_cb.num_frames();
   2052 
   2053      ASSERT_EQ(rev_out_length, fwrite(float_data.get(), sizeof(float_data[0]),
   2054                                       rev_out_length, rev_out_file));
   2055 
   2056      analog_level = ap->recommended_stream_analog_level();
   2057    }
   2058    fclose(far_file);
   2059    fclose(near_file);
   2060    fclose(out_file);
   2061    fclose(rev_out_file);
   2062  }
   2063 
   2064 protected:
   2065  int input_rate_;
   2066  int output_rate_;
   2067  int reverse_input_rate_;
   2068  int reverse_output_rate_;
   2069  double expected_snr_;
   2070  double expected_reverse_snr_;
   2071 };
   2072 
   2073 TEST_P(AudioProcessingTest, Formats) {
   2074  struct ChannelFormat {
   2075    int num_input;
   2076    int num_output;
   2077    int num_reverse_input;
   2078    int num_reverse_output;
   2079  };
   2080  ChannelFormat cf[] = {
   2081      {.num_input = 1,
   2082       .num_output = 1,
   2083       .num_reverse_input = 1,
   2084       .num_reverse_output = 1},
   2085      {.num_input = 1,
   2086       .num_output = 1,
   2087       .num_reverse_input = 2,
   2088       .num_reverse_output = 1},
   2089      {.num_input = 2,
   2090       .num_output = 1,
   2091       .num_reverse_input = 1,
   2092       .num_reverse_output = 1},
   2093      {.num_input = 2,
   2094       .num_output = 1,
   2095       .num_reverse_input = 2,
   2096       .num_reverse_output = 1},
   2097      {.num_input = 2,
   2098       .num_output = 2,
   2099       .num_reverse_input = 1,
   2100       .num_reverse_output = 1},
   2101      {.num_input = 2,
   2102       .num_output = 2,
   2103       .num_reverse_input = 2,
   2104       .num_reverse_output = 2},
   2105  };
   2106 
   2107  for (auto [num_input, num_output, num_reverse_input, num_reverse_output] :
   2108       cf) {
   2109    ProcessFormat(input_rate_, output_rate_, reverse_input_rate_,
   2110                  reverse_output_rate_, num_input, num_output,
   2111                  num_reverse_input, num_reverse_output, "out");
   2112 
   2113    // Verify output for both directions.
   2114    std::vector<StreamDirection> stream_directions;
   2115    stream_directions.push_back(kForward);
   2116    stream_directions.push_back(kReverse);
   2117    for (StreamDirection file_direction : stream_directions) {
   2118      const int in_rate = file_direction ? reverse_input_rate_ : input_rate_;
   2119      const int out_rate = file_direction ? reverse_output_rate_ : output_rate_;
   2120      const int out_num = file_direction ? num_reverse_output : num_output;
   2121      const double expected_snr =
   2122          file_direction ? expected_reverse_snr_ : expected_snr_;
   2123 
   2124      const int min_ref_rate = std::min(in_rate, out_rate);
   2125      int ref_rate;
   2126      if (min_ref_rate > 32000) {
   2127        ref_rate = 48000;
   2128      } else if (min_ref_rate > 16000) {
   2129        ref_rate = 32000;
   2130      } else {
   2131        ref_rate = 16000;
   2132      }
   2133 
   2134      FILE* out_file = fopen(
   2135          OutputFilePath("out", input_rate_, output_rate_, reverse_input_rate_,
   2136                         reverse_output_rate_, num_input, num_output,
   2137                         num_reverse_input, num_reverse_output, file_direction)
   2138              .c_str(),
   2139          "rb");
   2140      // The reference files always have matching input and output channels.
   2141      FILE* ref_file =
   2142          fopen(OutputFilePath("ref", ref_rate, ref_rate, ref_rate, ref_rate,
   2143                               num_output, num_output, num_reverse_output,
   2144                               num_reverse_output, file_direction)
   2145                    .c_str(),
   2146                "rb");
   2147      ASSERT_TRUE(out_file != nullptr);
   2148      ASSERT_TRUE(ref_file != nullptr);
   2149 
   2150      const size_t ref_samples_per_channel =
   2151          AudioProcessing::GetFrameSize(ref_rate);
   2152      const size_t ref_length = ref_samples_per_channel * out_num;
   2153      const size_t out_samples_per_channel =
   2154          AudioProcessing::GetFrameSize(out_rate);
   2155      const size_t out_length = out_samples_per_channel * out_num;
   2156      // Data from the reference file.
   2157      std::unique_ptr<float[]> ref_data(new float[ref_length]);
   2158      // Data from the output file.
   2159      std::unique_ptr<float[]> out_data(new float[out_length]);
   2160      // Data from the resampled output, in case the reference and output rates
   2161      // don't match.
   2162      std::unique_ptr<float[]> cmp_data(new float[ref_length]);
   2163 
   2164      PushResampler<float> resampler(out_samples_per_channel,
   2165                                     ref_samples_per_channel, out_num);
   2166 
   2167      // Compute the resampling delay of the output relative to the reference,
   2168      // to find the region over which we should search for the best SNR.
   2169      float expected_delay_sec = 0;
   2170      if (in_rate != ref_rate) {
   2171        // Input resampling delay.
   2172        expected_delay_sec +=
   2173            PushSincResampler::AlgorithmicDelaySeconds(in_rate);
   2174      }
   2175      if (out_rate != ref_rate) {
   2176        // Output resampling delay.
   2177        expected_delay_sec +=
   2178            PushSincResampler::AlgorithmicDelaySeconds(ref_rate);
   2179        // Delay of converting the output back to its processing rate for
   2180        // testing.
   2181        expected_delay_sec +=
   2182            PushSincResampler::AlgorithmicDelaySeconds(out_rate);
   2183      }
   2184      // The delay is multiplied by the number of channels because
   2185      // UpdateBestSNR() computes the SNR over interleaved data without taking
   2186      // channels into account.
   2187      int expected_delay =
   2188          std::floor(expected_delay_sec * ref_rate + 0.5f) * out_num;
   2189 
   2190      double variance = 0;
   2191      double sq_error = 0;
   2192      while (fread(out_data.get(), sizeof(out_data[0]), out_length, out_file) &&
   2193             fread(ref_data.get(), sizeof(ref_data[0]), ref_length, ref_file)) {
   2194        float* out_ptr = out_data.get();
   2195        if (out_rate != ref_rate) {
   2196          // Resample the output back to its internal processing rate if
   2197          // necessary.
   2198          InterleavedView<const float> src(out_ptr, out_samples_per_channel,
   2199                                           out_num);
   2200          InterleavedView<float> dst(cmp_data.get(), ref_samples_per_channel,
   2201                                     out_num);
   2202          resampler.Resample(src, dst);
   2203          out_ptr = cmp_data.get();
   2204        }
   2205 
   2206        // Update the `sq_error` and `variance` accumulators with the highest
   2207        // SNR of reference vs output.
   2208        UpdateBestSNR(ref_data.get(), out_ptr, ref_length, expected_delay,
   2209                      &variance, &sq_error);
   2210      }
   2211 
   2212      std::cout << "(" << input_rate_ << ", " << output_rate_ << ", "
   2213                << reverse_input_rate_ << ", " << reverse_output_rate_ << ", "
   2214                << num_input << ", " << num_output << ", " << num_reverse_input
   2215                << ", " << num_reverse_output << ", " << file_direction
   2216                << "): ";
   2217      if (sq_error > 0) {
   2218        double snr = 10 * log10(variance / sq_error);
   2219        EXPECT_GE(snr, expected_snr);
   2220        EXPECT_NE(0, expected_snr);
   2221        std::cout << "SNR=" << snr << " dB" << std::endl;
   2222      } else {
   2223        std::cout << "SNR=inf dB" << std::endl;
   2224      }
   2225 
   2226      fclose(out_file);
   2227      fclose(ref_file);
   2228    }
   2229  }
   2230 }
   2231 
   2232 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
   2233 INSTANTIATE_TEST_SUITE_P(
   2234    CommonFormats,
   2235    AudioProcessingTest,
   2236    // Internal processing rates and the particularly common sample rate 44100
   2237    // Hz are tested in a grid of combinations (capture in, render in, out).
   2238    ::testing::Values(std::make_tuple(48000, 48000, 48000, 48000, 0, 0),
   2239                      std::make_tuple(48000, 48000, 32000, 48000, 40, 30),
   2240                      std::make_tuple(48000, 48000, 16000, 48000, 40, 20),
   2241                      std::make_tuple(48000, 44100, 48000, 44100, 20, 20),
   2242                      std::make_tuple(48000, 44100, 32000, 44100, 20, 15),
   2243                      std::make_tuple(48000, 44100, 16000, 44100, 20, 15),
   2244                      std::make_tuple(48000, 32000, 48000, 32000, 30, 35),
   2245                      std::make_tuple(48000, 32000, 32000, 32000, 30, 0),
   2246                      std::make_tuple(48000, 32000, 16000, 32000, 30, 20),
   2247                      std::make_tuple(48000, 16000, 48000, 16000, 25, 20),
   2248                      std::make_tuple(48000, 16000, 32000, 16000, 25, 20),
   2249                      std::make_tuple(48000, 16000, 16000, 16000, 25, 0),
   2250 
   2251                      std::make_tuple(44100, 48000, 48000, 48000, 30, 0),
   2252                      std::make_tuple(44100, 48000, 32000, 48000, 30, 30),
   2253                      std::make_tuple(44100, 48000, 16000, 48000, 30, 20),
   2254                      std::make_tuple(44100, 44100, 48000, 44100, 20, 20),
   2255                      std::make_tuple(44100, 44100, 32000, 44100, 20, 15),
   2256                      std::make_tuple(44100, 44100, 16000, 44100, 20, 15),
   2257                      std::make_tuple(44100, 32000, 48000, 32000, 30, 35),
   2258                      std::make_tuple(44100, 32000, 32000, 32000, 30, 0),
   2259                      std::make_tuple(44100, 32000, 16000, 32000, 30, 20),
   2260                      std::make_tuple(44100, 16000, 48000, 16000, 25, 20),
   2261                      std::make_tuple(44100, 16000, 32000, 16000, 25, 20),
   2262                      std::make_tuple(44100, 16000, 16000, 16000, 25, 0),
   2263 
   2264                      std::make_tuple(32000, 48000, 48000, 48000, 15, 0),
   2265                      std::make_tuple(32000, 48000, 32000, 48000, 15, 30),
   2266                      std::make_tuple(32000, 48000, 16000, 48000, 15, 20),
   2267                      std::make_tuple(32000, 44100, 48000, 44100, 19, 20),
   2268                      std::make_tuple(32000, 44100, 32000, 44100, 19, 15),
   2269                      std::make_tuple(32000, 44100, 16000, 44100, 19, 15),
   2270                      std::make_tuple(32000, 32000, 48000, 32000, 40, 35),
   2271                      std::make_tuple(32000, 32000, 32000, 32000, 0, 0),
   2272                      std::make_tuple(32000, 32000, 16000, 32000, 39, 20),
   2273                      std::make_tuple(32000, 16000, 48000, 16000, 25, 20),
   2274                      std::make_tuple(32000, 16000, 32000, 16000, 25, 20),
   2275                      std::make_tuple(32000, 16000, 16000, 16000, 25, 0),
   2276 
   2277                      std::make_tuple(16000, 48000, 48000, 48000, 9, 0),
   2278                      std::make_tuple(16000, 48000, 32000, 48000, 9, 30),
   2279                      std::make_tuple(16000, 48000, 16000, 48000, 9, 20),
   2280                      std::make_tuple(16000, 44100, 48000, 44100, 15, 20),
   2281                      std::make_tuple(16000, 44100, 32000, 44100, 15, 15),
   2282                      std::make_tuple(16000, 44100, 16000, 44100, 15, 15),
   2283                      std::make_tuple(16000, 32000, 48000, 32000, 25, 35),
   2284                      std::make_tuple(16000, 32000, 32000, 32000, 25, 0),
   2285                      std::make_tuple(16000, 32000, 16000, 32000, 25, 20),
   2286                      std::make_tuple(16000, 16000, 48000, 16000, 39, 20),
   2287                      std::make_tuple(16000, 16000, 32000, 16000, 39, 20),
   2288                      std::make_tuple(16000, 16000, 16000, 16000, 0, 0),
   2289 
   2290                      // Other sample rates are not tested exhaustively, to keep
   2291                      // the test runtime manageable.
   2292                      //
   2293                      // Testing most other sample rates logged by Chrome UMA:
   2294                      //  - WebRTC.AudioInputSampleRate
   2295                      //  - WebRTC.AudioOutputSampleRate
   2296                      // ApmConfiguration.HandlingOfRateCombinations covers
   2297                      // remaining sample rates.
   2298                      std::make_tuple(192000, 192000, 48000, 192000, 20, 40),
   2299                      std::make_tuple(176400, 176400, 48000, 176400, 20, 35),
   2300                      std::make_tuple(96000, 96000, 48000, 96000, 20, 40),
   2301                      std::make_tuple(88200, 88200, 48000, 88200, 20, 20),
   2302                      std::make_tuple(44100, 44100, 48000, 44100, 20, 20)));
   2303 
   2304 #elif defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
   2305 INSTANTIATE_TEST_SUITE_P(
   2306    CommonFormats,
   2307    AudioProcessingTest,
   2308    ::testing::Values(std::make_tuple(48000, 48000, 48000, 48000, 19, 0),
   2309                      std::make_tuple(48000, 48000, 32000, 48000, 19, 30),
   2310                      std::make_tuple(48000, 48000, 16000, 48000, 19, 20),
   2311                      std::make_tuple(48000, 44100, 48000, 44100, 15, 20),
   2312                      std::make_tuple(48000, 44100, 32000, 44100, 15, 15),
   2313                      std::make_tuple(48000, 44100, 16000, 44100, 15, 15),
   2314                      std::make_tuple(48000, 32000, 48000, 32000, 19, 35),
   2315                      std::make_tuple(48000, 32000, 32000, 32000, 19, 0),
   2316                      std::make_tuple(48000, 32000, 16000, 32000, 19, 20),
   2317                      std::make_tuple(48000, 16000, 48000, 16000, 20, 20),
   2318                      std::make_tuple(48000, 16000, 32000, 16000, 20, 20),
   2319                      std::make_tuple(48000, 16000, 16000, 16000, 20, 0),
   2320 
   2321                      std::make_tuple(44100, 48000, 48000, 48000, 15, 0),
   2322                      std::make_tuple(44100, 48000, 32000, 48000, 15, 30),
   2323                      std::make_tuple(44100, 48000, 16000, 48000, 15, 20),
   2324                      std::make_tuple(44100, 44100, 48000, 44100, 15, 20),
   2325                      std::make_tuple(44100, 44100, 32000, 44100, 15, 15),
   2326                      std::make_tuple(44100, 44100, 16000, 44100, 15, 15),
   2327                      std::make_tuple(44100, 32000, 48000, 32000, 18, 35),
   2328                      std::make_tuple(44100, 32000, 32000, 32000, 18, 0),
   2329                      std::make_tuple(44100, 32000, 16000, 32000, 18, 20),
   2330                      std::make_tuple(44100, 16000, 48000, 16000, 19, 20),
   2331                      std::make_tuple(44100, 16000, 32000, 16000, 19, 20),
   2332                      std::make_tuple(44100, 16000, 16000, 16000, 19, 0),
   2333 
   2334                      std::make_tuple(32000, 48000, 48000, 48000, 17, 0),
   2335                      std::make_tuple(32000, 48000, 32000, 48000, 17, 30),
   2336                      std::make_tuple(32000, 48000, 16000, 48000, 17, 20),
   2337                      std::make_tuple(32000, 44100, 48000, 44100, 20, 20),
   2338                      std::make_tuple(32000, 44100, 32000, 44100, 20, 15),
   2339                      std::make_tuple(32000, 44100, 16000, 44100, 20, 15),
   2340                      std::make_tuple(32000, 32000, 48000, 32000, 27, 35),
   2341                      std::make_tuple(32000, 32000, 32000, 32000, 0, 0),
   2342                      std::make_tuple(32000, 32000, 16000, 32000, 30, 20),
   2343                      std::make_tuple(32000, 16000, 48000, 16000, 20, 20),
   2344                      std::make_tuple(32000, 16000, 32000, 16000, 20, 20),
   2345                      std::make_tuple(32000, 16000, 16000, 16000, 20, 0),
   2346 
   2347                      std::make_tuple(16000, 48000, 48000, 48000, 11, 0),
   2348                      std::make_tuple(16000, 48000, 32000, 48000, 11, 30),
   2349                      std::make_tuple(16000, 48000, 16000, 48000, 11, 20),
   2350                      std::make_tuple(16000, 44100, 48000, 44100, 15, 20),
   2351                      std::make_tuple(16000, 44100, 32000, 44100, 15, 15),
   2352                      std::make_tuple(16000, 44100, 16000, 44100, 15, 15),
   2353                      std::make_tuple(16000, 32000, 48000, 32000, 24, 35),
   2354                      std::make_tuple(16000, 32000, 32000, 32000, 24, 0),
   2355                      std::make_tuple(16000, 32000, 16000, 32000, 25, 20),
   2356                      std::make_tuple(16000, 16000, 48000, 16000, 28, 20),
   2357                      std::make_tuple(16000, 16000, 32000, 16000, 28, 20),
   2358                      std::make_tuple(16000, 16000, 16000, 16000, 0, 0),
   2359 
   2360                      std::make_tuple(192000, 192000, 48000, 192000, 20, 40),
   2361                      std::make_tuple(176400, 176400, 48000, 176400, 20, 35),
   2362                      std::make_tuple(96000, 96000, 48000, 96000, 20, 40),
   2363                      std::make_tuple(88200, 88200, 48000, 88200, 20, 20),
   2364                      std::make_tuple(44100, 44100, 48000, 44100, 20, 20)));
   2365 #endif
   2366 
   2367 // Produces a scoped trace debug output.
   2368 std::string ProduceDebugText(int render_input_sample_rate_hz,
   2369                             int render_output_sample_rate_hz,
   2370                             int capture_input_sample_rate_hz,
   2371                             int capture_output_sample_rate_hz,
   2372                             size_t render_input_num_channels,
   2373                             size_t render_output_num_channels,
   2374                             size_t capture_input_num_channels,
   2375                             size_t capture_output_num_channels) {
   2376  StringBuilder ss;
   2377  ss << "Sample rates:"
   2378        "\n Render input: "
   2379     << render_input_sample_rate_hz
   2380     << " Hz"
   2381        "\n Render output: "
   2382     << render_output_sample_rate_hz
   2383     << " Hz"
   2384        "\n Capture input: "
   2385     << capture_input_sample_rate_hz
   2386     << " Hz"
   2387        "\n Capture output: "
   2388     << capture_output_sample_rate_hz
   2389     << " Hz"
   2390        "\nNumber of channels:"
   2391        "\n Render input: "
   2392     << render_input_num_channels
   2393     << "\n Render output: " << render_output_num_channels
   2394     << "\n Capture input: " << capture_input_num_channels
   2395     << "\n Capture output: " << capture_output_num_channels;
   2396  return ss.Release();
   2397 }
   2398 
   2399 // Validates that running the audio processing module using various combinations
   2400 // of sample rates and number of channels works as intended.
   2401 void RunApmRateAndChannelTest(ArrayView<const int> sample_rates_hz,
   2402                              ArrayView<const int> render_channel_counts,
   2403                              ArrayView<const int> capture_channel_counts) {
   2404  AudioProcessing::Config apm_config;
   2405  apm_config.pipeline.multi_channel_render = true;
   2406  apm_config.pipeline.multi_channel_capture = true;
   2407  apm_config.echo_canceller.enabled = true;
   2408  scoped_refptr<AudioProcessing> apm =
   2409      BuiltinAudioProcessingBuilder(apm_config).Build(CreateEnvironment());
   2410 
   2411  StreamConfig render_input_stream_config;
   2412  StreamConfig render_output_stream_config;
   2413  StreamConfig capture_input_stream_config;
   2414  StreamConfig capture_output_stream_config;
   2415 
   2416  std::vector<float> render_input_frame_channels;
   2417  std::vector<float*> render_input_frame;
   2418  std::vector<float> render_output_frame_channels;
   2419  std::vector<float*> render_output_frame;
   2420  std::vector<float> capture_input_frame_channels;
   2421  std::vector<float*> capture_input_frame;
   2422  std::vector<float> capture_output_frame_channels;
   2423  std::vector<float*> capture_output_frame;
   2424 
   2425  for (auto render_input_sample_rate_hz : sample_rates_hz) {
   2426    for (auto render_output_sample_rate_hz : sample_rates_hz) {
   2427      for (auto capture_input_sample_rate_hz : sample_rates_hz) {
   2428        for (auto capture_output_sample_rate_hz : sample_rates_hz) {
   2429          for (size_t render_input_num_channels : render_channel_counts) {
   2430            for (size_t capture_input_num_channels : capture_channel_counts) {
   2431              size_t render_output_num_channels = render_input_num_channels;
   2432              size_t capture_output_num_channels = capture_input_num_channels;
   2433              auto populate_audio_frame = [](int sample_rate_hz,
   2434                                             size_t num_channels,
   2435                                             StreamConfig* cfg,
   2436                                             std::vector<float>* channels_data,
   2437                                             std::vector<float*>* frame_data) {
   2438                cfg->set_sample_rate_hz(sample_rate_hz);
   2439                cfg->set_num_channels(num_channels);
   2440 
   2441                size_t max_frame_size =
   2442                    AudioProcessing::GetFrameSize(sample_rate_hz);
   2443                channels_data->resize(num_channels * max_frame_size);
   2444                std::fill(channels_data->begin(), channels_data->end(), 0.5f);
   2445                frame_data->resize(num_channels);
   2446                for (size_t channel = 0; channel < num_channels; ++channel) {
   2447                  (*frame_data)[channel] =
   2448                      &(*channels_data)[channel * max_frame_size];
   2449                }
   2450              };
   2451 
   2452              populate_audio_frame(
   2453                  render_input_sample_rate_hz, render_input_num_channels,
   2454                  &render_input_stream_config, &render_input_frame_channels,
   2455                  &render_input_frame);
   2456              populate_audio_frame(
   2457                  render_output_sample_rate_hz, render_output_num_channels,
   2458                  &render_output_stream_config, &render_output_frame_channels,
   2459                  &render_output_frame);
   2460              populate_audio_frame(
   2461                  capture_input_sample_rate_hz, capture_input_num_channels,
   2462                  &capture_input_stream_config, &capture_input_frame_channels,
   2463                  &capture_input_frame);
   2464              populate_audio_frame(
   2465                  capture_output_sample_rate_hz, capture_output_num_channels,
   2466                  &capture_output_stream_config, &capture_output_frame_channels,
   2467                  &capture_output_frame);
   2468 
   2469              for (size_t frame = 0; frame < 2; ++frame) {
   2470                SCOPED_TRACE(ProduceDebugText(
   2471                    render_input_sample_rate_hz, render_output_sample_rate_hz,
   2472                    capture_input_sample_rate_hz, capture_output_sample_rate_hz,
   2473                    render_input_num_channels, render_output_num_channels,
   2474                    render_input_num_channels, capture_output_num_channels));
   2475 
   2476                int result = apm->ProcessReverseStream(
   2477                    &render_input_frame[0], render_input_stream_config,
   2478                    render_output_stream_config, &render_output_frame[0]);
   2479                EXPECT_EQ(result, AudioProcessing::kNoError);
   2480                result = apm->ProcessStream(
   2481                    &capture_input_frame[0], capture_input_stream_config,
   2482                    capture_output_stream_config, &capture_output_frame[0]);
   2483                EXPECT_EQ(result, AudioProcessing::kNoError);
   2484              }
   2485            }
   2486          }
   2487        }
   2488      }
   2489    }
   2490  }
   2491 }
   2492 
   2493 constexpr void Toggle(bool& b) {
   2494  b ^= true;
   2495 }
   2496 
   2497 TEST(RuntimeSettingTest, TestDefaultCtor) {
   2498  auto s = AudioProcessing::RuntimeSetting();
   2499  EXPECT_EQ(AudioProcessing::RuntimeSetting::Type::kNotSpecified, s.type());
   2500 }
   2501 
   2502 TEST(RuntimeSettingTest, TestUsageWithSwapQueue) {
   2503  SwapQueue<AudioProcessing::RuntimeSetting> q(1);
   2504  auto s = AudioProcessing::RuntimeSetting();
   2505  ASSERT_TRUE(q.Insert(&s));
   2506  ASSERT_TRUE(q.Remove(&s));
   2507  EXPECT_EQ(AudioProcessing::RuntimeSetting::Type::kNotSpecified, s.type());
   2508 }
   2509 
   2510 TEST(ApmConfiguration, EnablePostProcessing) {
   2511  // Verify that apm uses a capture post processing module if one is provided.
   2512  auto mock_post_processor_ptr =
   2513      new ::testing::NiceMock<test::MockCustomProcessing>();
   2514  auto mock_post_processor =
   2515      std::unique_ptr<CustomProcessing>(mock_post_processor_ptr);
   2516  scoped_refptr<AudioProcessing> apm =
   2517      BuiltinAudioProcessingBuilder()
   2518          .SetCapturePostProcessing(std::move(mock_post_processor))
   2519          .Build(CreateEnvironment());
   2520 
   2521  Int16FrameData audio;
   2522  audio.SetProperties(AudioProcessing::GetFrameSize(
   2523                          AudioProcessing::NativeRate::kSampleRate16kHz),
   2524                      /* num_channels=*/1);
   2525 
   2526  EXPECT_CALL(*mock_post_processor_ptr, Process(::testing::_)).Times(1);
   2527  apm->ProcessStream(audio.data.data(),
   2528                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2529                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2530                     audio.data.data());
   2531 }
   2532 
   2533 TEST(ApmConfiguration, EnablePreProcessing) {
   2534  // Verify that apm uses a capture post processing module if one is provided.
   2535  auto mock_pre_processor_ptr =
   2536      new ::testing::NiceMock<test::MockCustomProcessing>();
   2537  auto mock_pre_processor =
   2538      std::unique_ptr<CustomProcessing>(mock_pre_processor_ptr);
   2539  scoped_refptr<AudioProcessing> apm =
   2540      BuiltinAudioProcessingBuilder()
   2541          .SetRenderPreProcessing(std::move(mock_pre_processor))
   2542          .Build(CreateEnvironment());
   2543 
   2544  Int16FrameData audio;
   2545  audio.SetProperties(AudioProcessing::GetFrameSize(
   2546                          AudioProcessing::NativeRate::kSampleRate16kHz),
   2547                      /* num_channels=*/1);
   2548 
   2549  EXPECT_CALL(*mock_pre_processor_ptr, Process(::testing::_)).Times(1);
   2550  apm->ProcessReverseStream(
   2551      audio.data.data(),
   2552      StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2553      StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2554      audio.data.data());
   2555 }
   2556 
   2557 TEST(ApmConfiguration, EnableCaptureAnalyzer) {
   2558  // Verify that apm uses a capture analyzer if one is provided.
   2559  auto mock_capture_analyzer_ptr =
   2560      new ::testing::NiceMock<test::MockCustomAudioAnalyzer>();
   2561  auto mock_capture_analyzer =
   2562      std::unique_ptr<CustomAudioAnalyzer>(mock_capture_analyzer_ptr);
   2563  scoped_refptr<AudioProcessing> apm =
   2564      BuiltinAudioProcessingBuilder()
   2565          .SetCaptureAnalyzer(std::move(mock_capture_analyzer))
   2566          .Build(CreateEnvironment());
   2567 
   2568  Int16FrameData audio;
   2569  audio.SetProperties(AudioProcessing::GetFrameSize(
   2570                          AudioProcessing::NativeRate::kSampleRate16kHz),
   2571                      /* num_channels=*/1);
   2572 
   2573  EXPECT_CALL(*mock_capture_analyzer_ptr, Analyze(::testing::_)).Times(1);
   2574  apm->ProcessStream(audio.data.data(),
   2575                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2576                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2577                     audio.data.data());
   2578 }
   2579 
   2580 TEST(ApmConfiguration, PreProcessingReceivesRuntimeSettings) {
   2581  auto mock_pre_processor_ptr =
   2582      new ::testing::NiceMock<test::MockCustomProcessing>();
   2583  auto mock_pre_processor =
   2584      std::unique_ptr<CustomProcessing>(mock_pre_processor_ptr);
   2585  scoped_refptr<AudioProcessing> apm =
   2586      BuiltinAudioProcessingBuilder()
   2587          .SetRenderPreProcessing(std::move(mock_pre_processor))
   2588          .Build(CreateEnvironment());
   2589  apm->SetRuntimeSetting(
   2590      AudioProcessing::RuntimeSetting::CreateCustomRenderSetting(0));
   2591 
   2592  // RuntimeSettings forwarded during 'Process*Stream' calls.
   2593  // Therefore we have to make one such call.
   2594  Int16FrameData audio;
   2595  audio.SetProperties(AudioProcessing::GetFrameSize(
   2596                          AudioProcessing::NativeRate::kSampleRate16kHz),
   2597                      /* num_channels=*/1);
   2598 
   2599  EXPECT_CALL(*mock_pre_processor_ptr, SetRuntimeSetting(::testing::_))
   2600      .Times(1);
   2601  apm->ProcessReverseStream(
   2602      audio.data.data(),
   2603      StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2604      StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2605      audio.data.data());
   2606 }
   2607 
   2608 class MockEchoControlFactory : public EchoControlFactory {
   2609 public:
   2610  MOCK_METHOD(std::unique_ptr<EchoControl>,
   2611              Create,
   2612              (const Environment&, int, int, int),
   2613              (override));
   2614  MOCK_METHOD(std::unique_ptr<EchoControl>,
   2615              Create,
   2616              (const Environment&, int, int, int, NeuralResidualEchoEstimator*),
   2617              (override));
   2618 };
   2619 
   2620 TEST(ApmConfiguration, EchoControlInjection) {
   2621  // Verify that apm uses an injected echo controller if one is provided.
   2622  auto echo_control_factory = std::make_unique<MockEchoControlFactory>();
   2623  EXPECT_CALL(*echo_control_factory, Create(_, _, _, _, _))
   2624      .WillOnce(WithoutArgs([] {
   2625        auto ec = std::make_unique<test::MockEchoControl>();
   2626        EXPECT_CALL(*ec, AnalyzeRender).Times(1);
   2627        EXPECT_CALL(*ec, AnalyzeCapture).Times(2);
   2628        EXPECT_CALL(*ec, ProcessCapture(_, _, _)).Times(2);
   2629        return ec;
   2630      }));
   2631 
   2632  scoped_refptr<AudioProcessing> apm =
   2633      BuiltinAudioProcessingBuilder()
   2634          .SetEchoControlFactory(std::move(echo_control_factory))
   2635          .Build(CreateEnvironment());
   2636 
   2637  Int16FrameData audio;
   2638  audio.SetProperties(AudioProcessing::GetFrameSize(
   2639                          AudioProcessing::NativeRate::kSampleRate16kHz),
   2640                      /* num_channels=*/1);
   2641  apm->ProcessStream(audio.data.data(),
   2642                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2643                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2644                     audio.data.data());
   2645  apm->ProcessReverseStream(
   2646      audio.data.data(),
   2647      StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2648      StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2649      audio.data.data());
   2650  apm->ProcessStream(audio.data.data(),
   2651                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2652                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
   2653                     audio.data.data());
   2654 }
   2655 
   2656 TEST(ApmConfiguration, EchoDetectorInjection) {
   2657  using ::testing::_;
   2658  scoped_refptr<test::MockEchoDetector> mock_echo_detector =
   2659      make_ref_counted<::testing::StrictMock<test::MockEchoDetector>>();
   2660  EXPECT_CALL(*mock_echo_detector,
   2661              Initialize(/*capture_sample_rate_hz=*/16000, _,
   2662                         /*render_sample_rate_hz=*/16000, _))
   2663      .Times(1);
   2664  scoped_refptr<AudioProcessing> apm = BuiltinAudioProcessingBuilder()
   2665                                           .SetEchoDetector(mock_echo_detector)
   2666                                           .Build(CreateEnvironment());
   2667 
   2668  // The echo detector is included in processing when enabled.
   2669  EXPECT_CALL(*mock_echo_detector, AnalyzeRenderAudio(_))
   2670      .WillOnce([](ArrayView<const float> render_audio) {
   2671        EXPECT_EQ(render_audio.size(), 160u);
   2672      });
   2673  EXPECT_CALL(*mock_echo_detector, AnalyzeCaptureAudio(_))
   2674      .WillOnce([](ArrayView<const float> capture_audio) {
   2675        EXPECT_EQ(capture_audio.size(), 160u);
   2676      });
   2677  EXPECT_CALL(*mock_echo_detector, GetMetrics()).Times(1);
   2678 
   2679  Int16FrameData frame;
   2680  frame.SetProperties(AudioProcessing::GetFrameSize(
   2681                          AudioProcessing::NativeRate::kSampleRate16kHz),
   2682                      /* num_channels=*/1);
   2683 
   2684  apm->ProcessReverseStream(frame.data.data(), StreamConfig(16000, 1),
   2685                            StreamConfig(16000, 1), frame.data.data());
   2686  apm->ProcessStream(frame.data.data(), StreamConfig(16000, 1),
   2687                     StreamConfig(16000, 1), frame.data.data());
   2688 
   2689  // When processing rates change, the echo detector is also reinitialized to
   2690  // match those.
   2691  EXPECT_CALL(*mock_echo_detector,
   2692              Initialize(/*capture_sample_rate_hz=*/48000, _,
   2693                         /*render_sample_rate_hz=*/16000, _))
   2694      .Times(1);
   2695  EXPECT_CALL(*mock_echo_detector,
   2696              Initialize(/*capture_sample_rate_hz=*/48000, _,
   2697                         /*render_sample_rate_hz=*/48000, _))
   2698      .Times(1);
   2699  EXPECT_CALL(*mock_echo_detector, AnalyzeRenderAudio(_))
   2700      .WillOnce([](ArrayView<const float> render_audio) {
   2701        EXPECT_EQ(render_audio.size(), 480u);
   2702      });
   2703  EXPECT_CALL(*mock_echo_detector, AnalyzeCaptureAudio(_))
   2704      .Times(2)
   2705      .WillRepeatedly([](ArrayView<const float> capture_audio) {
   2706        EXPECT_EQ(capture_audio.size(), 480u);
   2707      });
   2708  EXPECT_CALL(*mock_echo_detector, GetMetrics()).Times(2);
   2709 
   2710  frame.SetProperties(AudioProcessing::GetFrameSize(
   2711                          AudioProcessing::NativeRate::kSampleRate48kHz),
   2712                      frame.num_channels());
   2713  apm->ProcessStream(frame.data.data(), StreamConfig(48000, 1),
   2714                     StreamConfig(48000, 1), frame.data.data());
   2715  apm->ProcessReverseStream(frame.data.data(), StreamConfig(48000, 1),
   2716                            StreamConfig(48000, 1), frame.data.data());
   2717  apm->ProcessStream(frame.data.data(), StreamConfig(48000, 1),
   2718                     StreamConfig(48000, 1), frame.data.data());
   2719 }
   2720 
   2721 scoped_refptr<AudioProcessing> CreateApm(bool mobile_aec) {
   2722  // Enable residual echo detection, for stats.
   2723  scoped_refptr<AudioProcessing> apm =
   2724      BuiltinAudioProcessingBuilder()
   2725          .SetEchoDetector(CreateEchoDetector())
   2726          .Build(CreateEnvironment());
   2727  if (!apm) {
   2728    return apm;
   2729  }
   2730 
   2731  ProcessingConfig processing_config = {
   2732      {{32000, 1}, {32000, 1}, {32000, 1}, {32000, 1}}};
   2733 
   2734  if (apm->Initialize(processing_config) != 0) {
   2735    return nullptr;
   2736  }
   2737 
   2738  // Disable all components except for an AEC.
   2739  AudioProcessing::Config apm_config;
   2740  apm_config.high_pass_filter.enabled = false;
   2741  apm_config.gain_controller1.enabled = false;
   2742  apm_config.gain_controller2.enabled = false;
   2743  apm_config.echo_canceller.enabled = true;
   2744  apm_config.echo_canceller.mobile_mode = mobile_aec;
   2745  apm_config.noise_suppression.enabled = false;
   2746  apm->ApplyConfig(apm_config);
   2747  return apm;
   2748 }
   2749 
   2750 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) || defined(WEBRTC_MAC)
   2751 #define MAYBE_ApmStatistics DISABLED_ApmStatistics
   2752 #else
   2753 #define MAYBE_ApmStatistics ApmStatistics
   2754 #endif
   2755 
   2756 TEST(MAYBE_ApmStatistics, AECEnabledTest) {
   2757  // Set up APM with AEC3 and process some audio.
   2758  scoped_refptr<AudioProcessing> apm = CreateApm(false);
   2759  ASSERT_TRUE(apm);
   2760  AudioProcessing::Config apm_config;
   2761  apm_config.echo_canceller.enabled = true;
   2762  apm->ApplyConfig(apm_config);
   2763 
   2764  // Set up an audioframe.
   2765  Int16FrameData frame;
   2766  frame.SetProperties(AudioProcessing::GetFrameSize(
   2767                          AudioProcessing::NativeRate::kSampleRate32kHz),
   2768                      /* num_channels=*/1);
   2769 
   2770  // Fill the audio frame with a sawtooth pattern.
   2771  int16_t* ptr = frame.data.data();
   2772  for (size_t i = 0; i < Int16FrameData::kMaxDataSizeSamples; i++) {
   2773    ptr[i] = 10000 * ((i % 3) - 1);
   2774  }
   2775 
   2776  // Do some processing.
   2777  for (int i = 0; i < 200; i++) {
   2778    EXPECT_EQ(apm->ProcessReverseStream(
   2779                  frame.data.data(),
   2780                  StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2781                  StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2782                  frame.data.data()),
   2783              0);
   2784    EXPECT_EQ(apm->set_stream_delay_ms(0), 0);
   2785    EXPECT_EQ(apm->ProcessStream(
   2786                  frame.data.data(),
   2787                  StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2788                  StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2789                  frame.data.data()),
   2790              0);
   2791  }
   2792 
   2793  // Test statistics interface.
   2794  AudioProcessingStats stats = apm->GetStatistics();
   2795  // We expect all statistics to be set and have a sensible value.
   2796  ASSERT_TRUE(stats.residual_echo_likelihood.has_value());
   2797  EXPECT_GE(*stats.residual_echo_likelihood, 0.0);
   2798  EXPECT_LE(*stats.residual_echo_likelihood, 1.0);
   2799  ASSERT_TRUE(stats.residual_echo_likelihood_recent_max.has_value());
   2800  EXPECT_GE(*stats.residual_echo_likelihood_recent_max, 0.0);
   2801  EXPECT_LE(*stats.residual_echo_likelihood_recent_max, 1.0);
   2802  ASSERT_TRUE(stats.echo_return_loss.has_value());
   2803  EXPECT_NE(*stats.echo_return_loss, -100.0);
   2804  ASSERT_TRUE(stats.echo_return_loss_enhancement.has_value());
   2805  EXPECT_NE(*stats.echo_return_loss_enhancement, -100.0);
   2806 }
   2807 
   2808 TEST(MAYBE_ApmStatistics, AECMEnabledTest) {
   2809  // Set up APM with AECM and process some audio.
   2810  scoped_refptr<AudioProcessing> apm = CreateApm(true);
   2811  ASSERT_TRUE(apm);
   2812 
   2813  // Set up an audioframe.
   2814  Int16FrameData frame;
   2815  frame.SetProperties(AudioProcessing::GetFrameSize(
   2816                          AudioProcessing::NativeRate::kSampleRate32kHz),
   2817                      /* num_channels=*/1);
   2818 
   2819  // Fill the audio frame with a sawtooth pattern.
   2820  int16_t* ptr = frame.data.data();
   2821  for (size_t i = 0; i < Int16FrameData::kMaxDataSizeSamples; i++) {
   2822    ptr[i] = 10000 * ((i % 3) - 1);
   2823  }
   2824 
   2825  // Do some processing.
   2826  for (int i = 0; i < 200; i++) {
   2827    EXPECT_EQ(apm->ProcessReverseStream(
   2828                  frame.data.data(),
   2829                  StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2830                  StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2831                  frame.data.data()),
   2832              0);
   2833    EXPECT_EQ(apm->set_stream_delay_ms(0), 0);
   2834    EXPECT_EQ(apm->ProcessStream(
   2835                  frame.data.data(),
   2836                  StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2837                  StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2838                  frame.data.data()),
   2839              0);
   2840  }
   2841 
   2842  // Test statistics interface.
   2843  AudioProcessingStats stats = apm->GetStatistics();
   2844  // We expect only the residual echo detector statistics to be set and have a
   2845  // sensible value.
   2846  ASSERT_TRUE(stats.residual_echo_likelihood.has_value());
   2847  EXPECT_GE(*stats.residual_echo_likelihood, 0.0);
   2848  EXPECT_LE(*stats.residual_echo_likelihood, 1.0);
   2849  ASSERT_TRUE(stats.residual_echo_likelihood_recent_max.has_value());
   2850  EXPECT_GE(*stats.residual_echo_likelihood_recent_max, 0.0);
   2851  EXPECT_LE(*stats.residual_echo_likelihood_recent_max, 1.0);
   2852  EXPECT_FALSE(stats.echo_return_loss.has_value());
   2853  EXPECT_FALSE(stats.echo_return_loss_enhancement.has_value());
   2854 }
   2855 
   2856 TEST(ApmStatistics, DoNotReportVoiceDetectedStat) {
   2857  ProcessingConfig processing_config = {
   2858      {{32000, 1}, {32000, 1}, {32000, 1}, {32000, 1}}};
   2859 
   2860  // Set up an audioframe.
   2861  Int16FrameData frame;
   2862  frame.SetProperties(AudioProcessing::GetFrameSize(
   2863                          AudioProcessing::NativeRate::kSampleRate32kHz),
   2864                      /* num_channels=*/1);
   2865 
   2866  // Fill the audio frame with a sawtooth pattern.
   2867  int16_t* ptr = frame.data.data();
   2868  for (size_t i = 0; i < Int16FrameData::kMaxDataSizeSamples; i++) {
   2869    ptr[i] = 10000 * ((i % 3) - 1);
   2870  }
   2871 
   2872  scoped_refptr<AudioProcessing> apm =
   2873      BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
   2874  apm->Initialize(processing_config);
   2875 
   2876  // No metric should be reported.
   2877  EXPECT_EQ(apm->ProcessStream(
   2878                frame.data.data(),
   2879                StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2880                StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2881                frame.data.data()),
   2882            0);
   2883 #pragma clang diagnostic push
   2884 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
   2885  EXPECT_FALSE(apm->GetStatistics().voice_detected.has_value());
   2886 #pragma clang diagnostic pop
   2887 }
   2888 
   2889 TEST(ApmStatistics, GetStatisticsReportsNoEchoDetectorStatsWhenDisabled) {
   2890  scoped_refptr<AudioProcessing> apm =
   2891      BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
   2892  Int16FrameData frame;
   2893  frame.SetProperties(AudioProcessing::GetFrameSize(
   2894                          AudioProcessing::NativeRate::kSampleRate32kHz),
   2895                      /* num_channels=*/1);
   2896  ASSERT_EQ(apm->ProcessStream(
   2897                frame.data.data(),
   2898                StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2899                StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2900                frame.data.data()),
   2901            0);
   2902  // Echo detector is disabled by default, no stats reported.
   2903  AudioProcessingStats stats = apm->GetStatistics();
   2904  EXPECT_FALSE(stats.residual_echo_likelihood.has_value());
   2905  EXPECT_FALSE(stats.residual_echo_likelihood_recent_max.has_value());
   2906 }
   2907 
   2908 TEST(ApmStatistics, GetStatisticsReportsEchoDetectorStatsWhenEnabled) {
   2909  // Create APM with an echo detector injected.
   2910  scoped_refptr<AudioProcessing> apm =
   2911      BuiltinAudioProcessingBuilder()
   2912          .SetEchoDetector(CreateEchoDetector())
   2913          .Build(CreateEnvironment());
   2914  Int16FrameData frame;
   2915  frame.SetProperties(AudioProcessing::GetFrameSize(
   2916                          AudioProcessing::NativeRate::kSampleRate32kHz),
   2917                      /* num_channels=*/1);
   2918  // Echo detector enabled: Report stats.
   2919  ASSERT_EQ(apm->ProcessStream(
   2920                frame.data.data(),
   2921                StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2922                StreamConfig(frame.sample_rate_hz, frame.num_channels()),
   2923                frame.data.data()),
   2924            0);
   2925  AudioProcessingStats stats = apm->GetStatistics();
   2926  EXPECT_TRUE(stats.residual_echo_likelihood.has_value());
   2927  EXPECT_TRUE(stats.residual_echo_likelihood_recent_max.has_value());
   2928 }
   2929 
   2930 TEST(ApmConfiguration, HandlingOfRateAndChannelCombinations) {
   2931  std::array<int, 3> sample_rates_hz = {16000, 32000, 48000};
   2932  std::array<int, 2> render_channel_counts = {1, 7};
   2933  std::array<int, 2> capture_channel_counts = {1, 7};
   2934  RunApmRateAndChannelTest(sample_rates_hz, render_channel_counts,
   2935                           capture_channel_counts);
   2936 }
   2937 
   2938 TEST(ApmConfiguration, HandlingOfChannelCombinations) {
   2939  std::array<int, 1> sample_rates_hz = {48000};
   2940  std::array<int, 8> render_channel_counts = {1, 2, 3, 4, 5, 6, 7, 8};
   2941  std::array<int, 8> capture_channel_counts = {1, 2, 3, 4, 5, 6, 7, 8};
   2942  RunApmRateAndChannelTest(sample_rates_hz, render_channel_counts,
   2943                           capture_channel_counts);
   2944 }
   2945 
   2946 TEST(ApmConfiguration, HandlingOfRateCombinations) {
   2947  // Test rates <= 96000 logged by Chrome UMA:
   2948  //  - WebRTC.AudioInputSampleRate
   2949  //  - WebRTC.AudioOutputSampleRate
   2950  // Higher rates are tested in AudioProcessingTest.Format, to keep the number
   2951  // of combinations in this test manageable.
   2952  std::array<int, 9> sample_rates_hz = {8000,  11025, 16000, 22050, 32000,
   2953                                        44100, 48000, 88200, 96000};
   2954  std::array<int, 1> render_channel_counts = {2};
   2955  std::array<int, 1> capture_channel_counts = {2};
   2956  RunApmRateAndChannelTest(sample_rates_hz, render_channel_counts,
   2957                           capture_channel_counts);
   2958 }
   2959 
   2960 TEST(ApmConfiguration, SelfAssignment) {
   2961  // At some point memory sanitizer was complaining about self-assigment.
   2962  // Make sure we don't regress.
   2963  AudioProcessing::Config config;
   2964  AudioProcessing::Config* config2 = &config;
   2965  *config2 = *config2;  // Workaround -Wself-assign-overloaded
   2966  SUCCEED();  // Real success is absence of defects from asan/msan/ubsan.
   2967 }
   2968 
   2969 TEST(AudioProcessing, GainController1ConfigEqual) {
   2970  AudioProcessing::Config::GainController1 a;
   2971  AudioProcessing::Config::GainController1 b;
   2972  EXPECT_EQ(a, b);
   2973 
   2974  Toggle(a.enabled);
   2975  b.enabled = a.enabled;
   2976  EXPECT_EQ(a, b);
   2977 
   2978  a.mode = AudioProcessing::Config::GainController1::Mode::kAdaptiveDigital;
   2979  b.mode = a.mode;
   2980  EXPECT_EQ(a, b);
   2981 
   2982  a.target_level_dbfs++;
   2983  b.target_level_dbfs = a.target_level_dbfs;
   2984  EXPECT_EQ(a, b);
   2985 
   2986  a.compression_gain_db++;
   2987  b.compression_gain_db = a.compression_gain_db;
   2988  EXPECT_EQ(a, b);
   2989 
   2990  Toggle(a.enable_limiter);
   2991  b.enable_limiter = a.enable_limiter;
   2992  EXPECT_EQ(a, b);
   2993 
   2994  auto& a_analog = a.analog_gain_controller;
   2995  auto& b_analog = b.analog_gain_controller;
   2996 
   2997  Toggle(a_analog.enabled);
   2998  b_analog.enabled = a_analog.enabled;
   2999  EXPECT_EQ(a, b);
   3000 
   3001  a_analog.startup_min_volume++;
   3002  b_analog.startup_min_volume = a_analog.startup_min_volume;
   3003  EXPECT_EQ(a, b);
   3004 
   3005  a_analog.clipped_level_min++;
   3006  b_analog.clipped_level_min = a_analog.clipped_level_min;
   3007  EXPECT_EQ(a, b);
   3008 
   3009  Toggle(a_analog.enable_digital_adaptive);
   3010  b_analog.enable_digital_adaptive = a_analog.enable_digital_adaptive;
   3011  EXPECT_EQ(a, b);
   3012 }
   3013 
   3014 // Checks that one differing parameter is sufficient to make two configs
   3015 // different.
   3016 TEST(AudioProcessing, GainController1ConfigNotEqual) {
   3017  AudioProcessing::Config::GainController1 a;
   3018  const AudioProcessing::Config::GainController1 b;
   3019 
   3020  Toggle(a.enabled);
   3021  EXPECT_NE(a, b);
   3022  a = b;
   3023 
   3024  a.mode = AudioProcessing::Config::GainController1::Mode::kAdaptiveDigital;
   3025  EXPECT_NE(a, b);
   3026  a = b;
   3027 
   3028  a.target_level_dbfs++;
   3029  EXPECT_NE(a, b);
   3030  a = b;
   3031 
   3032  a.compression_gain_db++;
   3033  EXPECT_NE(a, b);
   3034  a = b;
   3035 
   3036  Toggle(a.enable_limiter);
   3037  EXPECT_NE(a, b);
   3038  a = b;
   3039 
   3040  auto& a_analog = a.analog_gain_controller;
   3041  const auto& b_analog = b.analog_gain_controller;
   3042 
   3043  Toggle(a_analog.enabled);
   3044  EXPECT_NE(a, b);
   3045  a_analog = b_analog;
   3046 
   3047  a_analog.startup_min_volume++;
   3048  EXPECT_NE(a, b);
   3049  a_analog = b_analog;
   3050 
   3051  a_analog.clipped_level_min++;
   3052  EXPECT_NE(a, b);
   3053  a_analog = b_analog;
   3054 
   3055  Toggle(a_analog.enable_digital_adaptive);
   3056  EXPECT_NE(a, b);
   3057  a_analog = b_analog;
   3058 }
   3059 
   3060 TEST(AudioProcessing, GainController2ConfigEqual) {
   3061  AudioProcessing::Config::GainController2 a;
   3062  AudioProcessing::Config::GainController2 b;
   3063  EXPECT_EQ(a, b);
   3064 
   3065  Toggle(a.enabled);
   3066  b.enabled = a.enabled;
   3067  EXPECT_EQ(a, b);
   3068 
   3069  a.fixed_digital.gain_db += 1.0f;
   3070  b.fixed_digital.gain_db = a.fixed_digital.gain_db;
   3071  EXPECT_EQ(a, b);
   3072 
   3073  auto& a_adaptive = a.adaptive_digital;
   3074  auto& b_adaptive = b.adaptive_digital;
   3075 
   3076  Toggle(a_adaptive.enabled);
   3077  b_adaptive.enabled = a_adaptive.enabled;
   3078  EXPECT_EQ(a, b);
   3079 
   3080  a_adaptive.headroom_db += 1.0f;
   3081  b_adaptive.headroom_db = a_adaptive.headroom_db;
   3082  EXPECT_EQ(a, b);
   3083 
   3084  a_adaptive.max_gain_db += 1.0f;
   3085  b_adaptive.max_gain_db = a_adaptive.max_gain_db;
   3086  EXPECT_EQ(a, b);
   3087 
   3088  a_adaptive.initial_gain_db += 1.0f;
   3089  b_adaptive.initial_gain_db = a_adaptive.initial_gain_db;
   3090  EXPECT_EQ(a, b);
   3091 
   3092  a_adaptive.max_gain_change_db_per_second += 1.0f;
   3093  b_adaptive.max_gain_change_db_per_second =
   3094      a_adaptive.max_gain_change_db_per_second;
   3095  EXPECT_EQ(a, b);
   3096 
   3097  a_adaptive.max_output_noise_level_dbfs += 1.0f;
   3098  b_adaptive.max_output_noise_level_dbfs =
   3099      a_adaptive.max_output_noise_level_dbfs;
   3100  EXPECT_EQ(a, b);
   3101 }
   3102 
   3103 // Checks that one differing parameter is sufficient to make two configs
   3104 // different.
   3105 TEST(AudioProcessing, GainController2ConfigNotEqual) {
   3106  AudioProcessing::Config::GainController2 a;
   3107  const AudioProcessing::Config::GainController2 b;
   3108 
   3109  Toggle(a.enabled);
   3110  EXPECT_NE(a, b);
   3111  a = b;
   3112 
   3113  a.fixed_digital.gain_db += 1.0f;
   3114  EXPECT_NE(a, b);
   3115  a.fixed_digital = b.fixed_digital;
   3116 
   3117  auto& a_adaptive = a.adaptive_digital;
   3118  const auto& b_adaptive = b.adaptive_digital;
   3119 
   3120  Toggle(a_adaptive.enabled);
   3121  EXPECT_NE(a, b);
   3122  a_adaptive = b_adaptive;
   3123 
   3124  a_adaptive.headroom_db += 1.0f;
   3125  EXPECT_NE(a, b);
   3126  a_adaptive = b_adaptive;
   3127 
   3128  a_adaptive.max_gain_db += 1.0f;
   3129  EXPECT_NE(a, b);
   3130  a_adaptive = b_adaptive;
   3131 
   3132  a_adaptive.initial_gain_db += 1.0f;
   3133  EXPECT_NE(a, b);
   3134  a_adaptive = b_adaptive;
   3135 
   3136  a_adaptive.max_gain_change_db_per_second += 1.0f;
   3137  EXPECT_NE(a, b);
   3138  a_adaptive = b_adaptive;
   3139 
   3140  a_adaptive.max_output_noise_level_dbfs += 1.0f;
   3141  EXPECT_NE(a, b);
   3142  a_adaptive = b_adaptive;
   3143 }
   3144 
   3145 struct ApmFormatHandlingTestParams {
   3146  enum class ExpectedOutput {
   3147    kErrorAndUnmodified,
   3148    kErrorAndSilence,
   3149    kErrorAndCopyOfFirstChannel,
   3150    kErrorAndExactCopy,
   3151    kNoError
   3152  };
   3153 
   3154  StreamConfig input_config;
   3155  StreamConfig output_config;
   3156  ExpectedOutput expected_output;
   3157 };
   3158 
   3159 class ApmFormatHandlingTest
   3160    : public ::testing::TestWithParam<
   3161          std::tuple<StreamDirection, ApmFormatHandlingTestParams>> {
   3162 public:
   3163  ApmFormatHandlingTest()
   3164      : stream_direction_(std::get<0>(GetParam())),
   3165        test_params_(std::get<1>(GetParam())) {}
   3166 
   3167 protected:
   3168  ::testing::Message ProduceDebugMessage() {
   3169    return ::testing::Message()
   3170           << "input sample_rate_hz="
   3171           << test_params_.input_config.sample_rate_hz()
   3172           << " num_channels=" << test_params_.input_config.num_channels()
   3173           << ", output sample_rate_hz="
   3174           << test_params_.output_config.sample_rate_hz()
   3175           << " num_channels=" << test_params_.output_config.num_channels()
   3176           << ", stream_direction=" << stream_direction_ << ", expected_output="
   3177           << static_cast<int>(test_params_.expected_output);
   3178  }
   3179 
   3180  StreamDirection stream_direction_;
   3181  ApmFormatHandlingTestParams test_params_;
   3182 };
   3183 
   3184 INSTANTIATE_TEST_SUITE_P(
   3185    FormatValidation,
   3186    ApmFormatHandlingTest,
   3187    testing::Combine(
   3188        ::testing::Values(kForward, kReverse),
   3189        ::testing::Values(
   3190            // Test cases with values on the boundary of legal ranges.
   3191            ApmFormatHandlingTestParams{
   3192                StreamConfig(16000, 1), StreamConfig(8000, 1),
   3193                ApmFormatHandlingTestParams::ExpectedOutput::kNoError},
   3194            ApmFormatHandlingTestParams{
   3195                StreamConfig(8000, 1), StreamConfig(16000, 1),
   3196                ApmFormatHandlingTestParams::ExpectedOutput::kNoError},
   3197            ApmFormatHandlingTestParams{
   3198                StreamConfig(384000, 1), StreamConfig(16000, 1),
   3199                ApmFormatHandlingTestParams::ExpectedOutput::kNoError},
   3200            ApmFormatHandlingTestParams{
   3201                StreamConfig(16000, 1), StreamConfig(384000, 1),
   3202                ApmFormatHandlingTestParams::ExpectedOutput::kNoError},
   3203            ApmFormatHandlingTestParams{
   3204                StreamConfig(16000, 2), StreamConfig(16000, 1),
   3205                ApmFormatHandlingTestParams::ExpectedOutput::kNoError},
   3206            ApmFormatHandlingTestParams{
   3207                StreamConfig(16000, 3), StreamConfig(16000, 3),
   3208                ApmFormatHandlingTestParams::ExpectedOutput::kNoError},
   3209 
   3210            // Supported but incompatible formats.
   3211            ApmFormatHandlingTestParams{
   3212                StreamConfig(16000, 3), StreamConfig(16000, 2),
   3213                ApmFormatHandlingTestParams::ExpectedOutput::
   3214                    kErrorAndCopyOfFirstChannel},
   3215            ApmFormatHandlingTestParams{
   3216                StreamConfig(16000, 3), StreamConfig(16000, 4),
   3217                ApmFormatHandlingTestParams::ExpectedOutput::
   3218                    kErrorAndCopyOfFirstChannel},
   3219 
   3220            // Unsupported format and input / output mismatch.
   3221            ApmFormatHandlingTestParams{
   3222                StreamConfig(7900, 1), StreamConfig(16000, 1),
   3223                ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence},
   3224            ApmFormatHandlingTestParams{
   3225                StreamConfig(16000, 1), StreamConfig(7900, 1),
   3226                ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence},
   3227            ApmFormatHandlingTestParams{
   3228                StreamConfig(390000, 1), StreamConfig(16000, 1),
   3229                ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence},
   3230            ApmFormatHandlingTestParams{
   3231                StreamConfig(16000, 1), StreamConfig(390000, 1),
   3232                ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence},
   3233            ApmFormatHandlingTestParams{
   3234                StreamConfig(-16000, 1), StreamConfig(16000, 1),
   3235                ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence},
   3236 
   3237            // Unsupported format but input / output formats match.
   3238            ApmFormatHandlingTestParams{StreamConfig(7900, 1),
   3239                                        StreamConfig(7900, 1),
   3240                                        ApmFormatHandlingTestParams::
   3241                                            ExpectedOutput::kErrorAndExactCopy},
   3242            ApmFormatHandlingTestParams{StreamConfig(390000, 1),
   3243                                        StreamConfig(390000, 1),
   3244                                        ApmFormatHandlingTestParams::
   3245                                            ExpectedOutput::kErrorAndExactCopy},
   3246 
   3247            // Unsupported but identical sample rate, channel mismatch.
   3248            ApmFormatHandlingTestParams{
   3249                StreamConfig(7900, 1), StreamConfig(7900, 2),
   3250                ApmFormatHandlingTestParams::ExpectedOutput::
   3251                    kErrorAndCopyOfFirstChannel},
   3252            ApmFormatHandlingTestParams{
   3253                StreamConfig(7900, 2), StreamConfig(7900, 1),
   3254                ApmFormatHandlingTestParams::ExpectedOutput::
   3255                    kErrorAndCopyOfFirstChannel},
   3256 
   3257            // Test cases with meaningless output format.
   3258            ApmFormatHandlingTestParams{
   3259                StreamConfig(16000, 1), StreamConfig(-16000, 1),
   3260                ApmFormatHandlingTestParams::ExpectedOutput::
   3261                    kErrorAndUnmodified},
   3262            ApmFormatHandlingTestParams{
   3263                StreamConfig(-16000, 1), StreamConfig(-16000, 1),
   3264                ApmFormatHandlingTestParams::ExpectedOutput::
   3265                    kErrorAndUnmodified})));
   3266 
   3267 TEST_P(ApmFormatHandlingTest, IntApi) {
   3268  SCOPED_TRACE(ProduceDebugMessage());
   3269 
   3270  // Set up input and output data.
   3271  const size_t num_input_samples =
   3272      test_params_.input_config.num_channels() *
   3273      std::abs(test_params_.input_config.sample_rate_hz() / 100);
   3274  const size_t num_output_samples =
   3275      test_params_.output_config.num_channels() *
   3276      std::abs(test_params_.output_config.sample_rate_hz() / 100);
   3277  std::vector<int16_t> input_block(num_input_samples);
   3278  for (int i = 0; i < static_cast<int>(input_block.size()); ++i) {
   3279    input_block[i] = i;
   3280  }
   3281  std::vector<int16_t> output_block(num_output_samples);
   3282  constexpr int kUnlikelyOffset = 37;
   3283  for (int i = 0; i < static_cast<int>(output_block.size()); ++i) {
   3284    output_block[i] = i - kUnlikelyOffset;
   3285  }
   3286 
   3287  // Call APM.
   3288  scoped_refptr<AudioProcessing> ap =
   3289      BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
   3290  int error;
   3291  if (stream_direction_ == kForward) {
   3292    error = ap->ProcessStream(input_block.data(), test_params_.input_config,
   3293                              test_params_.output_config, output_block.data());
   3294  } else {
   3295    error = ap->ProcessReverseStream(
   3296        input_block.data(), test_params_.input_config,
   3297        test_params_.output_config, output_block.data());
   3298  }
   3299 
   3300  // Check output.
   3301  switch (test_params_.expected_output) {
   3302    case ApmFormatHandlingTestParams::ExpectedOutput::kNoError:
   3303      EXPECT_EQ(error, AudioProcessing::kNoError);
   3304      break;
   3305    case ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndUnmodified:
   3306      EXPECT_NE(error, AudioProcessing::kNoError);
   3307      for (int i = 0; i < static_cast<int>(output_block.size()); ++i) {
   3308        EXPECT_EQ(output_block[i], i - kUnlikelyOffset);
   3309      }
   3310      break;
   3311    case ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence:
   3312      EXPECT_NE(error, AudioProcessing::kNoError);
   3313      for (int i = 0; i < static_cast<int>(output_block.size()); ++i) {
   3314        EXPECT_EQ(output_block[i], 0);
   3315      }
   3316      break;
   3317    case ApmFormatHandlingTestParams::ExpectedOutput::
   3318        kErrorAndCopyOfFirstChannel:
   3319      EXPECT_NE(error, AudioProcessing::kNoError);
   3320      for (size_t ch = 0; ch < test_params_.output_config.num_channels();
   3321           ++ch) {
   3322        for (size_t i = 0; i < test_params_.output_config.num_frames(); ++i) {
   3323          EXPECT_EQ(
   3324              output_block[ch + i * test_params_.output_config.num_channels()],
   3325              static_cast<int16_t>(i *
   3326                                   test_params_.input_config.num_channels()));
   3327        }
   3328      }
   3329      break;
   3330    case ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndExactCopy:
   3331      EXPECT_NE(error, AudioProcessing::kNoError);
   3332      for (int i = 0; i < static_cast<int>(output_block.size()); ++i) {
   3333        EXPECT_EQ(output_block[i], i);
   3334      }
   3335      break;
   3336  }
   3337 }
   3338 
   3339 TEST_P(ApmFormatHandlingTest, FloatApi) {
   3340  SCOPED_TRACE(ProduceDebugMessage());
   3341 
   3342  // Set up input and output data.
   3343  const size_t input_samples_per_channel =
   3344      std::abs(test_params_.input_config.sample_rate_hz()) / 100;
   3345  const size_t output_samples_per_channel =
   3346      std::abs(test_params_.output_config.sample_rate_hz()) / 100;
   3347  const size_t input_num_channels = test_params_.input_config.num_channels();
   3348  const size_t output_num_channels = test_params_.output_config.num_channels();
   3349  ChannelBuffer<float> input_block(input_samples_per_channel,
   3350                                   input_num_channels);
   3351  ChannelBuffer<float> output_block(output_samples_per_channel,
   3352                                    output_num_channels);
   3353  for (size_t ch = 0; ch < input_num_channels; ++ch) {
   3354    for (size_t i = 0; i < input_samples_per_channel; ++i) {
   3355      input_block.channels()[ch][i] = ch + i * input_num_channels;
   3356    }
   3357  }
   3358  constexpr int kUnlikelyOffset = 37;
   3359  for (size_t ch = 0; ch < output_num_channels; ++ch) {
   3360    for (size_t i = 0; i < output_samples_per_channel; ++i) {
   3361      output_block.channels()[ch][i] =
   3362          ch + i * output_num_channels - kUnlikelyOffset;
   3363    }
   3364  }
   3365 
   3366  // Call APM.
   3367  scoped_refptr<AudioProcessing> ap =
   3368      BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
   3369  int error;
   3370  if (stream_direction_ == kForward) {
   3371    error =
   3372        ap->ProcessStream(input_block.channels(), test_params_.input_config,
   3373                          test_params_.output_config, output_block.channels());
   3374  } else {
   3375    error = ap->ProcessReverseStream(
   3376        input_block.channels(), test_params_.input_config,
   3377        test_params_.output_config, output_block.channels());
   3378  }
   3379 
   3380  // Check output.
   3381  switch (test_params_.expected_output) {
   3382    case ApmFormatHandlingTestParams::ExpectedOutput::kNoError:
   3383      EXPECT_EQ(error, AudioProcessing::kNoError);
   3384      break;
   3385    case ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndUnmodified:
   3386      EXPECT_NE(error, AudioProcessing::kNoError);
   3387      for (size_t ch = 0; ch < output_num_channels; ++ch) {
   3388        for (size_t i = 0; i < output_samples_per_channel; ++i) {
   3389          EXPECT_EQ(output_block.channels()[ch][i],
   3390                    ch + i * output_num_channels - kUnlikelyOffset);
   3391        }
   3392      }
   3393      break;
   3394    case ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence:
   3395      EXPECT_NE(error, AudioProcessing::kNoError);
   3396      for (size_t ch = 0; ch < output_num_channels; ++ch) {
   3397        for (size_t i = 0; i < output_samples_per_channel; ++i) {
   3398          EXPECT_EQ(output_block.channels()[ch][i], 0);
   3399        }
   3400      }
   3401      break;
   3402    case ApmFormatHandlingTestParams::ExpectedOutput::
   3403        kErrorAndCopyOfFirstChannel:
   3404      EXPECT_NE(error, AudioProcessing::kNoError);
   3405      for (size_t ch = 0; ch < output_num_channels; ++ch) {
   3406        for (size_t i = 0; i < output_samples_per_channel; ++i) {
   3407          EXPECT_EQ(output_block.channels()[ch][i],
   3408                    input_block.channels()[0][i]);
   3409        }
   3410      }
   3411      break;
   3412    case ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndExactCopy:
   3413      EXPECT_NE(error, AudioProcessing::kNoError);
   3414      for (size_t ch = 0; ch < output_num_channels; ++ch) {
   3415        for (size_t i = 0; i < output_samples_per_channel; ++i) {
   3416          EXPECT_EQ(output_block.channels()[ch][i],
   3417                    input_block.channels()[ch][i]);
   3418        }
   3419      }
   3420      break;
   3421  }
   3422 }
   3423 
   3424 TEST(ApmAnalyzeReverseStreamFormatTest, AnalyzeReverseStream) {
   3425  for (auto&& [input_config, expect_error] :
   3426       {std::tuple(StreamConfig(16000, 2), /*expect_error=*/false),
   3427        std::tuple(StreamConfig(8000, 1), /*expect_error=*/false),
   3428        std::tuple(StreamConfig(384000, 1), /*expect_error=*/false),
   3429        std::tuple(StreamConfig(7900, 1), /*expect_error=*/true),
   3430        std::tuple(StreamConfig(390000, 1), /*expect_error=*/true),
   3431        std::tuple(StreamConfig(16000, 0), /*expect_error=*/true),
   3432        std::tuple(StreamConfig(-16000, 0), /*expect_error=*/true)}) {
   3433    SCOPED_TRACE(::testing::Message()
   3434                 << "sample_rate_hz=" << input_config.sample_rate_hz()
   3435                 << " num_channels=" << input_config.num_channels());
   3436 
   3437    // Set up input data.
   3438    ChannelBuffer<float> input_block(
   3439        std::abs(input_config.sample_rate_hz()) / 100,
   3440        input_config.num_channels());
   3441 
   3442    // Call APM.
   3443    scoped_refptr<AudioProcessing> ap =
   3444        BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
   3445    int error = ap->AnalyzeReverseStream(input_block.channels(), input_config);
   3446 
   3447    // Check output.
   3448    if (expect_error) {
   3449      EXPECT_NE(error, AudioProcessing::kNoError);
   3450    } else {
   3451      EXPECT_EQ(error, AudioProcessing::kNoError);
   3452    }
   3453  }
   3454 }
   3455 
   3456 }  // namespace
   3457 }  // namespace webrtc