Break apart AudioCodingModule and AcmReceiver

This change makes AudioCodingModule a pure sender and AcmReceiver a pure
receiver.

The Config struct is in practice no longer used by AudioCodingModule,
so a new definition is included in AcmReceiver. The old definition
remains in AudioCodingModule while downstream clients are being
updated.

Bug: webrtc:14867
Change-Id: If0d0b4214c5aa278cf6c85c5b62c6da644de20e0
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291533
Reviewed-by: Tomas Lundqvist <tomasl@google.com>
Commit-Queue: Henrik Lundin <henrik.lundin@webrtc.org>
Reviewed-by: Jakob Ivarsson‎ <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39244}
diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc
index 04ccc98..5b7ff7b 100644
--- a/audio/channel_receive.cc
+++ b/audio/channel_receive.cc
@@ -65,13 +65,13 @@
 constexpr int kVoiceEngineMinMinPlayoutDelayMs = 0;
 constexpr int kVoiceEngineMaxMinPlayoutDelayMs = 10000;
 
-AudioCodingModule::Config AcmConfig(
+acm2::AcmReceiver::Config AcmConfig(
     NetEqFactory* neteq_factory,
     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
     absl::optional<AudioCodecPairId> codec_pair_id,
     size_t jitter_buffer_max_packets,
     bool jitter_buffer_fast_playout) {
-  AudioCodingModule::Config acm_config;
+  acm2::AcmReceiver::Config acm_config;
   acm_config.neteq_factory = neteq_factory;
   acm_config.decoder_factory = decoder_factory;
   acm_config.neteq_config.codec_pair_id = codec_pair_id;
diff --git a/audio/channel_send.cc b/audio/channel_send.cc
index d00688f..3e734aa 100644
--- a/audio/channel_send.cc
+++ b/audio/channel_send.cc
@@ -472,7 +472,7 @@
       encoder_queue_(task_queue_factory->CreateTaskQueue(
           "AudioEncoder",
           TaskQueueFactory::Priority::NORMAL)) {
-  audio_coding_.reset(AudioCodingModule::Create(AudioCodingModule::Config()));
+  audio_coding_ = AudioCodingModule::Create();
 
   RtpRtcpInterface::Configuration configuration;
   configuration.bandwidth_callback = rtcp_observer_.get();
diff --git a/audio/voip/audio_egress.cc b/audio/voip/audio_egress.cc
index 1162824..ae98d91 100644
--- a/audio/voip/audio_egress.cc
+++ b/audio/voip/audio_egress.cc
@@ -22,7 +22,7 @@
                          TaskQueueFactory* task_queue_factory)
     : rtp_rtcp_(rtp_rtcp),
       rtp_sender_audio_(clock, rtp_rtcp_->RtpSender()),
-      audio_coding_(AudioCodingModule::Create(AudioCodingModule::Config())),
+      audio_coding_(AudioCodingModule::Create()),
       encoder_queue_(task_queue_factory->CreateTaskQueue(
           "AudioEncoder",
           TaskQueueFactory::Priority::NORMAL)) {
diff --git a/audio/voip/audio_ingress.cc b/audio/voip/audio_ingress.cc
index 0f9c9cc..26191c2 100644
--- a/audio/voip/audio_ingress.cc
+++ b/audio/voip/audio_ingress.cc
@@ -29,9 +29,9 @@
 
 namespace {
 
-AudioCodingModule::Config CreateAcmConfig(
+acm2::AcmReceiver::Config CreateAcmConfig(
     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory) {
-  AudioCodingModule::Config acm_config;
+  acm2::AcmReceiver::Config acm_config;
   acm_config.neteq_config.enable_muted_state = true;
   acm_config.decoder_factory = decoder_factory;
   return acm_config;
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index dddc3ed..fc07126 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -1082,8 +1082,6 @@
       "test/TestVADDTX.cc",
       "test/TestVADDTX.h",
       "test/Tester.cc",
-      "test/TwoWayCommunication.cc",
-      "test/TwoWayCommunication.h",
       "test/target_delay_unittest.cc",
     ]
     deps = [
diff --git a/modules/audio_coding/acm2/acm_receive_test.cc b/modules/audio_coding/acm2/acm_receive_test.cc
index 8bc76cd..66f6255 100644
--- a/modules/audio_coding/acm2/acm_receive_test.cc
+++ b/modules/audio_coding/acm2/acm_receive_test.cc
@@ -25,10 +25,10 @@
 namespace test {
 
 namespace {
-AudioCodingModule::Config MakeAcmConfig(
-    Clock* clock,
+acm2::AcmReceiver::Config MakeAcmConfig(
+    Clock& clock,
     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory) {
-  AudioCodingModule::Config config;
+  acm2::AcmReceiver::Config config;
   config.clock = clock;
   config.decoder_factory = std::move(decoder_factory);
   return config;
@@ -42,8 +42,8 @@
     NumOutputChannels exptected_output_channels,
     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory)
     : clock_(0),
-      acm_(webrtc::AudioCodingModule::Create(
-          MakeAcmConfig(&clock_, std::move(decoder_factory)))),
+      acm_receiver_(std::make_unique<acm2::AcmReceiver>(
+          MakeAcmConfig(clock_, std::move(decoder_factory)))),
       packet_source_(packet_source),
       audio_sink_(audio_sink),
       output_freq_hz_(output_freq_hz),
@@ -52,43 +52,43 @@
 AcmReceiveTestOldApi::~AcmReceiveTestOldApi() = default;
 
 void AcmReceiveTestOldApi::RegisterDefaultCodecs() {
-  acm_->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
-                          {104, {"ISAC", 32000, 1}},
-                          {107, {"L16", 8000, 1}},
-                          {108, {"L16", 16000, 1}},
-                          {109, {"L16", 32000, 1}},
-                          {111, {"L16", 8000, 2}},
-                          {112, {"L16", 16000, 2}},
-                          {113, {"L16", 32000, 2}},
-                          {0, {"PCMU", 8000, 1}},
-                          {110, {"PCMU", 8000, 2}},
-                          {8, {"PCMA", 8000, 1}},
-                          {118, {"PCMA", 8000, 2}},
-                          {102, {"ILBC", 8000, 1}},
-                          {9, {"G722", 8000, 1}},
-                          {119, {"G722", 8000, 2}},
-                          {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
-                          {13, {"CN", 8000, 1}},
-                          {98, {"CN", 16000, 1}},
-                          {99, {"CN", 32000, 1}}});
+  acm_receiver_->SetCodecs({{103, {"ISAC", 16000, 1}},
+                            {104, {"ISAC", 32000, 1}},
+                            {107, {"L16", 8000, 1}},
+                            {108, {"L16", 16000, 1}},
+                            {109, {"L16", 32000, 1}},
+                            {111, {"L16", 8000, 2}},
+                            {112, {"L16", 16000, 2}},
+                            {113, {"L16", 32000, 2}},
+                            {0, {"PCMU", 8000, 1}},
+                            {110, {"PCMU", 8000, 2}},
+                            {8, {"PCMA", 8000, 1}},
+                            {118, {"PCMA", 8000, 2}},
+                            {102, {"ILBC", 8000, 1}},
+                            {9, {"G722", 8000, 1}},
+                            {119, {"G722", 8000, 2}},
+                            {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
+                            {13, {"CN", 8000, 1}},
+                            {98, {"CN", 16000, 1}},
+                            {99, {"CN", 32000, 1}}});
 }
 
 // Remaps payload types from ACM's default to those used in the resource file
 // neteq_universal_new.rtp.
 void AcmReceiveTestOldApi::RegisterNetEqTestCodecs() {
-  acm_->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
-                          {104, {"ISAC", 32000, 1}},
-                          {93, {"L16", 8000, 1}},
-                          {94, {"L16", 16000, 1}},
-                          {95, {"L16", 32000, 1}},
-                          {0, {"PCMU", 8000, 1}},
-                          {8, {"PCMA", 8000, 1}},
-                          {102, {"ILBC", 8000, 1}},
-                          {9, {"G722", 8000, 1}},
-                          {120, {"OPUS", 48000, 2}},
-                          {13, {"CN", 8000, 1}},
-                          {98, {"CN", 16000, 1}},
-                          {99, {"CN", 32000, 1}}});
+  acm_receiver_->SetCodecs({{103, {"ISAC", 16000, 1}},
+                            {104, {"ISAC", 32000, 1}},
+                            {93, {"L16", 8000, 1}},
+                            {94, {"L16", 16000, 1}},
+                            {95, {"L16", 32000, 1}},
+                            {0, {"PCMU", 8000, 1}},
+                            {8, {"PCMA", 8000, 1}},
+                            {102, {"ILBC", 8000, 1}},
+                            {9, {"G722", 8000, 1}},
+                            {120, {"OPUS", 48000, 2}},
+                            {13, {"CN", 8000, 1}},
+                            {98, {"CN", 16000, 1}},
+                            {99, {"CN", 32000, 1}}});
 }
 
 void AcmReceiveTestOldApi::Run() {
@@ -98,8 +98,8 @@
     while (clock_.TimeInMilliseconds() < packet->time_ms()) {
       AudioFrame output_frame;
       bool muted;
-      EXPECT_EQ(0,
-                acm_->PlayoutData10Ms(output_freq_hz_, &output_frame, &muted));
+      EXPECT_EQ(
+          0, acm_receiver_->GetAudio(output_freq_hz_, &output_frame, &muted));
       ASSERT_EQ(output_freq_hz_, output_frame.sample_rate_hz_);
       ASSERT_FALSE(muted);
       const size_t samples_per_block =
@@ -119,10 +119,10 @@
       AfterGetAudio();
     }
 
-    EXPECT_EQ(0, acm_->IncomingPacket(
-                     packet->payload(),
-                     static_cast<int32_t>(packet->payload_length_bytes()),
-                     packet->header()))
+    EXPECT_EQ(0, acm_receiver_->InsertPacket(
+                     packet->header(),
+                     rtc::ArrayView<const uint8_t>(
+                         packet->payload(), packet->payload_length_bytes())))
         << "Failure when inserting packet:" << std::endl
         << "  PT = " << static_cast<int>(packet->header().payloadType)
         << std::endl
diff --git a/modules/audio_coding/acm2/acm_receive_test.h b/modules/audio_coding/acm2/acm_receive_test.h
index 2095ef9..d0195dd 100644
--- a/modules/audio_coding/acm2/acm_receive_test.h
+++ b/modules/audio_coding/acm2/acm_receive_test.h
@@ -18,6 +18,7 @@
 
 #include "api/audio_codecs/audio_decoder_factory.h"
 #include "api/scoped_refptr.h"
+#include "modules/audio_coding/acm2/acm_receiver.h"
 #include "system_wrappers/include/clock.h"
 
 namespace webrtc {
@@ -57,14 +58,12 @@
   // Runs the test and returns true if successful.
   void Run();
 
-  AudioCodingModule* get_acm() { return acm_.get(); }
-
  protected:
   // Method is called after each block of output audio is received from ACM.
   virtual void AfterGetAudio() {}
 
   SimulatedClock clock_;
-  std::unique_ptr<AudioCodingModule> acm_;
+  std::unique_ptr<acm2::AcmReceiver> acm_receiver_;
   PacketSource* packet_source_;
   AudioSink* audio_sink_;
   int output_freq_hz_;
diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc
index a8fded6..a77e472 100644
--- a/modules/audio_coding/acm2/acm_receiver.cc
+++ b/modules/audio_coding/acm2/acm_receiver.cc
@@ -56,11 +56,6 @@
   neteq_config.enable_post_decode_vad = true;
 }
 
-AcmReceiver::Config::Config(const AudioCodingModule::Config& acm_config)
-    : neteq_config(acm_config.neteq_config),
-      clock(*acm_config.clock),
-      decoder_factory(acm_config.decoder_factory) {}
-
 AcmReceiver::Config::Config(const Config&) = default;
 AcmReceiver::Config::~Config() = default;
 
@@ -76,9 +71,6 @@
          sizeof(int16_t) * AudioFrame::kMaxDataSizeSamples);
 }
 
-AcmReceiver::AcmReceiver(const AudioCodingModule::Config& acm_config)
-    : AcmReceiver(Config(acm_config)) {}
-
 AcmReceiver::~AcmReceiver() = default;
 
 int AcmReceiver::SetMinimumDelay(int delay_ms) {
diff --git a/modules/audio_coding/acm2/acm_receiver.h b/modules/audio_coding/acm2/acm_receiver.h
index 25105ec..820150a 100644
--- a/modules/audio_coding/acm2/acm_receiver.h
+++ b/modules/audio_coding/acm2/acm_receiver.h
@@ -28,7 +28,6 @@
 #include "api/neteq/neteq_factory.h"
 #include "modules/audio_coding/acm2/acm_resampler.h"
 #include "modules/audio_coding/acm2/call_statistics.h"
-#include "modules/audio_coding/include/audio_coding_module.h"
 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
 #include "rtc_base/synchronization/mutex.h"
 #include "rtc_base/thread_annotations.h"
@@ -46,7 +45,6 @@
   struct Config {
     explicit Config(
         rtc::scoped_refptr<AudioDecoderFactory> decoder_factory = nullptr);
-    explicit Config(const AudioCodingModule::Config& acm_config);
     Config(const Config&);
     ~Config();
 
@@ -58,9 +56,6 @@
 
   // Constructor of the class
   explicit AcmReceiver(const Config& config);
-  // Deprecated constructor.
-  // TODO(webrtc:14867): Remove when downstream projects are ready.
-  explicit AcmReceiver(const AudioCodingModule::Config& acm_config);
 
   // Destructor of the class.
   ~AcmReceiver();
diff --git a/modules/audio_coding/acm2/acm_receiver_unittest.cc b/modules/audio_coding/acm2/acm_receiver_unittest.cc
index 6dd44b6..a5095f0 100644
--- a/modules/audio_coding/acm2/acm_receiver_unittest.cc
+++ b/modules/audio_coding/acm2/acm_receiver_unittest.cc
@@ -44,11 +44,10 @@
   ~AcmReceiverTestOldApi() {}
 
   void SetUp() override {
-    acm_.reset(AudioCodingModule::Create(config_));
+    acm_ = AudioCodingModule::Create();
     receiver_.reset(new AcmReceiver(config_));
     ASSERT_TRUE(receiver_.get() != NULL);
     ASSERT_TRUE(acm_.get() != NULL);
-    acm_->InitializeReceiver();
     acm_->RegisterTransportCallback(this);
 
     rtp_header_.sequenceNumber = 0;
@@ -135,7 +134,7 @@
       CreateBuiltinAudioEncoderFactory();
   const rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_ =
       CreateBuiltinAudioDecoderFactory();
-  AudioCodingModule::Config config_;
+  acm2::AcmReceiver::Config config_;
   std::unique_ptr<AcmReceiver> receiver_;
   std::unique_ptr<AudioCodingModule> acm_;
   RTPHeader rtp_header_;
@@ -383,6 +382,24 @@
   EXPECT_EQ(0, stats.decoded_muted_output);
 }
 
+#if defined(WEBRTC_ANDROID)
+#define MAYBE_VerifyOutputFrame DISABLED_VerifyOutputFrame
+#else
+#define MAYBE_VerifyOutputFrame VerifyOutputFrame
+#endif
+TEST_F(AcmReceiverTestOldApi, MAYBE_VerifyOutputFrame) {
+  AudioFrame audio_frame;
+  const int kSampleRateHz = 32000;
+  bool muted;
+  EXPECT_EQ(0, receiver_->GetAudio(kSampleRateHz, &audio_frame, &muted));
+  ASSERT_FALSE(muted);
+  EXPECT_EQ(0u, audio_frame.timestamp_);
+  EXPECT_GT(audio_frame.num_channels_, 0u);
+  EXPECT_EQ(static_cast<size_t>(kSampleRateHz / 100),
+            audio_frame.samples_per_channel_);
+  EXPECT_EQ(kSampleRateHz, audio_frame.sample_rate_hz_);
+}
+
 // Insert some packets and pull audio. Check statistics are valid. Then,
 // simulate packet loss and check if PLC and PLC-to-CNG statistics are
 // correctly updated.
diff --git a/modules/audio_coding/acm2/acm_send_test.cc b/modules/audio_coding/acm2/acm_send_test.cc
index 3e65f94..fddaa87 100644
--- a/modules/audio_coding/acm2/acm_send_test.cc
+++ b/modules/audio_coding/acm2/acm_send_test.cc
@@ -32,12 +32,7 @@
                                      int source_rate_hz,
                                      int test_duration_ms)
     : clock_(0),
-      acm_(webrtc::AudioCodingModule::Create([this] {
-        AudioCodingModule::Config config;
-        config.clock = &clock_;
-        config.decoder_factory = CreateBuiltinAudioDecoderFactory();
-        return config;
-      }())),
+      acm_(webrtc::AudioCodingModule::Create()),
       audio_source_(audio_source),
       source_rate_hz_(source_rate_hz),
       input_block_size_samples_(
diff --git a/modules/audio_coding/acm2/audio_coding_module.cc b/modules/audio_coding/acm2/audio_coding_module.cc
index 4367ab0..9618ad2 100644
--- a/modules/audio_coding/acm2/audio_coding_module.cc
+++ b/modules/audio_coding/acm2/audio_coding_module.cc
@@ -16,7 +16,6 @@
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
 #include "api/array_view.h"
-#include "modules/audio_coding/acm2/acm_receiver.h"
 #include "modules/audio_coding/acm2/acm_remixing.h"
 #include "modules/audio_coding/acm2/acm_resampler.h"
 #include "modules/include/module_common_types.h"
@@ -41,7 +40,7 @@
 
 class AudioCodingModuleImpl final : public AudioCodingModule {
  public:
-  explicit AudioCodingModuleImpl(const AudioCodingModule::Config& config);
+  explicit AudioCodingModuleImpl();
   ~AudioCodingModuleImpl() override;
 
   /////////////////////////////////////////
@@ -66,31 +65,9 @@
   int SetPacketLossRate(int loss_rate) override;
 
   /////////////////////////////////////////
-  //   Receiver
-  //
-
-  // Initialize receiver, resets codec database etc.
-  int InitializeReceiver() override;
-
-  void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs) override;
-
-  // Incoming packet from network parsed and ready for decode.
-  int IncomingPacket(const uint8_t* incoming_payload,
-                     const size_t payload_length,
-                     const RTPHeader& rtp_info) override;
-
-  // Get 10 milliseconds of raw audio data to play out, and
-  // automatic resample to the requested frequency if > 0.
-  int PlayoutData10Ms(int desired_freq_hz,
-                      AudioFrame* audio_frame,
-                      bool* muted) override;
-
-  /////////////////////////////////////////
   //   Statistics
   //
 
-  int GetNetworkStatistics(NetworkStatistics* statistics) override;
-
   ANAStats GetANAStats() const override;
 
   int GetTargetBitrate() const override;
@@ -134,8 +111,6 @@
              absl::optional<int64_t> absolute_capture_timestamp_ms)
       RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_mutex_);
 
-  int InitializeReceiverSafe() RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_mutex_);
-
   bool HaveValidEncoder(absl::string_view caller_name) const
       RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_mutex_);
 
@@ -163,7 +138,6 @@
   uint32_t expected_codec_ts_ RTC_GUARDED_BY(acm_mutex_);
   uint32_t expected_in_ts_ RTC_GUARDED_BY(acm_mutex_);
   acm2::ACMResampler resampler_ RTC_GUARDED_BY(acm_mutex_);
-  acm2::AcmReceiver receiver_;  // AcmReceiver has it's own internal lock.
   ChangeLogger bitrate_logger_ RTC_GUARDED_BY(acm_mutex_);
 
   // Current encoder stack, provided by a call to RegisterEncoder.
@@ -172,8 +146,6 @@
   // This is to keep track of CN instances where we can send DTMFs.
   uint8_t previous_pltype_ RTC_GUARDED_BY(acm_mutex_);
 
-  bool receiver_initialized_ RTC_GUARDED_BY(acm_mutex_);
-
   AudioFrame preprocess_frame_ RTC_GUARDED_BY(acm_mutex_);
   bool first_10ms_data_ RTC_GUARDED_BY(acm_mutex_);
 
@@ -206,23 +178,17 @@
   }
 }
 
-AudioCodingModuleImpl::AudioCodingModuleImpl(
-    const AudioCodingModule::Config& config)
+AudioCodingModuleImpl::AudioCodingModuleImpl()
     : expected_codec_ts_(0xD87F3F9F),
       expected_in_ts_(0xD87F3F9F),
-      receiver_(config),
       bitrate_logger_("WebRTC.Audio.TargetBitrateInKbps"),
       encoder_stack_(nullptr),
       previous_pltype_(255),
-      receiver_initialized_(false),
       first_10ms_data_(false),
       first_frame_(true),
       packetization_callback_(NULL),
       codec_histogram_bins_log_(),
       number_of_consecutive_empty_packets_(0) {
-  if (InitializeReceiverSafe() < 0) {
-    RTC_LOG(LS_ERROR) << "Cannot initialize receiver";
-  }
   RTC_LOG(LS_INFO) << "Created";
 }
 
@@ -529,67 +495,9 @@
 }
 
 /////////////////////////////////////////
-//   Receiver
-//
-
-int AudioCodingModuleImpl::InitializeReceiver() {
-  MutexLock lock(&acm_mutex_);
-  return InitializeReceiverSafe();
-}
-
-// Initialize receiver, resets codec database etc.
-int AudioCodingModuleImpl::InitializeReceiverSafe() {
-  // If the receiver is already initialized then we want to destroy any
-  // existing decoders. After a call to this function, we should have a clean
-  // start-up.
-  if (receiver_initialized_)
-    receiver_.RemoveAllCodecs();
-  receiver_.FlushBuffers();
-
-  receiver_initialized_ = true;
-  return 0;
-}
-
-void AudioCodingModuleImpl::SetReceiveCodecs(
-    const std::map<int, SdpAudioFormat>& codecs) {
-  MutexLock lock(&acm_mutex_);
-  receiver_.SetCodecs(codecs);
-}
-
-// Incoming packet from network parsed and ready for decode.
-int AudioCodingModuleImpl::IncomingPacket(const uint8_t* incoming_payload,
-                                          const size_t payload_length,
-                                          const RTPHeader& rtp_header) {
-  RTC_DCHECK_EQ(payload_length == 0, incoming_payload == nullptr);
-  return receiver_.InsertPacket(
-      rtp_header,
-      rtc::ArrayView<const uint8_t>(incoming_payload, payload_length));
-}
-
-// Get 10 milliseconds of raw audio data to play out.
-// Automatic resample to the requested frequency.
-int AudioCodingModuleImpl::PlayoutData10Ms(int desired_freq_hz,
-                                           AudioFrame* audio_frame,
-                                           bool* muted) {
-  // GetAudio always returns 10 ms, at the requested sample rate.
-  if (receiver_.GetAudio(desired_freq_hz, audio_frame, muted) != 0) {
-    RTC_LOG(LS_ERROR) << "PlayoutData failed, RecOut Failed";
-    return -1;
-  }
-  return 0;
-}
-
-/////////////////////////////////////////
 //   Statistics
 //
 
-// TODO(turajs) change the return value to void. Also change the corresponding
-// NetEq function.
-int AudioCodingModuleImpl::GetNetworkStatistics(NetworkStatistics* statistics) {
-  receiver_.GetNetworkStatistics(statistics);
-  return 0;
-}
-
 bool AudioCodingModuleImpl::HaveValidEncoder(
     absl::string_view caller_name) const {
   if (!encoder_stack_) {
@@ -617,21 +525,12 @@
 
 }  // namespace
 
-AudioCodingModule::Config::Config(
-    rtc::scoped_refptr<AudioDecoderFactory> decoder_factory)
-    : neteq_config(),
-      clock(Clock::GetRealTimeClock()),
-      decoder_factory(decoder_factory) {
-  // Post-decode VAD is disabled by default in NetEq, however, Audio
-  // Conference Mixer relies on VAD decisions and fails without them.
-  neteq_config.enable_post_decode_vad = true;
+std::unique_ptr<AudioCodingModule> AudioCodingModule::Create() {
+  return std::make_unique<AudioCodingModuleImpl>();
 }
 
-AudioCodingModule::Config::Config(const Config&) = default;
-AudioCodingModule::Config::~Config() = default;
-
 AudioCodingModule* AudioCodingModule::Create(const Config& config) {
-  return new AudioCodingModuleImpl(config);
+  return new AudioCodingModuleImpl();
 }
 
 }  // namespace webrtc
diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
index f1eb81c..42f4a7e 100644
--- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc
+++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
@@ -172,12 +172,11 @@
   void TearDown() {}
 
   void SetUp() {
-    acm_.reset(AudioCodingModule::Create([this] {
-      AudioCodingModule::Config config;
-      config.clock = clock_;
-      config.decoder_factory = CreateBuiltinAudioDecoderFactory();
-      return config;
-    }()));
+    acm_ = AudioCodingModule::Create();
+    acm2::AcmReceiver::Config config;
+    config.clock = *clock_;
+    config.decoder_factory = CreateBuiltinAudioDecoderFactory();
+    acm_receiver_ = std::make_unique<acm2::AcmReceiver>(config);
 
     rtp_utility_->Populate(&rtp_header_);
 
@@ -200,7 +199,7 @@
   }
 
   virtual void RegisterCodec() {
-    acm_->SetReceiveCodecs({{kPayloadType, *audio_format_}});
+    acm_receiver_->SetCodecs({{kPayloadType, *audio_format_}});
     acm_->SetEncoder(CreateBuiltinAudioEncoderFactory()->MakeAudioEncoder(
         kPayloadType, *audio_format_, absl::nullopt));
   }
@@ -212,15 +211,16 @@
 
   virtual void InsertPacket() {
     const uint8_t kPayload[kPayloadSizeBytes] = {0};
-    ASSERT_EQ(0,
-              acm_->IncomingPacket(kPayload, kPayloadSizeBytes, rtp_header_));
+    ASSERT_EQ(0, acm_receiver_->InsertPacket(rtp_header_,
+                                             rtc::ArrayView<const uint8_t>(
+                                                 kPayload, kPayloadSizeBytes)));
     rtp_utility_->Forward(&rtp_header_);
   }
 
   virtual void PullAudio() {
     AudioFrame audio_frame;
     bool muted;
-    ASSERT_EQ(0, acm_->PlayoutData10Ms(-1, &audio_frame, &muted));
+    ASSERT_EQ(0, acm_receiver_->GetAudio(-1, &audio_frame, &muted));
     ASSERT_FALSE(muted);
   }
 
@@ -242,6 +242,7 @@
 
   std::unique_ptr<RtpData> rtp_utility_;
   std::unique_ptr<AudioCodingModule> acm_;
+  std::unique_ptr<acm2::AcmReceiver> acm_receiver_;
   PacketizationCallbackStubOldApi packet_cb_;
   RTPHeader rtp_header_;
   AudioFrame input_frame_;
@@ -255,19 +256,6 @@
 class AudioCodingModuleTestOldApiDeathTest
     : public AudioCodingModuleTestOldApi {};
 
-TEST_F(AudioCodingModuleTestOldApi, VerifyOutputFrame) {
-  AudioFrame audio_frame;
-  const int kSampleRateHz = 32000;
-  bool muted;
-  EXPECT_EQ(0, acm_->PlayoutData10Ms(kSampleRateHz, &audio_frame, &muted));
-  ASSERT_FALSE(muted);
-  EXPECT_EQ(0u, audio_frame.timestamp_);
-  EXPECT_GT(audio_frame.num_channels_, 0u);
-  EXPECT_EQ(static_cast<size_t>(kSampleRateHz / 100),
-            audio_frame.samples_per_channel_);
-  EXPECT_EQ(kSampleRateHz, audio_frame.sample_rate_hz_);
-}
-
 // The below test is temporarily disabled on Windows due to problems
 // with clang debug builds.
 // TODO(tommi): Re-enable when we've figured out what the problem is.
@@ -277,7 +265,7 @@
 TEST_F(AudioCodingModuleTestOldApiDeathTest, FailOnZeroDesiredFrequency) {
   AudioFrame audio_frame;
   bool muted;
-  RTC_EXPECT_DEATH(acm_->PlayoutData10Ms(0, &audio_frame, &muted),
+  RTC_EXPECT_DEATH(acm_receiver_->GetAudio(0, &audio_frame, &muted),
                    "dst_sample_rate_hz");
 }
 #endif
@@ -310,8 +298,8 @@
     : public AudioCodingModuleTestOldApi {
  protected:
   void RegisterCngCodec(int rtp_payload_type) {
-    acm_->SetReceiveCodecs({{kPayloadType, *audio_format_},
-                            {rtp_payload_type, {"cn", kSampleRateHz, 1}}});
+    acm_receiver_->SetCodecs({{kPayloadType, *audio_format_},
+                              {rtp_payload_type, {"cn", kSampleRateHz, 1}}});
     acm_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* enc) {
       AudioEncoderCngConfig config;
       config.speech_encoder = std::move(*enc);
diff --git a/modules/audio_coding/include/audio_coding_module.h b/modules/audio_coding/include/audio_coding_module.h
index 8b518fb..d7bee84 100644
--- a/modules/audio_coding/include/audio_coding_module.h
+++ b/modules/audio_coding/include/audio_coding_module.h
@@ -64,11 +64,11 @@
   AudioCodingModule() {}
 
  public:
+  // Deprecated. Will be deleted when downlink clients have migrated off it.
   struct Config {
-    explicit Config(
-        rtc::scoped_refptr<AudioDecoderFactory> decoder_factory = nullptr);
-    Config(const Config&);
-    ~Config();
+    Config() = default;
+    Config(const Config&) = default;
+    ~Config() = default;
 
     NetEq::Config neteq_config;
     Clock* clock;
@@ -76,13 +76,12 @@
     NetEqFactory* neteq_factory = nullptr;
   };
 
+  static std::unique_ptr<AudioCodingModule> Create();
+  // Deprecated. Will be deleted when downlink clients have migrated to the
+  // above method.
   static AudioCodingModule* Create(const Config& config);
   virtual ~AudioCodingModule() = default;
 
-  ///////////////////////////////////////////////////////////////////////////
-  //   Sender
-  //
-
   // `modifier` is called exactly once with one argument: a pointer to the
   // unique_ptr that holds the current encoder (which is null if there is no
   // current encoder). For the duration of the call, `modifier` has exclusive
@@ -153,89 +152,9 @@
   virtual int SetPacketLossRate(int packet_loss_rate) = 0;
 
   ///////////////////////////////////////////////////////////////////////////
-  //   Receiver
-  //
-
-  ///////////////////////////////////////////////////////////////////////////
-  // int32_t InitializeReceiver()
-  // Any decoder-related state of ACM will be initialized to the
-  // same state when ACM is created. This will not interrupt or
-  // effect encoding functionality of ACM. ACM would lose all the
-  // decoding-related settings by calling this function.
-  // For instance, all registered codecs are deleted and have to be
-  // registered again.
-  //
-  // Return value:
-  //   -1 if failed to initialize,
-  //    0 if succeeded.
-  //
-  virtual int32_t InitializeReceiver() = 0;
-
-  // Replace any existing decoders with the given payload type -> decoder map.
-  virtual void SetReceiveCodecs(
-      const std::map<int, SdpAudioFormat>& codecs) = 0;
-
-  ///////////////////////////////////////////////////////////////////////////
-  // int32_t IncomingPacket()
-  // Call this function to insert a parsed RTP packet into ACM.
-  //
-  // Inputs:
-  //   -incoming_payload   : received payload.
-  //   -payload_len_bytes  : the length of payload in bytes.
-  //   -rtp_info           : the relevant information retrieved from RTP
-  //                         header.
-  //
-  // Return value:
-  //   -1 if failed to push in the payload
-  //    0 if payload is successfully pushed in.
-  //
-  virtual int32_t IncomingPacket(const uint8_t* incoming_payload,
-                                 size_t payload_len_bytes,
-                                 const RTPHeader& rtp_header) = 0;
-
-  ///////////////////////////////////////////////////////////////////////////
-  // int32_t PlayoutData10Ms(
-  // Get 10 milliseconds of raw audio data for playout, at the given sampling
-  // frequency. ACM will perform a resampling if required.
-  //
-  // Input:
-  //   -desired_freq_hz    : the desired sampling frequency, in Hertz, of the
-  //                         output audio. If set to -1, the function returns
-  //                         the audio at the current sampling frequency.
-  //
-  // Output:
-  //   -audio_frame        : output audio frame which contains raw audio data
-  //                         and other relevant parameters.
-  //   -muted              : if true, the sample data in audio_frame is not
-  //                         populated, and must be interpreted as all zero.
-  //
-  // Return value:
-  //   -1 if the function fails,
-  //    0 if the function succeeds.
-  //
-  virtual int32_t PlayoutData10Ms(int32_t desired_freq_hz,
-                                  AudioFrame* audio_frame,
-                                  bool* muted) = 0;
-
-  ///////////////////////////////////////////////////////////////////////////
   //   statistics
   //
 
-  ///////////////////////////////////////////////////////////////////////////
-  // int32_t  GetNetworkStatistics()
-  // Get network statistics. Note that the internal statistics of NetEq are
-  // reset by this call.
-  //
-  // Input:
-  //   -network_statistics : a structure that contains network statistics.
-  //
-  // Return value:
-  //   -1 if failed to set the network statistics,
-  //    0 if statistics are set successfully.
-  //
-  virtual int32_t GetNetworkStatistics(
-      NetworkStatistics* network_statistics) = 0;
-
   virtual ANAStats GetANAStats() const = 0;
 
   virtual int GetTargetBitrate() const = 0;
diff --git a/modules/audio_coding/neteq/tools/rtp_encode.cc b/modules/audio_coding/neteq/tools/rtp_encode.cc
index 8adca92..e7fca1b 100644
--- a/modules/audio_coding/neteq/tools/rtp_encode.cc
+++ b/modules/audio_coding/neteq/tools/rtp_encode.cc
@@ -307,8 +307,7 @@
 
   // Set up ACM.
   const int timestamp_rate_hz = codec->RtpTimestampRateHz();
-  AudioCodingModule::Config config;
-  std::unique_ptr<AudioCodingModule> acm(AudioCodingModule::Create(config));
+  auto acm(AudioCodingModule::Create());
   acm->SetEncoder(std::move(codec));
 
   // Open files.
diff --git a/modules/audio_coding/test/Channel.cc b/modules/audio_coding/test/Channel.cc
index 35aa6cb..8f634db 100644
--- a/modules/audio_coding/test/Channel.cc
+++ b/modules/audio_coding/test/Channel.cc
@@ -82,8 +82,8 @@
     return 0;
   }
 
-  status =
-      _receiverACM->IncomingPacket(_payloadData, payloadDataSize, rtp_header);
+  status = _receiverACM->InsertPacket(
+      rtp_header, rtc::ArrayView<const uint8_t>(_payloadData, payloadDataSize));
 
   return status;
 }
@@ -228,8 +228,8 @@
 
 Channel::~Channel() {}
 
-void Channel::RegisterReceiverACM(AudioCodingModule* acm) {
-  _receiverACM = acm;
+void Channel::RegisterReceiverACM(acm2::AcmReceiver* acm_receiver) {
+  _receiverACM = acm_receiver;
   return;
 }
 
diff --git a/modules/audio_coding/test/Channel.h b/modules/audio_coding/test/Channel.h
index 7a8829e..ebf4461 100644
--- a/modules/audio_coding/test/Channel.h
+++ b/modules/audio_coding/test/Channel.h
@@ -13,6 +13,7 @@
 
 #include <stdio.h>
 
+#include "modules/audio_coding/acm2/acm_receiver.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
 #include "modules/include/module_common_types.h"
 #include "rtc_base/synchronization/mutex.h"
@@ -54,7 +55,7 @@
                    size_t payloadSize,
                    int64_t absolute_capture_timestamp_ms) override;
 
-  void RegisterReceiverACM(AudioCodingModule* acm);
+  void RegisterReceiverACM(acm2::AcmReceiver* acm_receiver);
 
   void ResetStats();
 
@@ -83,7 +84,7 @@
  private:
   void CalcStatistics(const RTPHeader& rtp_header, size_t payloadSize);
 
-  AudioCodingModule* _receiverACM;
+  acm2::AcmReceiver* _receiverACM;
   uint16_t _seqNo;
   // 60msec * 32 sample(max)/msec * 2 description (maybe) * 2 bytes/sample
   uint8_t _payloadData[60 * 32 * 2 * 2];
diff --git a/modules/audio_coding/test/EncodeDecodeTest.cc b/modules/audio_coding/test/EncodeDecodeTest.cc
index 9f9c4aa..014a1d2 100644
--- a/modules/audio_coding/test/EncodeDecodeTest.cc
+++ b/modules/audio_coding/test/EncodeDecodeTest.cc
@@ -102,34 +102,32 @@
     : _playoutLengthSmpls(kWebRtc10MsPcmAudio),
       _payloadSizeBytes(MAX_INCOMING_PAYLOAD) {}
 
-void Receiver::Setup(AudioCodingModule* acm,
+void Receiver::Setup(acm2::AcmReceiver* acm_receiver,
                      RTPStream* rtpStream,
                      absl::string_view out_file_name,
                      size_t channels,
                      int file_num) {
-  EXPECT_EQ(0, acm->InitializeReceiver());
-
   if (channels == 1) {
-    acm->SetReceiveCodecs({{107, {"L16", 8000, 1}},
-                           {108, {"L16", 16000, 1}},
-                           {109, {"L16", 32000, 1}},
-                           {0, {"PCMU", 8000, 1}},
-                           {8, {"PCMA", 8000, 1}},
-                           {102, {"ILBC", 8000, 1}},
-                           {9, {"G722", 8000, 1}},
-                           {120, {"OPUS", 48000, 2}},
-                           {13, {"CN", 8000, 1}},
-                           {98, {"CN", 16000, 1}},
-                           {99, {"CN", 32000, 1}}});
+    acm_receiver->SetCodecs({{107, {"L16", 8000, 1}},
+                             {108, {"L16", 16000, 1}},
+                             {109, {"L16", 32000, 1}},
+                             {0, {"PCMU", 8000, 1}},
+                             {8, {"PCMA", 8000, 1}},
+                             {102, {"ILBC", 8000, 1}},
+                             {9, {"G722", 8000, 1}},
+                             {120, {"OPUS", 48000, 2}},
+                             {13, {"CN", 8000, 1}},
+                             {98, {"CN", 16000, 1}},
+                             {99, {"CN", 32000, 1}}});
   } else {
     ASSERT_EQ(channels, 2u);
-    acm->SetReceiveCodecs({{111, {"L16", 8000, 2}},
-                           {112, {"L16", 16000, 2}},
-                           {113, {"L16", 32000, 2}},
-                           {110, {"PCMU", 8000, 2}},
-                           {118, {"PCMA", 8000, 2}},
-                           {119, {"G722", 8000, 2}},
-                           {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}});
+    acm_receiver->SetCodecs({{111, {"L16", 8000, 2}},
+                             {112, {"L16", 16000, 2}},
+                             {113, {"L16", 32000, 2}},
+                             {110, {"PCMU", 8000, 2}},
+                             {118, {"PCMA", 8000, 2}},
+                             {119, {"G722", 8000, 2}},
+                             {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}});
   }
 
   int playSampFreq;
@@ -146,7 +144,7 @@
   _realPayloadSizeBytes = 0;
   _playoutBuffer = new int16_t[kWebRtc10MsPcmAudio];
   _frequency = playSampFreq;
-  _acm = acm;
+  _acm_receiver = acm_receiver;
   _firstTime = true;
 }
 
@@ -171,8 +169,9 @@
       }
     }
 
-    EXPECT_EQ(0, _acm->IncomingPacket(_incomingPayload, _realPayloadSizeBytes,
-                                      _rtpHeader));
+    EXPECT_EQ(0, _acm_receiver->InsertPacket(
+                     _rtpHeader, rtc::ArrayView<const uint8_t>(
+                                     _incomingPayload, _realPayloadSizeBytes)));
     _realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload,
                                              _payloadSizeBytes, &_nextTime);
     if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile()) {
@@ -185,7 +184,7 @@
 bool Receiver::PlayoutData() {
   AudioFrame audioFrame;
   bool muted;
-  int32_t ok = _acm->PlayoutData10Ms(_frequency, &audioFrame, &muted);
+  int32_t ok = _acm_receiver->GetAudio(_frequency, &audioFrame, &muted);
   if (muted) {
     ADD_FAILURE();
     return false;
@@ -240,8 +239,7 @@
   int file_num = 0;
   for (const auto& send_codec : send_codecs) {
     RTPFile rtpFile;
-    std::unique_ptr<AudioCodingModule> acm(AudioCodingModule::Create(
-        AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory())));
+    std::unique_ptr<AudioCodingModule> acm(AudioCodingModule::Create());
 
     std::string fileName = webrtc::test::TempFilename(
         webrtc::test::OutputPath(), "encode_decode_rtp");
@@ -256,8 +254,12 @@
 
     rtpFile.Open(fileName.c_str(), "rb");
     rtpFile.ReadHeader();
+    std::unique_ptr<acm2::AcmReceiver> acm_receiver(
+        std::make_unique<acm2::AcmReceiver>(
+            acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory())));
     Receiver receiver;
-    receiver.Setup(acm.get(), &rtpFile, "encodeDecode_out", 1, file_num);
+    receiver.Setup(acm_receiver.get(), &rtpFile, "encodeDecode_out", 1,
+                   file_num);
     receiver.Run();
     receiver.Teardown();
     rtpFile.Close();
diff --git a/modules/audio_coding/test/EncodeDecodeTest.h b/modules/audio_coding/test/EncodeDecodeTest.h
index 89b7644..9cd2c23 100644
--- a/modules/audio_coding/test/EncodeDecodeTest.h
+++ b/modules/audio_coding/test/EncodeDecodeTest.h
@@ -15,6 +15,7 @@
 #include <string.h>
 
 #include "absl/strings/string_view.h"
+#include "modules/audio_coding/acm2/acm_receiver.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
 #include "modules/audio_coding/test/PCMFile.h"
 #include "modules/audio_coding/test/RTPFile.h"
@@ -73,7 +74,7 @@
  public:
   Receiver();
   virtual ~Receiver() {}
-  void Setup(AudioCodingModule* acm,
+  void Setup(acm2::AcmReceiver* acm_receiver,
              RTPStream* rtpStream,
              absl::string_view out_file_name,
              size_t channels,
@@ -91,7 +92,7 @@
   bool _firstTime;
 
  protected:
-  AudioCodingModule* _acm;
+  acm2::AcmReceiver* _acm_receiver;
   uint8_t _incomingPayload[MAX_INCOMING_PAYLOAD];
   RTPStream* _rtpStream;
   RTPHeader _rtpHeader;
diff --git a/modules/audio_coding/test/PacketLossTest.cc b/modules/audio_coding/test/PacketLossTest.cc
index 799e9c5..c4f6656 100644
--- a/modules/audio_coding/test/PacketLossTest.cc
+++ b/modules/audio_coding/test/PacketLossTest.cc
@@ -27,7 +27,7 @@
       lost_packet_counter_(0),
       burst_lost_counter_(burst_length_) {}
 
-void ReceiverWithPacketLoss::Setup(AudioCodingModule* acm,
+void ReceiverWithPacketLoss::Setup(acm2::AcmReceiver* acm_receiver,
                                    RTPStream* rtpStream,
                                    absl::string_view out_file_name,
                                    int channels,
@@ -39,7 +39,7 @@
   burst_lost_counter_ = burst_length_;  // To prevent first packet gets lost.
   rtc::StringBuilder ss;
   ss << out_file_name << "_" << loss_rate_ << "_" << burst_length_ << "_";
-  Receiver::Setup(acm, rtpStream, ss.str(), channels, file_num);
+  Receiver::Setup(acm_receiver, rtpStream, ss.str(), channels, file_num);
 }
 
 bool ReceiverWithPacketLoss::IncomingPacket() {
@@ -58,7 +58,9 @@
     }
 
     if (!PacketLost()) {
-      _acm->IncomingPacket(_incomingPayload, _realPayloadSizeBytes, _rtpHeader);
+      _acm_receiver->InsertPacket(
+          _rtpHeader, rtc::ArrayView<const uint8_t>(_incomingPayload,
+                                                    _realPayloadSizeBytes));
     }
     packet_counter_++;
     _realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload,
@@ -135,8 +137,7 @@
   return;
 #else
   RTPFile rtpFile;
-  std::unique_ptr<AudioCodingModule> acm(AudioCodingModule::Create(
-      AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory())));
+  std::unique_ptr<AudioCodingModule> acm(AudioCodingModule::Create());
   SdpAudioFormat send_format = SdpAudioFormat("opus", 48000, 2);
   if (channels_ == 2) {
     send_format.parameters = {{"stereo", "1"}};
@@ -155,8 +156,11 @@
 
   rtpFile.Open(fileName.c_str(), "rb");
   rtpFile.ReadHeader();
+  std::unique_ptr<acm2::AcmReceiver> acm_receiver(
+      std::make_unique<acm2::AcmReceiver>(
+          acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory())));
   ReceiverWithPacketLoss receiver;
-  receiver.Setup(acm.get(), &rtpFile, "packetLoss_out", channels_, 15,
+  receiver.Setup(acm_receiver.get(), &rtpFile, "packetLoss_out", channels_, 15,
                  actual_loss_rate_, burst_length_);
   receiver.Run();
   receiver.Teardown();
diff --git a/modules/audio_coding/test/PacketLossTest.h b/modules/audio_coding/test/PacketLossTest.h
index d841d65..7569e23 100644
--- a/modules/audio_coding/test/PacketLossTest.h
+++ b/modules/audio_coding/test/PacketLossTest.h
@@ -21,7 +21,7 @@
 class ReceiverWithPacketLoss : public Receiver {
  public:
   ReceiverWithPacketLoss();
-  void Setup(AudioCodingModule* acm,
+  void Setup(acm2::AcmReceiver* acm_receiver,
              RTPStream* rtpStream,
              absl::string_view out_file_name,
              int channels,
diff --git a/modules/audio_coding/test/TestAllCodecs.cc b/modules/audio_coding/test/TestAllCodecs.cc
index b44037d..dd51760 100644
--- a/modules/audio_coding/test/TestAllCodecs.cc
+++ b/modules/audio_coding/test/TestAllCodecs.cc
@@ -55,8 +55,8 @@
 
 TestPack::~TestPack() {}
 
-void TestPack::RegisterReceiverACM(AudioCodingModule* acm) {
-  receiver_acm_ = acm;
+void TestPack::RegisterReceiverACM(acm2::AcmReceiver* acm_receiver) {
+  receiver_acm_ = acm_receiver;
   return;
 }
 
@@ -83,8 +83,8 @@
   // Only run mono for all test cases.
   memcpy(payload_data_, payload_data, payload_size);
 
-  status =
-      receiver_acm_->IncomingPacket(payload_data_, payload_size, rtp_header);
+  status = receiver_acm_->InsertPacket(
+      rtp_header, rtc::ArrayView<const uint8_t>(payload_data_, payload_size));
 
   payload_size_ = payload_size;
   timestamp_diff_ = timestamp - last_in_timestamp_;
@@ -106,10 +106,9 @@
 }
 
 TestAllCodecs::TestAllCodecs()
-    : acm_a_(AudioCodingModule::Create(
-          AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
-      acm_b_(AudioCodingModule::Create(
-          AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
+    : acm_a_(AudioCodingModule::Create()),
+      acm_b_(std::make_unique<acm2::AcmReceiver>(
+          acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory()))),
       channel_a_to_b_(NULL),
       test_count_(0),
       packet_size_samples_(0),
@@ -127,26 +126,23 @@
       webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
   infile_a_.Open(file_name, 32000, "rb");
 
-  acm_a_->InitializeReceiver();
-  acm_b_->InitializeReceiver();
-
-  acm_b_->SetReceiveCodecs({{107, {"L16", 8000, 1}},
-                            {108, {"L16", 16000, 1}},
-                            {109, {"L16", 32000, 1}},
-                            {111, {"L16", 8000, 2}},
-                            {112, {"L16", 16000, 2}},
-                            {113, {"L16", 32000, 2}},
-                            {0, {"PCMU", 8000, 1}},
-                            {110, {"PCMU", 8000, 2}},
-                            {8, {"PCMA", 8000, 1}},
-                            {118, {"PCMA", 8000, 2}},
-                            {102, {"ILBC", 8000, 1}},
-                            {9, {"G722", 8000, 1}},
-                            {119, {"G722", 8000, 2}},
-                            {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
-                            {13, {"CN", 8000, 1}},
-                            {98, {"CN", 16000, 1}},
-                            {99, {"CN", 32000, 1}}});
+  acm_b_->SetCodecs({{107, {"L16", 8000, 1}},
+                     {108, {"L16", 16000, 1}},
+                     {109, {"L16", 32000, 1}},
+                     {111, {"L16", 8000, 2}},
+                     {112, {"L16", 16000, 2}},
+                     {113, {"L16", 32000, 2}},
+                     {0, {"PCMU", 8000, 1}},
+                     {110, {"PCMU", 8000, 2}},
+                     {8, {"PCMA", 8000, 1}},
+                     {118, {"PCMA", 8000, 2}},
+                     {102, {"ILBC", 8000, 1}},
+                     {9, {"G722", 8000, 1}},
+                     {119, {"G722", 8000, 2}},
+                     {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
+                     {13, {"CN", 8000, 1}},
+                     {98, {"CN", 16000, 1}},
+                     {99, {"CN", 32000, 1}}});
 
   // Create and connect the channel
   channel_a_to_b_ = new TestPack;
@@ -158,113 +154,113 @@
   test_count_++;
   OpenOutFile(test_count_);
   char codec_g722[] = "G722";
-  RegisterSendCodec('A', codec_g722, 16000, 64000, 160, 0);
+  RegisterSendCodec(codec_g722, 16000, 64000, 160, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_g722, 16000, 64000, 320, 0);
+  RegisterSendCodec(codec_g722, 16000, 64000, 320, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_g722, 16000, 64000, 480, 0);
+  RegisterSendCodec(codec_g722, 16000, 64000, 480, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_g722, 16000, 64000, 640, 0);
+  RegisterSendCodec(codec_g722, 16000, 64000, 640, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_g722, 16000, 64000, 800, 0);
+  RegisterSendCodec(codec_g722, 16000, 64000, 800, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_g722, 16000, 64000, 960, 0);
+  RegisterSendCodec(codec_g722, 16000, 64000, 960, 0);
   Run(channel_a_to_b_);
   outfile_b_.Close();
 #ifdef WEBRTC_CODEC_ILBC
   test_count_++;
   OpenOutFile(test_count_);
   char codec_ilbc[] = "ILBC";
-  RegisterSendCodec('A', codec_ilbc, 8000, 13300, 240, 0);
+  RegisterSendCodec(codec_ilbc, 8000, 13300, 240, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_ilbc, 8000, 13300, 480, 0);
+  RegisterSendCodec(codec_ilbc, 8000, 13300, 480, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_ilbc, 8000, 15200, 160, 0);
+  RegisterSendCodec(codec_ilbc, 8000, 15200, 160, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_ilbc, 8000, 15200, 320, 0);
+  RegisterSendCodec(codec_ilbc, 8000, 15200, 320, 0);
   Run(channel_a_to_b_);
   outfile_b_.Close();
 #endif
   test_count_++;
   OpenOutFile(test_count_);
   char codec_l16[] = "L16";
-  RegisterSendCodec('A', codec_l16, 8000, 128000, 80, 0);
+  RegisterSendCodec(codec_l16, 8000, 128000, 80, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_l16, 8000, 128000, 160, 0);
+  RegisterSendCodec(codec_l16, 8000, 128000, 160, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_l16, 8000, 128000, 240, 0);
+  RegisterSendCodec(codec_l16, 8000, 128000, 240, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_l16, 8000, 128000, 320, 0);
+  RegisterSendCodec(codec_l16, 8000, 128000, 320, 0);
   Run(channel_a_to_b_);
   outfile_b_.Close();
 
   test_count_++;
   OpenOutFile(test_count_);
-  RegisterSendCodec('A', codec_l16, 16000, 256000, 160, 0);
+  RegisterSendCodec(codec_l16, 16000, 256000, 160, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_l16, 16000, 256000, 320, 0);
+  RegisterSendCodec(codec_l16, 16000, 256000, 320, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_l16, 16000, 256000, 480, 0);
+  RegisterSendCodec(codec_l16, 16000, 256000, 480, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_l16, 16000, 256000, 640, 0);
+  RegisterSendCodec(codec_l16, 16000, 256000, 640, 0);
   Run(channel_a_to_b_);
   outfile_b_.Close();
 
   test_count_++;
   OpenOutFile(test_count_);
-  RegisterSendCodec('A', codec_l16, 32000, 512000, 320, 0);
+  RegisterSendCodec(codec_l16, 32000, 512000, 320, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_l16, 32000, 512000, 640, 0);
+  RegisterSendCodec(codec_l16, 32000, 512000, 640, 0);
   Run(channel_a_to_b_);
   outfile_b_.Close();
 
   test_count_++;
   OpenOutFile(test_count_);
   char codec_pcma[] = "PCMA";
-  RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, 0);
+  RegisterSendCodec(codec_pcma, 8000, 64000, 80, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_pcma, 8000, 64000, 160, 0);
+  RegisterSendCodec(codec_pcma, 8000, 64000, 160, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_pcma, 8000, 64000, 240, 0);
+  RegisterSendCodec(codec_pcma, 8000, 64000, 240, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_pcma, 8000, 64000, 320, 0);
+  RegisterSendCodec(codec_pcma, 8000, 64000, 320, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_pcma, 8000, 64000, 400, 0);
+  RegisterSendCodec(codec_pcma, 8000, 64000, 400, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_pcma, 8000, 64000, 480, 0);
+  RegisterSendCodec(codec_pcma, 8000, 64000, 480, 0);
   Run(channel_a_to_b_);
 
   char codec_pcmu[] = "PCMU";
-  RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, 0);
+  RegisterSendCodec(codec_pcmu, 8000, 64000, 80, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_pcmu, 8000, 64000, 160, 0);
+  RegisterSendCodec(codec_pcmu, 8000, 64000, 160, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_pcmu, 8000, 64000, 240, 0);
+  RegisterSendCodec(codec_pcmu, 8000, 64000, 240, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_pcmu, 8000, 64000, 320, 0);
+  RegisterSendCodec(codec_pcmu, 8000, 64000, 320, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_pcmu, 8000, 64000, 400, 0);
+  RegisterSendCodec(codec_pcmu, 8000, 64000, 400, 0);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_pcmu, 8000, 64000, 480, 0);
+  RegisterSendCodec(codec_pcmu, 8000, 64000, 480, 0);
   Run(channel_a_to_b_);
   outfile_b_.Close();
 #ifdef WEBRTC_CODEC_OPUS
   test_count_++;
   OpenOutFile(test_count_);
   char codec_opus[] = "OPUS";
-  RegisterSendCodec('A', codec_opus, 48000, 6000, 480, kVariableSize);
+  RegisterSendCodec(codec_opus, 48000, 6000, 480, kVariableSize);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_opus, 48000, 20000, 480 * 2, kVariableSize);
+  RegisterSendCodec(codec_opus, 48000, 20000, 480 * 2, kVariableSize);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_opus, 48000, 32000, 480 * 4, kVariableSize);
+  RegisterSendCodec(codec_opus, 48000, 32000, 480 * 4, kVariableSize);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_opus, 48000, 48000, 480, kVariableSize);
+  RegisterSendCodec(codec_opus, 48000, 48000, 480, kVariableSize);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_opus, 48000, 64000, 480 * 4, kVariableSize);
+  RegisterSendCodec(codec_opus, 48000, 64000, 480 * 4, kVariableSize);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_opus, 48000, 96000, 480 * 6, kVariableSize);
+  RegisterSendCodec(codec_opus, 48000, 96000, 480 * 6, kVariableSize);
   Run(channel_a_to_b_);
-  RegisterSendCodec('A', codec_opus, 48000, 500000, 480 * 2, kVariableSize);
+  RegisterSendCodec(codec_opus, 48000, 500000, 480 * 2, kVariableSize);
   Run(channel_a_to_b_);
   outfile_b_.Close();
 #endif
@@ -272,8 +268,7 @@
 
 // Register Codec to use in the test
 //
-// Input:  side             - which ACM to use, 'A' or 'B'
-//         codec_name       - name to use when register the codec
+// Input:  codec_name       - name to use when register the codec
 //         sampling_freq_hz - sampling frequency in Herz
 //         rate             - bitrate in bytes
 //         packet_size      - packet size in samples
@@ -281,8 +276,7 @@
 //                            used when registering, can be an internal header
 //                            set to kVariableSize if the codec is a variable
 //                            rate codec
-void TestAllCodecs::RegisterSendCodec(char side,
-                                      char* codec_name,
+void TestAllCodecs::RegisterSendCodec(char* codec_name,
                                       int32_t sampling_freq_hz,
                                       int rate,
                                       int packet_size,
@@ -316,29 +310,12 @@
     packet_size_bytes_ = kVariableSize;
   }
 
-  // Set pointer to the ACM where to register the codec.
-  AudioCodingModule* my_acm = NULL;
-  switch (side) {
-    case 'A': {
-      my_acm = acm_a_.get();
-      break;
-    }
-    case 'B': {
-      my_acm = acm_b_.get();
-      break;
-    }
-    default: {
-      break;
-    }
-  }
-  ASSERT_TRUE(my_acm != NULL);
-
   auto factory = CreateBuiltinAudioEncoderFactory();
   constexpr int payload_type = 17;
   SdpAudioFormat format = {codec_name, clockrate_hz, num_channels};
   format.parameters["ptime"] = rtc::ToString(rtc::CheckedDivExact(
       packet_size, rtc::CheckedDivExact(sampling_freq_hz, 1000)));
-  my_acm->SetEncoder(
+  acm_a_->SetEncoder(
       factory->MakeAudioEncoder(payload_type, format, absl::nullopt));
 }
 
@@ -381,7 +358,7 @@
 
     // Run received side of ACM.
     bool muted;
-    CHECK_ERROR(acm_b_->PlayoutData10Ms(out_freq_hz, &audio_frame, &muted));
+    CHECK_ERROR(acm_b_->GetAudio(out_freq_hz, &audio_frame, &muted));
     ASSERT_FALSE(muted);
 
     // Write output speech to file.
diff --git a/modules/audio_coding/test/TestAllCodecs.h b/modules/audio_coding/test/TestAllCodecs.h
index 0c27641..a17038a 100644
--- a/modules/audio_coding/test/TestAllCodecs.h
+++ b/modules/audio_coding/test/TestAllCodecs.h
@@ -13,6 +13,7 @@
 
 #include <memory>
 
+#include "modules/audio_coding/acm2/acm_receiver.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
 #include "modules/audio_coding/test/PCMFile.h"
 
@@ -23,7 +24,7 @@
   TestPack();
   ~TestPack();
 
-  void RegisterReceiverACM(AudioCodingModule* acm);
+  void RegisterReceiverACM(acm2::AcmReceiver* acm_receiver);
 
   int32_t SendData(AudioFrameType frame_type,
                    uint8_t payload_type,
@@ -37,7 +38,7 @@
   void reset_payload_size();
 
  private:
-  AudioCodingModule* receiver_acm_;
+  acm2::AcmReceiver* receiver_acm_;
   uint16_t sequence_number_;
   uint8_t payload_data_[60 * 32 * 2 * 2];
   uint32_t timestamp_diff_;
@@ -58,8 +59,7 @@
   // codec name, and a sampling frequency matching is not required.
   // This is useful for codecs which support several sampling frequency.
   // Note! Only mono mode is tested in this test.
-  void RegisterSendCodec(char side,
-                         char* codec_name,
+  void RegisterSendCodec(char* codec_name,
                          int32_t sampling_freq_hz,
                          int rate,
                          int packet_size,
@@ -69,7 +69,7 @@
   void OpenOutFile(int test_number);
 
   std::unique_ptr<AudioCodingModule> acm_a_;
-  std::unique_ptr<AudioCodingModule> acm_b_;
+  std::unique_ptr<acm2::AcmReceiver> acm_b_;
   TestPack* channel_a_to_b_;
   PCMFile infile_a_;
   PCMFile outfile_b_;
diff --git a/modules/audio_coding/test/TestRedFec.cc b/modules/audio_coding/test/TestRedFec.cc
index fff48b2..f8acf48 100644
--- a/modules/audio_coding/test/TestRedFec.cc
+++ b/modules/audio_coding/test/TestRedFec.cc
@@ -42,10 +42,9 @@
                                                  AudioDecoderG722,
                                                  AudioDecoderL16,
                                                  AudioDecoderOpus>()),
-      _acmA(AudioCodingModule::Create(
-          AudioCodingModule::Config(decoder_factory_))),
-      _acmB(AudioCodingModule::Create(
-          AudioCodingModule::Config(decoder_factory_))),
+      _acmA(AudioCodingModule::Create()),
+      _acm_receiver(std::make_unique<acm2::AcmReceiver>(
+          acm2::AcmReceiver::Config(decoder_factory_))),
       _channelA2B(NULL),
       _testCntr(0) {}
 
@@ -61,13 +60,10 @@
       webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
   _inFileA.Open(file_name, 32000, "rb");
 
-  ASSERT_EQ(0, _acmA->InitializeReceiver());
-  ASSERT_EQ(0, _acmB->InitializeReceiver());
-
   // Create and connect the channel
   _channelA2B = new Channel;
   _acmA->RegisterTransportCallback(_channelA2B);
-  _channelA2B->RegisterReceiverACM(_acmB.get());
+  _channelA2B->RegisterReceiverACM(_acm_receiver.get());
 
   RegisterSendCodec(_acmA, {"L16", 8000, 1}, Vad::kVadAggressive, true);
 
@@ -136,7 +132,6 @@
     absl::optional<Vad::Aggressiveness> vad_mode,
     bool use_red) {
   constexpr int payload_type = 17, cn_payload_type = 27, red_payload_type = 37;
-  const auto& other_acm = &acm == &_acmA ? _acmB : _acmA;
 
   auto encoder = encoder_factory_->MakeAudioEncoder(payload_type, codec_format,
                                                     absl::nullopt);
@@ -165,7 +160,7 @@
     }
   }
   acm->SetEncoder(std::move(encoder));
-  other_acm->SetReceiveCodecs(receive_codecs);
+  _acm_receiver->SetCodecs(receive_codecs);
 }
 
 void TestRedFec::Run() {
@@ -180,7 +175,7 @@
     EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0);
     EXPECT_GE(_acmA->Add10MsData(audioFrame), 0);
     bool muted;
-    EXPECT_EQ(0, _acmB->PlayoutData10Ms(outFreqHzB, &audioFrame, &muted));
+    EXPECT_EQ(0, _acm_receiver->GetAudio(outFreqHzB, &audioFrame, &muted));
     ASSERT_FALSE(muted);
     _outFileB.Write10MsData(audioFrame.data(), audioFrame.samples_per_channel_);
   }
diff --git a/modules/audio_coding/test/TestRedFec.h b/modules/audio_coding/test/TestRedFec.h
index dbadd88..173b03f 100644
--- a/modules/audio_coding/test/TestRedFec.h
+++ b/modules/audio_coding/test/TestRedFec.h
@@ -17,13 +17,14 @@
 #include "api/audio_codecs/audio_decoder_factory.h"
 #include "api/audio_codecs/audio_encoder_factory.h"
 #include "common_audio/vad/include/vad.h"
+#include "modules/audio_coding/acm2/acm_receiver.h"
 #include "modules/audio_coding/test/Channel.h"
 #include "modules/audio_coding/test/PCMFile.h"
 #include "test/scoped_key_value_config.h"
 
 namespace webrtc {
 
-class TestRedFec {
+class TestRedFec final {
  public:
   explicit TestRedFec();
   ~TestRedFec();
@@ -42,7 +43,7 @@
   const rtc::scoped_refptr<AudioEncoderFactory> encoder_factory_;
   const rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
   std::unique_ptr<AudioCodingModule> _acmA;
-  std::unique_ptr<AudioCodingModule> _acmB;
+  std::unique_ptr<acm2::AcmReceiver> _acm_receiver;
 
   Channel* _channelA2B;
 
diff --git a/modules/audio_coding/test/TestStereo.cc b/modules/audio_coding/test/TestStereo.cc
index 599fafb..94a1576 100644
--- a/modules/audio_coding/test/TestStereo.cc
+++ b/modules/audio_coding/test/TestStereo.cc
@@ -35,8 +35,8 @@
 
 TestPackStereo::~TestPackStereo() {}
 
-void TestPackStereo::RegisterReceiverACM(AudioCodingModule* acm) {
-  receiver_acm_ = acm;
+void TestPackStereo::RegisterReceiverACM(acm2::AcmReceiver* acm_receiver) {
+  receiver_acm_ = acm_receiver;
   return;
 }
 
@@ -60,8 +60,8 @@
   }
 
   if (lost_packet_ == false) {
-    status =
-        receiver_acm_->IncomingPacket(payload_data, payload_size, rtp_header);
+    status = receiver_acm_->InsertPacket(
+        rtp_header, rtc::ArrayView<const uint8_t>(payload_data, payload_size));
 
     if (frame_type != AudioFrameType::kAudioFrameCN) {
       payload_size_ = static_cast<int>(payload_size);
@@ -97,10 +97,9 @@
 }
 
 TestStereo::TestStereo()
-    : acm_a_(AudioCodingModule::Create(
-          AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
-      acm_b_(AudioCodingModule::Create(
-          AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
+    : acm_a_(AudioCodingModule::Create()),
+      acm_b_(std::make_unique<acm2::AcmReceiver>(
+          acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory()))),
       channel_a2b_(NULL),
       test_cntr_(0),
       pack_size_samp_(0),
@@ -134,28 +133,27 @@
 
   // Create and initialize two ACMs, one for each side of a one-to-one call.
   ASSERT_TRUE((acm_a_.get() != NULL) && (acm_b_.get() != NULL));
-  EXPECT_EQ(0, acm_a_->InitializeReceiver());
-  EXPECT_EQ(0, acm_b_->InitializeReceiver());
+  acm_b_->FlushBuffers();
 
-  acm_b_->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
-                            {104, {"ISAC", 32000, 1}},
-                            {107, {"L16", 8000, 1}},
-                            {108, {"L16", 16000, 1}},
-                            {109, {"L16", 32000, 1}},
-                            {111, {"L16", 8000, 2}},
-                            {112, {"L16", 16000, 2}},
-                            {113, {"L16", 32000, 2}},
-                            {0, {"PCMU", 8000, 1}},
-                            {110, {"PCMU", 8000, 2}},
-                            {8, {"PCMA", 8000, 1}},
-                            {118, {"PCMA", 8000, 2}},
-                            {102, {"ILBC", 8000, 1}},
-                            {9, {"G722", 8000, 1}},
-                            {119, {"G722", 8000, 2}},
-                            {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
-                            {13, {"CN", 8000, 1}},
-                            {98, {"CN", 16000, 1}},
-                            {99, {"CN", 32000, 1}}});
+  acm_b_->SetCodecs({{103, {"ISAC", 16000, 1}},
+                     {104, {"ISAC", 32000, 1}},
+                     {107, {"L16", 8000, 1}},
+                     {108, {"L16", 16000, 1}},
+                     {109, {"L16", 32000, 1}},
+                     {111, {"L16", 8000, 2}},
+                     {112, {"L16", 16000, 2}},
+                     {113, {"L16", 32000, 2}},
+                     {0, {"PCMU", 8000, 1}},
+                     {110, {"PCMU", 8000, 2}},
+                     {8, {"PCMA", 8000, 1}},
+                     {118, {"PCMA", 8000, 2}},
+                     {102, {"ILBC", 8000, 1}},
+                     {9, {"G722", 8000, 1}},
+                     {119, {"G722", 8000, 2}},
+                     {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
+                     {13, {"CN", 8000, 1}},
+                     {98, {"CN", 16000, 1}},
+                     {99, {"CN", 32000, 1}}});
 
   // Create and connect the channel.
   channel_a2b_ = new TestPackStereo;
@@ -389,7 +387,7 @@
   OpenOutFile(test_cntr_);
   // Encode and decode in mono.
   RegisterSendCodec('A', codec_opus, 48000, 32000, 960, codec_channels);
-  acm_b_->SetReceiveCodecs({{120, {"OPUS", 48000, 2}}});
+  acm_b_->SetCodecs({{120, {"OPUS", 48000, 2}}});
   Run(channel_a2b_, audio_channels, codec_channels);
 
   // Encode in stereo, decode in mono.
@@ -408,13 +406,13 @@
   // Decode in stereo.
   test_cntr_++;
   OpenOutFile(test_cntr_);
-  acm_b_->SetReceiveCodecs({{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}});
+  acm_b_->SetCodecs({{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}});
   Run(channel_a2b_, audio_channels, 2);
   out_file_.Close();
   // Decode in mono.
   test_cntr_++;
   OpenOutFile(test_cntr_);
-  acm_b_->SetReceiveCodecs({{120, {"OPUS", 48000, 2}}});
+  acm_b_->SetCodecs({{120, {"OPUS", 48000, 2}}});
   Run(channel_a2b_, audio_channels, codec_channels);
   out_file_.Close();
 #endif
@@ -455,7 +453,9 @@
       break;
     }
     case 'B': {
-      my_acm = acm_b_.get();
+      // We no longer use this case. Refactor code to avoid the switch.
+      ASSERT_TRUE(false);
+      // my_acm = acm_b_.get();
       break;
     }
     default:
@@ -559,7 +559,7 @@
 
     // Run receive side of ACM
     bool muted;
-    EXPECT_EQ(0, acm_b_->PlayoutData10Ms(out_freq_hz_b, &audio_frame, &muted));
+    EXPECT_EQ(0, acm_b_->GetAudio(out_freq_hz_b, &audio_frame, &muted));
     ASSERT_FALSE(muted);
 
     // Write output speech to file
diff --git a/modules/audio_coding/test/TestStereo.h b/modules/audio_coding/test/TestStereo.h
index 4c50a4b..a215c90 100644
--- a/modules/audio_coding/test/TestStereo.h
+++ b/modules/audio_coding/test/TestStereo.h
@@ -15,6 +15,7 @@
 
 #include <memory>
 
+#include "modules/audio_coding/acm2/acm_receiver.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
 #include "modules/audio_coding/test/PCMFile.h"
 
@@ -29,7 +30,7 @@
   TestPackStereo();
   ~TestPackStereo();
 
-  void RegisterReceiverACM(AudioCodingModule* acm);
+  void RegisterReceiverACM(acm2::AcmReceiver* acm_receiver);
 
   int32_t SendData(AudioFrameType frame_type,
                    uint8_t payload_type,
@@ -45,7 +46,7 @@
   void set_lost_packet(bool lost);
 
  private:
-  AudioCodingModule* receiver_acm_;
+  acm2::AcmReceiver* receiver_acm_;
   int16_t seq_no_;
   uint32_t timestamp_diff_;
   uint32_t last_in_timestamp_;
@@ -81,7 +82,7 @@
   void OpenOutFile(int16_t test_number);
 
   std::unique_ptr<AudioCodingModule> acm_a_;
-  std::unique_ptr<AudioCodingModule> acm_b_;
+  std::unique_ptr<acm2::AcmReceiver> acm_b_;
 
   TestPackStereo* channel_a2b_;
 
diff --git a/modules/audio_coding/test/TestVADDTX.cc b/modules/audio_coding/test/TestVADDTX.cc
index de26caf..1789efd 100644
--- a/modules/audio_coding/test/TestVADDTX.cc
+++ b/modules/audio_coding/test/TestVADDTX.cc
@@ -70,10 +70,9 @@
           CreateAudioEncoderFactory<AudioEncoderIlbc, AudioEncoderOpus>()),
       decoder_factory_(
           CreateAudioDecoderFactory<AudioDecoderIlbc, AudioDecoderOpus>()),
-      acm_send_(AudioCodingModule::Create(
-          AudioCodingModule::Config(decoder_factory_))),
-      acm_receive_(AudioCodingModule::Create(
-          AudioCodingModule::Config(decoder_factory_))),
+      acm_send_(AudioCodingModule::Create()),
+      acm_receive_(std::make_unique<acm2::AcmReceiver>(
+          acm2::AcmReceiver::Config(decoder_factory_))),
       channel_(std::make_unique<Channel>()),
       packetization_callback_(
           std::make_unique<MonitoringAudioPacketizationCallback>(
@@ -104,7 +103,7 @@
   acm_send_->SetEncoder(std::move(encoder));
 
   std::map<int, SdpAudioFormat> receive_codecs = {{payload_type, codec_format}};
-  acm_receive_->SetReceiveCodecs(receive_codecs);
+  acm_receive_->SetCodecs(receive_codecs);
 
   return added_comfort_noise;
 }
@@ -143,7 +142,7 @@
     time_stamp_ += frame_size_samples;
     EXPECT_GE(acm_send_->Add10MsData(audio_frame), 0);
     bool muted;
-    acm_receive_->PlayoutData10Ms(kOutputFreqHz, &audio_frame, &muted);
+    acm_receive_->GetAudio(kOutputFreqHz, &audio_frame, &muted);
     ASSERT_FALSE(muted);
     out_file.Write10MsData(audio_frame);
   }
diff --git a/modules/audio_coding/test/TestVADDTX.h b/modules/audio_coding/test/TestVADDTX.h
index d81ae28..17b3f41 100644
--- a/modules/audio_coding/test/TestVADDTX.h
+++ b/modules/audio_coding/test/TestVADDTX.h
@@ -17,6 +17,7 @@
 #include "api/audio_codecs/audio_decoder_factory.h"
 #include "api/audio_codecs/audio_encoder_factory.h"
 #include "common_audio/vad/include/vad.h"
+#include "modules/audio_coding/acm2/acm_receiver.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
 #include "modules/audio_coding/test/Channel.h"
@@ -84,7 +85,7 @@
   const rtc::scoped_refptr<AudioEncoderFactory> encoder_factory_;
   const rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
   std::unique_ptr<AudioCodingModule> acm_send_;
-  std::unique_ptr<AudioCodingModule> acm_receive_;
+  std::unique_ptr<acm2::AcmReceiver> acm_receive_;
   std::unique_ptr<Channel> channel_;
   std::unique_ptr<MonitoringAudioPacketizationCallback> packetization_callback_;
   uint32_t time_stamp_ = 0x12345678;
diff --git a/modules/audio_coding/test/Tester.cc b/modules/audio_coding/test/Tester.cc
index 7612aa4..9dbc645 100644
--- a/modules/audio_coding/test/Tester.cc
+++ b/modules/audio_coding/test/Tester.cc
@@ -20,7 +20,6 @@
 #include "modules/audio_coding/test/TestRedFec.h"
 #include "modules/audio_coding/test/TestStereo.h"
 #include "modules/audio_coding/test/TestVADDTX.h"
-#include "modules/audio_coding/test/TwoWayCommunication.h"
 #include "modules/audio_coding/test/opus_test.h"
 #include "test/gtest.h"
 #include "test/testsupport/file_utils.h"
diff --git a/modules/audio_coding/test/TwoWayCommunication.cc b/modules/audio_coding/test/TwoWayCommunication.cc
deleted file mode 100644
index b42415a..0000000
--- a/modules/audio_coding/test/TwoWayCommunication.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "TwoWayCommunication.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include <memory>
-
-#include "api/audio_codecs/builtin_audio_decoder_factory.h"
-#include "api/audio_codecs/builtin_audio_encoder_factory.h"
-#include "modules/audio_coding/test/PCMFile.h"
-#include "test/gtest.h"
-#include "test/testsupport/file_utils.h"
-
-namespace webrtc {
-
-#define MAX_FILE_NAME_LENGTH_BYTE 500
-
-TwoWayCommunication::TwoWayCommunication()
-    : _acmA(AudioCodingModule::Create(
-          AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
-      _acmRefA(AudioCodingModule::Create(
-          AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))) {
-  AudioCodingModule::Config config;
-  // The clicks will be more obvious if time-stretching is not allowed.
-  // TODO(henrik.lundin) Really?
-  config.neteq_config.for_test_no_time_stretching = true;
-  config.decoder_factory = CreateBuiltinAudioDecoderFactory();
-  _acmB.reset(AudioCodingModule::Create(config));
-  _acmRefB.reset(AudioCodingModule::Create(config));
-}
-
-TwoWayCommunication::~TwoWayCommunication() {
-  delete _channel_A2B;
-  delete _channel_B2A;
-  delete _channelRef_A2B;
-  delete _channelRef_B2A;
-  _inFileA.Close();
-  _inFileB.Close();
-  _outFileA.Close();
-  _outFileB.Close();
-  _outFileRefA.Close();
-  _outFileRefB.Close();
-}
-
-void TwoWayCommunication::SetUpAutotest(
-    AudioEncoderFactory* const encoder_factory,
-    const SdpAudioFormat& format1,
-    const int payload_type1,
-    const SdpAudioFormat& format2,
-    const int payload_type2) {
-  //--- Set A codecs
-  _acmA->SetEncoder(
-      encoder_factory->MakeAudioEncoder(payload_type1, format1, absl::nullopt));
-  _acmA->SetReceiveCodecs({{payload_type2, format2}});
-
-  //--- Set ref-A codecs
-  _acmRefA->SetEncoder(
-      encoder_factory->MakeAudioEncoder(payload_type1, format1, absl::nullopt));
-  _acmRefA->SetReceiveCodecs({{payload_type2, format2}});
-
-  //--- Set B codecs
-  _acmB->SetEncoder(
-      encoder_factory->MakeAudioEncoder(payload_type2, format2, absl::nullopt));
-  _acmB->SetReceiveCodecs({{payload_type1, format1}});
-
-  //--- Set ref-B codecs
-  _acmRefB->SetEncoder(
-      encoder_factory->MakeAudioEncoder(payload_type2, format2, absl::nullopt));
-  _acmRefB->SetReceiveCodecs({{payload_type1, format1}});
-
-  uint16_t frequencyHz;
-
-  //--- Input A and B
-  std::string in_file_name =
-      webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
-  frequencyHz = 16000;
-  _inFileA.Open(in_file_name, frequencyHz, "rb");
-  _inFileB.Open(in_file_name, frequencyHz, "rb");
-
-  //--- Output A
-  std::string output_file_a = webrtc::test::OutputPath() + "outAutotestA.pcm";
-  frequencyHz = 16000;
-  _outFileA.Open(output_file_a, frequencyHz, "wb");
-  std::string output_ref_file_a =
-      webrtc::test::OutputPath() + "ref_outAutotestA.pcm";
-  _outFileRefA.Open(output_ref_file_a, frequencyHz, "wb");
-
-  //--- Output B
-  std::string output_file_b = webrtc::test::OutputPath() + "outAutotestB.pcm";
-  frequencyHz = 16000;
-  _outFileB.Open(output_file_b, frequencyHz, "wb");
-  std::string output_ref_file_b =
-      webrtc::test::OutputPath() + "ref_outAutotestB.pcm";
-  _outFileRefB.Open(output_ref_file_b, frequencyHz, "wb");
-
-  //--- Set A-to-B channel
-  _channel_A2B = new Channel;
-  _acmA->RegisterTransportCallback(_channel_A2B);
-  _channel_A2B->RegisterReceiverACM(_acmB.get());
-  //--- Do the same for the reference
-  _channelRef_A2B = new Channel;
-  _acmRefA->RegisterTransportCallback(_channelRef_A2B);
-  _channelRef_A2B->RegisterReceiverACM(_acmRefB.get());
-
-  //--- Set B-to-A channel
-  _channel_B2A = new Channel;
-  _acmB->RegisterTransportCallback(_channel_B2A);
-  _channel_B2A->RegisterReceiverACM(_acmA.get());
-  //--- Do the same for reference
-  _channelRef_B2A = new Channel;
-  _acmRefB->RegisterTransportCallback(_channelRef_B2A);
-  _channelRef_B2A->RegisterReceiverACM(_acmRefA.get());
-}
-
-void TwoWayCommunication::Perform() {
-  const SdpAudioFormat format1("ISAC", 16000, 1);
-  const SdpAudioFormat format2("L16", 8000, 1);
-  constexpr int payload_type1 = 17, payload_type2 = 18;
-
-  auto encoder_factory = CreateBuiltinAudioEncoderFactory();
-
-  SetUpAutotest(encoder_factory.get(), format1, payload_type1, format2,
-                payload_type2);
-
-  unsigned int msecPassed = 0;
-  unsigned int secPassed = 0;
-
-  int32_t outFreqHzA = _outFileA.SamplingFrequency();
-  int32_t outFreqHzB = _outFileB.SamplingFrequency();
-
-  AudioFrame audioFrame;
-
-  // In the following loop we tests that the code can handle misuse of the APIs.
-  // In the middle of a session with data flowing between two sides, called A
-  // and B, APIs will be called, and the code should continue to run, and be
-  // able to recover.
-  while (!_inFileA.EndOfFile() && !_inFileB.EndOfFile()) {
-    msecPassed += 10;
-    EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0);
-    EXPECT_GE(_acmA->Add10MsData(audioFrame), 0);
-    EXPECT_GE(_acmRefA->Add10MsData(audioFrame), 0);
-
-    EXPECT_GT(_inFileB.Read10MsData(audioFrame), 0);
-
-    EXPECT_GE(_acmB->Add10MsData(audioFrame), 0);
-    EXPECT_GE(_acmRefB->Add10MsData(audioFrame), 0);
-    bool muted;
-    EXPECT_EQ(0, _acmA->PlayoutData10Ms(outFreqHzA, &audioFrame, &muted));
-    ASSERT_FALSE(muted);
-    _outFileA.Write10MsData(audioFrame);
-    EXPECT_EQ(0, _acmRefA->PlayoutData10Ms(outFreqHzA, &audioFrame, &muted));
-    ASSERT_FALSE(muted);
-    _outFileRefA.Write10MsData(audioFrame);
-    EXPECT_EQ(0, _acmB->PlayoutData10Ms(outFreqHzB, &audioFrame, &muted));
-    ASSERT_FALSE(muted);
-    _outFileB.Write10MsData(audioFrame);
-    EXPECT_EQ(0, _acmRefB->PlayoutData10Ms(outFreqHzB, &audioFrame, &muted));
-    ASSERT_FALSE(muted);
-    _outFileRefB.Write10MsData(audioFrame);
-
-    // Update time counters each time a second of data has passed.
-    if (msecPassed >= 1000) {
-      msecPassed = 0;
-      secPassed++;
-    }
-    // Re-register send codec on side B.
-    if (((secPassed % 5) == 4) && (msecPassed >= 990)) {
-      _acmB->SetEncoder(encoder_factory->MakeAudioEncoder(
-          payload_type2, format2, absl::nullopt));
-    }
-    // Initialize receiver on side A.
-    if (((secPassed % 7) == 6) && (msecPassed == 0))
-      EXPECT_EQ(0, _acmA->InitializeReceiver());
-    // Re-register codec on side A.
-    if (((secPassed % 7) == 6) && (msecPassed >= 990)) {
-      _acmA->SetReceiveCodecs({{payload_type2, format2}});
-    }
-  }
-}
-
-}  // namespace webrtc
diff --git a/modules/audio_coding/test/TwoWayCommunication.h b/modules/audio_coding/test/TwoWayCommunication.h
deleted file mode 100644
index b7eb9e5..0000000
--- a/modules/audio_coding/test/TwoWayCommunication.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef MODULES_AUDIO_CODING_TEST_TWOWAYCOMMUNICATION_H_
-#define MODULES_AUDIO_CODING_TEST_TWOWAYCOMMUNICATION_H_
-
-#include <memory>
-
-#include "api/audio_codecs/audio_encoder_factory.h"
-#include "api/audio_codecs/audio_format.h"
-#include "modules/audio_coding/include/audio_coding_module.h"
-#include "modules/audio_coding/test/Channel.h"
-#include "modules/audio_coding/test/PCMFile.h"
-
-namespace webrtc {
-
-class TwoWayCommunication {
- public:
-  TwoWayCommunication();
-  ~TwoWayCommunication();
-
-  void Perform();
-
- private:
-  void SetUpAutotest(AudioEncoderFactory* const encoder_factory,
-                     const SdpAudioFormat& format1,
-                     int payload_type1,
-                     const SdpAudioFormat& format2,
-                     int payload_type2);
-
-  std::unique_ptr<AudioCodingModule> _acmA;
-  std::unique_ptr<AudioCodingModule> _acmB;
-
-  std::unique_ptr<AudioCodingModule> _acmRefA;
-  std::unique_ptr<AudioCodingModule> _acmRefB;
-
-  Channel* _channel_A2B;
-  Channel* _channel_B2A;
-
-  Channel* _channelRef_A2B;
-  Channel* _channelRef_B2A;
-
-  PCMFile _inFileA;
-  PCMFile _inFileB;
-
-  PCMFile _outFileA;
-  PCMFile _outFileB;
-
-  PCMFile _outFileRefA;
-  PCMFile _outFileRefB;
-};
-
-}  // namespace webrtc
-
-#endif  // MODULES_AUDIO_CODING_TEST_TWOWAYCOMMUNICATION_H_
diff --git a/modules/audio_coding/test/opus_test.cc b/modules/audio_coding/test/opus_test.cc
index 6822bc3..dfebb5f 100644
--- a/modules/audio_coding/test/opus_test.cc
+++ b/modules/audio_coding/test/opus_test.cc
@@ -22,8 +22,8 @@
 namespace webrtc {
 
 OpusTest::OpusTest()
-    : acm_receiver_(AudioCodingModule::Create(
-          AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
+    : acm_receiver_(std::make_unique<acm2::AcmReceiver>(
+          acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory()))),
       channel_a2b_(NULL),
       counter_(0),
       payload_type_(255),
@@ -83,13 +83,13 @@
   WebRtcOpus_DecoderInit(opus_stereo_decoder_);
 
   ASSERT_TRUE(acm_receiver_.get() != NULL);
-  EXPECT_EQ(0, acm_receiver_->InitializeReceiver());
+  acm_receiver_->FlushBuffers();
 
   // Register Opus stereo as receiving codec.
   constexpr int kOpusPayloadType = 120;
   const SdpAudioFormat kOpusFormatStereo("opus", 48000, 2, {{"stereo", "1"}});
   payload_type_ = kOpusPayloadType;
-  acm_receiver_->SetReceiveCodecs({{kOpusPayloadType, kOpusFormatStereo}});
+  acm_receiver_->SetCodecs({{kOpusPayloadType, kOpusFormatStereo}});
 
   // Create and connect the channel.
   channel_a2b_ = new TestPackStereo;
@@ -154,7 +154,7 @@
 
   // Register Opus mono as receiving codec.
   const SdpAudioFormat kOpusFormatMono("opus", 48000, 2);
-  acm_receiver_->SetReceiveCodecs({{kOpusPayloadType, kOpusFormatMono}});
+  acm_receiver_->SetCodecs({{kOpusPayloadType, kOpusFormatMono}});
 
   // Run Opus with 2.5 ms frame size.
   Run(channel_a2b_, audio_channels, 32000, 120);
@@ -353,8 +353,7 @@
 
     // Run received side of ACM.
     bool muted;
-    ASSERT_EQ(
-        0, acm_receiver_->PlayoutData10Ms(out_freq_hz_b, &audio_frame, &muted));
+    ASSERT_EQ(0, acm_receiver_->GetAudio(out_freq_hz_b, &audio_frame, &muted));
     ASSERT_FALSE(muted);
 
     // Write output speech to file.
diff --git a/modules/audio_coding/test/opus_test.h b/modules/audio_coding/test/opus_test.h
index c69f922..cf5581a 100644
--- a/modules/audio_coding/test/opus_test.h
+++ b/modules/audio_coding/test/opus_test.h
@@ -15,6 +15,7 @@
 
 #include <memory>
 
+#include "modules/audio_coding/acm2/acm_receiver.h"
 #include "modules/audio_coding/acm2/acm_resampler.h"
 #include "modules/audio_coding/codecs/opus/opus_interface.h"
 #include "modules/audio_coding/test/PCMFile.h"
@@ -38,7 +39,7 @@
 
   void OpenOutFile(int test_number);
 
-  std::unique_ptr<AudioCodingModule> acm_receiver_;
+  std::unique_ptr<acm2::AcmReceiver> acm_receiver_;
   TestPackStereo* channel_a2b_;
   PCMFile in_file_stereo_;
   PCMFile in_file_mono_;
diff --git a/modules/audio_coding/test/target_delay_unittest.cc b/modules/audio_coding/test/target_delay_unittest.cc
index 5eccdcf..2a71627 100644
--- a/modules/audio_coding/test/target_delay_unittest.cc
+++ b/modules/audio_coding/test/target_delay_unittest.cc
@@ -25,7 +25,7 @@
  protected:
   TargetDelayTest()
       : receiver_(
-            AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory())) {}
+            acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory())) {}
 
   ~TargetDelayTest() {}