Update AudioFrameOperations to require ArrayView
Bug: chromium:335805780
Change-Id: I14d97315f4cffa21bcc11b063e86c5adcebe78ae
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/348800
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Reviewed-by: Per Ã…hgren <peah@webrtc.org>
Reviewed-by: Olga Sharonova <olka@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42204}
diff --git a/api/audio/audio_frame.cc b/api/audio/audio_frame.cc
index 375e1b5..ce89323 100644
--- a/api/audio/audio_frame.cc
+++ b/api/audio/audio_frame.cc
@@ -91,6 +91,16 @@
if (this == &src)
return;
+ if (muted_ && !src.muted()) {
+ // TODO: bugs.webrtc.org/5647 - Since the default value for `muted_` is
+ // false and `data_` may still be uninitialized (because we don't initialize
+ // data_ as part of construction), we clear the full buffer here before
+ // copying over new values. If we don't, msan might complain in some tests.
+ // Consider locking down construction, avoiding the default constructor and
+ // prefering construction that initializes all state.
+ memset(data_, 0, kMaxDataSizeBytes);
+ }
+
timestamp_ = src.timestamp_;
elapsed_time_ms_ = src.elapsed_time_ms_;
ntp_time_ms_ = src.ntp_time_ms_;
@@ -104,11 +114,10 @@
channel_layout_ = src.channel_layout_;
absolute_capture_timestamp_ms_ = src.absolute_capture_timestamp_ms();
- const size_t length = samples_per_channel_ * num_channels_;
- RTC_CHECK_LE(length, kMaxDataSizeSamples);
- if (!src.muted()) {
- memcpy(data_, src.data(), sizeof(int16_t) * length);
- muted_ = false;
+ auto data = src.data_view();
+ RTC_CHECK_LE(data.size(), kMaxDataSizeSamples);
+ if (!muted_ && !data.empty()) {
+ memcpy(&data_[0], &data[0], sizeof(int16_t) * data.size());
}
}
@@ -158,10 +167,12 @@
RTC_CHECK_LE(total_samples, kMaxDataSizeSamples);
RTC_CHECK_LE(num_channels, kMaxConcurrentChannels);
// Sanity check for valid argument values during development.
- // If `samples_per_channel` is <= kMaxConcurrentChannels but larger than 0,
+ // If `samples_per_channel` is < `num_channels` but larger than 0,
// then chances are the order of arguments is incorrect.
RTC_DCHECK((samples_per_channel == 0 && num_channels == 0) ||
- samples_per_channel > kMaxConcurrentChannels);
+ num_channels <= samples_per_channel)
+ << "samples_per_channel=" << samples_per_channel
+ << "num_channels=" << num_channels;
// TODO: bugs.webrtc.org/5647 - Can we skip zeroing the buffer?
// Consider instead if we should rather zero the whole buffer when `muted_` is
diff --git a/audio/remix_resample.cc b/audio/remix_resample.cc
index a0cf7cc..06752c2 100644
--- a/audio/remix_resample.cc
+++ b/audio/remix_resample.cc
@@ -31,6 +31,7 @@
dst_frame->packet_infos_ = src_frame.packet_infos_;
}
+// TODO: b/335805780 - Accept ArrayView.
void RemixAndResample(const int16_t* src_data,
size_t samples_per_channel,
size_t num_channels,
@@ -49,8 +50,11 @@
<< "dst_frame->num_channels_: " << dst_frame->num_channels_;
AudioFrameOperations::DownmixChannels(
- src_data, num_channels, samples_per_channel, dst_frame->num_channels_,
- downmixed_audio);
+ rtc::ArrayView<const int16_t>(src_data,
+ num_channels * samples_per_channel),
+ num_channels, samples_per_channel, dst_frame->num_channels_,
+ rtc::ArrayView<int16_t>(&downmixed_audio[0], dst_frame->num_channels_ *
+ samples_per_channel));
audio_ptr = downmixed_audio;
audio_ptr_num_channels = dst_frame->num_channels_;
}
diff --git a/audio/utility/BUILD.gn b/audio/utility/BUILD.gn
index 983b628..c84302a 100644
--- a/audio/utility/BUILD.gn
+++ b/audio/utility/BUILD.gn
@@ -23,6 +23,7 @@
]
deps = [
+ "../../api:array_view",
"../../api/audio:audio_frame_api",
"../../common_audio",
"../../rtc_base:checks",
diff --git a/audio/utility/audio_frame_operations.cc b/audio/utility/audio_frame_operations.cc
index 47f7b71..23cc645 100644
--- a/audio/utility/audio_frame_operations.cc
+++ b/audio/utility/audio_frame_operations.cc
@@ -56,14 +56,13 @@
result_frame->speech_type_ = AudioFrame::kUndefined;
if (!frame_to_add.muted()) {
- const int16_t* in_data = frame_to_add.data();
- int16_t* out_data = result_frame->mutable_data();
- size_t length =
- frame_to_add.samples_per_channel_ * frame_to_add.num_channels_;
+ auto in_data = frame_to_add.data_view();
+ auto out_data = result_frame->mutable_data(
+ frame_to_add.samples_per_channel_, frame_to_add.num_channels_);
if (no_previous_data) {
- std::copy(in_data, in_data + length, out_data);
+ std::copy(in_data.begin(), in_data.end(), out_data.data());
} else {
- for (size_t i = 0; i < length; i++) {
+ for (size_t i = 0; i < in_data.size(); ++i) {
const int32_t wrap_guard = static_cast<int32_t>(out_data[i]) +
static_cast<int32_t>(in_data[i]);
out_data[i] = rtc::saturated_cast<int16_t>(wrap_guard);
@@ -72,9 +71,11 @@
}
}
-void AudioFrameOperations::QuadToStereo(const int16_t* src_audio,
+void AudioFrameOperations::QuadToStereo(rtc::ArrayView<const int16_t> src_audio,
size_t samples_per_channel,
- int16_t* dst_audio) {
+ rtc::ArrayView<int16_t> dst_audio) {
+ RTC_DCHECK_EQ(src_audio.size(), samples_per_channel * 4);
+ RTC_DCHECK_EQ(dst_audio.size(), samples_per_channel * 2);
for (size_t i = 0; i < samples_per_channel; i++) {
dst_audio[i * 2] =
(static_cast<int32_t>(src_audio[4 * i]) + src_audio[4 * i + 1]) >> 1;
@@ -93,30 +94,33 @@
AudioFrame::kMaxDataSizeSamples);
if (!frame->muted()) {
- QuadToStereo(frame->data(), frame->samples_per_channel_,
- frame->mutable_data());
+ auto current_data = frame->data_view();
+ QuadToStereo(current_data, frame->samples_per_channel_,
+ frame->mutable_data(frame->samples_per_channel_, 2));
+ } else {
+ frame->num_channels_ = 2;
}
- frame->num_channels_ = 2;
return 0;
}
-void AudioFrameOperations::DownmixChannels(const int16_t* src_audio,
- size_t src_channels,
- size_t samples_per_channel,
- size_t dst_channels,
- int16_t* dst_audio) {
+void AudioFrameOperations::DownmixChannels(
+ rtc::ArrayView<const int16_t> src_audio,
+ size_t src_channels,
+ size_t samples_per_channel,
+ size_t dst_channels,
+ rtc::ArrayView<int16_t> dst_audio) {
+ RTC_DCHECK_EQ(src_audio.size(), src_channels * samples_per_channel);
+ RTC_DCHECK_EQ(dst_audio.size(), dst_channels * samples_per_channel);
if (src_channels > 1 && dst_channels == 1) {
- DownmixInterleavedToMono(src_audio, samples_per_channel, src_channels,
- dst_audio);
- return;
+ DownmixInterleavedToMono(src_audio.data(), samples_per_channel,
+ src_channels, &dst_audio[0]);
} else if (src_channels == 4 && dst_channels == 2) {
QuadToStereo(src_audio, samples_per_channel, dst_audio);
- return;
+ } else {
+ RTC_DCHECK_NOTREACHED() << "src_channels: " << src_channels
+ << ", dst_channels: " << dst_channels;
}
-
- RTC_DCHECK_NOTREACHED() << "src_channels: " << src_channels
- << ", dst_channels: " << dst_channels;
}
void AudioFrameOperations::DownmixChannels(size_t dst_channels,
@@ -153,14 +157,16 @@
if (!frame->muted()) {
// Up-mixing done in place. Going backwards through the frame ensure nothing
// is irrevocably overwritten.
- int16_t* frame_data = frame->mutable_data();
- for (int i = frame->samples_per_channel_ - 1; i >= 0; i--) {
+ auto frame_data = frame->mutable_data(frame->samples_per_channel_,
+ target_number_of_channels);
+ for (int i = frame->samples_per_channel_ - 1; i >= 0; --i) {
for (size_t j = 0; j < target_number_of_channels; ++j) {
frame_data[target_number_of_channels * i + j] = frame_data[i];
}
}
+ } else {
+ frame->num_channels_ = target_number_of_channels;
}
- frame->num_channels_ = target_number_of_channels;
}
void AudioFrameOperations::SwapStereoChannels(AudioFrame* frame) {
diff --git a/audio/utility/audio_frame_operations.h b/audio/utility/audio_frame_operations.h
index 26a2d5e..7b076e1 100644
--- a/audio/utility/audio_frame_operations.h
+++ b/audio/utility/audio_frame_operations.h
@@ -15,6 +15,7 @@
#include <stdint.h>
#include "absl/base/attributes.h"
+#include "api/array_view.h"
#include "api/audio/audio_frame.h"
namespace webrtc {
@@ -36,9 +37,9 @@
// Downmixes 4 channels `src_audio` to stereo `dst_audio`. This is an in-place
// operation, meaning `src_audio` and `dst_audio` may point to the same
// buffer.
- static void QuadToStereo(const int16_t* src_audio,
+ static void QuadToStereo(rtc::ArrayView<const int16_t> src_audio,
size_t samples_per_channel,
- int16_t* dst_audio);
+ rtc::ArrayView<int16_t> dst_audio);
// `frame.num_channels_` will be updated. This version checks that
// `num_channels_` is 4 channels.
@@ -48,11 +49,11 @@
// This is an in-place operation, meaning `src_audio` and `dst_audio`
// may point to the same buffer. Supported channel combinations are
// Stereo to Mono, Quad to Mono, and Quad to Stereo.
- static void DownmixChannels(const int16_t* src_audio,
+ static void DownmixChannels(rtc::ArrayView<const int16_t> src_audio,
size_t src_channels,
size_t samples_per_channel,
size_t dst_channels,
- int16_t* dst_audio);
+ rtc::ArrayView<int16_t> dst_audio);
// `frame.num_channels_` will be updated. This version checks that
// `num_channels_` and `dst_channels` are valid and performs relevant downmix.
diff --git a/audio/utility/audio_frame_operations_unittest.cc b/audio/utility/audio_frame_operations_unittest.cc
index 1a2c16e..a1f8db3 100644
--- a/audio/utility/audio_frame_operations_unittest.cc
+++ b/audio/utility/audio_frame_operations_unittest.cc
@@ -18,13 +18,10 @@
class AudioFrameOperationsTest : public ::testing::Test {
protected:
- AudioFrameOperationsTest() {
- // Set typical values.
- frame_.samples_per_channel_ = 320;
- frame_.num_channels_ = 2;
- }
+ AudioFrameOperationsTest() = default;
- AudioFrame frame_;
+ // Set typical values.
+ AudioFrame frame_{/*sample_rate=*/32000, /*num_channels*/ 2};
};
class AudioFrameOperationsDeathTest : public AudioFrameOperationsTest {};
@@ -34,7 +31,8 @@
int16_t ch3,
int16_t ch4,
AudioFrame* frame) {
- int16_t* frame_data = frame->mutable_data();
+ rtc::ArrayView<int16_t> frame_data =
+ frame->mutable_data(frame->samples_per_channel_, 4);
for (size_t i = 0; i < frame->samples_per_channel_ * 4; i += 4) {
frame_data[i] = ch1;
frame_data[i + 1] = ch2;
@@ -44,7 +42,8 @@
}
void SetFrameData(int16_t left, int16_t right, AudioFrame* frame) {
- int16_t* frame_data = frame->mutable_data();
+ rtc::ArrayView<int16_t> frame_data =
+ frame->mutable_data(frame->samples_per_channel_, 2);
for (size_t i = 0; i < frame->samples_per_channel_ * 2; i += 2) {
frame_data[i] = left;
frame_data[i + 1] = right;
@@ -52,7 +51,8 @@
}
void SetFrameData(int16_t data, AudioFrame* frame) {
- int16_t* frame_data = frame->mutable_data();
+ rtc::ArrayView<int16_t> frame_data =
+ frame->mutable_data(frame->samples_per_channel_, 1);
for (size_t i = 0; i < frame->samples_per_channel_ * frame->num_channels_;
i++) {
frame_data[i] = data;
@@ -60,15 +60,18 @@
}
void VerifyFramesAreEqual(const AudioFrame& frame1, const AudioFrame& frame2) {
- EXPECT_EQ(frame1.num_channels_, frame2.num_channels_);
- EXPECT_EQ(frame1.samples_per_channel_, frame2.samples_per_channel_);
+ ASSERT_EQ(frame1.num_channels_, frame2.num_channels_);
+ ASSERT_EQ(frame1.samples_per_channel_, frame2.samples_per_channel_);
+ EXPECT_EQ(frame1.muted(), frame2.muted());
const int16_t* frame1_data = frame1.data();
const int16_t* frame2_data = frame2.data();
+ // TODO(tommi): Use sample_count() or data_view().
for (size_t i = 0; i < frame1.samples_per_channel_ * frame1.num_channels_;
i++) {
EXPECT_EQ(frame1_data[i], frame2_data[i]);
+ if (frame1_data[i] != frame2_data[i])
+ break; // To avoid spamming the log.
}
- EXPECT_EQ(frame1.muted(), frame2.muted());
}
void InitFrame(AudioFrame* frame,
@@ -76,17 +79,16 @@
size_t samples_per_channel,
int16_t left_data,
int16_t right_data) {
- RTC_DCHECK(frame);
RTC_DCHECK_GE(2, channels);
RTC_DCHECK_GE(AudioFrame::kMaxDataSizeSamples,
samples_per_channel * channels);
frame->samples_per_channel_ = samples_per_channel;
- frame->num_channels_ = channels;
if (channels == 2) {
SetFrameData(left_data, right_data, frame);
} else if (channels == 1) {
SetFrameData(left_data, frame);
}
+ ASSERT_EQ(frame->num_channels_, channels);
}
int16_t GetChannelData(const AudioFrame& frame, size_t channel, size_t index) {
@@ -116,7 +118,6 @@
#endif
TEST_F(AudioFrameOperationsTest, MonoToStereoSucceeds) {
- frame_.num_channels_ = 1;
SetFrameData(1, &frame_);
AudioFrameOperations::UpmixChannels(2, &frame_);
@@ -124,7 +125,6 @@
AudioFrame stereo_frame;
stereo_frame.samples_per_channel_ = 320;
- stereo_frame.num_channels_ = 2;
SetFrameData(1, 1, &stereo_frame);
VerifyFramesAreEqual(stereo_frame, frame_);
}
@@ -151,7 +151,6 @@
AudioFrame mono_frame;
mono_frame.samples_per_channel_ = 320;
- mono_frame.num_channels_ = 1;
SetFrameData(3, &mono_frame);
VerifyFramesAreEqual(mono_frame, frame_);
}
@@ -167,16 +166,12 @@
AudioFrame target_frame;
SetFrameData(4, 2, &frame_);
- target_frame.num_channels_ = 1;
- target_frame.samples_per_channel_ = frame_.samples_per_channel_;
-
- AudioFrameOperations::DownmixChannels(frame_.data(), 2,
- frame_.samples_per_channel_, 1,
- target_frame.mutable_data());
+ AudioFrameOperations::DownmixChannels(
+ frame_.data_view(), 2, frame_.samples_per_channel_, 1,
+ target_frame.mutable_data(frame_.samples_per_channel_, 1));
AudioFrame mono_frame;
mono_frame.samples_per_channel_ = 320;
- mono_frame.num_channels_ = 1;
SetFrameData(3, &mono_frame);
VerifyFramesAreEqual(mono_frame, target_frame);
}
@@ -187,13 +182,11 @@
EXPECT_EQ(1u, frame_.num_channels_);
AudioFrame mono_frame;
mono_frame.samples_per_channel_ = 320;
- mono_frame.num_channels_ = 1;
SetFrameData(-32768, &mono_frame);
VerifyFramesAreEqual(mono_frame, frame_);
}
TEST_F(AudioFrameOperationsTest, QuadToMonoSucceeds) {
- frame_.num_channels_ = 4;
SetFrameData(4, 2, 6, 8, &frame_);
AudioFrameOperations::DownmixChannels(1, &frame_);
@@ -201,7 +194,6 @@
AudioFrame mono_frame;
mono_frame.samples_per_channel_ = 320;
- mono_frame.num_channels_ = 1;
SetFrameData(5, &mono_frame);
VerifyFramesAreEqual(mono_frame, frame_);
}
@@ -216,31 +208,24 @@
TEST_F(AudioFrameOperationsTest, QuadToMonoBufferSucceeds) {
AudioFrame target_frame;
- frame_.num_channels_ = 4;
SetFrameData(4, 2, 6, 8, &frame_);
- target_frame.num_channels_ = 1;
- target_frame.samples_per_channel_ = frame_.samples_per_channel_;
-
- AudioFrameOperations::DownmixChannels(frame_.data(), 4,
- frame_.samples_per_channel_, 1,
- target_frame.mutable_data());
+ AudioFrameOperations::DownmixChannels(
+ frame_.data_view(), 4, frame_.samples_per_channel_, 1,
+ target_frame.mutable_data(frame_.samples_per_channel_, 1));
AudioFrame mono_frame;
mono_frame.samples_per_channel_ = 320;
- mono_frame.num_channels_ = 1;
SetFrameData(5, &mono_frame);
VerifyFramesAreEqual(mono_frame, target_frame);
}
TEST_F(AudioFrameOperationsTest, QuadToMonoDoesNotWrapAround) {
- frame_.num_channels_ = 4;
SetFrameData(-32768, -32768, -32768, -32768, &frame_);
AudioFrameOperations::DownmixChannels(1, &frame_);
EXPECT_EQ(1u, frame_.num_channels_);
AudioFrame mono_frame;
mono_frame.samples_per_channel_ = 320;
- mono_frame.num_channels_ = 1;
SetFrameData(-32768, &mono_frame);
VerifyFramesAreEqual(mono_frame, frame_);
}
@@ -253,13 +238,11 @@
}
TEST_F(AudioFrameOperationsTest, QuadToStereoSucceeds) {
- frame_.num_channels_ = 4;
SetFrameData(4, 2, 6, 8, &frame_);
EXPECT_EQ(0, AudioFrameOperations::QuadToStereo(&frame_));
AudioFrame stereo_frame;
stereo_frame.samples_per_channel_ = 320;
- stereo_frame.num_channels_ = 2;
SetFrameData(3, 7, &stereo_frame);
VerifyFramesAreEqual(stereo_frame, frame_);
}
@@ -273,29 +256,23 @@
TEST_F(AudioFrameOperationsTest, QuadToStereoBufferSucceeds) {
AudioFrame target_frame;
- frame_.num_channels_ = 4;
SetFrameData(4, 2, 6, 8, &frame_);
- target_frame.num_channels_ = 2;
- target_frame.samples_per_channel_ = frame_.samples_per_channel_;
-
- AudioFrameOperations::QuadToStereo(frame_.data(), frame_.samples_per_channel_,
- target_frame.mutable_data());
+ AudioFrameOperations::QuadToStereo(
+ frame_.data_view(), frame_.samples_per_channel_,
+ target_frame.mutable_data(frame_.samples_per_channel_, 2));
AudioFrame stereo_frame;
stereo_frame.samples_per_channel_ = 320;
- stereo_frame.num_channels_ = 2;
SetFrameData(3, 7, &stereo_frame);
VerifyFramesAreEqual(stereo_frame, target_frame);
}
TEST_F(AudioFrameOperationsTest, QuadToStereoDoesNotWrapAround) {
- frame_.num_channels_ = 4;
SetFrameData(-32768, -32768, -32768, -32768, &frame_);
EXPECT_EQ(0, AudioFrameOperations::QuadToStereo(&frame_));
AudioFrame stereo_frame;
stereo_frame.samples_per_channel_ = 320;
- stereo_frame.num_channels_ = 2;
SetFrameData(-32768, -32768, &stereo_frame);
VerifyFramesAreEqual(stereo_frame, frame_);
}
@@ -305,7 +282,6 @@
AudioFrame swapped_frame;
swapped_frame.samples_per_channel_ = 320;
- swapped_frame.num_channels_ = 2;
SetFrameData(1, 0, &swapped_frame);
AudioFrameOperations::SwapStereoChannels(&frame_);
@@ -319,9 +295,9 @@
}
TEST_F(AudioFrameOperationsTest, SwapStereoChannelsFailsOnMono) {
- frame_.num_channels_ = 1;
// Set data to "stereo", despite it being a mono frame.
SetFrameData(0, 1, &frame_);
+ frame_.num_channels_ = 1; // Reset to mono after SetFrameData().
AudioFrame orig_frame;
orig_frame.CopyFrom(frame_);
@@ -336,7 +312,6 @@
AudioFrame muted_frame;
muted_frame.samples_per_channel_ = 320;
- muted_frame.num_channels_ = 2;
SetFrameData(1000, -1000, &muted_frame);
VerifyFramesAreEqual(muted_frame, frame_);
}
@@ -506,7 +481,6 @@
AudioFrame clipped_frame;
clipped_frame.samples_per_channel_ = 320;
- clipped_frame.num_channels_ = 2;
SetFrameData(32767, -32768, &clipped_frame);
VerifyFramesAreEqual(clipped_frame, frame_);
}
@@ -517,7 +491,6 @@
AudioFrame scaled_frame;
scaled_frame.samples_per_channel_ = 320;
- scaled_frame.num_channels_ = 2;
SetFrameData(2, -3, &scaled_frame);
VerifyFramesAreEqual(scaled_frame, frame_);
}
@@ -534,13 +507,11 @@
}
TEST_F(AudioFrameOperationsTest, ScaleWithSatDoesNotWrapAround) {
- frame_.num_channels_ = 1;
SetFrameData(4000, &frame_);
EXPECT_EQ(0, AudioFrameOperations::ScaleWithSat(10.0, &frame_));
AudioFrame clipped_frame;
clipped_frame.samples_per_channel_ = 320;
- clipped_frame.num_channels_ = 1;
SetFrameData(32767, &clipped_frame);
VerifyFramesAreEqual(clipped_frame, frame_);
@@ -551,13 +522,11 @@
}
TEST_F(AudioFrameOperationsTest, ScaleWithSatSucceeds) {
- frame_.num_channels_ = 1;
SetFrameData(1, &frame_);
EXPECT_EQ(0, AudioFrameOperations::ScaleWithSat(2.0, &frame_));
AudioFrame scaled_frame;
scaled_frame.samples_per_channel_ = 320;
- scaled_frame.num_channels_ = 1;
SetFrameData(2, &scaled_frame);
VerifyFramesAreEqual(scaled_frame, frame_);
}
@@ -573,10 +542,11 @@
AudioFrame frame_to_add_to;
frame_to_add_to.mutable_data(); // Unmute the frame.
ASSERT_FALSE(frame_to_add_to.muted());
+
+ SetFrameData(1000, &frame_);
frame_to_add_to.samples_per_channel_ = 0;
frame_to_add_to.num_channels_ = frame_.num_channels_;
- SetFrameData(1000, &frame_);
AudioFrameOperations::Add(frame_, &frame_to_add_to);
VerifyFramesAreEqual(frame_, frame_to_add_to);
}
@@ -584,19 +554,27 @@
TEST_F(AudioFrameOperationsTest, AddingXToMutedGivesX) {
AudioFrame frame_to_add_to;
ASSERT_TRUE(frame_to_add_to.muted());
+
frame_to_add_to.samples_per_channel_ = frame_.samples_per_channel_;
+ SetFrameData(1000, &frame_);
frame_to_add_to.num_channels_ = frame_.num_channels_;
- SetFrameData(1000, &frame_);
AudioFrameOperations::Add(frame_, &frame_to_add_to);
VerifyFramesAreEqual(frame_, frame_to_add_to);
}
TEST_F(AudioFrameOperationsTest, AddingMutedToXGivesX) {
AudioFrame frame_to_add_to;
+
+ // Clear the internal buffer to avoid msan issues since we're changing
+ // buffer dimension member variables outside of the class without updating
+ // the buffer.
+ RTC_DCHECK(frame_to_add_to.muted());
+ frame_to_add_to.mutable_data();
+
frame_to_add_to.samples_per_channel_ = frame_.samples_per_channel_;
+ SetFrameData(1000, &frame_to_add_to); // sets frame to mono.
frame_to_add_to.num_channels_ = frame_.num_channels_;
- SetFrameData(1000, &frame_to_add_to);
AudioFrame frame_copy;
frame_copy.CopyFrom(frame_to_add_to);
@@ -609,7 +587,6 @@
TEST_F(AudioFrameOperationsTest, AddingTwoFramesProducesTheirSum) {
AudioFrame frame_to_add_to;
frame_to_add_to.samples_per_channel_ = frame_.samples_per_channel_;
- frame_to_add_to.num_channels_ = frame_.num_channels_;
SetFrameData(1000, &frame_to_add_to);
SetFrameData(2000, &frame_);
diff --git a/common_audio/include/audio_util.h b/common_audio/include/audio_util.h
index 4ce4680..4cbea67 100644
--- a/common_audio/include/audio_util.h
+++ b/common_audio/include/audio_util.h
@@ -94,6 +94,7 @@
// Copy audio from `src` channels to `dest` channels unless `src` and `dest`
// point to the same address. `src` and `dest` must have the same number of
// channels, and there must be sufficient space allocated in `dest`.
+// TODO: b/335805780 - Accept ArrayView.
template <typename T>
void CopyAudioIfNeeded(const T* const* src,
int num_frames,
@@ -110,6 +111,7 @@
// by `deinterleaved`. There must be sufficient space allocated in the
// `deinterleaved` buffers (`num_channel` buffers with `samples_per_channel`
// per buffer).
+// TODO: b/335805780 - Accept ArrayView.
template <typename T>
void Deinterleave(const T* interleaved,
size_t samples_per_channel,
@@ -128,6 +130,7 @@
// Interleave audio from the channel buffers pointed to by `deinterleaved` to
// `interleaved`. There must be sufficient space allocated in `interleaved`
// (`samples_per_channel` * `num_channels`).
+// TODO: b/335805780 - Accept ArrayView.
template <typename T>
void Interleave(const T* const* deinterleaved,
size_t samples_per_channel,
@@ -146,6 +149,7 @@
// Copies audio from a single channel buffer pointed to by `mono` to each
// channel of `interleaved`. There must be sufficient space allocated in
// `interleaved` (`samples_per_channel` * `num_channels`).
+// TODO: b/335805780 - Accept ArrayView.
template <typename T>
void UpmixMonoToInterleaved(const T* mono,
int num_frames,
@@ -159,6 +163,7 @@
}
}
+// TODO: b/335805780 - Accept ArrayView.
template <typename T, typename Intermediate>
void DownmixToMono(const T* const* input_channels,
size_t num_frames,
@@ -175,6 +180,7 @@
// Downmixes an interleaved multichannel signal to a single channel by averaging
// all channels.
+// TODO: b/335805780 - Accept ArrayView.
template <typename T, typename Intermediate>
void DownmixInterleavedToMonoImpl(const T* interleaved,
size_t num_frames,
@@ -197,12 +203,14 @@
}
}
+// TODO: b/335805780 - Accept ArrayView.
template <typename T>
void DownmixInterleavedToMono(const T* interleaved,
size_t num_frames,
int num_channels,
T* deinterleaved);
+// TODO: b/335805780 - Accept ArrayView.
template <>
void DownmixInterleavedToMono<int16_t>(const int16_t* interleaved,
size_t num_frames,