Files
Alicho/tests/unit/engine/audio_buffer_processing_test.cpp
2025-10-28 10:27:49 +08:00

252 lines
8.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ================================================================================================
// Audio Backend - 音频缓冲区处理测试
// ================================================================================================
#include <gtest/gtest.h>
#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<AudioBuffer>(buffer_size_, channels_, AudioFormat::FLOAT32);
target_buffer_ = std::make_unique<AudioBuffer>(buffer_size_, channels_, AudioFormat::FLOAT32);
mix_buffer_ = std::make_unique<AudioBuffer>(buffer_size_, channels_, AudioFormat::FLOAT32);
// 填充源缓冲区
float* src_data = source_buffer_->interleaved_data<float>();
for (size_t i = 0; i < buffer_size_ * channels_; ++i) {
src_data[i] = 0.5f; // 所有样本设为0.5
}
// 填充混音缓冲区
float* mix_data = mix_buffer_->interleaved_data<float>();
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<AudioBuffer> source_buffer_;
std::unique_ptr<AudioBuffer> target_buffer_;
std::unique_ptr<AudioBuffer> 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<float>();
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<float>();
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>();
float* mix_data = mix_buffer_->interleaved_data<float>();
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<float>();
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>();
float* target_data = target_buffer_->interleaved_data<float>();
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>();
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>();
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<float>();
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<float>();
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<float>();
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();
}