添加测试支持,重构CMake配置,优化进程管理器测试代码

This commit is contained in:
2025-11-04 13:20:27 +08:00
parent 44625ac60a
commit 3c451e3cd8
19 changed files with 230 additions and 309 deletions

View File

@@ -0,0 +1,799 @@
/**
* @file test_audio_processing_comprehensive.cpp
* @brief 音频处理函数综合测试套件
*
* 测试覆盖:
* - 9个音频处理函数确性测试
* - 标量与SIMD版本的一致性测试
* - 边界条件和错误处理测试
* - 性能对比测试
* - 跨平台兼容性测试
*/
#include <gtest/gtest.h>
#include <vector>
#include <cmath>
#include <random>
#include <chrono>
#include <iomanip>
#include <algorithm>
#include <numeric>
#include <functional>
// 确保M_PI定义可用
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
// 音频处理函数头文件
#include "aligned_allocator.h"
#include "simd_func_dispatcher.h"
#include "audio_processing/scalar_audio_processing_func.h"
#include "audio_processing/simd_audio_processing.h"
#if ALICHO_PLATFORM_X86
#include "audio_processing/x86_simd_audio_processing_func.h"
#endif
#if ALICHO_PLATFORM_ARM
#include "audio_processing/arm_simd_audio_processing_func.h"
#endif
// 测试容差设置
constexpr float FLOAT_TOLERANCE = 1e-6f;
constexpr float RMS_TOLERANCE = 1e-5f;
constexpr float PEAK_TOLERANCE = 1e-6f;
// 性能测试设置
constexpr size_t PERF_TEST_SIZE = 1024 * 1024; // 1M samples
constexpr int PERF_TEST_ITERATIONS = 100;
using aligned_audio_buffer = std::vector<float, avx512_aligned_allocator<float>>;
/**
* 浮点数比较函数
*/
bool float_equal(float a, float b, float tolerance = FLOAT_TOLERANCE) {
if (std::isnan(a) && std::isnan(b))
return true;
if (std::isinf(a) && std::isinf(b))
return (a > 0) == (b > 0);
return std::abs(a - b) <= tolerance;
}
/**
* 数组比较函数
*/
bool arrays_equal(const float* arr1, const float* arr2, size_t size, float tolerance = FLOAT_TOLERANCE) {
for (size_t i = 0; i < size; ++i) {
if (!float_equal(arr1[i], arr2[i], tolerance)) {
std::cout << " 差异在位置 " << i << ": " << arr1[i] << " vs " << arr2[i]
<< " (差值: " << std::abs(arr1[i] - arr2[i]) << ")" << std::endl;
return false;
}
}
return true;
}
/**
* 测试数据生成器
*/
class AudioDataGenerator {
private:
mutable std::mt19937 rng_{std::random_device{}()};
public:
// 生成正弦波
auto generate_sine_wave(size_t num_samples, float frequency = 440.0f,
float sample_rate = 44100.0f, float amplitude = 1.0f) const {
std::vector<float, aligned_allocator<float, ALIGNMENT_AVX512>> data(num_samples);
for (size_t i = 0; i < num_samples; ++i) {
data[i] = amplitude * std::sin(2.0f * M_PI * frequency * i / sample_rate);
}
return data;
}
// 生成白噪声
auto generate_white_noise(size_t num_samples, float amplitude = 1.0f) const {
std::vector<float, aligned_allocator<float, ALIGNMENT_AVX512>> data(num_samples);
std::uniform_real_distribution<float> dist(-amplitude, amplitude);
for (size_t i = 0; i < num_samples; ++i) {
data[i] = dist(rng_);
}
return data;
}
// 生成脉冲信号
auto generate_impulse(size_t num_samples, size_t impulse_pos = 0, float amplitude = 1.0f) const {
std::vector<float, aligned_allocator<float, ALIGNMENT_AVX512>> data(num_samples, 0.0f);
if (impulse_pos < num_samples) {
data[impulse_pos] = amplitude;
}
return data;
}
// 生成直流信号
aligned_audio_buffer generate_dc(size_t num_samples, float value = 1.0f) const {
return aligned_audio_buffer(num_samples, value);
}
// 生成立体声测试数据
aligned_audio_buffer generate_stereo_test_data(size_t num_stereo_samples) const {
aligned_audio_buffer data(num_stereo_samples * 2);
for (size_t i = 0; i < num_stereo_samples; ++i) {
data[i * 2] = std::sin(2.0f * M_PI * 440.0f * i / 44100.0f); // 左声道: 440Hz
data[i * 2 + 1] = std::sin(2.0f * M_PI * 880.0f * i / 44100.0f); // 右声道: 880Hz
}
return data;
}
// 生成边界测试数据
aligned_audio_buffer generate_boundary_data(size_t num_samples) const {
aligned_audio_buffer data;
data.reserve(num_samples);
// 添加各种边界值
if (num_samples > 0)
data.push_back(0.0f);
if (num_samples > 1)
data.push_back(1.0f);
if (num_samples > 2)
data.push_back(-1.0f);
if (num_samples > 3)
data.push_back(std::numeric_limits<float>::min());
if (num_samples > 4)
data.push_back(std::numeric_limits<float>::max());
if (num_samples > 5)
data.push_back(std::numeric_limits<float>::epsilon());
if (num_samples > 6)
data.push_back(-std::numeric_limits<float>::epsilon());
// 填充剩余位置
std::uniform_real_distribution<float> dist(-1.0f, 1.0f);
while (data.size() < num_samples) {
data.push_back(dist(rng_));
}
return data;
}
};
/**
* 性能测试辅助类
*/
class PerformanceTester {
public:
template <typename Func>
double measure_execution_time(Func&& func, int iterations = PERF_TEST_ITERATIONS) {
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < iterations; ++i) {
func();
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
return duration.count() / 1e6 / iterations; // 返回平均毫秒数
}
void print_performance_comparison(const std::string& test_name,
double scalar_time,
double simd_time) {
double speedup = scalar_time / simd_time;
std::cout << "[PERF] " << test_name << std::endl;
std::cout << " 标量版本: " << std::fixed << std::setprecision(3) << scalar_time << "ms" << std::endl;
std::cout << " SIMD版本: " << std::fixed << std::setprecision(3) << simd_time << "ms" << std::endl;
std::cout << " 加速比: " << std::fixed << std::setprecision(2) << speedup << "x" << std::endl;
}
};
// 音频处理函数测试类
class AudioProcessingTest : public ::testing::Test {
protected:
void SetUp() override {
// 初始化测试环境
audio_processing_registry::register_all_functions();
}
void TearDown() override {
// 清理测试环境
}
// 全局实例
AudioDataGenerator data_gen;
PerformanceTester perf_tester;
};
/**
* ========================================
* 基础功能测试
* ========================================
*/
// 测试 simd_audio_processing_registry 注册功能
TEST_F(AudioProcessingTest, RegistryRegistration) {
// 打印已注册的函数以供调试
audio_processing_registry::print_available_functions();
// 验证关键函数已注册
auto& dispatcher = simd_func_dispatcher::instance();
EXPECT_NO_THROW({
dispatcher.get_function<void(const float*, const float*, float*, size_t)>("mix_audio");
}) << "函数 mix_audio 未正确注册";
EXPECT_NO_THROW({
dispatcher.get_function<void(const float*, float*, float, size_t)>("apply_gain");
}) << "函数 apply_gain 未正确注册";
EXPECT_NO_THROW({
dispatcher.get_function<float(const float*, size_t)>("calculate_rms");
}) << "函数 calculate_rms 未正确注册";
EXPECT_NO_THROW({
dispatcher.get_function<float(const float*, size_t)>("calculate_peak");
}) << "函数 calculate_peak 未正确注册";
EXPECT_NO_THROW({
dispatcher.get_function<void(const float*, float*, float, size_t)>("normalize_audio");
}) << "函数 normalize_audio 未正确注册";
EXPECT_NO_THROW({
dispatcher.get_function<void(const float*, float*, size_t)>("stereo_to_mono");
}) << "函数 stereo_to_mono 未正确注册";
}
// 测试 mix_audio 函数
TEST_F(AudioProcessingTest, MixAudioBasic) {
const size_t num_samples = 16;
auto src1 = data_gen.generate_sine_wave(num_samples, 440.0f);
auto src2 = data_gen.generate_sine_wave(num_samples, 880.0f);
aligned_audio_buffer result(num_samples);
aligned_audio_buffer expected(num_samples);
// 计算期望结果
for (size_t i = 0; i < num_samples; ++i) {
expected[i] = src1[i] + src2[i];
}
// 测试标量版本
scalar_audio_processing_func::mix_audio(src1.data(), src2.data(), result.data(), num_samples);
EXPECT_TRUE(arrays_equal(result.data(), expected.data(), num_samples))
<< "混合音频结果与期望不符";
}
// 测试 apply_gain 函数
TEST_F(AudioProcessingTest, ApplyGainBasic) {
const size_t num_samples = 16;
const float gain = 0.5f;
auto src = data_gen.generate_sine_wave(num_samples);
std::vector<float, avx512_aligned_allocator<float>> result(num_samples);
std::vector<float, avx512_aligned_allocator<float>> expected(num_samples);
// 计算期望结果
for (size_t i = 0; i < num_samples; ++i) {
expected[i] = src[i] * gain;
}
// 测试标量版本
scalar_audio_processing_func::apply_gain(src.data(), result.data(), gain, num_samples);
EXPECT_TRUE(arrays_equal(result.data(), expected.data(), num_samples))
<< "增益应用结果与期望不符";
}
// 测试 calculate_rms 函数
TEST_F(AudioProcessingTest, CalculateRmsBasic) {
const size_t num_samples = 1024;
auto src = data_gen.generate_sine_wave(num_samples);
// 计算期望的RMS值
double sum_squares = 0.0;
for (size_t i = 0; i < num_samples; ++i) {
sum_squares += src[i] * src[i];
}
float expected_rms = std::sqrt(sum_squares / num_samples);
// 测试标量版本
float result_rms = scalar_audio_processing_func::calculate_rms(src.data(), num_samples);
EXPECT_TRUE(float_equal(result_rms, expected_rms, RMS_TOLERANCE))
<< "期望 RMS: " << expected_rms << ", 得到: " << result_rms;
}
// 测试 calculate_peak 函数
TEST_F(AudioProcessingTest, CalculatePeakBasic) {
const size_t num_samples = 1024;
auto src = data_gen.generate_boundary_data(num_samples);
// 计算期望的峰值
float expected_peak = 0.0f;
for (size_t i = 0; i < num_samples; ++i) {
expected_peak = std::max(expected_peak, std::abs(src[i]));
}
// 测试标量版本
float result_peak = scalar_audio_processing_func::calculate_peak(src.data(), num_samples);
EXPECT_TRUE(float_equal(result_peak, expected_peak, PEAK_TOLERANCE))
<< "期望峰值: " << expected_peak << ", 得到: " << result_peak;
}
/**
* ========================================
* 新增功能测试
* ========================================
*/
// 测试 normalize_audio 函数
TEST_F(AudioProcessingTest, NormalizeAudioBasic) {
const size_t num_samples = 1024;
const float target_peak = 0.8f;
auto src = data_gen.generate_sine_wave(num_samples, 440.0f, 44100.0f, 2.0f); // 超过1.0的幅度
aligned_audio_buffer result(num_samples);
// 测试标量版本
scalar_audio_processing_func::normalize_audio(src.data(), result.data(), target_peak, num_samples);
// 验证归一化后的峰值
float actual_peak = scalar_audio_processing_func::calculate_peak(result.data(), num_samples);
EXPECT_TRUE(float_equal(actual_peak, target_peak, PEAK_TOLERANCE))
<< "期望峰值: " << target_peak << ", 实际峰值: " << actual_peak;
}
// 测试 stereo_to_mono 函数
TEST_F(AudioProcessingTest, StereoToMonoBasic) {
const size_t num_stereo_samples = 512;
auto stereo_src = data_gen.generate_stereo_test_data(num_stereo_samples);
aligned_audio_buffer mono_result(num_stereo_samples);
aligned_audio_buffer expected_mono(num_stereo_samples);
// 计算期望结果
for (size_t i = 0; i < num_stereo_samples; ++i) {
expected_mono[i] = (stereo_src[i * 2] + stereo_src[i * 2 + 1]) * 0.5f;
}
// 测试标量版本
scalar_audio_processing_func::stereo_to_mono(stereo_src.data(), mono_result.data(), num_stereo_samples);
EXPECT_TRUE(arrays_equal(mono_result.data(), expected_mono.data(), num_stereo_samples))
<< "立体声转单声道果与期望不符";
}
// 测试 limit_audio 函数
TEST_F(AudioProcessingTest, LimitAudioBasic) {
const size_t num_samples = 1024;
const float threshold = 0.5f;
auto src = data_gen.generate_sine_wave(num_samples, 440.0f, 44100.0f, 1.0f);
aligned_audio_buffer result(num_samples);
float limiter_state = 1.0f;
// 测试标量版本
scalar_audio_processing_func::limit_audio(src.data(), result.data(), threshold, &limiter_state, 44100.f,
num_samples);
// 验证没有样本超过阈值
bool all_samples_limited = true;
size_t violation_index = 0;
float violation_value = 0.0f;
for (size_t i = 0; i < num_samples; ++i) {
if (std::abs(result[i]) > threshold + FLOAT_TOLERANCE) {
all_samples_limited = false;
violation_index = i;
violation_value = result[i];
break;
}
}
EXPECT_TRUE(all_samples_limited)
<< "样本 " << violation_index << " 超过阈值: " << violation_value;
}
// 测试 fade_audio 函数
TEST_F(AudioProcessingTest, FadeAudioBasic) {
const size_t num_samples = 1024;
const size_t fade_in_samples = 100;
const size_t fade_out_samples = 100;
auto src = data_gen.generate_dc(num_samples, 1.0f);
aligned_audio_buffer result(num_samples);
// 测试标量版本
scalar_audio_processing_func::fade_audio(src.data(), result.data(), fade_in_samples, fade_out_samples, num_samples);
// 验证淡入淡出效果
// 检查淡入部分
EXPECT_FLOAT_EQ(result[0], 0.0f)
<< "淡入开始应为0实际为: " << result[0];
// 检查中间部分应该是1.0
EXPECT_FLOAT_EQ(result[num_samples / 2], 1.0f)
<< "中间部分应保持原始值1.0,实际为: " << result[num_samples / 2];
// 检查淡出部分
EXPECT_TRUE(float_equal(result[num_samples - 1], 0.0f, FLOAT_TOLERANCE))
<< "淡出结束应为0实际为: " << result[num_samples - 1];
}
// 测试 simple_eq 函数
TEST_F(AudioProcessingTest, SimpleEqBasic) {
const size_t num_samples = 1024;
const float low_gain = 1.2f;
const float mid_gain = 1.0f;
const float high_gain = 0.8f;
auto src = data_gen.generate_white_noise(num_samples, 0.5f);
aligned_audio_buffer result(num_samples);
aligned_audio_buffer eq_state(2, 0.0f); // 低通和高通滤波器状态
// 测试标量版本
scalar_audio_processing_func::simple_eq(src.data(), result.data(), low_gain, mid_gain, high_gain, eq_state.data(),
num_samples);
// 基本验证:结果不应该全为零(除非输入全为零)
bool has_nonzero = false;
for (size_t i = 0; i < num_samples; ++i) {
if (result[i] != 0.0f) {
has_nonzero = true;
break;
}
}
EXPECT_TRUE(has_nonzero)
<< "EQ处理后的结果全为零可能存在处理错误";
}
/**
* ========================================
* 边界条件测试
* ========================================
*/
// 测试零长度输入
TEST_F(AudioProcessingTest, ZeroLengthInput) {
const size_t num_samples = 0;
aligned_audio_buffer dummy(1, 0.0f);
aligned_audio_buffer result(1, 0.0f);
float state = 1.0f;
// 这些函数应该能安全处理零长度输入
EXPECT_NO_THROW({
scalar_audio_processing_func::mix_audio(dummy.data(), dummy.data(), result.data(), num_samples);
scalar_audio_processing_func::apply_gain(dummy.data(), result.data(), 1.0f, num_samples);
scalar_audio_processing_func::normalize_audio(dummy.data(), result.data(), 1.0f, num_samples);
scalar_audio_processing_func::stereo_to_mono(dummy.data(), result.data(), num_samples);
scalar_audio_processing_func::limit_audio(dummy.data(), result.data(), 1.0f, &state, 44100.f, num_samples);
scalar_audio_processing_func::fade_audio(dummy.data(), result.data(), 0, 0, num_samples);
scalar_audio_processing_func::simple_eq(dummy.data(), result.data(), 1.0f, 1.0f, 1.0f, &state, num_samples);
});
}
// 测试单样本输入
TEST_F(AudioProcessingTest, SingleSampleInput) {
const size_t num_samples = 1;
aligned_audio_buffer src1{0.5f};
aligned_audio_buffer src2{0.3f};
aligned_audio_buffer result(1);
float state = 1.0f;
// 测试混合
scalar_audio_processing_func::mix_audio(src1.data(), src2.data(), result.data(), num_samples);
EXPECT_TRUE(float_equal(result[0], 0.8f))
<< "混合单样本: 期望0.8,实际" << result[0];
// 测试增益
scalar_audio_processing_func::apply_gain(src1.data(), result.data(), 2.0f, num_samples);
EXPECT_TRUE(float_equal(result[0], 1.0f))
<< "应用增益: 期望1.0,实际" << result[0];
// 测试RMS
float rms = scalar_audio_processing_func::calculate_rms(src1.data(), num_samples);
EXPECT_TRUE(float_equal(rms, 0.5f))
<< "单样本RMS: 期望0.5,实际" << rms;
// 测试峰值
float peak = scalar_audio_processing_func::calculate_peak(src1.data(), num_samples);
EXPECT_TRUE(float_equal(peak, 0.5f))
<< "单样本峰值: 期望0.5,实际" << peak;
}
// 测试极值处理
TEST_F(AudioProcessingTest, ExtremeValues) {
const size_t num_samples = 8;
aligned_audio_buffer extreme_values = {
0.0f,
1.0f,
-1.0f,
std::numeric_limits<float>::max(),
-std::numeric_limits<float>::max(),
std::numeric_limits<float>::min(),
std::numeric_limits<float>::epsilon(),
-std::numeric_limits<float>::epsilon()
};
aligned_audio_buffer result(num_samples);
// 测试峰值计算对极值的处理
float peak = scalar_audio_processing_func::calculate_peak(extreme_values.data(), num_samples);
EXPECT_EQ(peak, std::numeric_limits<float>::max())
<< "极值峰值检测失败,期望" << std::numeric_limits<float>::max() << ",实际" << peak;
// 测试增益对极值的处理
scalar_audio_processing_func::apply_gain(extreme_values.data(), result.data(), 0.5f, num_samples);
bool all_finite = true;
size_t nan_inf_index = 0;
for (size_t i = 0; i < num_samples; ++i) {
if (std::isnan(result[i]) || std::isinf(result[i])) {
all_finite = false;
nan_inf_index = i;
break;
}
}
EXPECT_TRUE(all_finite)
<< "增益处理后在位置" << nan_inf_index << "存在NaN或Inf";
}
/**
* ========================================
* 一致性测试(标量 vs SIMD
* ========================================
*/
#if ALICHO_PLATFORM_X86
// 测试x86 SIMD版本与标量版的一致性
TEST_F(AudioProcessingTest, X86SimdConsistency) {
const size_t num_samples = 1024;
auto src1 = data_gen.generate_sine_wave(num_samples, 440.0f);
auto src2 = data_gen.generate_sine_wave(num_samples, 880.0f);
auto stereo_src = data_gen.generate_stereo_test_data(num_samples);
aligned_audio_buffer scalar_result(num_samples);
aligned_audio_buffer sse_result(num_samples);
aligned_audio_buffer avx_result(num_samples);
std::vector<float, aligned_allocator<float, ALIGNMENT_AVX512>> avx512_result(num_samples);
// 测试 mix_audio 一致性
scalar_audio_processing_func::mix_audio(src1.data(), src2.data(), scalar_result.data(), num_samples);
x86_simd_audio_processing_func::mix_audio_sse(src1.data(), src2.data(), sse_result.data(), num_samples);
x86_simd_audio_processing_func::mix_audio_avx(src1.data(), src2.data(), avx_result.data(), num_samples);
x86_simd_audio_processing_func::mix_audio_avx512(src1.data(), src2.data(), avx512_result.data(), num_samples);
EXPECT_TRUE(arrays_equal(scalar_result.data(), sse_result.data(), num_samples))
<< "mix_audio SSE版本与标量版本不一致";
EXPECT_TRUE(arrays_equal(scalar_result.data(), avx_result.data(), num_samples))
<< "mix_audio AVX版本与标量版本不一致";
EXPECT_TRUE(arrays_equal(scalar_result.data(), avx512_result.data(), num_samples))
<< "mix_audio AVX512版本与标量版本不一致";
// 测试 apply_gain 一致性
const float gain = 0.75f;
scalar_audio_processing_func::apply_gain(src1.data(), scalar_result.data(), gain, num_samples);
x86_simd_audio_processing_func::apply_gain_sse(src1.data(), sse_result.data(), gain, num_samples);
x86_simd_audio_processing_func::apply_gain_avx(src1.data(), avx_result.data(), gain, num_samples);
x86_simd_audio_processing_func::apply_gain_avx512(src1.data(), avx512_result.data(), gain, num_samples);
EXPECT_TRUE(arrays_equal(scalar_result.data(), sse_result.data(), num_samples))
<< "apply_gain SSE版本与标量版本不一致";
EXPECT_TRUE(arrays_equal(scalar_result.data(), avx_result.data(), num_samples))
<< "apply_gain AVX版本与标量版本不一致";
EXPECT_TRUE(arrays_equal(scalar_result.data(), avx512_result.data(), num_samples))
<< "apply_gain AVX512版本与标量版本不一致";
// 测试 calculate_rms 一致性
float scalar_rms = scalar_audio_processing_func::calculate_rms(src1.data(), num_samples);
float sse_rms = x86_simd_audio_processing_func::calculate_rms_sse(src1.data(), num_samples);
float avx_rms = x86_simd_audio_processing_func::calculate_rms_avx(src1.data(), num_samples);
float avx512_rms = x86_simd_audio_processing_func::calculate_rms_avx512(src1.data(), num_samples);
EXPECT_TRUE(float_equal(scalar_rms, sse_rms, RMS_TOLERANCE))
<< "calculate_rms SSE版本与标量版本不一致: " << scalar_rms << " vs " << sse_rms;
EXPECT_TRUE(float_equal(scalar_rms, avx_rms, RMS_TOLERANCE))
<< "calculate_rms AVX版本与标量版本不一致: " << scalar_rms << " vs " << avx_rms;
EXPECT_TRUE(float_equal(scalar_rms, avx512_rms, RMS_TOLERANCE))
<< "calculate_rms AVX512版本与标量版本不一致: " << scalar_rms << " vs " << avx512_rms;
// 测试 calculate_peak 一致性
float scalar_peak = scalar_audio_processing_func::calculate_peak(src1.data(), num_samples);
float sse_peak = x86_simd_audio_processing_func::calculate_peak_sse(src1.data(), num_samples);
float avx_peak = x86_simd_audio_processing_func::calculate_peak_avx(src1.data(), num_samples);
float avx512_peak = x86_simd_audio_processing_func::calculate_peak_avx512(src1.data(), num_samples);
EXPECT_TRUE(float_equal(scalar_peak, sse_peak, PEAK_TOLERANCE))
<< "calculate_peak SSE版本与标量版本不一致: " << scalar_peak << " vs " << sse_peak;
EXPECT_TRUE(float_equal(scalar_peak, avx_peak, PEAK_TOLERANCE))
<< "calculate_peak AVX版本与标量版本不一致: " << scalar_peak << " vs " << avx_peak;
EXPECT_TRUE(float_equal(scalar_peak, avx512_peak, PEAK_TOLERANCE))
<< "calculate_peak AVX512版本与标量版本不一致: " << scalar_peak << " vs " << avx512_peak;
}
#endif // ALICHO_PLATFORM_X86
#if ALICHO_PLATFORM_ARM
// 测试ARM NEON版本与标量版的一致性
TEST_F(AudioProcessingTest, ArmSimdConsistency) {
const size_t num_samples = 1024;
auto src1 = data_gen.generate_sine_wave(num_samples, 440.0f);
auto src2 = data_gen.generate_sine_wave(num_samples, 880.0f);
aligned_audio_buffer scalar_result(num_samples);
aligned_audio_buffer neon_result(num_samples);
// 测试 mix_audio 一致性
scalar_audio_processing_func::mix_audio(src1.data(), src2.data(), scalar_result.data(), num_samples);
arm_simd_audio_processing_func::mix_audio_neon(src1.data(), src2.data(), neon_result.data(), num_samples);
EXPECT_TRUE(arrays_equal(scalar_result.data(), neon_result.data(), num_samples))
<< "mix_audio NEON版本与标量版不一致";
// 测试 apply_gain 一致性
const float gain = 0.75f;
scalar_audio_processing_func::apply_gain(src1.data(), scalar_result.data(), gain, num_samples);
arm_simd_audio_processing_func::apply_gain_neon(src1.data(), neon_result.data(), gain, num_samples);
EXPECT_TRUE(arrays_equal(scalar_result.data(), neon_result.data(), num_samples))
<< "apply_gain NEON版本与标量版不一致";
// 测试 calculate_rms 一致性
float scalar_rms = scalar_audio_processing_func::calculate_rms(src1.data(), num_samples);
float neon_rms = arm_simd_audio_processing_func::calculate_rms_neon(src1.data(), num_samples);
EXPECT_TRUE(float_equal(scalar_rms, neon_rms, RMS_TOLERANCE))
<< "calculate_rms NEON版本与标量版不一致: " << scalar_rms << " vs " << neon_rms;
// 测试 calculate_peak 一致性
float scalar_peak = scalar_audio_processing_func::calculate_peak(src1.data(), num_samples);
float neon_peak = arm_simd_audio_processing_func::calculate_peak_neon(src1.data(), num_samples);
EXPECT_TRUE(float_equal(scalar_peak, neon_peak, PEAK_TOLERANCE))
<< "calculate_peak NEON版本与标量版不一致: " << scalar_peak << " vs " << neon_peak;
}
#endif // ALICHO_PLATFORM_ARM
/**
* ========================================
* 性能测试
* ========================================
*/
// 性能测试运行为 TEST_F 测试,但不使用 EXPECT/ASSERT
TEST_F(AudioProcessingTest, PerformanceTests) {
std::cout << "\n=== 性能测试 ===" << std::endl;
// 生成大量测试数据
auto src1 = data_gen.generate_sine_wave(PERF_TEST_SIZE, 440.0f);
auto src2 = data_gen.generate_sine_wave(PERF_TEST_SIZE, 880.0f);
aligned_audio_buffer result(PERF_TEST_SIZE);
// 性能测试mix_audio
{
double scalar_time = perf_tester.measure_execution_time([&]() {
scalar_audio_processing_func::mix_audio(src1.data(), src2.data(), result.data(), PERF_TEST_SIZE);
});
#if ALICHO_PLATFORM_X86
double sse_time = perf_tester.measure_execution_time([&]() {
x86_simd_audio_processing_func::mix_audio_sse(src1.data(), src2.data(), result.data(), PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("mix_audio (SSE vs Scalar)", scalar_time, sse_time);
double avx_time = perf_tester.measure_execution_time([&]() {
x86_simd_audio_processing_func::mix_audio_avx(src1.data(), src2.data(), result.data(), PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("mix_audio (AVX vs Scalar)", scalar_time, avx_time);
double avx512_time = perf_tester.measure_execution_time([&]() {
x86_simd_audio_processing_func::mix_audio_avx512(src1.data(), src2.data(), result.data(), PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("mix_audio (AVX512 vs Scalar)", scalar_time, avx512_time);
#endif
#if ALICHO_PLATFORM_ARM
double neon_time = perf_tester.measure_execution_time([&]() {
arm_simd_audio_processing_func::mix_audio_neon(src1.data(), src2.data(), result.data(), PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("mix_audio (NEON vs Scalar)", scalar_time, neon_time);
#endif
}
// 性能测试apply_gain
{
const float gain = 0.5f;
double scalar_time = perf_tester.measure_execution_time([&]() {
scalar_audio_processing_func::apply_gain(src1.data(), result.data(), gain, PERF_TEST_SIZE);
});
#if ALICHO_PLATFORM_X86
double sse_time = perf_tester.measure_execution_time([&]() {
x86_simd_audio_processing_func::apply_gain_sse(src1.data(), result.data(), gain, PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("apply_gain (SSE vs Scalar)", scalar_time, sse_time);
double avx_time = perf_tester.measure_execution_time([&]() {
x86_simd_audio_processing_func::apply_gain_avx(src1.data(), result.data(), gain, PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("apply_gain (AVX vs Scalar)", scalar_time, avx_time);
double avx512_time = perf_tester.measure_execution_time([&]() {
x86_simd_audio_processing_func::apply_gain_avx512(src1.data(), result.data(), gain, PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("apply_gain (AVX512 vs Scalar)", scalar_time, avx512_time);
#endif
#if ALICHO_PLATFORM_ARM
double neon_time = perf_tester.measure_execution_time([&]() {
arm_simd_audio_processing_func::apply_gain_neon(src1.data(), result.data(), gain, PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("apply_gain (NEON vs Scalar)", scalar_time, neon_time);
#endif
}
// 性能测试calculate_rms
{
double scalar_time = perf_tester.measure_execution_time([&]() {
scalar_audio_processing_func::calculate_rms(src1.data(), PERF_TEST_SIZE);
});
#if ALICHO_PLATFORM_X86
double sse_time = perf_tester.measure_execution_time([&]() {
x86_simd_audio_processing_func::calculate_rms_sse(src1.data(), PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("calculate_rms (SSE vs Scalar)", scalar_time, sse_time);
double avx_time = perf_tester.measure_execution_time([&]() {
x86_simd_audio_processing_func::calculate_rms_avx(src1.data(), PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("calculate_rms (AVX vs Scalar)", scalar_time, avx_time);
double avx512_time = perf_tester.measure_execution_time([&]() {
x86_simd_audio_processing_func::calculate_rms_avx512(src1.data(), PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("calculate_rms (AVX512 vs Scalar)", scalar_time, avx512_time);
#endif
#if ALICHO_PLATFORM_ARM
double neon_time = perf_tester.measure_execution_time([&]() {
arm_simd_audio_processing_func::calculate_rms_neon(src1.data(), PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("calculate_rms (NEON vs Scalar)", scalar_time, neon_time);
#endif
}
// 性能测试calculate_peak
{
double scalar_time = perf_tester.measure_execution_time([&]() {
scalar_audio_processing_func::calculate_peak(src1.data(), PERF_TEST_SIZE);
});
#if ALICHO_PLATFORM_X86
double sse_time = perf_tester.measure_execution_time([&]() {
x86_simd_audio_processing_func::calculate_peak_sse(src1.data(), PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("calculate_peak (SSE vs Scalar)", scalar_time, sse_time);
double avx_time = perf_tester.measure_execution_time([&]() {
x86_simd_audio_processing_func::calculate_peak_avx(src1.data(), PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("calculate_peak (AVX vs Scalar)", scalar_time, avx_time);
double avx512_time = perf_tester.measure_execution_time([&]() {
x86_simd_audio_processing_func::calculate_peak_avx512(src1.data(), PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("calculate_peak (AVX512 vs Scalar)", scalar_time, avx512_time);
#endif
#if ALICHO_PLATFORM_ARM
double neon_time = perf_tester.measure_execution_time([&]() {
arm_simd_audio_processing_func::calculate_peak_neon(src1.data(), PERF_TEST_SIZE);
});
perf_tester.print_performance_comparison("calculate_peak (NEON vs Scalar)", scalar_time, neon_time);
#endif
}
}