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");
}
注意事项
- 该库提供了从C移植的绑定接口,某些API可能不够Rust风格
- 质量参数范围是0-10,数值越高质量越好但CPU消耗也越大
- 需要处理可能的剩余数据,特别是在音频流结束时
该库采用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);
// 这里可以添加保存或播放重采样后音频的代码
}
注意事项
- 输入和输出缓冲区必须是连续的切片
- 多通道数据必须是交错的
- 质量设置越高,CPU使用率越高
- 创建重采样器相对昂贵,应重用实例
speexdsp-resampler
是处理音频重采样任务的高效工具,特别适合需要实时处理或高质量转换的场景。