Use MonoView for deinterleaved channels in AudioFrameView

Allow skipping the deinterleaving steps in PushResampler
before resampling when deinterleaved buffers already exist.

Bug: chromium:335805780
Change-Id: I2080ce2624636cb743beef78f6f08887db01120f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/352202
Reviewed-by: Per Ã…hgren <peah@webrtc.org>
Auto-Submit: Tomas Gunnarsson <tommi@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42438}
diff --git a/api/audio/audio_view.h b/api/audio/audio_view.h
index c877ee4..e75769b 100644
--- a/api/audio/audio_view.h
+++ b/api/audio/audio_view.h
@@ -243,7 +243,7 @@
   //               "Incompatible view types");
   RTC_DCHECK_EQ(NumChannels(destination), NumChannels(source));
   RTC_DCHECK_EQ(SamplesPerChannel(destination), SamplesPerChannel(source));
-  RTC_DCHECK_GE(destination.data().size(), source.data().size());
+  RTC_DCHECK_GE(destination.size(), source.size());
   memcpy(&destination[0], &source[0],
          source.size() * sizeof(typename S::value_type));
 }
diff --git a/common_audio/resampler/include/push_resampler.h b/common_audio/resampler/include/push_resampler.h
index 0ed463b..4a23d46 100644
--- a/common_audio/resampler/include/push_resampler.h
+++ b/common_audio/resampler/include/push_resampler.h
@@ -37,8 +37,12 @@
   // Returns the total number of samples provided in destination (e.g. 32 kHz,
   // 2 channel audio gives 640 samples).
   int Resample(InterleavedView<const T> src, InterleavedView<T> dst);
+  // For when a deinterleaved/mono channel already exists and we can skip the
+  // deinterleaved operation.
+  int Resample(MonoView<const T> src, MonoView<T> dst);
 
  private:
+  // Buffers used for when a deinterleaving step is necessary.
   std::unique_ptr<T[]> source_;
   std::unique_ptr<T[]> destination_;
   DeinterleavedView<T> source_view_;
diff --git a/common_audio/resampler/push_resampler.cc b/common_audio/resampler/push_resampler.cc
index 5d732dd..1cbf421 100644
--- a/common_audio/resampler/push_resampler.cc
+++ b/common_audio/resampler/push_resampler.cc
@@ -95,6 +95,20 @@
   return static_cast<int>(dst.size());
 }
 
+template <typename T>
+int PushResampler<T>::Resample(MonoView<const T> src, MonoView<T> dst) {
+  RTC_DCHECK_EQ(resamplers_.size(), 1);
+  RTC_DCHECK_EQ(SamplesPerChannel(src), SamplesPerChannel(source_view_));
+  RTC_DCHECK_EQ(SamplesPerChannel(dst), SamplesPerChannel(destination_view_));
+
+  if (SamplesPerChannel(src) == SamplesPerChannel(dst)) {
+    CopySamples(dst, src);
+    return static_cast<int>(src.size());
+  }
+
+  return resamplers_[0]->Resample(src, dst);
+}
+
 // Explictly generate required instantiations.
 template class PushResampler<int16_t>;
 template class PushResampler<float>;
diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn
index 9764917..2f32a4a 100644
--- a/modules/audio_processing/BUILD.gn
+++ b/modules/audio_processing/BUILD.gn
@@ -269,7 +269,7 @@
 
 rtc_source_set("audio_frame_view") {
   sources = [ "include/audio_frame_view.h" ]
-  deps = [ "../../api:array_view" ]
+  deps = [ "../../api/audio:audio_frame_api" ]
 }
 
 if (rtc_enable_protobuf) {
diff --git a/modules/audio_processing/agc2/vad_wrapper.cc b/modules/audio_processing/agc2/vad_wrapper.cc
index 331fd36..d4fa32a 100644
--- a/modules/audio_processing/agc2/vad_wrapper.cc
+++ b/modules/audio_processing/agc2/vad_wrapper.cc
@@ -102,18 +102,11 @@
     vad_->Reset();
     time_to_vad_reset_ = vad_reset_period_frames_;
   }
+
   // Resample the first channel of `frame`.
   RTC_DCHECK_EQ(frame.samples_per_channel(), frame_size_);
-
-  // TODO: b/335805780 - channel() should return a MonoView<> which there
-  // should be a Resample() implementation for. There's no need to
-  // "deinterleave" a mono buffer, which is what Resample() currently does,
-  // so here we should be able to directly resample the channel buffer.
-  auto channel = frame.channel(0);
-  InterleavedView<const float> src(channel.data(), channel.size(), 1);
-  InterleavedView<float> dst(resampled_buffer_.data(), resampled_buffer_.size(),
-                             1);
-  resampler_.Resample(src, dst);
+  MonoView<float> dst(resampled_buffer_.data(), resampled_buffer_.size());
+  resampler_.Resample(frame.channel(0), dst);
 
   return vad_->Analyze(resampled_buffer_);
 }
diff --git a/modules/audio_processing/include/audio_frame_view.h b/modules/audio_processing/include/audio_frame_view.h
index 164784a..1c717e9 100644
--- a/modules/audio_processing/include/audio_frame_view.h
+++ b/modules/audio_processing/include/audio_frame_view.h
@@ -11,7 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_INCLUDE_AUDIO_FRAME_VIEW_H_
 #define MODULES_AUDIO_PROCESSING_INCLUDE_AUDIO_FRAME_VIEW_H_
 
-#include "api/array_view.h"
+#include "api/audio/audio_view.h"
 
 namespace webrtc {
 
@@ -44,16 +44,16 @@
 
   int samples_per_channel() const { return channel_size_; }
 
-  rtc::ArrayView<T> channel(int idx) {
+  MonoView<T> channel(int idx) {
     RTC_DCHECK_LE(0, idx);
     RTC_DCHECK_LE(idx, num_channels_);
-    return rtc::ArrayView<T>(audio_samples_[idx], channel_size_);
+    return MonoView<T>(audio_samples_[idx], channel_size_);
   }
 
-  rtc::ArrayView<const T> channel(int idx) const {
+  MonoView<const T> channel(int idx) const {
     RTC_DCHECK_LE(0, idx);
     RTC_DCHECK_LE(idx, num_channels_);
-    return rtc::ArrayView<const T>(audio_samples_[idx], channel_size_);
+    return MonoView<const T>(audio_samples_[idx], channel_size_);
   }
 
   T* const* data() { return audio_samples_; }