Rust音频处理库speexdsp-resampler的使用:高性能音频重采样与DSP处理

Rust音频处理库speexdsp-resampler的使用:高性能音频重采样与DSP处理

speexdsp-resampler是基于c2rust工具移植的speexdsp音频重采样库的Rust绑定。

特性

  • [x] 简单的绑定接口
  • [x] 安全抽象
  • [x] 使用示例
  • [ ] 更干净的代码
  • [ ] 更全面的API覆盖

安装

在Cargo.toml中添加依赖:

speexdsp-resampler = "0.1.0"

或者运行:

cargo add speexdsp-resampler

示例代码

以下是一个完整的音频重采样示例:

use speexdsp_resampler::Resampler;

fn main() {
    // 输入音频参数
    let in_rate = 44100; // 输入采样率
    let out_rate = 48000; // 输出采样率
    let channels = 2; // 声道数
    let quality = 10; // 质量等级(0-10)
    
    // 创建重采样器
    let mut resampler = Resampler::new(
        channels as u32,
        in_rate as u32,
        out_rate as u32,
        quality,
    ).expect("Failed to create resampler");

    // 示例输入音频数据(双声道)
    let input: Vec<i16> = vec![0; 4410 * 2]; // 0.1秒的静音
    let mut output = vec![0i16; 4800 * 2]; // 输出缓冲区
    
    // 执行重采样
    let (in_len, out_len) = resampler.process_interleaved(
        0, // 输入帧偏移
        &input,
        &mut output,
    ).expect("Resampling failed");
    
    println!("Processed {} input frames to {} output frames", in_len, out_len);
}

更复杂的示例

以下是一个处理真实音频数据的完整示例:

use speexdsp_resampler::Resampler;

fn main() {
    // 假设我们有一些PCM音频数据
    let input_samples = vec![0i16; 44100 * 2]; // 1秒立体声音频
    let input_rate = 44100;
    let output_rate = 48000;
    
    // 计算输出缓冲区大小
    let ratio = output_rate as f32 / input_rate as f32;
    let out_len = (input_samples.len() as f32 * ratio).ceil() as usize;
    let mut output = vec![0i16; out_len];
    
    // 创建高质量重采样器
    let mut resampler = Resampler::new(
        2,          // 立体声
        input_rate, 
        output_rate,
        10,         // 最高质量
    ).unwrap();
    
    // 处理音频
    let (in_processed, out_processed) = resampler
        .process_interleaved(0, &input_samples, &mut output)
        .unwrap();
    
    println!("Resampled {} frames to {} frames", 
        in_processed, 
        out_processed
    );
    
    // 如果需要,可以处理剩余的数据
    let mut remaining_output = vec![0i16; resampler.get_output_len().unwrap()];
    let (_, remaining_out) = resampler
        .process_interleaved(
            in_processed, 
            &[], 
            &mut remaining_output
        )
        .unwrap();
    
    println!("Processed remaining {} frames", remaining_out);
}

完整示例代码

以下是结合上述示例的完整音频重采样实现:

use speexdsp_resampler::Resampler;
use std::fs::File;
use std::io::Read;
use std::path::Path;

fn main() {
    // 1. 读取音频文件(PCM格式)
    let audio_path = Path::new("input.pcm");
    let mut audio_file = File::open(audio_path).expect("无法打开音频文件");
    let mut input_buffer = Vec::new();
    audio_file.read_to_end(&mut input_buffer).expect("读取音频文件失败");
    
    // 转换为i16样本(假设是16位PCM)
    let input_samples: Vec<i16> = input_buffer
        .chunks_exact(2)
        .map(|chunk| i16::from_le_bytes([chunk[0], chunk[1]]))
        .collect();
    
    // 2. 设置重采样参数
    let input_rate = 44100;
    let output_rate = 48000;
    let channels = 2; // 立体声
    let quality = 8; // 平衡质量和性能
    
    // 3. 创建重采样器
    let mut resampler = Resampler::new(
        channels,
        input_rate,
        output_rate,
        quality,
    ).expect("创建重采样器失败");
    
    // 4. 计算输出缓冲区大小
    let ratio = output_rate as f32 / input_rate as f32;
    let out_len = (input_samples.len() as f32 * ratio).ceil() as usize;
    let mut output = vec![0i16; out_len];
    
    // 5. 执行重采样
    let (in_processed, out_processed) = resampler
        .process_interleaved(0, &input_samples, &mut output)
        .expect("重采样失败");
    
    println!("已处理 {} 个输入帧到 {} 个输出帧", in_processed, out_processed);
    
    // 6. 处理剩余数据
    let remaining_len = resampler.get_output_len().expect("获取剩余长度失败");
    if remaining_len > 0 {
        let mut remaining_output = vec![0i16; remaining_len];
        let (_, remaining_out) = resampler
            .process_interleaved(in_processed, &[], &mut remaining_output)
            .expect("处理剩余数据失败");
        
        println!("处理了剩余的 {} 帧", remaining_out);
        
        // 合并输出
        output.extend_from_slice(&remaining_output);
    }
    
    // 7. 保存重采样后的音频
    let output_path = Path::new("output.pcm");
    let mut output_file = File::create(output_path).expect("无法创建输出文件");
    
    // 将i16转换为字节
    let output_bytes: Vec<u8> = output
        .iter()
        .flat_map(|sample| sample.to_le_bytes().to_vec())
        .collect();
    
    output_file.write_all(&output_bytes).expect("写入输出文件失败");
    println!("重采样完成,结果已保存到 output.pcm");
}

注意事项

  1. 该库提供了从C移植的绑定接口,某些API可能不够Rust风格
  2. 质量参数范围是0-10,数值越高质量越好但CPU消耗也越大
  3. 需要处理可能的剩余数据,特别是在音频流结束时

该库采用BSD-3-Clause许可证,适合需要高性能音频重采样的Rust项目。


1 回复

Rust音频处理库speexdsp-resampler的使用:高性能音频重采样与DSP处理

speexdsp-resampler 是一个 Rust 封装的 SpeexDSP 音频处理库,主要用于高性能音频重采样和数字信号处理(DSP)操作。

主要特性

  • 高性能音频重采样
  • 支持任意采样率转换
  • 低延迟处理
  • 良好的抗混叠滤波
  • 支持浮点和16位整数输入

安装

Cargo.toml 中添加依赖:

[dependencies]
speexdsp-resampler = "0.7"

基本使用方法

1. 创建重采样器

use speexdsp_resampler::Resampler;

// 创建重采样器
// 参数: 输入通道数, 输入采样率, 输出采样率, 质量(0-10)
let mut resampler = Resampler::new(1, 44100, 48000, 10).unwrap();

2. 执行重采样

// 输入音频数据(假设是单通道44100Hz的音频)
let input: Vec<f32> = vec![0.0; 1024]; // 示例输入数据

// 计算输出缓冲区大小
let output_len = resampler.output_len(input.len()).unwrap();
let mut output = vec![0.0f32; output_len];

// 执行重采样
let (input_used, output_used) = resampler.process_float(0, &input, &mut output).unwrap();

println!("处理了 {} 个输入样本,生成 {} 个输出样本", input_used, output_used);

高级用法

多通道处理

// 创建立体声重采样器
let mut stereo_resampler = Resampler::new(2, 44100, 48000, 10).unwrap();

// 交错格式的立体声数据(左、右、左、右...)
let stereo_input = vec![0.0f32; 2048]; // 1024帧立体声
let stereo_output_len = stereo_resampler.output_len(1024).unwrap() * 2;
let mut stereo_output = vec![0.0f32; stereo_output_len];

// 处理立体声数据
let (in_used, out_used) = stereo_resampler.process_float(0, &stereo_input, &mut stereo_output).unwrap();

使用整数输入

use speexdsp_resampler::Resampler;

let mut resampler = Resampler::new(1, 44100, 48000, 8).unwrap();

let input: Vec<i16> = vec![0; 1024]; // 16位整数输入
let output_len = resampler.output_len(input.len()).unwrap();
let mut output = vec![0i16; output_len];

let (input_used, output_used) = resampler.process_int(0, &input, &mut output).unwrap();

质量设置

质量参数范围是0-10,影响性能和重采样质量:

  • 0: 最低质量,最快
  • 10: 最高质量,最慢
  • 通常4-6是质量与性能的良好平衡
// 中等质量设置
let mut resampler = Resampler::new(1, 44100, 48000, 5).unwrap();

实时音频处理示例

use speexdsp_resampler::Resampler;

fn process_audio_chunk(input: &[f32], in_rate: u32, out_rate: u32) -> Vec<f32> {
    let mut resampler = Resampler::new(1, in_rate, out_rate, 7).unwrap();
    let output_len = resampler.output_len(input.len()).unwrap();
    let mut output = vec![0.0f32; output_len];
    
    let (_, out_used) = resampler.process_float(0, input, &mut output).unwrap();
    output.truncate(out_used);
    output
}

完整示例demo

下面是一个完整的音频重采样示例,包含从生成测试音频到重采样的完整流程:

use speexdsp_resampler::Resampler;
use std::f32::consts::PI;

// 生成测试音频信号 - 正弦波
fn generate_sine_wave(sample_rate: u32, frequency: f32, duration: f32) -> Vec<f32> {
    let num_samples = (sample_rate as f32 * duration) as usize;
    let mut samples = Vec::with_capacity(num_samples);
    
    for i in 0..num_samples {
        let t = i as f32 / sample_rate as f32;
        samples.push((2.0 * PI * frequency * t).sin() * 0.5); // 0.5是振幅
    }
    
    samples
}

fn main() {
    // 1. 生成测试音频(44100Hz, 440Hz正弦波)
    let input_sample_rate = 44100;
    let sine_wave = generate_sine_wave(input_sample_rate, 440.0, 1.0); // 1秒音频
    
    // 2. 创建重采样器(44100 -> 48000)
    let output_sample_rate = 48000;
    let quality = 6; // 中等质量
    let mut resampler = Resampler::new(1, input_sample_rate, output_sample_rate, quality).unwrap();
    
    // 3. 计算输出缓冲区大小
    let output_len = resampler.output_len(sine_wave.len()).unwrap();
    let mut output = vec![0.0f32; output_len];
    
    // 4. 执行重采样
    let (input_used, output_used) = resampler.process_float(0, &sine_wave, &mut output).unwrap();
    
    // 5. 截取实际使用的输出
    output.truncate(output_used);
    
    println!("重采样完成!");
    println!("输入样本数: {}, 输出样本数: {}", input_used, output_used);
    println!("输入采样率: {}Hz, 输出采样率: {}Hz", input_sample_rate, output_sample_rate);
    
    // 这里可以添加保存或播放重采样后音频的代码
}

注意事项

  1. 输入和输出缓冲区必须是连续的切片
  2. 多通道数据必须是交错的
  3. 质量设置越高,CPU使用率越高
  4. 创建重采样器相对昂贵,应重用实例

speexdsp-resampler 是处理音频重采样任务的高效工具,特别适合需要实时处理或高质量转换的场景。

回到顶部