at
This commit is contained in:
252
tests/unit/engine/audio_buffer_processing_test.cpp
Normal file
252
tests/unit/engine/audio_buffer_processing_test.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
// ================================================================================================
|
||||
// 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();
|
||||
}
|
||||
Reference in New Issue
Block a user