diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn index 7959fdbd0d..8cabb1d71a 100644 --- a/modules/audio_processing/BUILD.gn +++ b/modules/audio_processing/BUILD.gn @@ -56,6 +56,7 @@ rtc_library("audio_buffer") { deps = [ "../../api:array_view", + "../../api/audio:audio_frame_api", "../../api/audio:audio_processing", "../../common_audio", "../../common_audio:common_audio_c", @@ -364,6 +365,7 @@ if (rtc_include_tests) { "../../api:scoped_refptr", "../../api/audio:aec3_config", "../../api/audio:aec3_factory", + "../../api/audio:audio_frame_api", "../../api/audio:audio_processing", "../../api/audio:echo_detector_creator", "../../common_audio", diff --git a/modules/audio_processing/audio_buffer.h b/modules/audio_processing/audio_buffer.h index 3fdc06419f..9369572af8 100644 --- a/modules/audio_processing/audio_buffer.h +++ b/modules/audio_processing/audio_buffer.h @@ -18,6 +18,7 @@ #include #include "api/audio/audio_processing.h" +#include "api/audio/audio_view.h" #include "common_audio/channel_buffer.h" #include "common_audio/include/audio_util.h" @@ -58,6 +59,13 @@ class AudioBuffer { // reset at each call to CopyFrom or InterleaveFrom. void set_num_channels(size_t num_channels); + // Returns a DeinterleavedView<> over the channel data. + DeinterleavedView view() { + return DeinterleavedView( + num_channels_ && buffer_num_frames_ ? channels()[0] : nullptr, + buffer_num_frames_, num_channels_); + } + size_t num_channels() const { return num_channels_; } size_t num_frames() const { return buffer_num_frames_; } size_t num_frames_per_band() const { return num_split_frames_; } diff --git a/modules/audio_processing/audio_buffer_unittest.cc b/modules/audio_processing/audio_buffer_unittest.cc index f3b2ddc689..ef3479e4f5 100644 --- a/modules/audio_processing/audio_buffer_unittest.cc +++ b/modules/audio_processing/audio_buffer_unittest.cc @@ -12,6 +12,7 @@ #include +#include "api/audio/audio_view.h" #include "test/gtest.h" #include "test/testsupport/rtc_expect_death.h" @@ -90,4 +91,28 @@ TEST(AudioBufferTest, CopyWithResampling) { // Verify that energies match. EXPECT_NEAR(energy_ab1, energy_ab2 * 32000.f / 48000.f, .01f * energy_ab1); } + +TEST(AudioBufferTest, DeinterleavedView) { + AudioBuffer ab(48000, 2, 48000, 2, 48000, 2); + // Fill the buffer with data. + const float pi = std::acos(-1.f); + float* const* channels = ab.channels(); + for (size_t ch = 0; ch < ab.num_channels(); ++ch) { + for (size_t i = 0; i < ab.num_frames(); ++i) { + channels[ch][i] = std::sin(2 * pi * 100.f / 32000.f * i); + } + } + + // Verify that the DeinterleavedView correctly maps to channels. + DeinterleavedView view = ab.view(); + ASSERT_EQ(view.num_channels(), ab.num_channels()); + for (size_t c = 0; c < view.num_channels(); ++c) { + MonoView channel = view[c]; + EXPECT_EQ(SamplesPerChannel(channel), ab.num_frames()); + for (size_t s = 0; s < SamplesPerChannel(channel); ++s) { + ASSERT_EQ(channel[s], channels[c][s]); + } + } +} + } // namespace webrtc diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc index 2d0b327843..f0625c5dc2 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -1474,9 +1474,7 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() { absl::optional voice_probability; if (!!submodules_.voice_activity_detector) { voice_probability = submodules_.voice_activity_detector->Analyze( - AudioFrameView(capture_buffer->channels(), - capture_buffer->num_channels(), - capture_buffer->num_frames())); + AudioFrameView(capture_buffer->view())); } if (submodules_.transient_suppressor) {