blob: 7127ee3d1877e6414d85893c620aae36cee686e2 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/media/audio/audio_core/reusable_buffer.h"
#include <gtest/gtest.h>
#include "src/lib/fxl/strings/string_printf.h"
namespace media::audio {
static auto kFormatOneChan =
Format::Create(fuchsia::media::AudioStreamType{
.sample_format = fuchsia::media::AudioSampleFormat::SIGNED_16,
.channels = 1,
.frames_per_second = 48000,
})
.take_value();
static auto kFormatTwoChan =
Format::Create(fuchsia::media::AudioStreamType{
.sample_format = fuchsia::media::AudioSampleFormat::SIGNED_16,
.channels = 2,
.frames_per_second = 48000,
})
.take_value();
TEST(ReusableBufferTest, AppendDataOneChan) {
ReusableBuffer buffer(kFormatOneChan, 20);
std::vector<int16_t> payload1{1, 2, 3, 4, 5};
std::vector<int16_t> payload2{6, 7, 8, 9, 10};
std::vector<int16_t> payload3{11, 12, 13, 14, 15};
// Starts empty.
// Can call these before Reset().
EXPECT_EQ(buffer.length(), 0);
EXPECT_EQ(buffer.capacity(), 20);
EXPECT_TRUE(buffer.empty());
// Must call these after Reset().
buffer.Reset(Fixed(0));
EXPECT_EQ(buffer.start(), Fixed(0));
EXPECT_EQ(buffer.end(), Fixed(0));
EXPECT_EQ(buffer.length(), 0);
EXPECT_TRUE(buffer.empty());
buffer.AppendData(Fixed(0), payload1.size(), &payload1[0]);
EXPECT_EQ(buffer.start(), Fixed(0)) << "start = " << ffl::String(buffer.start()).c_str();
EXPECT_EQ(buffer.end(), Fixed(5)) << "end = " << ffl::String(buffer.end()).c_str();
EXPECT_EQ(buffer.length(), 5);
EXPECT_FALSE(buffer.empty());
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[0], 1);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[4], 5);
// Append without a gap.
buffer.AppendData(Fixed(5), payload2.size(), &payload2[0]);
EXPECT_EQ(buffer.start(), Fixed(0)) << "start = " << ffl::String(buffer.start()).c_str();
EXPECT_EQ(buffer.end(), Fixed(10)) << "end = " << ffl::String(buffer.end()).c_str();
EXPECT_EQ(buffer.length(), 10);
EXPECT_FALSE(buffer.empty());
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[0], 1);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[4], 5);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[5], 6);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[9], 10);
// Append with a gap.
buffer.AppendData(Fixed(15), payload3.size(), &payload3[0]);
EXPECT_EQ(buffer.start(), Fixed(0)) << "start = " << ffl::String(buffer.start()).c_str();
EXPECT_EQ(buffer.end(), Fixed(20)) << "end = " << ffl::String(buffer.end()).c_str();
EXPECT_EQ(buffer.length(), 20);
EXPECT_FALSE(buffer.empty());
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[0], 1);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[4], 5);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[5], 6);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[9], 10);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[10], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[14], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[15], 11);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[19], 15);
}
TEST(ReusableBufferTest, AppendSilenceOneChan) {
ReusableBuffer buffer(kFormatOneChan, 25);
std::vector<int16_t> payload{1, 2, 3, 4, 5};
buffer.Reset(Fixed(0));
EXPECT_EQ(buffer.start(), Fixed(0));
EXPECT_EQ(buffer.end(), Fixed(0));
EXPECT_EQ(buffer.length(), 0);
EXPECT_TRUE(buffer.empty());
buffer.AppendSilence(Fixed(0), 5);
EXPECT_EQ(buffer.start(), Fixed(0)) << "start = " << ffl::String(buffer.start()).c_str();
EXPECT_EQ(buffer.end(), Fixed(5)) << "end = " << ffl::String(buffer.end()).c_str();
EXPECT_EQ(buffer.length(), 5);
EXPECT_FALSE(buffer.empty());
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[0], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[4], 0);
buffer.AppendData(Fixed(5), payload.size(), &payload[0]);
EXPECT_EQ(buffer.start(), Fixed(0)) << "start = " << ffl::String(buffer.start()).c_str();
EXPECT_EQ(buffer.end(), Fixed(10)) << "end = " << ffl::String(buffer.end()).c_str();
EXPECT_EQ(buffer.length(), 10);
EXPECT_FALSE(buffer.empty());
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[0], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[4], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[5], 1);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[9], 5);
// Skip [10, 15).
buffer.AppendSilence(Fixed(15), 5);
buffer.AppendSilence(Fixed(20), 5);
EXPECT_EQ(buffer.start(), Fixed(0)) << "start = " << ffl::String(buffer.start()).c_str();
EXPECT_EQ(buffer.end(), Fixed(25)) << "end = " << ffl::String(buffer.end()).c_str();
EXPECT_EQ(buffer.length(), 25);
EXPECT_FALSE(buffer.empty());
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[0], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[4], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[5], 1);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[9], 5);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[10], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[14], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[15], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[19], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[20], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[24], 0);
}
TEST(ReusableBufferTest, AppendTwoChan) {
ReusableBuffer buffer(kFormatTwoChan, 8);
std::vector<int16_t> payload1{1, 2, 3, 4};
// Starts empty.
buffer.Reset(Fixed(0));
EXPECT_EQ(buffer.start(), Fixed(0));
EXPECT_EQ(buffer.end(), Fixed(0));
EXPECT_EQ(buffer.length(), 0);
EXPECT_TRUE(buffer.empty());
// Append data.
buffer.AppendData(Fixed(0), 2, &payload1[0]);
EXPECT_EQ(buffer.start(), Fixed(0)) << "start = " << ffl::String(buffer.start()).c_str();
EXPECT_EQ(buffer.end(), Fixed(2)) << "end = " << ffl::String(buffer.end()).c_str();
EXPECT_EQ(buffer.length(), 2);
EXPECT_FALSE(buffer.empty());
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[0], 1);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[3], 4);
// Append silence.
buffer.AppendSilence(Fixed(2), 2);
EXPECT_EQ(buffer.start(), Fixed(0)) << "start = " << ffl::String(buffer.start()).c_str();
EXPECT_EQ(buffer.end(), Fixed(4)) << "end = " << ffl::String(buffer.end()).c_str();
EXPECT_EQ(buffer.length(), 4);
EXPECT_FALSE(buffer.empty());
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[0], 1);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[3], 4);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[4], 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[7], 0);
}
TEST(ReusableBufferTest, AppendResetAppend) {
ReusableBuffer buffer(kFormatOneChan, 5);
std::vector<int16_t> payload{1, 2, 3, 4, 5};
for (int k = 0; k < 2; k++) {
SCOPED_TRACE(fxl::StringPrintf("reset#%d", k));
buffer.Reset(Fixed(0));
EXPECT_EQ(buffer.start(), Fixed(0));
EXPECT_EQ(buffer.end(), Fixed(0));
EXPECT_EQ(buffer.length(), 0);
if (k == 0) {
buffer.AppendData(Fixed(0), payload.size(), &payload[0]);
} else {
buffer.AppendSilence(Fixed(0), 5);
}
EXPECT_EQ(buffer.start(), Fixed(0)) << "start = " << ffl::String(buffer.start()).c_str();
EXPECT_EQ(buffer.end(), Fixed(5)) << "end = " << ffl::String(buffer.end()).c_str();
EXPECT_EQ(buffer.length(), 5);
EXPECT_FALSE(buffer.empty());
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[0], (k == 0) ? 1 : 0);
EXPECT_EQ(reinterpret_cast<int16_t*>(buffer.payload())[4], (k == 0) ? 5 : 0);
}
}
} // namespace media::audio