403 lines
17 KiB
C++
403 lines
17 KiB
C++
// ================================================================================================
|
||
// 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;
|
||
} |