Remove all use of AcmReceiver from WebRTC

The class itself and its unit test remains, for now, but will be removed
later.

Bug: webrtc:14867
Change-Id: I36cec8fca7913663f63c53622ed2760e5e048c2f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/362580
Reviewed-by: Jakob Ivarsson‎ <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43023}
diff --git a/audio/voip/BUILD.gn b/audio/voip/BUILD.gn
index 42fc665..2ae743a 100644
--- a/audio/voip/BUILD.gn
+++ b/audio/voip/BUILD.gn
@@ -64,8 +64,10 @@
     "../../api/audio:audio_mixer_api",
     "../../api/audio_codecs:audio_codecs_api",
     "../../api/environment",
+    "../../api/neteq:neteq_api",
     "../../api/voip:voip_api",
     "../../modules/audio_coding",
+    "../../modules/audio_coding:default_neteq_factory",
     "../../modules/rtp_rtcp",
     "../../modules/rtp_rtcp:rtp_rtcp_format",
     "../../rtc_base:criticalsection",
diff --git a/audio/voip/audio_ingress.cc b/audio/voip/audio_ingress.cc
index 50332c1..82b4012 100644
--- a/audio/voip/audio_ingress.cc
+++ b/audio/voip/audio_ingress.cc
@@ -18,6 +18,7 @@
 #include "api/audio_codecs/audio_format.h"
 #include "audio/utility/audio_frame_operations.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
+#include "modules/audio_coding/neteq/default_neteq_factory.h"
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
@@ -30,12 +31,10 @@
 
 namespace {
 
-acm2::AcmReceiver::Config CreateAcmConfig(
-    rtc::scoped_refptr<AudioDecoderFactory> decoder_factory) {
-  acm2::AcmReceiver::Config acm_config;
-  acm_config.neteq_config.enable_muted_state = true;
-  acm_config.decoder_factory = decoder_factory;
-  return acm_config;
+NetEq::Config CreateNetEqConfig() {
+  NetEq::Config config;
+  config.enable_muted_state = true;
+  return config;
 }
 
 }  // namespace
@@ -51,7 +50,9 @@
       first_rtp_timestamp_(-1),
       rtp_receive_statistics_(receive_statistics),
       rtp_rtcp_(rtp_rtcp),
-      acm_receiver_(env_, CreateAcmConfig(decoder_factory)),
+      neteq_(DefaultNetEqFactory().Create(env,
+                                          CreateNetEqConfig(),
+                                          decoder_factory)),
       ntp_estimator_(&env_.clock()) {}
 
 AudioIngress::~AudioIngress() = default;
@@ -63,13 +64,17 @@
 
   // Get 10ms raw PCM data from the ACM.
   bool muted = false;
-  if (acm_receiver_.GetAudio(sampling_rate, audio_frame, &muted) == -1) {
-    RTC_DLOG(LS_ERROR) << "GetAudio() failed!";
-    // In all likelihood, the audio in this frame is garbage. We return an
-    // error so that the audio mixer module doesn't add it to the mix. As
-    // a result, it won't be played out and the actions skipped here are
-    // irrelevant.
-    return AudioMixer::Source::AudioFrameInfo::kError;
+  {
+    MutexLock lock(&lock_);
+    if ((neteq_->GetAudio(audio_frame, &muted) != NetEq::kOK) ||
+        !resampler_helper_.MaybeResample(sampling_rate, audio_frame)) {
+      RTC_DLOG(LS_ERROR) << "GetAudio() failed!";
+      // In all likelihood, the audio in this frame is garbage. We return an
+      // error so that the audio mixer module doesn't add it to the mix. As
+      // a result, it won't be played out and the actions skipped here are
+      // irrelevant.
+      return AudioMixer::Source::AudioFrameInfo::kError;
+    }
   }
 
   if (muted) {
@@ -103,10 +108,10 @@
     }
     // For clock rate, default to the playout sampling rate if we haven't
     // received any packets yet.
-    std::optional<std::pair<int, SdpAudioFormat>> decoder =
-        acm_receiver_.LastDecoder();
-    int clock_rate = decoder ? decoder->second.clockrate_hz
-                             : acm_receiver_.last_output_sample_rate_hz();
+    std::optional<NetEq::DecoderFormat> decoder =
+        neteq_->GetCurrentDecoderFormat();
+    int clock_rate = decoder ? decoder->sdp_format.clockrate_hz
+                             : neteq_->last_output_sample_rate_hz();
     RTC_DCHECK_GT(clock_rate, 0);
     audio_frame->elapsed_time_ms_ =
         (unwrap_timestamp - first_rtp_timestamp_) / (clock_rate / 1000);
@@ -136,7 +141,7 @@
       receive_codec_info_[kv.first] = kv.second.clockrate_hz;
     }
   }
-  acm_receiver_.SetCodecs(codecs);
+  neteq_->SetCodecs(codecs);
 }
 
 void AudioIngress::ReceivedRTPPacket(rtc::ArrayView<const uint8_t> rtp_packet) {
@@ -186,10 +191,12 @@
   auto data_view = rtc::ArrayView<const uint8_t>(payload, payload_data_length);
 
   // Push the incoming payload (parsed and ready for decoding) into the ACM.
-  if (acm_receiver_.InsertPacket(header, data_view,
-                                 env_.clock().CurrentTime()) != 0) {
-    RTC_DLOG(LS_ERROR) << "AudioIngress::ReceivedRTPPacket() unable to "
-                          "push data to the ACM";
+  if (data_view.empty()) {
+    neteq_->InsertEmptyPacket(header);
+  } else if (neteq_->InsertPacket(header, data_view,
+                                  env_.clock().CurrentTime()) < 0) {
+    RTC_DLOG(LS_ERROR) << "ChannelReceive::OnReceivedPayloadData() unable to "
+                          "insert packet into NetEq";
   }
 }
 
@@ -235,16 +242,63 @@
   }
 }
 
+NetworkStatistics AudioIngress::GetNetworkStatistics() const {
+  NetworkStatistics stats;
+  stats.currentExpandRate = 0;
+  stats.currentSpeechExpandRate = 0;
+  stats.currentPreemptiveRate = 0;
+  stats.currentAccelerateRate = 0;
+  stats.currentSecondaryDecodedRate = 0;
+  stats.currentSecondaryDiscardedRate = 0;
+  stats.meanWaitingTimeMs = -1;
+  stats.maxWaitingTimeMs = 1;
+
+  NetEqNetworkStatistics neteq_stat = neteq_->CurrentNetworkStatistics();
+  stats.currentBufferSize = neteq_stat.current_buffer_size_ms;
+  stats.preferredBufferSize = neteq_stat.preferred_buffer_size_ms;
+  stats.jitterPeaksFound = neteq_stat.jitter_peaks_found ? true : false;
+
+  NetEqLifetimeStatistics neteq_lifetime_stat = neteq_->GetLifetimeStatistics();
+  stats.totalSamplesReceived = neteq_lifetime_stat.total_samples_received;
+  stats.concealedSamples = neteq_lifetime_stat.concealed_samples;
+  stats.silentConcealedSamples = neteq_lifetime_stat.silent_concealed_samples;
+  stats.concealmentEvents = neteq_lifetime_stat.concealment_events;
+  stats.jitterBufferDelayMs = neteq_lifetime_stat.jitter_buffer_delay_ms;
+  stats.jitterBufferTargetDelayMs =
+      neteq_lifetime_stat.jitter_buffer_target_delay_ms;
+  stats.jitterBufferMinimumDelayMs =
+      neteq_lifetime_stat.jitter_buffer_minimum_delay_ms;
+  stats.jitterBufferEmittedCount =
+      neteq_lifetime_stat.jitter_buffer_emitted_count;
+  stats.delayedPacketOutageSamples =
+      neteq_lifetime_stat.delayed_packet_outage_samples;
+  stats.relativePacketArrivalDelayMs =
+      neteq_lifetime_stat.relative_packet_arrival_delay_ms;
+  stats.interruptionCount = neteq_lifetime_stat.interruption_count;
+  stats.totalInterruptionDurationMs =
+      neteq_lifetime_stat.total_interruption_duration_ms;
+  stats.insertedSamplesForDeceleration =
+      neteq_lifetime_stat.inserted_samples_for_deceleration;
+  stats.removedSamplesForAcceleration =
+      neteq_lifetime_stat.removed_samples_for_acceleration;
+  stats.fecPacketsReceived = neteq_lifetime_stat.fec_packets_received;
+  stats.fecPacketsDiscarded = neteq_lifetime_stat.fec_packets_discarded;
+  stats.totalProcessingDelayUs = neteq_lifetime_stat.total_processing_delay_us;
+  stats.packetsDiscarded = neteq_lifetime_stat.packets_discarded;
+
+  NetEqOperationsAndState neteq_operations_and_state =
+      neteq_->GetOperationsAndState();
+  stats.packetBufferFlushes = neteq_operations_and_state.packet_buffer_flushes;
+
+  return stats;
+}
+
 ChannelStatistics AudioIngress::GetChannelStatistics() {
   ChannelStatistics channel_stats;
 
   // Get clockrate for current decoder ahead of jitter calculation.
-  uint32_t clockrate_hz = 0;
-  std::optional<std::pair<int, SdpAudioFormat>> decoder =
-      acm_receiver_.LastDecoder();
-  if (decoder) {
-    clockrate_hz = decoder->second.clockrate_hz;
-  }
+  auto decoder = neteq_->GetCurrentDecoderFormat();
+  const uint32_t clockrate_hz = decoder ? decoder->sdp_format.clockrate_hz : 0;
 
   StreamStatistician* statistician =
       rtp_receive_statistics_->GetStatistician(remote_ssrc_);
diff --git a/audio/voip/audio_ingress.h b/audio/voip/audio_ingress.h
index 9651871..3569f21 100644
--- a/audio/voip/audio_ingress.h
+++ b/audio/voip/audio_ingress.h
@@ -20,12 +20,14 @@
 
 #include "api/array_view.h"
 #include "api/audio/audio_mixer.h"
+#include "api/audio_codecs/audio_decoder_factory.h"
 #include "api/environment/environment.h"
+#include "api/neteq/neteq.h"
 #include "api/rtp_headers.h"
 #include "api/scoped_refptr.h"
 #include "api/voip/voip_statistics.h"
 #include "audio/audio_level.h"
-#include "modules/audio_coding/acm2/acm_receiver.h"
+#include "modules/audio_coding/acm2/acm_resampler.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
 #include "modules/rtp_rtcp/include/receive_statistics.h"
 #include "modules/rtp_rtcp/include/remote_ntp_time_estimator.h"
@@ -81,12 +83,7 @@
     return output_audio_level_.TotalDuration();
   }
 
-  NetworkStatistics GetNetworkStatistics() const {
-    NetworkStatistics stats;
-    acm_receiver_.GetNetworkStatistics(&stats,
-                                       /*get_and_clear_legacy_stats=*/false);
-    return stats;
-  }
+  NetworkStatistics GetNetworkStatistics() const;
 
   ChannelStatistics GetChannelStatistics();
 
@@ -98,11 +95,14 @@
     return rtc::dchecked_cast<int>(remote_ssrc_.load());
   }
   int PreferredSampleRate() const override {
+    std::optional<NetEq::DecoderFormat> decoder =
+        neteq_->GetCurrentDecoderFormat();
+
     // If we haven't received any RTP packet from remote and thus
     // last_packet_sampling_rate is not available then use NetEq's sampling
     // rate as that would be what would be used for audio output sample.
-    return std::max(acm_receiver_.last_packet_sample_rate_hz().value_or(0),
-                    acm_receiver_.last_output_sample_rate_hz());
+    return std::max(decoder ? decoder->sample_rate_hz : 0,
+                    neteq_->last_output_sample_rate_hz());
   }
 
  private:
@@ -126,8 +126,8 @@
   // Synchronizaton is handled internally by RtpRtcpInterface.
   RtpRtcpInterface* const rtp_rtcp_;
 
-  // Synchronizaton is handled internally by acm2::AcmReceiver.
-  acm2::AcmReceiver acm_receiver_;
+  // Synchronizaton is handled internally by NetEq.
+  const std::unique_ptr<NetEq> neteq_;
 
   // Synchronizaton is handled internally by voe::AudioLevel.
   voe::AudioLevel output_audio_level_;
@@ -141,6 +141,9 @@
   std::map<int, int> receive_codec_info_ RTC_GUARDED_BY(lock_);
 
   RtpTimestampUnwrapper timestamp_wrap_handler_ RTC_GUARDED_BY(lock_);
+
+  // Resampler for the output audio.
+  acm2::ResamplerHelper resampler_helper_ RTC_GUARDED_BY(lock_);
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index c92a26f..8c42487 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -1067,8 +1067,10 @@
       "../../api/audio_codecs/opus:audio_encoder_opus",
       "../../api/environment",
       "../../api/environment:environment_factory",
+      "../../api/neteq:neteq_api",
       "../../api/units:timestamp",
       "../../common_audio",
+      "../../modules/audio_coding:default_neteq_factory",
       "../../rtc_base:checks",
       "../../rtc_base:logging",
       "../../rtc_base:macromagic",
@@ -1126,6 +1128,8 @@
       "../../api/audio_codecs:audio_codecs_api",
       "../../api/audio_codecs:builtin_audio_decoder_factory",
       "../../api/environment:environment_factory",
+      "../../api/neteq:neteq_api",
+      "../../modules/audio_coding:default_neteq_factory",
       "../../test:test_support",
       "//testing/gtest",
     ]
diff --git a/modules/audio_coding/acm2/acm_receive_test.cc b/modules/audio_coding/acm2/acm_receive_test.cc
index fa48433..e23dfc7 100644
--- a/modules/audio_coding/acm2/acm_receive_test.cc
+++ b/modules/audio_coding/acm2/acm_receive_test.cc
@@ -17,6 +17,7 @@
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
 #include "api/environment/environment_factory.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
+#include "modules/audio_coding/neteq/default_neteq_factory.h"
 #include "modules/audio_coding/neteq/tools/audio_sink.h"
 #include "modules/audio_coding/neteq/tools/packet.h"
 #include "modules/audio_coding/neteq/tools/packet_source.h"
@@ -25,15 +26,6 @@
 namespace webrtc {
 namespace test {
 
-namespace {
-acm2::AcmReceiver::Config MakeAcmConfig(
-    rtc::scoped_refptr<AudioDecoderFactory> decoder_factory) {
-  acm2::AcmReceiver::Config config;
-  config.decoder_factory = std::move(decoder_factory);
-  return config;
-}
-}  // namespace
-
 AcmReceiveTestOldApi::AcmReceiveTestOldApi(
     PacketSource* packet_source,
     AudioSink* audio_sink,
@@ -41,9 +33,9 @@
     NumOutputChannels exptected_output_channels,
     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory)
     : clock_(0),
-      acm_receiver_(std::make_unique<acm2::AcmReceiver>(
-          CreateEnvironment(&clock_),
-          MakeAcmConfig(std::move(decoder_factory)))),
+      neteq_(DefaultNetEqFactory().Create(CreateEnvironment(&clock_),
+                                          NetEq::Config(),
+                                          std::move(decoder_factory))),
       packet_source_(packet_source),
       audio_sink_(audio_sink),
       output_freq_hz_(output_freq_hz),
@@ -52,43 +44,43 @@
 AcmReceiveTestOldApi::~AcmReceiveTestOldApi() = default;
 
 void AcmReceiveTestOldApi::RegisterDefaultCodecs() {
-  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}}});
+  neteq_->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_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}}});
+  neteq_->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 +90,9 @@
     while (clock_.TimeInMilliseconds() < packet->time_ms()) {
       AudioFrame output_frame;
       bool muted;
-      EXPECT_EQ(
-          0, acm_receiver_->GetAudio(output_freq_hz_, &output_frame, &muted));
+      EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_frame, &muted));
+      EXPECT_TRUE(
+          resampler_helper_.MaybeResample(output_freq_hz_, &output_frame));
       ASSERT_EQ(output_freq_hz_, output_frame.sample_rate_hz_);
       ASSERT_FALSE(muted);
       const size_t samples_per_block =
@@ -119,7 +112,7 @@
       AfterGetAudio();
     }
 
-    EXPECT_EQ(0, acm_receiver_->InsertPacket(
+    EXPECT_EQ(0, neteq_->InsertPacket(
                      packet->header(),
                      rtc::ArrayView<const uint8_t>(
                          packet->payload(), packet->payload_length_bytes()),
diff --git a/modules/audio_coding/acm2/acm_receive_test.h b/modules/audio_coding/acm2/acm_receive_test.h
index d0195dd..5e775af 100644
--- a/modules/audio_coding/acm2/acm_receive_test.h
+++ b/modules/audio_coding/acm2/acm_receive_test.h
@@ -17,8 +17,9 @@
 #include <string>
 
 #include "api/audio_codecs/audio_decoder_factory.h"
+#include "api/neteq/neteq.h"
 #include "api/scoped_refptr.h"
-#include "modules/audio_coding/acm2/acm_receiver.h"
+#include "modules/audio_coding/acm2/acm_resampler.h"
 #include "system_wrappers/include/clock.h"
 
 namespace webrtc {
@@ -63,7 +64,8 @@
   virtual void AfterGetAudio() {}
 
   SimulatedClock clock_;
-  std::unique_ptr<acm2::AcmReceiver> acm_receiver_;
+  std::unique_ptr<NetEq> neteq_;
+  acm2::ResamplerHelper resampler_helper_;
   PacketSource* packet_source_;
   AudioSink* audio_sink_;
   int output_freq_hz_;
diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
index c7e9dfc..62c3c39 100644
--- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc
+++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
@@ -34,6 +34,7 @@
 #include "modules/audio_coding/codecs/g711/audio_decoder_pcm.h"
 #include "modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
+#include "modules/audio_coding/neteq/default_neteq_factory.h"
 #include "modules/audio_coding/neteq/tools/audio_checksum.h"
 #include "modules/audio_coding/neteq/tools/audio_loop.h"
 #include "modules/audio_coding/neteq/tools/constant_pcm_packet_source.h"
@@ -174,9 +175,8 @@
 
   void SetUp() {
     acm_ = AudioCodingModule::Create();
-    acm2::AcmReceiver::Config config;
-    config.decoder_factory = CreateBuiltinAudioDecoderFactory();
-    acm_receiver_ = std::make_unique<acm2::AcmReceiver>(env_, config);
+    neteq_ = DefaultNetEqFactory().Create(env_, NetEq::Config(),
+                                          CreateBuiltinAudioDecoderFactory());
 
     rtp_utility_->Populate(&rtp_header_);
 
@@ -199,7 +199,7 @@
   }
 
   virtual void RegisterCodec() {
-    acm_receiver_->SetCodecs({{kPayloadType, *audio_format_}});
+    neteq_->SetCodecs({{kPayloadType, *audio_format_}});
     acm_->SetEncoder(CreateBuiltinAudioEncoderFactory()->Create(
         env_, *audio_format_, {.payload_type = kPayloadType}));
   }
@@ -211,7 +211,7 @@
 
   virtual void InsertPacket() {
     const uint8_t kPayload[kPayloadSizeBytes] = {0};
-    ASSERT_EQ(0, acm_receiver_->InsertPacket(
+    ASSERT_EQ(0, neteq_->InsertPacket(
                      rtp_header_,
                      rtc::ArrayView<const uint8_t>(kPayload, kPayloadSizeBytes),
                      /*receive_time=*/Timestamp::MinusInfinity()));
@@ -221,7 +221,7 @@
   virtual void PullAudio() {
     AudioFrame audio_frame;
     bool muted;
-    ASSERT_EQ(0, acm_receiver_->GetAudio(-1, &audio_frame, &muted));
+    ASSERT_EQ(0, neteq_->GetAudio(&audio_frame, &muted));
     ASSERT_FALSE(muted);
   }
 
@@ -244,7 +244,7 @@
   Environment env_;
   std::unique_ptr<RtpData> rtp_utility_;
   std::unique_ptr<AudioCodingModule> acm_;
-  std::unique_ptr<acm2::AcmReceiver> acm_receiver_;
+  std::unique_ptr<NetEq> neteq_;
   PacketizationCallbackStubOldApi packet_cb_;
   RTPHeader rtp_header_;
   AudioFrame input_frame_;
@@ -256,19 +256,6 @@
 class AudioCodingModuleTestOldApiDeathTest
     : public AudioCodingModuleTestOldApi {};
 
-// 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.
-// http://crbug.com/615050
-#if !defined(WEBRTC_WIN) && defined(__clang__) && RTC_DCHECK_IS_ON && \
-    GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
-TEST_F(AudioCodingModuleTestOldApiDeathTest, FailOnZeroDesiredFrequency) {
-  AudioFrame audio_frame;
-  bool muted;
-  RTC_EXPECT_DEATH(acm_receiver_->GetAudio(0, &audio_frame, &muted), "");
-}
-#endif
-
 // Checks that the transport callback is invoked once for each speech packet.
 // Also checks that the frame type is kAudioFrameSpeech.
 TEST_F(AudioCodingModuleTestOldApi, TransportCallbackIsInvokedForEachPacket) {
@@ -297,8 +284,8 @@
     : public AudioCodingModuleTestOldApi {
  protected:
   void RegisterCngCodec(int rtp_payload_type) {
-    acm_receiver_->SetCodecs({{kPayloadType, *audio_format_},
-                              {rtp_payload_type, {"cn", kSampleRateHz, 1}}});
+    neteq_->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/test/Channel.cc b/modules/audio_coding/test/Channel.cc
index f09b357..705f8a1 100644
--- a/modules/audio_coding/test/Channel.cc
+++ b/modules/audio_coding/test/Channel.cc
@@ -82,7 +82,7 @@
     return 0;
   }
 
-  status = _receiverACM->InsertPacket(
+  status = _neteq->InsertPacket(
       rtp_header, rtc::ArrayView<const uint8_t>(_payloadData, payloadDataSize),
       /*receive_time=*/Timestamp::MinusInfinity());
 
@@ -187,7 +187,7 @@
 }
 
 Channel::Channel(int16_t chID)
-    : _receiverACM(NULL),
+    : _neteq(NULL),
       _seqNo(0),
       _bitStreamFile(NULL),
       _saveBitStream(false),
@@ -229,8 +229,8 @@
 
 Channel::~Channel() {}
 
-void Channel::RegisterReceiverACM(acm2::AcmReceiver* acm_receiver) {
-  _receiverACM = acm_receiver;
+void Channel::RegisterReceiverNetEq(NetEq* neteq) {
+  _neteq = neteq;
   return;
 }
 
diff --git a/modules/audio_coding/test/Channel.h b/modules/audio_coding/test/Channel.h
index ebf4461..616e283 100644
--- a/modules/audio_coding/test/Channel.h
+++ b/modules/audio_coding/test/Channel.h
@@ -13,7 +13,7 @@
 
 #include <stdio.h>
 
-#include "modules/audio_coding/acm2/acm_receiver.h"
+#include "api/neteq/neteq.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
 #include "modules/include/module_common_types.h"
 #include "rtc_base/synchronization/mutex.h"
@@ -55,7 +55,7 @@
                    size_t payloadSize,
                    int64_t absolute_capture_timestamp_ms) override;
 
-  void RegisterReceiverACM(acm2::AcmReceiver* acm_receiver);
+  void RegisterReceiverNetEq(NetEq* neteq);
 
   void ResetStats();
 
@@ -84,7 +84,7 @@
  private:
   void CalcStatistics(const RTPHeader& rtp_header, size_t payloadSize);
 
-  acm2::AcmReceiver* _receiverACM;
+  NetEq* _neteq;
   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 70e18b3..665d0d9 100644
--- a/modules/audio_coding/test/EncodeDecodeTest.cc
+++ b/modules/audio_coding/test/EncodeDecodeTest.cc
@@ -21,6 +21,7 @@
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
+#include "modules/audio_coding/neteq/default_neteq_factory.h"
 #include "rtc_base/strings/string_builder.h"
 #include "test/gtest.h"
 #include "test/testsupport/file_utils.h"
@@ -105,32 +106,32 @@
     : _playoutLengthSmpls(kWebRtc10MsPcmAudio),
       _payloadSizeBytes(MAX_INCOMING_PAYLOAD) {}
 
-void Receiver::Setup(acm2::AcmReceiver* acm_receiver,
+void Receiver::Setup(NetEq* neteq,
                      RTPStream* rtpStream,
                      absl::string_view out_file_name,
                      size_t channels,
                      int file_num) {
   if (channels == 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}}});
+    neteq->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_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"}}}}});
+    neteq->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;
@@ -147,7 +148,7 @@
   _realPayloadSizeBytes = 0;
   _playoutBuffer = new int16_t[kWebRtc10MsPcmAudio];
   _frequency = playSampFreq;
-  _acm_receiver = acm_receiver;
+  _neteq = neteq;
   _firstTime = true;
 }
 
@@ -172,11 +173,11 @@
       }
     }
 
-    EXPECT_EQ(0, _acm_receiver->InsertPacket(
-                     _rtpHeader,
-                     rtc::ArrayView<const uint8_t>(_incomingPayload,
-                                                   _realPayloadSizeBytes),
-                     /*receive_time=*/Timestamp::Millis(_nextTime)));
+    EXPECT_GE(
+        0, _neteq->InsertPacket(_rtpHeader,
+                                rtc::ArrayView<const uint8_t>(
+                                    _incomingPayload, _realPayloadSizeBytes),
+                                /*receive_time=*/Timestamp::Millis(_nextTime)));
     _realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload,
                                              _payloadSizeBytes, &_nextTime);
     if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile()) {
@@ -189,18 +190,19 @@
 bool Receiver::PlayoutData() {
   AudioFrame audioFrame;
   bool muted;
-  int32_t ok = _acm_receiver->GetAudio(_frequency, &audioFrame, &muted);
+  int ok = _neteq->GetAudio(&audioFrame, &muted);
   if (muted) {
     ADD_FAILURE();
     return false;
   }
-  EXPECT_EQ(0, ok);
+  EXPECT_EQ(NetEq::kOK, ok);
   if (ok < 0) {
     return false;
   }
   if (_playoutLengthSmpls == 0) {
     return false;
   }
+  EXPECT_TRUE(_resampler_helper.MaybeResample(_frequency, &audioFrame));
   _pcmFile.Write10MsData(audioFrame.data(), audioFrame.samples_per_channel_ *
                                                 audioFrame.num_channels_);
   return true;
@@ -264,12 +266,10 @@
 
     rtpFile.Open(fileName.c_str(), "rb");
     rtpFile.ReadHeader();
-    std::unique_ptr<acm2::AcmReceiver> acm_receiver =
-        std::make_unique<acm2::AcmReceiver>(
-            env, acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory()));
+    std::unique_ptr<NetEq> neteq = DefaultNetEqFactory().Create(
+        env, NetEq::Config(), CreateBuiltinAudioDecoderFactory());
     Receiver receiver;
-    receiver.Setup(acm_receiver.get(), &rtpFile, "encodeDecode_out", 1,
-                   file_num);
+    receiver.Setup(neteq.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 8acacb9..8a20998 100644
--- a/modules/audio_coding/test/EncodeDecodeTest.h
+++ b/modules/audio_coding/test/EncodeDecodeTest.h
@@ -16,7 +16,8 @@
 
 #include "absl/strings/string_view.h"
 #include "api/environment/environment.h"
-#include "modules/audio_coding/acm2/acm_receiver.h"
+#include "api/neteq/neteq.h"
+#include "modules/audio_coding/acm2/acm_resampler.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
 #include "modules/audio_coding/test/PCMFile.h"
 #include "modules/audio_coding/test/RTPFile.h"
@@ -76,7 +77,7 @@
  public:
   Receiver();
   virtual ~Receiver() {}
-  void Setup(acm2::AcmReceiver* acm_receiver,
+  void Setup(NetEq* neteq,
              RTPStream* rtpStream,
              absl::string_view out_file_name,
              size_t channels,
@@ -94,7 +95,8 @@
   bool _firstTime;
 
  protected:
-  acm2::AcmReceiver* _acm_receiver;
+  NetEq* _neteq;
+  acm2::ResamplerHelper _resampler_helper;
   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 9226b0f..24bca73 100644
--- a/modules/audio_coding/test/PacketLossTest.cc
+++ b/modules/audio_coding/test/PacketLossTest.cc
@@ -17,6 +17,7 @@
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "api/units/timestamp.h"
+#include "modules/audio_coding/neteq/default_neteq_factory.h"
 #include "rtc_base/strings/string_builder.h"
 #include "test/gtest.h"
 #include "test/testsupport/file_utils.h"
@@ -30,7 +31,7 @@
       lost_packet_counter_(0),
       burst_lost_counter_(burst_length_) {}
 
-void ReceiverWithPacketLoss::Setup(acm2::AcmReceiver* acm_receiver,
+void ReceiverWithPacketLoss::Setup(NetEq* neteq,
                                    RTPStream* rtpStream,
                                    absl::string_view out_file_name,
                                    int channels,
@@ -42,7 +43,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_receiver, rtpStream, ss.str(), channels, file_num);
+  Receiver::Setup(neteq, rtpStream, ss.str(), channels, file_num);
 }
 
 bool ReceiverWithPacketLoss::IncomingPacket() {
@@ -61,10 +62,10 @@
     }
 
     if (!PacketLost()) {
-      _acm_receiver->InsertPacket(_rtpHeader,
-                                  rtc::ArrayView<const uint8_t>(
-                                      _incomingPayload, _realPayloadSizeBytes),
-                                  Timestamp::Millis(_nextTime));
+      _neteq->InsertPacket(_rtpHeader,
+                           rtc::ArrayView<const uint8_t>(_incomingPayload,
+                                                         _realPayloadSizeBytes),
+                           Timestamp::Millis(_nextTime));
     }
     packet_counter_++;
     _realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload,
@@ -162,11 +163,10 @@
 
   rtpFile.Open(fileName.c_str(), "rb");
   rtpFile.ReadHeader();
-  std::unique_ptr<acm2::AcmReceiver> acm_receiver =
-      std::make_unique<acm2::AcmReceiver>(
-          env, acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory()));
+  std::unique_ptr<NetEq> neteq = DefaultNetEqFactory().Create(
+      env, NetEq::Config(), CreateBuiltinAudioDecoderFactory());
   ReceiverWithPacketLoss receiver;
-  receiver.Setup(acm_receiver.get(), &rtpFile, "packetLoss_out", channels_, 15,
+  receiver.Setup(neteq.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 b256393..41a62d5 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(acm2::AcmReceiver* acm_receiver,
+  void Setup(NetEq* neteq,
              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 41c4a3a..1a9887b 100644
--- a/modules/audio_coding/test/TestAllCodecs.cc
+++ b/modules/audio_coding/test/TestAllCodecs.cc
@@ -18,7 +18,10 @@
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
 #include "api/environment/environment_factory.h"
+#include "api/neteq/neteq.h"
+#include "modules/audio_coding/acm2/acm_resampler.h"
 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
+#include "modules/audio_coding/neteq/default_neteq_factory.h"
 #include "modules/include/module_common_types.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/string_encode.h"
@@ -47,7 +50,7 @@
 
 // Class for simulating packet handling.
 TestPack::TestPack()
-    : receiver_acm_(NULL),
+    : neteq_(NULL),
       sequence_number_(0),
       timestamp_diff_(0),
       last_in_timestamp_(0),
@@ -56,9 +59,8 @@
 
 TestPack::~TestPack() {}
 
-void TestPack::RegisterReceiverACM(acm2::AcmReceiver* acm_receiver) {
-  receiver_acm_ = acm_receiver;
-  return;
+void TestPack::RegisterReceiverNetEq(NetEq* neteq) {
+  neteq_ = neteq;
 }
 
 int32_t TestPack::SendData(AudioFrameType frame_type,
@@ -84,7 +86,7 @@
   // Only run mono for all test cases.
   memcpy(payload_data_, payload_data, payload_size);
 
-  status = receiver_acm_->InsertPacket(
+  status = neteq_->InsertPacket(
       rtp_header, rtc::ArrayView<const uint8_t>(payload_data_, payload_size),
       /*receive_time=*/Timestamp::MinusInfinity());
 
@@ -110,9 +112,9 @@
 TestAllCodecs::TestAllCodecs()
     : env_(CreateEnvironment()),
       acm_a_(AudioCodingModule::Create()),
-      acm_b_(std::make_unique<acm2::AcmReceiver>(
-          env_,
-          acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory()))),
+      neteq_(DefaultNetEqFactory().Create(env_,
+                                          NetEq::Config(),
+                                          CreateBuiltinAudioDecoderFactory())),
       channel_a_to_b_(NULL),
       test_count_(0),
       packet_size_samples_(0),
@@ -130,7 +132,7 @@
       webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
   infile_a_.Open(file_name, 32000, "rb");
 
-  acm_b_->SetCodecs({{107, {"L16", 8000, 1}},
+  neteq_->SetCodecs({{107, {"L16", 8000, 1}},
                      {108, {"L16", 16000, 1}},
                      {109, {"L16", 32000, 1}},
                      {111, {"L16", 8000, 2}},
@@ -151,7 +153,7 @@
   // Create and connect the channel
   channel_a_to_b_ = new TestPack;
   acm_a_->RegisterTransportCallback(channel_a_to_b_);
-  channel_a_to_b_->RegisterReceiverACM(acm_b_.get());
+  channel_a_to_b_->RegisterReceiverNetEq(neteq_.get());
 
   // All codecs are tested for all allowed sampling frequencies, rates and
   // packet sizes.
@@ -330,6 +332,7 @@
 
 void TestAllCodecs::Run(TestPack* channel) {
   AudioFrame audio_frame;
+  acm2::ResamplerHelper resampler_helper;
 
   int32_t out_freq_hz = outfile_b_.SamplingFrequency();
   size_t receive_size;
@@ -367,8 +370,9 @@
 
     // Run received side of ACM.
     bool muted;
-    CHECK_ERROR(acm_b_->GetAudio(out_freq_hz, &audio_frame, &muted));
+    CHECK_ERROR(neteq_->GetAudio(&audio_frame, &muted));
     ASSERT_FALSE(muted);
+    EXPECT_TRUE(resampler_helper.MaybeResample(out_freq_hz, &audio_frame));
 
     // Write output speech to file.
     outfile_b_.Write10MsData(audio_frame.data(),
diff --git a/modules/audio_coding/test/TestAllCodecs.h b/modules/audio_coding/test/TestAllCodecs.h
index e078f49..0712332 100644
--- a/modules/audio_coding/test/TestAllCodecs.h
+++ b/modules/audio_coding/test/TestAllCodecs.h
@@ -14,18 +14,19 @@
 #include <memory>
 
 #include "api/environment/environment.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"
 
 namespace webrtc {
 
+class NetEq;
+
 class TestPack : public AudioPacketizationCallback {
  public:
   TestPack();
   ~TestPack();
 
-  void RegisterReceiverACM(acm2::AcmReceiver* acm_receiver);
+  void RegisterReceiverNetEq(NetEq* neteq);
 
   int32_t SendData(AudioFrameType frame_type,
                    uint8_t payload_type,
@@ -39,7 +40,7 @@
   void reset_payload_size();
 
  private:
-  acm2::AcmReceiver* receiver_acm_;
+  NetEq* neteq_;
   uint16_t sequence_number_;
   uint8_t payload_data_[60 * 32 * 2 * 2];
   uint32_t timestamp_diff_;
@@ -71,7 +72,7 @@
 
   const Environment env_;
   std::unique_ptr<AudioCodingModule> acm_a_;
-  std::unique_ptr<acm2::AcmReceiver> acm_b_;
+  std::unique_ptr<NetEq> neteq_;
   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 b4d138b..c1d28e8 100644
--- a/modules/audio_coding/test/TestRedFec.cc
+++ b/modules/audio_coding/test/TestRedFec.cc
@@ -28,6 +28,7 @@
 #include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
 #include "modules/audio_coding/codecs/red/audio_encoder_copy_red.h"
 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
+#include "modules/audio_coding/neteq/default_neteq_factory.h"
 #include "rtc_base/strings/string_builder.h"
 #include "test/gtest.h"
 #include "test/testsupport/file_utils.h"
@@ -45,9 +46,9 @@
                                                  AudioDecoderL16,
                                                  AudioDecoderOpus>()),
       _acmA(AudioCodingModule::Create()),
-      _acm_receiver(std::make_unique<acm2::AcmReceiver>(
-          env_,
-          acm2::AcmReceiver::Config(decoder_factory_))),
+      _neteq(DefaultNetEqFactory().Create(env_,
+                                          NetEq::Config(),
+                                          decoder_factory_)),
       _channelA2B(NULL),
       _testCntr(0) {}
 
@@ -66,7 +67,7 @@
   // Create and connect the channel
   _channelA2B = new Channel;
   _acmA->RegisterTransportCallback(_channelA2B);
-  _channelA2B->RegisterReceiverACM(_acm_receiver.get());
+  _channelA2B->RegisterReceiverNetEq(_neteq.get());
 
   RegisterSendCodec(_acmA, {"L16", 8000, 1}, Vad::kVadAggressive, true);
 
@@ -166,7 +167,7 @@
     }
   }
   acm->SetEncoder(std::move(encoder));
-  _acm_receiver->SetCodecs(receive_codecs);
+  _neteq->SetCodecs(receive_codecs);
 }
 
 void TestRedFec::Run() {
@@ -181,7 +182,8 @@
     EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0);
     EXPECT_GE(_acmA->Add10MsData(audioFrame), 0);
     bool muted;
-    EXPECT_EQ(0, _acm_receiver->GetAudio(outFreqHzB, &audioFrame, &muted));
+    EXPECT_EQ(NetEq::kOK, _neteq->GetAudio(&audioFrame, &muted));
+    EXPECT_TRUE(_resampler_helper.MaybeResample(outFreqHzB, &audioFrame));
     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 56a6495..6235854 100644
--- a/modules/audio_coding/test/TestRedFec.h
+++ b/modules/audio_coding/test/TestRedFec.h
@@ -17,8 +17,9 @@
 #include "api/audio_codecs/audio_decoder_factory.h"
 #include "api/audio_codecs/audio_encoder_factory.h"
 #include "api/environment/environment.h"
+#include "api/neteq/neteq.h"
 #include "common_audio/vad/include/vad.h"
-#include "modules/audio_coding/acm2/acm_receiver.h"
+#include "modules/audio_coding/acm2/acm_resampler.h"
 #include "modules/audio_coding/test/Channel.h"
 #include "modules/audio_coding/test/PCMFile.h"
 #include "test/scoped_key_value_config.h"
@@ -45,7 +46,8 @@
   const rtc::scoped_refptr<AudioEncoderFactory> encoder_factory_;
   const rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
   std::unique_ptr<AudioCodingModule> _acmA;
-  std::unique_ptr<acm2::AcmReceiver> _acm_receiver;
+  std::unique_ptr<NetEq> _neteq;
+  acm2::ResamplerHelper _resampler_helper;
 
   Channel* _channelA2B;
 
diff --git a/modules/audio_coding/test/TestStereo.cc b/modules/audio_coding/test/TestStereo.cc
index 0c258e9..4561d4c 100644
--- a/modules/audio_coding/test/TestStereo.cc
+++ b/modules/audio_coding/test/TestStereo.cc
@@ -17,6 +17,7 @@
 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
 #include "api/environment/environment_factory.h"
 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
+#include "modules/audio_coding/neteq/default_neteq_factory.h"
 #include "modules/include/module_common_types.h"
 #include "rtc_base/strings/string_builder.h"
 #include "test/gtest.h"
@@ -26,7 +27,7 @@
 
 // Class for simulating packet handling
 TestPackStereo::TestPackStereo()
-    : receiver_acm_(NULL),
+    : neteq_(NULL),
       seq_no_(0),
       timestamp_diff_(0),
       last_in_timestamp_(0),
@@ -36,8 +37,8 @@
 
 TestPackStereo::~TestPackStereo() {}
 
-void TestPackStereo::RegisterReceiverACM(acm2::AcmReceiver* acm_receiver) {
-  receiver_acm_ = acm_receiver;
+void TestPackStereo::RegisterReceiverNetEq(NetEq* neteq) {
+  neteq_ = neteq;
   return;
 }
 
@@ -61,7 +62,7 @@
   }
 
   if (lost_packet_ == false) {
-    status = receiver_acm_->InsertPacket(
+    status = neteq_->InsertPacket(
         rtp_header, rtc::ArrayView<const uint8_t>(payload_data, payload_size),
         /*receive_time=*/Timestamp::MinusInfinity());
 
@@ -101,9 +102,9 @@
 TestStereo::TestStereo()
     : env_(CreateEnvironment()),
       acm_a_(AudioCodingModule::Create()),
-      acm_b_(std::make_unique<acm2::AcmReceiver>(
-          env_,
-          acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory()))),
+      neteq_(DefaultNetEqFactory().Create(env_,
+                                          NetEq::Config(),
+                                          CreateBuiltinAudioDecoderFactory())),
       channel_a2b_(NULL),
       test_cntr_(0),
       pack_size_samp_(0),
@@ -136,10 +137,10 @@
   in_file_mono_->ReadStereo(false);
 
   // 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));
-  acm_b_->FlushBuffers();
+  ASSERT_TRUE((acm_a_.get() != NULL) && (neteq_.get() != NULL));
+  neteq_->FlushBuffers();
 
-  acm_b_->SetCodecs({{103, {"ISAC", 16000, 1}},
+  neteq_->SetCodecs({{103, {"ISAC", 16000, 1}},
                      {104, {"ISAC", 32000, 1}},
                      {107, {"L16", 8000, 1}},
                      {108, {"L16", 16000, 1}},
@@ -162,7 +163,7 @@
   // Create and connect the channel.
   channel_a2b_ = new TestPackStereo;
   EXPECT_EQ(0, acm_a_->RegisterTransportCallback(channel_a2b_));
-  channel_a2b_->RegisterReceiverACM(acm_b_.get());
+  channel_a2b_->RegisterReceiverNetEq(neteq_.get());
 
   char codec_pcma_temp[] = "PCMA";
   RegisterSendCodec('A', codec_pcma_temp, 8000, 64000, 80, 2);
@@ -400,7 +401,7 @@
   OpenOutFile(test_cntr_);
   // Encode and decode in mono.
   RegisterSendCodec('A', codec_opus, 48000, 32000, 960, codec_channels);
-  acm_b_->SetCodecs({{120, {"OPUS", 48000, 2}}});
+  neteq_->SetCodecs({{120, {"OPUS", 48000, 2}}});
   Run(channel_a2b_, audio_channels, codec_channels);
 
   // Encode in stereo, decode in mono.
@@ -419,13 +420,13 @@
   // Decode in stereo.
   test_cntr_++;
   OpenOutFile(test_cntr_);
-  acm_b_->SetCodecs({{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}});
+  neteq_->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_->SetCodecs({{120, {"OPUS", 48000, 2}}});
+  neteq_->SetCodecs({{120, {"OPUS", 48000, 2}}});
   Run(channel_a2b_, audio_channels, codec_channels);
   out_file_.Close();
 #endif
@@ -468,7 +469,7 @@
     case 'B': {
       // We no longer use this case. Refactor code to avoid the switch.
       ASSERT_TRUE(false);
-      // my_acm = acm_b_.get();
+      // my_acm = neteq_.get();
       break;
     }
     default:
@@ -571,7 +572,8 @@
 
     // Run receive side of ACM
     bool muted;
-    EXPECT_EQ(0, acm_b_->GetAudio(out_freq_hz_b, &audio_frame, &muted));
+    EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&audio_frame, &muted));
+    EXPECT_TRUE(resampler_helper_.MaybeResample(out_freq_hz_b, &audio_frame));
     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 b53187b..7f31569 100644
--- a/modules/audio_coding/test/TestStereo.h
+++ b/modules/audio_coding/test/TestStereo.h
@@ -16,7 +16,8 @@
 #include <memory>
 
 #include "api/environment/environment.h"
-#include "modules/audio_coding/acm2/acm_receiver.h"
+#include "api/neteq/neteq.h"
+#include "modules/audio_coding/acm2/acm_resampler.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
 #include "modules/audio_coding/test/PCMFile.h"
 
@@ -31,7 +32,7 @@
   TestPackStereo();
   ~TestPackStereo();
 
-  void RegisterReceiverACM(acm2::AcmReceiver* acm_receiver);
+  void RegisterReceiverNetEq(NetEq* neteq);
 
   int32_t SendData(AudioFrameType frame_type,
                    uint8_t payload_type,
@@ -47,7 +48,7 @@
   void set_lost_packet(bool lost);
 
  private:
-  acm2::AcmReceiver* receiver_acm_;
+  NetEq* neteq_;
   int16_t seq_no_;
   uint32_t timestamp_diff_;
   uint32_t last_in_timestamp_;
@@ -84,7 +85,8 @@
 
   const Environment env_;
   std::unique_ptr<AudioCodingModule> acm_a_;
-  std::unique_ptr<acm2::AcmReceiver> acm_b_;
+  std::unique_ptr<NetEq> neteq_;
+  acm2::ResamplerHelper resampler_helper_;
 
   TestPackStereo* channel_a2b_;
 
diff --git a/modules/audio_coding/test/TestVADDTX.cc b/modules/audio_coding/test/TestVADDTX.cc
index ac87ae1..ce3247c 100644
--- a/modules/audio_coding/test/TestVADDTX.cc
+++ b/modules/audio_coding/test/TestVADDTX.cc
@@ -22,6 +22,7 @@
 #include "api/audio_codecs/opus/audio_encoder_opus.h"
 #include "api/environment/environment_factory.h"
 #include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
+#include "modules/audio_coding/neteq/default_neteq_factory.h"
 #include "modules/audio_coding/test/PCMFile.h"
 #include "rtc_base/strings/string_builder.h"
 #include "test/gtest.h"
@@ -73,16 +74,16 @@
       decoder_factory_(
           CreateAudioDecoderFactory<AudioDecoderIlbc, AudioDecoderOpus>()),
       acm_send_(AudioCodingModule::Create()),
-      acm_receive_(std::make_unique<acm2::AcmReceiver>(
-          env_,
-          acm2::AcmReceiver::Config(decoder_factory_))),
+      neteq_(DefaultNetEqFactory().Create(env_,
+                                          NetEq::Config(),
+                                          decoder_factory_)),
       channel_(std::make_unique<Channel>()),
       packetization_callback_(
           std::make_unique<MonitoringAudioPacketizationCallback>(
               channel_.get())) {
   EXPECT_EQ(
       0, acm_send_->RegisterTransportCallback(packetization_callback_.get()));
-  channel_->RegisterReceiverACM(acm_receive_.get());
+  channel_->RegisterReceiverNetEq(neteq_.get());
 }
 
 bool TestVadDtx::RegisterCodec(const SdpAudioFormat& codec_format,
@@ -106,7 +107,7 @@
   acm_send_->SetEncoder(std::move(encoder));
 
   std::map<int, SdpAudioFormat> receive_codecs = {{payload_type, codec_format}};
-  acm_receive_->SetCodecs(receive_codecs);
+  neteq_->SetCodecs(receive_codecs);
 
   return added_comfort_noise;
 }
@@ -145,7 +146,8 @@
     time_stamp_ += frame_size_samples;
     EXPECT_GE(acm_send_->Add10MsData(audio_frame), 0);
     bool muted;
-    acm_receive_->GetAudio(kOutputFreqHz, &audio_frame, &muted);
+    neteq_->GetAudio(&audio_frame, &muted);
+    resampler_helper_.MaybeResample(kOutputFreqHz, &audio_frame);
     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 b7f90a3..9d4f0af 100644
--- a/modules/audio_coding/test/TestVADDTX.h
+++ b/modules/audio_coding/test/TestVADDTX.h
@@ -17,8 +17,9 @@
 #include "api/audio_codecs/audio_decoder_factory.h"
 #include "api/audio_codecs/audio_encoder_factory.h"
 #include "api/environment/environment.h"
+#include "api/neteq/neteq.h"
 #include "common_audio/vad/include/vad.h"
-#include "modules/audio_coding/acm2/acm_receiver.h"
+#include "modules/audio_coding/acm2/acm_resampler.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"
@@ -87,7 +88,8 @@
   const rtc::scoped_refptr<AudioEncoderFactory> encoder_factory_;
   const rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
   std::unique_ptr<AudioCodingModule> acm_send_;
-  std::unique_ptr<acm2::AcmReceiver> acm_receive_;
+  std::unique_ptr<NetEq> neteq_;
+  acm2::ResamplerHelper resampler_helper_;
   std::unique_ptr<Channel> channel_;
   std::unique_ptr<MonitoringAudioPacketizationCallback> packetization_callback_;
   uint32_t time_stamp_ = 0x12345678;
diff --git a/modules/audio_coding/test/opus_test.cc b/modules/audio_coding/test/opus_test.cc
index 95cfef5..6377304 100644
--- a/modules/audio_coding/test/opus_test.cc
+++ b/modules/audio_coding/test/opus_test.cc
@@ -16,6 +16,7 @@
 #include "api/environment/environment_factory.h"
 #include "modules/audio_coding/codecs/opus/opus_interface.h"
 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
+#include "modules/audio_coding/neteq/default_neteq_factory.h"
 #include "modules/audio_coding/test/TestStereo.h"
 #include "test/gtest.h"
 #include "test/testsupport/file_utils.h"
@@ -23,9 +24,9 @@
 namespace webrtc {
 
 OpusTest::OpusTest()
-    : acm_receiver_(std::make_unique<acm2::AcmReceiver>(
-          CreateEnvironment(),
-          acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory()))),
+    : neteq_(DefaultNetEqFactory().Create(CreateEnvironment(),
+                                          NetEq::Config(),
+                                          CreateBuiltinAudioDecoderFactory())),
       channel_a2b_(NULL),
       counter_(0),
       payload_type_(255),
@@ -84,18 +85,18 @@
   WebRtcOpus_DecoderInit(opus_mono_decoder_);
   WebRtcOpus_DecoderInit(opus_stereo_decoder_);
 
-  ASSERT_TRUE(acm_receiver_.get() != NULL);
-  acm_receiver_->FlushBuffers();
+  ASSERT_TRUE(neteq_.get() != NULL);
+  neteq_->FlushBuffers();
 
   // Register Opus stereo as receiving codec.
   constexpr int kOpusPayloadType = 120;
   const SdpAudioFormat kOpusFormatStereo("opus", 48000, 2, {{"stereo", "1"}});
   payload_type_ = kOpusPayloadType;
-  acm_receiver_->SetCodecs({{kOpusPayloadType, kOpusFormatStereo}});
+  neteq_->SetCodecs({{kOpusPayloadType, kOpusFormatStereo}});
 
   // Create and connect the channel.
   channel_a2b_ = new TestPackStereo;
-  channel_a2b_->RegisterReceiverACM(acm_receiver_.get());
+  channel_a2b_->RegisterReceiverNetEq(neteq_.get());
 
   //
   // Test Stereo.
@@ -156,7 +157,7 @@
 
   // Register Opus mono as receiving codec.
   const SdpAudioFormat kOpusFormatMono("opus", 48000, 2);
-  acm_receiver_->SetCodecs({{kOpusPayloadType, kOpusFormatMono}});
+  neteq_->SetCodecs({{kOpusPayloadType, kOpusFormatMono}});
 
   // Run Opus with 2.5 ms frame size.
   Run(channel_a2b_, audio_channels, 32000, 120);
@@ -355,8 +356,8 @@
 
     // Run received side of ACM.
     bool muted;
-    ASSERT_EQ(0, acm_receiver_->GetAudio(out_freq_hz_b, &audio_frame, &muted));
-    ASSERT_FALSE(muted);
+    ASSERT_EQ(NetEq::kOK, neteq_->GetAudio(&audio_frame, &muted));
+    ASSERT_TRUE(resampler_helper_.MaybeResample(out_freq_hz_b, &audio_frame));
 
     // Write output speech to file.
     out_file_.Write10MsData(
diff --git a/modules/audio_coding/test/opus_test.h b/modules/audio_coding/test/opus_test.h
index cf5581a..a2ae758 100644
--- a/modules/audio_coding/test/opus_test.h
+++ b/modules/audio_coding/test/opus_test.h
@@ -15,7 +15,7 @@
 
 #include <memory>
 
-#include "modules/audio_coding/acm2/acm_receiver.h"
+#include "api/neteq/neteq.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"
@@ -39,7 +39,8 @@
 
   void OpenOutFile(int test_number);
 
-  std::unique_ptr<acm2::AcmReceiver> acm_receiver_;
+  std::unique_ptr<NetEq> neteq_;
+  acm2::ResamplerHelper resampler_helper_;
   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 cb15610..3d62aab 100644
--- a/modules/audio_coding/test/target_delay_unittest.cc
+++ b/modules/audio_coding/test/target_delay_unittest.cc
@@ -15,9 +15,9 @@
 #include "api/environment/environment_factory.h"
 #include "api/rtp_headers.h"
 #include "api/units/timestamp.h"
-#include "modules/audio_coding/acm2/acm_receiver.h"
 #include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
+#include "modules/audio_coding/neteq/default_neteq_factory.h"
 #include "test/gtest.h"
 #include "test/testsupport/file_utils.h"
 
@@ -26,9 +26,10 @@
 class TargetDelayTest : public ::testing::Test {
  protected:
   TargetDelayTest()
-      : receiver_(
-            CreateEnvironment(),
-            acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory())) {}
+      : neteq_(
+            DefaultNetEqFactory().Create(CreateEnvironment(),
+                                         NetEq::Config(),
+                                         CreateBuiltinAudioDecoderFactory())) {}
 
   ~TargetDelayTest() {}
 
@@ -36,7 +37,7 @@
     constexpr int pltype = 108;
     std::map<int, SdpAudioFormat> receive_codecs = {
         {pltype, {"L16", kSampleRateHz, 1}}};
-    receiver_.SetCodecs(receive_codecs);
+    neteq_->SetCodecs(receive_codecs);
 
     rtp_header_.payloadType = pltype;
     rtp_header_.timestamp = 0;
@@ -52,20 +53,20 @@
   }
 
   void OutOfRangeInput() {
-    EXPECT_EQ(-1, SetMinimumDelay(-1));
-    EXPECT_EQ(-1, SetMinimumDelay(10001));
+    EXPECT_FALSE(SetMinimumDelay(-1));
+    EXPECT_FALSE(SetMinimumDelay(10001));
   }
 
   void TargetDelayBufferMinMax() {
     const int kTargetMinDelayMs = kNum10msPerFrame * 10;
-    ASSERT_EQ(0, SetMinimumDelay(kTargetMinDelayMs));
+    ASSERT_TRUE(SetMinimumDelay(kTargetMinDelayMs));
     for (int m = 0; m < 30; ++m)  // Run enough iterations to fill the buffer.
       Run(true);
     int clean_optimal_delay = GetCurrentOptimalDelayMs();
     EXPECT_EQ(kTargetMinDelayMs, clean_optimal_delay);
 
     const int kTargetMaxDelayMs = 2 * (kNum10msPerFrame * 10);
-    ASSERT_EQ(0, SetMaximumDelay(kTargetMaxDelayMs));
+    ASSERT_TRUE(SetMaximumDelay(kTargetMaxDelayMs));
     for (int n = 0; n < 30; ++n)  // Run enough iterations to fill the buffer.
       Run(false);
 
@@ -86,10 +87,10 @@
   void Push() {
     rtp_header_.timestamp += kFrameSizeSamples;
     rtp_header_.sequenceNumber++;
-    ASSERT_EQ(0, receiver_.InsertPacket(rtp_header_,
-                                        rtc::ArrayView<const uint8_t>(
-                                            payload_, kFrameSizeSamples * 2),
-                                        Timestamp::MinusInfinity()));
+    ASSERT_EQ(0, neteq_->InsertPacket(rtp_header_,
+                                      rtc::ArrayView<const uint8_t>(
+                                          payload_, kFrameSizeSamples * 2),
+                                      Timestamp::MinusInfinity()));
   }
 
   // Pull audio equivalent to the amount of audio in one RTP packet.
@@ -97,7 +98,7 @@
     AudioFrame frame;
     bool muted;
     for (int k = 0; k < kNum10msPerFrame; ++k) {  // Pull one frame.
-      ASSERT_EQ(0, receiver_.GetAudio(-1, &frame, &muted));
+      ASSERT_EQ(NetEq::kOK, neteq_->GetAudio(&frame, &muted));
       ASSERT_FALSE(muted);
       // Had to use ASSERT_TRUE, ASSERT_EQ generated error.
       ASSERT_TRUE(kSampleRateHz == frame.sample_rate_hz_);
@@ -124,20 +125,20 @@
   }
 
   int SetMinimumDelay(int delay_ms) {
-    return receiver_.SetMinimumDelay(delay_ms);
+    return neteq_->SetMinimumDelay(delay_ms);
   }
 
   int SetMaximumDelay(int delay_ms) {
-    return receiver_.SetMaximumDelay(delay_ms);
+    return neteq_->SetMaximumDelay(delay_ms);
   }
 
   int GetCurrentOptimalDelayMs() {
-    NetworkStatistics stats;
-    receiver_.GetNetworkStatistics(&stats);
-    return stats.preferredBufferSize;
+    NetEqNetworkStatistics neteq_stats;
+    neteq_->NetworkStatistics(&neteq_stats);
+    return neteq_stats.preferred_buffer_size_ms;
   }
 
-  acm2::AcmReceiver receiver_;
+  std::unique_ptr<NetEq> neteq_;
   RTPHeader rtp_header_;
   uint8_t payload_[kPayloadLenBytes];
 };