0

[CodeHealth] Remove AudioBus::channel() usage (part 1)

This CL removes some uses of AudioBus::channel(), in favor of the safer
AudioBus::channel_span().

Bug: 373960632
Change-Id: Icbec30d12c65117369e215774271281f2ada7294
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6116936
Auto-Submit: Thomas Guilbert <tguilbert@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1401866}
This commit is contained in:
Thomas Guilbert
2025-01-03 09:51:31 -08:00
committed by Chromium LUCI CQ
parent 40ce1454d1
commit 9583255961
3 changed files with 150 additions and 123 deletions

@ -349,11 +349,9 @@ void AudioBus::CopyAndClipTo(AudioBus* dest) const {
DCHECK(!is_bitstream_format_);
CHECK_EQ(channels(), dest->channels());
CHECK_LE(frames(), dest->frames());
for (int i = 0; i < channels(); ++i) {
float* dest_ptr = dest->channel(i);
const float* source_ptr = channel(i);
for (int j = 0; j < frames(); ++j)
dest_ptr[j] = Float32SampleTypeTraits::FromFloat(source_ptr[j]);
for (int ch = 0; ch < channels(); ++ch) {
std::ranges::transform(channel_span(ch), dest->channel_span(ch).begin(),
Float32SampleTypeTraits::FromFloat);
}
}
@ -363,23 +361,25 @@ void AudioBus::CopyPartialFramesTo(int source_start_frame,
AudioBus* dest) const {
DCHECK(!is_bitstream_format_);
CHECK_EQ(channels(), dest->channels());
CHECK_LE(source_start_frame + frame_count, frames());
CHECK_LE(dest_start_frame + frame_count, dest->frames());
const size_t source_offset = base::checked_cast<size_t>(source_start_frame);
const size_t dest_offset = base::checked_cast<size_t>(dest_start_frame);
const size_t count = base::checked_cast<size_t>(frame_count);
// Since we don't know if the other AudioBus is wrapped or not (and we don't
// want to care), just copy using the public channel() accessors.
for (int i = 0; i < channels(); ++i) {
memcpy(dest->channel(i) + dest_start_frame,
channel(i) + source_start_frame,
sizeof(*channel(i)) * frame_count);
ConstChannel src_span = channel_span(i).subspan(source_offset, count);
dest->channel_span(i).subspan(dest_offset, count).copy_from(src_span);
}
}
void AudioBus::Scale(float volume) {
DCHECK(!is_bitstream_format_);
if (volume > 0 && volume != 1) {
for (int i = 0; i < channels(); ++i)
vector_math::FMUL(channel(i), volume, frames(), channel(i));
for (auto channel : channel_data_) {
vector_math::FMUL(channel.data(), volume, frames(), channel.data());
}
} else if (volume == 0) {
Zero();
}

@ -355,7 +355,7 @@ void AudioBus::CopyConvertFromInterleavedSourceToAudioBus(
AudioBus* dest) {
const int channels = dest->channels();
for (int ch = 0; ch < channels; ++ch) {
float* channel_data = dest->channel(ch);
AudioBus::Channel channel_data = dest->channel_span(ch);
for (int target_frame_index = write_offset_in_frames,
read_pos_in_source = ch;
target_frame_index < write_offset_in_frames + num_frames_to_write;
@ -377,7 +377,7 @@ void AudioBus::CopyConvertFromAudioBusToInterleavedTarget(
typename TargetSampleTypeTraits::ValueType* dest_buffer) {
const int channels = source->channels();
for (int ch = 0; ch < channels; ++ch) {
const float* channel_data = source->channel(ch);
AudioBus::ConstChannel channel_data = source->channel_span(ch);
for (int source_frame_index = read_offset_in_frames, write_pos_in_dest = ch;
source_frame_index < read_offset_in_frames + num_frames_to_read;
++source_frame_index, write_pos_in_dest += channels) {

@ -29,10 +29,12 @@
namespace media {
using AlignedFloatArray = base::AlignedHeapArray<float>;
static const int kChannels = 6;
static constexpr ChannelLayout kChannelLayout = CHANNEL_LAYOUT_5_1;
// Use a buffer size which is intentionally not a multiple of kChannelAlignment.
static const int kFrameCount = media::AudioBus::kChannelAlignment * 32 - 1;
static const size_t kFrameCount = media::AudioBus::kChannelAlignment * 32 - 1;
static const int kSampleRate = 48000;
class AudioBusTest : public testing::Test {
@ -42,19 +44,17 @@ class AudioBusTest : public testing::Test {
AudioBusTest(const AudioBusTest&) = delete;
AudioBusTest& operator=(const AudioBusTest&) = delete;
~AudioBusTest() override {
for (size_t i = 0; i < data_.size(); ++i)
base::AlignedFree(data_[i]);
}
~AudioBusTest() override = default;
void VerifyChannelAndFrameCount(AudioBus* bus) {
EXPECT_EQ(kChannels, bus->channels());
EXPECT_EQ(kFrameCount, bus->frames());
EXPECT_EQ(static_cast<int>(kFrameCount), bus->frames());
}
void VerifyArrayIsFilledWithValue(const float data[], int size, float value) {
for (int i = 0; i < size; ++i)
void VerifySpanIsFilledWithValue(AudioBus::ConstChannel data, float value) {
for (size_t i = 0; i < data.size(); ++i) {
ASSERT_FLOAT_EQ(value, data[i]) << "i=" << i;
}
}
// Verify values for each channel in |result| are within |epsilon| of
@ -77,10 +77,11 @@ class AudioBusTest : public testing::Test {
SCOPED_TRACE(base::StringPrintf("ch=%d, i=%d", ch, i));
if (epsilon == 0) {
ASSERT_FLOAT_EQ(expected->channel(ch)[i], result->channel(ch)[i]);
ASSERT_FLOAT_EQ(expected->channel_span(ch)[i],
result->channel_span(ch)[i]);
} else {
ASSERT_NEAR(expected->channel(ch)[i], result->channel(ch)[i],
epsilon);
ASSERT_NEAR(expected->channel_span(ch)[i],
result->channel_span(ch)[i], epsilon);
}
}
}
@ -95,22 +96,23 @@ class AudioBusTest : public testing::Test {
// the Zero() method and verify it does as advertised. Also test data if data
// is 16-byte aligned as advertised (see kChannelAlignment in audio_bus.h).
void VerifyReadWriteAndAlignment(AudioBus* bus) {
for (int i = 0; i < bus->channels(); ++i) {
int channel_count = 0;
for (auto channel : bus->AllChannels()) {
// Verify that the address returned by channel(i) is a multiple of
// AudioBus::kChannelAlignment.
ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(
bus->channel(i)) & (AudioBus::kChannelAlignment - 1));
ASSERT_TRUE(AudioBus::IsAligned(channel));
// Write into the channel buffer.
std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i);
std::ranges::fill(channel, channel_count++);
}
for (int i = 0; i < bus->channels(); ++i)
VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), i);
for (int i = 0; i < bus->channels(); ++i) {
VerifySpanIsFilledWithValue(bus->channel_span(i), i);
}
bus->Zero();
for (int i = 0; i < bus->channels(); ++i)
VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), 0);
for (int i = 0; i < bus->channels(); ++i) {
VerifySpanIsFilledWithValue(bus->channel_span(i), 0);
}
}
// Verify copying to and from |bus1| and |bus2|.
@ -142,12 +144,22 @@ class AudioBusTest : public testing::Test {
void AllocateDataPerChannel() {
data_.reserve(kChannels);
for (int i = 0; i < kChannels; ++i) {
data_.push_back(static_cast<float*>(base::AlignedAlloc(
sizeof(*data_[i]) * kFrameCount, AudioBus::kChannelAlignment)));
data_.push_back(
base::AlignedUninit<float>(kFrameCount, AudioBus::kChannelAlignment));
}
}
std::vector<float*> data_;
// TODO(crbug.com/373960632): remove this when all ctors take spans.
std::vector<float*> GetRawPointers(std::vector<AlignedFloatArray>& data) {
std::vector<float*> result;
result.reserve(data_.size());
for (AlignedFloatArray& array : data) {
result.push_back(array.as_span().data());
}
return result;
}
std::vector<AlignedFloatArray> data_;
};
// Verify basic Create(...) method works as advertised.
@ -174,8 +186,7 @@ TEST_F(AudioBusTest, CreateWrapper) {
std::unique_ptr<AudioBus> bus = AudioBus::CreateWrapper(kChannels);
bus->set_frames(kFrameCount);
for (int i = 0; i < bus->channels(); ++i) {
bus->SetChannelData(i,
base::span(data_[i], static_cast<size_t>(kFrameCount)));
bus->SetChannelData(i, data_[i].as_span());
}
bool deleted = false;
@ -197,8 +208,8 @@ TEST_F(AudioBusTest, AllChannels) {
bus->set_frames(kFrameCount);
AudioBus::ChannelVector channels;
int value = 1;
for (float* data : data_) {
AudioBus::Channel channel(data, static_cast<size_t>(kFrameCount));
for (AlignedFloatArray& data : data_) {
AudioBus::Channel channel(data);
// Fill each channel with a different value.
std::ranges::fill(channel, value++);
@ -226,8 +237,8 @@ TEST_F(AudioBusTest, AllChannelsSubspan) {
bus->set_frames(kFrameCount);
AudioBus::ChannelVector channels;
int value = 1;
for (float* data : data_) {
AudioBus::Channel channel(data, static_cast<size_t>(kFrameCount));
for (AlignedFloatArray& data : data_) {
AudioBus::Channel channel(data);
// Fill each sample with a different value.
for (float& sample : channel) {
@ -254,13 +265,17 @@ TEST_F(AudioBusTest, AllChannelsSubspan) {
// Verify an AudioBus created via wrapping a vector works as advertised.
TEST_F(AudioBusTest, WrapVector) {
data_.reserve(kChannels);
for (int i = 0; i < kChannels; ++i) {
data_.push_back(static_cast<float*>(base::AlignedAlloc(
sizeof(*data_[i]) * kFrameCount, AudioBus::kChannelAlignment)));
AllocateDataPerChannel();
std::vector<float*> data_pointers;
data_pointers.reserve(kChannels);
for (AlignedFloatArray& data : data_) {
data_pointers.push_back(data.as_span().data());
}
std::unique_ptr<AudioBus> bus = AudioBus::WrapVector(kFrameCount, data_);
std::unique_ptr<AudioBus> bus =
AudioBus::WrapVector(kFrameCount, GetRawPointers(data_));
VerifyChannelAndFrameCount(bus.get());
VerifyReadWriteAndAlignment(bus.get());
}
@ -270,26 +285,29 @@ TEST_F(AudioBusTest, WrapMemory) {
AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
ChannelLayoutConfig::FromLayout<kChannelLayout>(),
kSampleRate, kFrameCount);
size_t data_size = AudioBus::CalculateMemorySize(params);
std::unique_ptr<float, base::AlignedFreeDeleter> data(static_cast<float*>(
base::AlignedAlloc(data_size, AudioBus::kChannelAlignment)));
size_t total_frame_count =
AudioBus::CalculateMemorySize(params) / sizeof(float);
AlignedFloatArray data = base::AlignedUninit<float>(total_frame_count);
// Fill the memory with a test value we can check for after wrapping.
static const float kTestValue = 3;
std::fill(data.get(), data.get() + data_size / sizeof(*data.get()),
kTestValue);
std::ranges::fill(data, kTestValue);
std::unique_ptr<AudioBus> bus = AudioBus::WrapMemory(params, data.get());
std::unique_ptr<AudioBus> bus =
AudioBus::WrapMemory(params, data.as_span().data());
// Verify the test value we filled prior to wrapping.
for (int i = 0; i < bus->channels(); ++i)
VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), kTestValue);
for (auto channel : bus->AllChannels()) {
VerifySpanIsFilledWithValue(channel, kTestValue);
}
VerifyChannelAndFrameCount(bus.get());
VerifyReadWriteAndAlignment(bus.get());
// Verify the channel vectors lie within the provided memory block.
EXPECT_GE(bus->channel(0), data.get());
EXPECT_LT(bus->channel(bus->channels() - 1) + bus->frames(),
data.get() + data_size / sizeof(*data.get()));
const float* backing_memory_start = data.as_span().data();
const float* backing_memory_end = backing_memory_start + total_frame_count;
EXPECT_GE(bus->channel_span(0).data(), backing_memory_start);
EXPECT_LT(bus->channel_span(bus->channels() - 1).data() + bus->frames(),
backing_memory_end);
}
// Simulate a shared memory transfer and verify results.
@ -311,7 +329,7 @@ TEST_F(AudioBusTest, CopyTo) {
// Try a copy to an AudioBus wrapping a vector.
AllocateDataPerChannel();
bus2 = AudioBus::WrapVector(kFrameCount, data_);
bus2 = AudioBus::WrapVector(kFrameCount, GetRawPointers(data_));
CopyTest(bus1.get(), bus2.get());
}
{
@ -331,50 +349,60 @@ TEST_F(AudioBusTest, Zero) {
std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount);
// Fill the bus with dummy data.
for (int i = 0; i < bus->channels(); ++i)
std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1);
int value = 1;
for (auto channel : bus->AllChannels()) {
std::ranges::fill(channel, value++);
}
EXPECT_FALSE(bus->AreFramesZero());
// Zero first half the frames of each channel.
bus->ZeroFrames(kFrameCount / 2);
for (int i = 0; i < bus->channels(); ++i) {
value = 1;
for (auto channel : bus->AllChannels()) {
SCOPED_TRACE("First Half Zero");
VerifyArrayIsFilledWithValue(bus->channel(i), kFrameCount / 2, 0);
VerifyArrayIsFilledWithValue(bus->channel(i) + kFrameCount / 2,
kFrameCount - kFrameCount / 2, i + 1);
auto [first_half, second_half] = channel.split_at(kFrameCount / 2);
VerifySpanIsFilledWithValue(first_half, 0);
VerifySpanIsFilledWithValue(second_half, value++);
}
EXPECT_FALSE(bus->AreFramesZero());
// Fill the bus with dummy data.
for (int i = 0; i < bus->channels(); ++i)
std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1);
value = 1;
for (auto channel : bus->AllChannels()) {
std::ranges::fill(channel, value++);
}
// Zero the last half of the frames.
bus->ZeroFramesPartial(kFrameCount / 2, kFrameCount - kFrameCount / 2);
for (int i = 0; i < bus->channels(); ++i) {
static constexpr size_t kRemainingFrames = kFrameCount - kFrameCount / 2;
bus->ZeroFramesPartial(kFrameCount / 2, kRemainingFrames);
value = 1;
for (auto channel : bus->AllChannels()) {
SCOPED_TRACE("Last Half Zero");
VerifyArrayIsFilledWithValue(bus->channel(i) + kFrameCount / 2,
kFrameCount - kFrameCount / 2, 0);
VerifyArrayIsFilledWithValue(bus->channel(i), kFrameCount / 2, i + 1);
auto [first_half, second_half] = channel.split_at(kFrameCount / 2);
VerifySpanIsFilledWithValue(first_half, value++);
VerifySpanIsFilledWithValue(second_half, 0);
}
EXPECT_FALSE(bus->AreFramesZero());
// Fill the bus with dummy data.
for (int i = 0; i < bus->channels(); ++i)
std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1);
value = 1;
for (auto channel : bus->AllChannels()) {
std::ranges::fill(channel, value++);
}
// Zero all the frames of each channel.
bus->Zero();
for (int i = 0; i < bus->channels(); ++i) {
for (auto channel : bus->AllChannels()) {
SCOPED_TRACE("All Zero");
VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), 0);
VerifySpanIsFilledWithValue(channel, 0);
}
EXPECT_TRUE(bus->AreFramesZero());
}
// Each test vector represents two channels of data in the following arbitrary
// layout: <min, zero, max, min, max / 2, min / 2, zero, max, zero, zero>.
static const int kTestVectorSize = 10;
static constexpr int kTestVectorSize = 10;
static const uint8_t kTestVectorUint8[kTestVectorSize] = {
0, -INT8_MIN, UINT8_MAX,
0, INT8_MAX / 2 + 128, INT8_MIN / 2 + 128,
@ -407,7 +435,7 @@ static const float kTestVectorFloat32Sanitized[kTestVectorSize] = {
-1.0f, 0.0f, 1.0f, -1.0f, 0.5f, -0.5f, 0.0f, 1.0f, -1.0f, -1.0f};
// Expected results.
static const int kTestVectorFrameCount = kTestVectorSize / 2;
static constexpr size_t kTestVectorFrameCount = kTestVectorSize / 2;
static const float kTestVectorResult[][kTestVectorFrameCount] = {
{-1.0f, 1.0f, 0.5f, 0.0f, 0.0f},
{0.0f, -1.0f, -0.5f, 1.0f, 0.0f}};
@ -420,8 +448,7 @@ TEST_F(AudioBusTest, FromInterleaved) {
std::unique_ptr<AudioBus> expected =
AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
for (int ch = 0; ch < kTestVectorChannelCount; ++ch) {
memcpy(expected->channel(ch), kTestVectorResult[ch],
kTestVectorFrameCount * sizeof(*expected->channel(ch)));
expected->channel_span(ch).copy_from(base::span(kTestVectorResult[ch]));
}
{
@ -465,8 +492,8 @@ TEST_F(AudioBusTest, FromInterleaved) {
// Verify FromInterleavedPartial() deinterleaves audio correctly.
TEST_F(AudioBusTest, FromInterleavedPartial) {
// Only deinterleave the middle two frames in each channel.
static const int kPartialStart = 1;
static const int kPartialFrames = 2;
static constexpr size_t kPartialStart = 1;
static constexpr size_t kPartialFrames = 2;
ASSERT_LE(kPartialStart + kPartialFrames, kTestVectorFrameCount);
std::unique_ptr<AudioBus> bus =
@ -474,10 +501,11 @@ TEST_F(AudioBusTest, FromInterleavedPartial) {
std::unique_ptr<AudioBus> expected =
AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
expected->Zero();
for (int ch = 0; ch < kTestVectorChannelCount; ++ch) {
memcpy(expected->channel(ch) + kPartialStart,
kTestVectorResult[ch] + kPartialStart,
kPartialFrames * sizeof(*expected->channel(ch)));
int current_channel = 0;
for (auto partial_channel :
expected->AllChannelsSubspan(kPartialStart, kPartialFrames)) {
partial_channel.copy_from(base::span(kTestVectorResult[current_channel++])
.subspan(kPartialStart, kPartialFrames));
}
{
@ -496,8 +524,7 @@ TEST_F(AudioBusTest, ToInterleaved) {
AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
// Fill the bus with our test vector.
for (int ch = 0; ch < bus->channels(); ++ch) {
memcpy(bus->channel(ch), kTestVectorResult[ch],
kTestVectorFrameCount * sizeof(*bus->channel(ch)));
bus->channel_span(ch).copy_from(base::span(kTestVectorResult[ch]));
}
{
@ -548,7 +575,7 @@ TEST_F(AudioBusTest, ToInterleavedSanitized) {
bus->FromInterleaved<Float32SampleTypeTraits>(kTestVectorFloat32Invalid,
bus->frames());
// Verify FromInterleaved applied no sanity.
ASSERT_EQ(bus->channel(0)[0], kTestVectorFloat32Invalid[0]);
ASSERT_EQ(bus->channel_span(0)[0], kTestVectorFloat32Invalid[0]);
float test_array[std::size(kTestVectorFloat32Sanitized)];
bus->ToInterleaved<Float32SampleTypeTraits>(bus->frames(), test_array);
for (size_t i = 0; i < std::size(kTestVectorFloat32Sanitized); ++i)
@ -576,7 +603,7 @@ TEST_F(AudioBusTest, CopyAndClipTo) {
kTestVectorFloat32Sanitized, bus->frames());
// Verify FromInterleaved applied no sanity.
ASSERT_EQ(bus->channel(0)[0], kTestVectorFloat32Invalid[0]);
ASSERT_EQ(bus->channel_span(0)[0], kTestVectorFloat32Invalid[0]);
std::unique_ptr<AudioBus> copy_to_bus =
AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
@ -584,7 +611,8 @@ TEST_F(AudioBusTest, CopyAndClipTo) {
for (int ch = 0; ch < expected->channels(); ++ch) {
for (int i = 0; i < expected->frames(); ++i)
ASSERT_EQ(copy_to_bus->channel(ch)[i], expected->channel(ch)[i]);
ASSERT_EQ(copy_to_bus->channel_span(ch)[i],
expected->channel_span(ch)[i]);
}
ASSERT_EQ(expected->channels(), copy_to_bus->channels());
@ -596,15 +624,14 @@ TEST_F(AudioBusTest, CopyAndClipTo) {
// Verify ToInterleavedPartial() interleaves audio correctly.
TEST_F(AudioBusTest, ToInterleavedPartial) {
// Only interleave the middle two frames in each channel.
static const int kPartialStart = 1;
static const int kPartialFrames = 2;
static constexpr size_t kPartialStart = 1;
static constexpr size_t kPartialFrames = 2;
ASSERT_LE(kPartialStart + kPartialFrames, kTestVectorFrameCount);
std::unique_ptr<AudioBus> expected =
AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
for (int ch = 0; ch < kTestVectorChannelCount; ++ch) {
memcpy(expected->channel(ch), kTestVectorResult[ch],
kTestVectorFrameCount * sizeof(*expected->channel(ch)));
expected->channel_span(ch).copy_from(base::span(kTestVectorResult[ch]));
}
{
@ -631,11 +658,10 @@ struct ZeroingOutTestData {
// Create a bus and fill each channel with a test pattern of form
// [1.0, 2.0, 3.0, ...]
bus_under_test = AudioBus::Create(kChannelCount, kFrameCount);
for (int ch = 0; ch < kChannelCount; ++ch) {
auto* sample_array_for_current_channel = bus_under_test->channel(ch);
for (int frame_index = 0; frame_index < kFrameCount; frame_index++) {
sample_array_for_current_channel[frame_index] =
static_cast<float>(frame_index + 1);
for (auto channel : bus_under_test->AllChannels()) {
int value = 1;
for (float& sample : channel) {
sample = value++;
}
}
@ -654,13 +680,14 @@ TEST_F(AudioBusTest, FromInterleavedZerosOutUntouchedFrames) {
test_data.bus_under_test->FromInterleaved<Float32SampleTypeTraits>(
&test_data.interleaved_dummy_frames[0], test_data.kInterleavedFrameCount);
const size_t untouched_frame_count =
test_data.kFrameCount - test_data.kInterleavedFrameCount;
// Verification
for (int ch = 0; ch < test_data.kChannelCount; ++ch) {
auto* sample_array_for_current_channel =
test_data.bus_under_test->channel(ch);
for (int frame_index = test_data.kInterleavedFrameCount;
frame_index < test_data.kFrameCount; frame_index++) {
ASSERT_EQ(0.0f, sample_array_for_current_channel[frame_index]);
for (auto partial_channel : test_data.bus_under_test->AllChannelsSubspan(
test_data.kInterleavedFrameCount, untouched_frame_count)) {
for (auto sample : partial_channel) {
ASSERT_EQ(0.0f, sample);
}
}
}
@ -679,8 +706,8 @@ TEST_F(AudioBusTest, FromInterleavedPartialDoesNotZeroOutUntouchedFrames) {
// Verification
for (int ch = 0; ch < test_data.kChannelCount; ++ch) {
auto* sample_array_for_current_channel =
test_data.bus_under_test->channel(ch);
auto sample_array_for_current_channel =
test_data.bus_under_test->channel_span(ch);
for (int frame_index =
test_data.kInterleavedFrameCount + kWriteOffsetInFrames;
frame_index < test_data.kFrameCount; frame_index++) {
@ -702,8 +729,8 @@ TEST_F(AudioBusTest, FromInterleavedPartialDoesNotZeroOutUntouchedFrames) {
// Verification
for (int ch = 0; ch < test_data.kChannelCount; ++ch) {
auto* sample_array_for_current_channel =
test_data.bus_under_test->channel(ch);
auto sample_array_for_current_channel =
test_data.bus_under_test->channel_span(ch);
// Check untouched frames before write offset
for (int frame_index = 0; frame_index < kWriteOffsetInFrames;
frame_index++) {
@ -725,31 +752,31 @@ TEST_F(AudioBusTest, Scale) {
std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount);
// Fill the bus with dummy data.
static const float kFillValue = 1;
for (int i = 0; i < bus->channels(); ++i)
std::fill(bus->channel(i), bus->channel(i) + bus->frames(), kFillValue);
static constexpr float kFillValue = 1;
for (auto channel : bus->AllChannels()) {
std::ranges::fill(channel, kFillValue);
}
// Adjust by an invalid volume and ensure volume is unchanged.
bus->Scale(-1);
for (int i = 0; i < bus->channels(); ++i) {
for (auto channel : bus->AllChannels()) {
SCOPED_TRACE("Invalid Scale");
VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), kFillValue);
VerifySpanIsFilledWithValue(channel, kFillValue);
}
// Verify correct volume adjustment.
static const float kVolume = 0.5;
static constexpr float kVolume = 0.5;
bus->Scale(kVolume);
for (int i = 0; i < bus->channels(); ++i) {
for (auto channel : bus->AllChannels()) {
SCOPED_TRACE("Half Scale");
VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(),
kFillValue * kVolume);
VerifySpanIsFilledWithValue(channel, kFillValue * kVolume);
}
// Verify zero volume case.
bus->Scale(0);
for (int i = 0; i < bus->channels(); ++i) {
for (auto channel : bus->AllChannels()) {
SCOPED_TRACE("Zero Scale");
VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), 0);
VerifySpanIsFilledWithValue(channel, 0);
}
}
@ -767,7 +794,7 @@ TEST_F(AudioBusTest, Bitstream) {
EXPECT_EQ(0, bus->GetBitstreamFrames());
bus->SetBitstreamFrames(kFrameCount);
EXPECT_EQ(kFrameCount, bus->GetBitstreamFrames());
EXPECT_EQ(static_cast<int>(kFrameCount), bus->GetBitstreamFrames());
std::unique_ptr<AudioBus> bus2 = AudioBus::Create(1, kFrameCount);
CopyTest(bus.get(), bus2.get());