Files
Alicho/examples/simd_audio_processing_demo.cpp
2025-10-28 10:27:49 +08:00

403 lines
17 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 - SIMD音频处理示例
// ================================================================================================
// 描述: 演示SIMD优化的音频处理函数及性能对比
// 功能: 音频混音、增益控制、格式转换、效果处理
// ================================================================================================
#include "simd/audio_processing.h"
#include "common/logger.h"
#include <iostream>
#include <vector>
#include <random>
#include <chrono>
#include <functional>
#include <iomanip>
#include <algorithm>
#include <cmath>
using namespace audio_backend;
using namespace audio_backend::simd;
// 辅助函数:生成正弦波测试数据
void generate_sine_wave(float* buffer, size_t frames, uint16_t channels,
float frequency, float sample_rate, float amplitude = 0.5f) {
for (size_t i = 0; i < frames; ++i) {
float value = amplitude * std::sin(2.0f * 3.14159f * frequency * i / sample_rate);
for (uint16_t c = 0; c < channels; ++c) {
buffer[i * channels + c] = value;
}
}
}
// 辅助函数:测量函数执行时间(微秒)
template<typename Func, typename... Args>
double measure_execution_time(size_t iterations, Func&& func, Args&&... args) {
auto start = std::chrono::high_resolution_clock::now();
for (size_t i = 0; i < iterations; ++i) {
func(std::forward<Args>(args)...);
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
return static_cast<double>(duration.count()) / iterations;
}
// 标量实现无SIMD的音频混音
void mix_audio_scalar(const float* input1, const float* input2, float* output, size_t samples) {
for (size_t i = 0; i < samples; ++i) {
output[i] = input1[i] + input2[i];
}
}
// 标量实现无SIMD的音频增益
void apply_gain_scalar(const float* input, float gain, float* output, size_t samples) {
for (size_t i = 0; i < samples; ++i) {
output[i] = input[i] * gain;
}
}
// 标量实现无SIMD的格式转换(float32 -> int16)
void convert_f32_to_i16_scalar(const float* input, int16_t* output, size_t samples) {
for (size_t i = 0; i < samples; ++i) {
float sample = input[i] * 32767.0f;
if (sample > 32767.0f) sample = 32767.0f;
if (sample < -32768.0f) sample = -32768.0f;
output[i] = static_cast<int16_t>(sample);
}
}
// ================================================================================================
// 音频混音演示
// ================================================================================================
void demo_audio_mixing() {
std::cout << "\n=== 音频混音演示 ===\n";
// 创建音频缓冲区
const size_t buffer_size = 48000 * 10; // 10秒的音频 @ 48kHz
const size_t channels = 2; // 立体声
// 创建对齐的缓冲区
AudioBufferF32 buffer1(channels, buffer_size / channels);
AudioBufferF32 buffer2(channels, buffer_size / channels);
AudioBufferF32 output_buffer(channels, buffer_size / channels);
// 检查内存对齐
std::cout << "缓冲区1内存对齐: " << (buffer1.is_properly_aligned() ? "" : "") << std::endl;
std::cout << "缓冲区2内存对齐: " << (buffer2.is_properly_aligned() ? "" : "") << std::endl;
std::cout << "输出缓冲区内存对齐: " << (output_buffer.is_properly_aligned() ? "" : "") << std::endl;
// 生成测试数据 - 两个不同频率的音调
generate_sine_wave(buffer1.data(), buffer_size, channels, 440.0f, 48000.0f, 0.25f); // A4 音符
generate_sine_wave(buffer2.data(), buffer_size, channels, 554.37f, 48000.0f, 0.25f); // C#5 音符
// 性能对比
const size_t iterations = 100;
// 标量实现
double scalar_time = measure_execution_time(iterations, mix_audio_scalar,
buffer1.data(), buffer2.data(), output_buffer.data(),
buffer_size);
// SIMD实现自动选择最佳版本
double simd_time = measure_execution_time(iterations,
[&](const float* a, const float* b, float* out, size_t n) {
CALL_SIMD_AUDIO_FUNCTION(mix_audio_f32, a, b, out, n);
},
buffer1.data(), buffer2.data(), output_buffer.data(), buffer_size);
// 计算加速比
double speedup = scalar_time / simd_time;
std::cout << "混音性能对比 (10秒音频 x " << iterations << " 次迭代):" << std::endl;
std::cout << " 标量实现: " << std::fixed << std::setprecision(2) << scalar_time << " 微秒" << std::endl;
std::cout << " SIMD优化: " << std::fixed << std::setprecision(2) << simd_time << " 微秒" << std::endl;
std::cout << " 加速比: " << std::fixed << std::setprecision(2) << speedup << "x" << std::endl;
// 检验结果
std::cout << "\n混音结果检验 (前10个样本):" << std::endl;
// 使用SIMD函数重新混音
CALL_SIMD_AUDIO_FUNCTION(mix_audio_f32, buffer1.data(), buffer2.data(), output_buffer.data(), 10 * channels);
for (size_t i = 0; i < 10; ++i) {
std::cout << " 样本 " << i << ": " << buffer1.data()[i] << " + "
<< buffer2.data()[i] << " = " << output_buffer.data()[i] << std::endl;
}
}
// ================================================================================================
// 音频增益控制演示
// ================================================================================================
void demo_gain_control() {
std::cout << "\n=== 音频增益控制演示 ===\n";
// 创建音频缓冲区
const size_t buffer_size = 48000 * 5; // 5秒的音频 @ 48kHz
// 创建对齐的缓冲区
AlignedBuffer<float, ALIGNMENT_AVX> input_buffer(buffer_size);
AlignedBuffer<float, ALIGNMENT_AVX> output_buffer(buffer_size);
// 生成测试数据 - 440Hz正弦波
generate_sine_wave(input_buffer.data(), buffer_size, 1, 440.0f, 48000.0f, 0.5f);
// 应用不同类型的增益控制
const float gain = 0.8f; // 降低音量到80%
std::cout << "1. 恒定增益:" << std::endl;
// 对比标量和SIMD实现
const size_t iterations = 200;
// 标量实现
double scalar_time = measure_execution_time(iterations, apply_gain_scalar,
input_buffer.data(), gain, output_buffer.data(),
buffer_size);
// SIMD实现
double simd_time = measure_execution_time(iterations,
[&](const float* in, float g, float* out, size_t n) {
CALL_SIMD_AUDIO_FUNCTION(apply_gain_f32, in, g, out, n);
},
input_buffer.data(), gain, output_buffer.data(), buffer_size);
// 计算加速比
double speedup = scalar_time / simd_time;
std::cout << " 增益控制性能对比 (5秒音频 x " << iterations << " 次迭代):" << std::endl;
std::cout << " 标量实现: " << std::fixed << std::setprecision(2) << scalar_time << " 微秒" << std::endl;
std::cout << " SIMD优化: " << std::fixed << std::setprecision(2) << simd_time << " 微秒" << std::endl;
std::cout << " 加速比: " << std::fixed << std::setprecision(2) << speedup << "x" << std::endl;
// 渐变增益示例
std::cout << "\n2. 渐变增益 (淡入):" << std::endl;
const float start_gain = 0.0f;
const float end_gain = 1.0f;
// 测量SIMD实现的渐变增益性能
double ramp_time = measure_execution_time(iterations,
[&](const float* in, float start, float end, float* out, size_t n) {
CALL_SIMD_AUDIO_FUNCTION(apply_gain_ramp_f32, in, start, end, out, n);
},
input_buffer.data(), start_gain, end_gain, output_buffer.data(), buffer_size);
std::cout << " 渐变增益 (SIMD优化): " << std::fixed << std::setprecision(2) << ramp_time << " 微秒" << std::endl;
// 应用渐变增益并显示结果
CALL_SIMD_AUDIO_FUNCTION(apply_gain_ramp_f32, input_buffer.data(), start_gain, end_gain,
output_buffer.data(), buffer_size);
std::cout << " 淡入效果样本值 (10等分点):" << std::endl;
for (size_t i = 0; i < 10; ++i) {
size_t index = i * buffer_size / 10;
std::cout << " " << std::fixed << std::setprecision(2)
<< (static_cast<float>(i) / 10.0f * 100.0f) << "% 位置: 原始="
<< input_buffer.data()[index] << ", 淡入后="
<< output_buffer.data()[index] << std::endl;
}
}
// ================================================================================================
// 格式转换演示
// ================================================================================================
void demo_format_conversion() {
std::cout << "\n=== 格式转换演示 ===\n";
// 创建音频缓冲区
const size_t buffer_size = 48000 * 8; // 8秒的音频 @ 48kHz
// 创建对齐的缓冲区
AlignedBuffer<float, ALIGNMENT_AVX> float_buffer(buffer_size);
AlignedBuffer<int16_t, ALIGNMENT_AVX> int16_buffer(buffer_size);
AlignedBuffer<int32_t, ALIGNMENT_AVX> int32_buffer(buffer_size);
// 生成测试数据 - 包含多个频率的复合波形
for (size_t i = 0; i < buffer_size; ++i) {
// 440Hz (A4) + 554.37Hz (C#5) + 659.25Hz (E5) = A major chord
float t = static_cast<float>(i) / 48000.0f;
float_buffer[i] = 0.2f * std::sin(2.0f * 3.14159f * 440.0f * t) +
0.15f * std::sin(2.0f * 3.14159f * 554.37f * t) +
0.15f * std::sin(2.0f * 3.14159f * 659.25f * t);
}
// 测量格式转换性能 (float32 -> int16)
const size_t iterations = 100;
// 标量实现
double scalar_time = measure_execution_time(iterations, convert_f32_to_i16_scalar,
float_buffer.data(), int16_buffer.data(),
buffer_size);
// SIMD实现
double simd_time = measure_execution_time(iterations,
[&](const float* in, int16_t* out, size_t n) {
CALL_SIMD_AUDIO_FUNCTION(convert_f32_to_i16, in, out, n);
},
float_buffer.data(), int16_buffer.data(), buffer_size);
// 计算加速比
double speedup = scalar_time / simd_time;
std::cout << "Float32 -> Int16 性能对比 (8秒音频 x " << iterations << " 次迭代):" << std::endl;
std::cout << " 标量实现: " << std::fixed << std::setprecision(2) << scalar_time << " 微秒" << std::endl;
std::cout << " SIMD优化: " << std::fixed << std::setprecision(2) << simd_time << " 微秒" << std::endl;
std::cout << " 加速比: " << std::fixed << std::setprecision(2) << speedup << "x" << std::endl;
// 应用转换并检查结果
CALL_SIMD_AUDIO_FUNCTION(convert_f32_to_i16, float_buffer.data(), int16_buffer.data(), 20);
std::cout << "\n转换结果对比 (前5个样本):" << std::endl;
for (size_t i = 0; i < 5; ++i) {
// 标量转换
int16_t scalar_result;
convert_f32_to_i16_scalar(&float_buffer[i], &scalar_result, 1);
// 显示对比
std::cout << " 样本 " << i << ": Float=" << float_buffer[i]
<< ", Int16(标量)=" << scalar_result
<< ", Int16(SIMD)=" << int16_buffer[i]
<< std::endl;
}
// Float32 -> Int32 转换
CALL_SIMD_AUDIO_FUNCTION(convert_f32_to_i32, float_buffer.data(), int32_buffer.data(), buffer_size);
std::cout << "\nFloat32 -> Int32 转换 (前3个样本):" << std::endl;
for (size_t i = 0; i < 3; ++i) {
std::cout << " 样本 " << i << ": Float=" << float_buffer[i]
<< ", Int32=" << int32_buffer[i]
<< std::endl;
}
}
// ================================================================================================
// 音频分析功能演示
// ================================================================================================
void demo_audio_analysis() {
std::cout << "\n=== 音频分析功能演示 ===\n";
// 创建音频缓冲区
const size_t buffer_size = 48000; // 1秒的音频 @ 48kHz
// 创建对齐的缓冲区
AlignedBuffer<float, ALIGNMENT_AVX> audio_buffer(buffer_size);
// 生成测试数据 - 添加一些不同的波形和噪声
std::default_random_engine generator;
std::uniform_real_distribution<float> distribution(-0.05f, 0.05f);
// 基本波形 + 少量噪声
for (size_t i = 0; i < buffer_size; ++i) {
float t = static_cast<float>(i) / 48000.0f;
audio_buffer[i] = 0.5f * std::sin(2.0f * 3.14159f * 440.0f * t) + distribution(generator);
}
// 计算RMS电平
float rms = CALL_SIMD_AUDIO_FUNCTION(calculate_rms_f32, audio_buffer.data(), buffer_size);
// 计算峰值电平
float peak = CALL_SIMD_AUDIO_FUNCTION(calculate_peak_f32, audio_buffer.data(), buffer_size);
std::cout << "基本音频分析:" << std::endl;
std::cout << " RMS电平: " << std::fixed << std::setprecision(4) << rms << std::endl;
std::cout << " 峰值电平: " << std::fixed << std::setprecision(4) << peak << std::endl;
std::cout << " 峰值因数(Crest Factor): " << std::fixed << std::setprecision(2) << (peak / rms) << " dB" << std::endl;
// 检测静音和削波
bool is_silent = CALL_SIMD_AUDIO_FUNCTION(detect_silence_f32, audio_buffer.data(), buffer_size);
bool is_clipping = CALL_SIMD_AUDIO_FUNCTION(detect_clipping_f32, audio_buffer.data(), buffer_size);
std::cout << "信号特性:" << std::endl;
std::cout << " 静音检测: " << (is_silent ? "" : "") << std::endl;
std::cout << " 削波检测: " << (is_clipping ? "" : "") << std::endl;
// 创建一些有削波的音频用于测试
for (size_t i = buffer_size / 2; i < buffer_size / 2 + 1000; ++i) {
audio_buffer[i] = 1.2f; // 值超过1.0,产生削波
}
// 再次检测削波
is_clipping = CALL_SIMD_AUDIO_FUNCTION(detect_clipping_f32, audio_buffer.data(), buffer_size);
std::cout << " 添加削波后检测: " << (is_clipping ? "" : "") << std::endl;
// 计算新的峰值
peak = CALL_SIMD_AUDIO_FUNCTION(calculate_peak_f32, audio_buffer.data(), buffer_size);
std::cout << " 新的峰值电平: " << std::fixed << std::setprecision(4) << peak << std::endl;
}
// ================================================================================================
// SIMD函数调度系统演示
// ================================================================================================
void demo_function_dispatcher() {
std::cout << "\n=== SIMD函数调度系统演示 ===\n";
// 注册系统支持的SIMD函数
AudioProcessingRegistry::register_all_functions();
// 打印可用函数
AudioProcessingRegistry::print_available_functions();
// 获取CPU信息
const CPUInfo& cpu_info = get_cpu_info();
std::cout << "\nCPU信息:" << std::endl;
std::cout << " 厂商: " << cpu_info.vendor << std::endl;
std::cout << " 品牌: " << cpu_info.brand << std::endl;
std::cout << " 最高SIMD级别: ";
switch (cpu_info.max_simd_level) {
case SIMDLevel::NONE: std::cout << "无SIMD支持"; break;
case SIMDLevel::SSE: std::cout << "SSE"; break;
case SIMDLevel::SSE3: std::cout << "SSE3"; break;
case SIMDLevel::SSE4: std::cout << "SSE4"; break;
case SIMDLevel::AVX: std::cout << "AVX"; break;
case SIMDLevel::AVX2: std::cout << "AVX2"; break;
case SIMDLevel::AVX512: std::cout << "AVX512"; break;
case SIMDLevel::NEON: std::cout << "NEON"; break;
case SIMDLevel::NEON_FP16: std::cout << "NEON_FP16"; break;
default: std::cout << "未知"; break;
}
std::cout << std::endl;
std::cout << " 支持的SIMD特性: " << cpu_info.features_string() << std::endl;
}
// ================================================================================================
// 主函数
// ================================================================================================
int main() {
std::cout << "====================================\n";
std::cout << "Audio Backend SIMD音频处理演示\n";
std::cout << "====================================\n";
try {
// 初始化日志系统
common::Logger::instance().initialize("SIMDDemo", common::LogLevel::INFO);
common::log_info("SIMD音频处理演示开始运行");
// 注册所有SIMD优化函数
AudioProcessingRegistry::register_all_functions();
// 运行各个示例
demo_function_dispatcher();
demo_audio_mixing();
demo_gain_control();
demo_format_conversion();
demo_audio_analysis();
std::cout << "\n====================================\n";
std::cout << "演示完成\n";
std::cout << "====================================\n";
common::log_info("SIMD音频处理演示完成");
} catch (const std::exception& e) {
common::log_err("演示过程中发生错误: {}", e.what());
std::cerr << "演示过程中发生错误: " << e.what() << "\n";
return 1;
}
return 0;
}