// ================================================================================================ // Audio Backend - 音频缓冲区处理测试 // ================================================================================================ #include #include "engine/audio_buffer.h" #include "tests/common/test_fixtures.h" #include "tests/common/test_utils.h" using namespace audio_backend; using namespace audio_backend::engine; // 音频缓冲区处理测试固定装置 class AudioBufferProcessingTest : public test::AudioEngineTest { protected: void SetUp() override { test::AudioEngineTest::SetUp(); // 创建测试缓冲区 source_buffer_ = std::make_unique(buffer_size_, channels_, AudioFormat::FLOAT32); target_buffer_ = std::make_unique(buffer_size_, channels_, AudioFormat::FLOAT32); mix_buffer_ = std::make_unique(buffer_size_, channels_, AudioFormat::FLOAT32); // 填充源缓冲区 float* src_data = source_buffer_->interleaved_data(); for (size_t i = 0; i < buffer_size_ * channels_; ++i) { src_data[i] = 0.5f; // 所有样本设为0.5 } // 填充混音缓冲区 float* mix_data = mix_buffer_->interleaved_data(); for (size_t i = 0; i < buffer_size_ * channels_; ++i) { mix_data[i] = 0.25f; // 所有样本设为0.25 } // 清空目标缓冲区 target_buffer_->clear(); } void TearDown() override { source_buffer_.reset(); target_buffer_.reset(); mix_buffer_.reset(); test::AudioEngineTest::TearDown(); } protected: std::unique_ptr source_buffer_; std::unique_ptr target_buffer_; std::unique_ptr mix_buffer_; const size_t buffer_size_ = 256; const size_t channels_ = 2; }; // 测试应用增益 TEST_F(AudioBufferProcessingTest, ApplyGain) { // 拷贝原始数据 source_buffer_->copy_to(*target_buffer_); // 检查拷贝是否成功 float* target_data = target_buffer_->interleaved_data(); for (size_t i = 0; i < buffer_size_ * channels_; ++i) { EXPECT_FLOAT_EQ(target_data[i], 0.5f); } // 应用增益 (2.0) target_buffer_->apply_gain(2.0f); // 检查增益应用效果 for (size_t i = 0; i < buffer_size_ * channels_; ++i) { EXPECT_FLOAT_EQ(target_data[i], 1.0f); } // 应用零增益 target_buffer_->apply_gain(0.0f); // 检查零增益效果(应该全为零) for (size_t i = 0; i < buffer_size_ * channels_; ++i) { EXPECT_FLOAT_EQ(target_data[i], 0.0f); } // 应用负增益 target_buffer_->copy_from(*source_buffer_); target_buffer_->apply_gain(-1.0f); // 检查负增益效果 for (size_t i = 0; i < buffer_size_ * channels_; ++i) { EXPECT_FLOAT_EQ(target_data[i], -0.5f); } } // 测试混音 TEST_F(AudioBufferProcessingTest, Mixing) { // 先将源缓冲区拷贝到目标缓冲区 source_buffer_->copy_to(*target_buffer_); // 混入mix_buffer (增益为1.0) target_buffer_->mix_from(*mix_buffer_, 1.0f); // 检查混音效果:0.5 + 0.25 = 0.75 float* target_data = target_buffer_->interleaved_data(); for (size_t i = 0; i < buffer_size_ * channels_; ++i) { EXPECT_FLOAT_EQ(target_data[i], 0.75f); } // 混入mix_buffer (增益为2.0) target_buffer_->copy_from(*source_buffer_); target_buffer_->mix_from(*mix_buffer_, 2.0f); // 检查混音效果:0.5 + 0.25*2.0 = 1.0 for (size_t i = 0; i < buffer_size_ * channels_; ++i) { EXPECT_FLOAT_EQ(target_data[i], 1.0f); } // 混入mix_buffer (增益为-1.0) target_buffer_->copy_from(*source_buffer_); target_buffer_->mix_from(*mix_buffer_, -1.0f); // 检查混音效果:0.5 + 0.25*(-1.0) = 0.25 for (size_t i = 0; i < buffer_size_ * channels_; ++i) { EXPECT_FLOAT_EQ(target_data[i], 0.25f); } } // 测试混音时的溢出保护 TEST_F(AudioBufferProcessingTest, MixingOverflow) { // 将源缓冲区和混音缓冲区都填充为0.8 float* src_data = source_buffer_->interleaved_data(); float* mix_data = mix_buffer_->interleaved_data(); for (size_t i = 0; i < buffer_size_ * channels_; ++i) { src_data[i] = 0.8f; mix_data[i] = 0.8f; } // 拷贝到目标缓冲区并混音 source_buffer_->copy_to(*target_buffer_); target_buffer_->mix_from(*mix_buffer_); // 检查混音结果:0.8 + 0.8 = 1.6,但应该被限制在1.0 float* target_data = target_buffer_->interleaved_data(); for (size_t i = 0; i < buffer_size_ * channels_; ++i) { // 注意:根据实现不同,可能会有或没有限幅功能 // 如果有限幅:EXPECT_FLOAT_EQ(target_data[i], 1.0f); // 如果没有限幅:EXPECT_FLOAT_EQ(target_data[i], 1.6f); // 我们这里假设实现了限幅功能 if (target_data[i] > 1.0f) { EXPECT_FLOAT_EQ(target_data[i], 1.0f); } else { EXPECT_FLOAT_EQ(target_data[i], 1.6f); } } } // 测试复制功能(copy_to和copy_from) TEST_F(AudioBufferProcessingTest, CopyOperations) { // 测试copy_to source_buffer_->copy_to(*target_buffer_); float* src_data = source_buffer_->interleaved_data(); float* target_data = target_buffer_->interleaved_data(); for (size_t i = 0; i < buffer_size_ * channels_; ++i) { EXPECT_FLOAT_EQ(target_data[i], src_data[i]); } // 修改目标缓冲区 for (size_t i = 0; i < buffer_size_ * channels_; ++i) { target_data[i] = 0.0f; } // 测试copy_from target_buffer_->copy_from(*source_buffer_); for (size_t i = 0; i < buffer_size_ * channels_; ++i) { EXPECT_FLOAT_EQ(target_data[i], src_data[i]); } } // 测试不同格式缓冲区之间的复制 TEST_F(AudioBufferProcessingTest, CopyBetweenFormats) { // 创建INT16格式的缓冲区 AudioBuffer int_buffer(buffer_size_, channels_, AudioFormat::INT16); // 填充INT16缓冲区 int16_t* int_data = int_buffer.interleaved_data(); int16_t value = 16384; // 2^14, 半程最大值 for (size_t i = 0; i < buffer_size_ * channels_; ++i) { int_data[i] = value; } // 尝试从INT16复制到FLOAT32 target_buffer_->copy_from(int_buffer); // 检查复制结果 float* target_data = target_buffer_->interleaved_data(); float expected = value / 32768.0f; // INT16归一化到FLOAT32 for (size_t i = 0; i < buffer_size_ * channels_; ++i) { EXPECT_NEAR(target_data[i], expected, 0.01f); } } // 测试不同大小缓冲区之间的复制 TEST_F(AudioBufferProcessingTest, CopyBetweenDifferentSizes) { // 创建更大的缓冲区 AudioBuffer larger_buffer(buffer_size_ * 2, channels_, AudioFormat::FLOAT32); // 填充大缓冲区 float* larger_data = larger_buffer.interleaved_data(); for (size_t i = 0; i < buffer_size_ * 2 * channels_; ++i) { larger_data[i] = 1.0f; } // 从大缓冲区复制到小缓冲区 target_buffer_->copy_from(larger_buffer); // 检查复制结果(应该只复制了小缓冲区能容纳的部分) float* target_data = target_buffer_->interleaved_data(); for (size_t i = 0; i < buffer_size_ * channels_; ++i) { EXPECT_FLOAT_EQ(target_data[i], 1.0f); } // 创建更小的缓冲区 AudioBuffer smaller_buffer(buffer_size_ / 2, channels_, AudioFormat::FLOAT32); // 填充小缓冲区 float* smaller_data = smaller_buffer.interleaved_data(); for (size_t i = 0; i < (buffer_size_ / 2) * channels_; ++i) { smaller_data[i] = 0.5f; } // 从小缓冲区复制到大缓冲区 target_buffer_->clear(); target_buffer_->copy_from(smaller_buffer); // 检查复制结果 for (size_t i = 0; i < (buffer_size_ / 2) * channels_; ++i) { EXPECT_FLOAT_EQ(target_data[i], 0.5f); } // 剩余部分应该保持为0 for (size_t i = (buffer_size_ / 2) * channels_; i < buffer_size_ * channels_; ++i) { EXPECT_FLOAT_EQ(target_data[i], 0.0f); } } int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }