30 个版本 (14 个稳定版)
1.5.0 | 2023 年 9 月 21 日 |
---|---|
1.4.0 | 2023 年 3 月 5 日 |
1.2.6 | 2022 年 7 月 20 日 |
1.2.3 | 2021 年 11 月 26 日 |
0.4.1 | 2021 年 3 月 30 日 |
#7 在 多媒体 中
每月 852 次下载
在 11 个包 中使用 (8 个直接使用)
110KB
1.5K SLoC
Rust:使用 FFT 进行频谱分析的库
一个易于使用且快速的 no_std
库(包含 alloc
),用于通过 FFT 获取数字信号(例如音频)的频谱。
最小支持的 Rust 版本(MSRV)是 1.63.0
。
我想了解 FFT 如何用于获取频谱
请参阅文件 /EDUCATIONAL.md。
如何使用(包括 no_std
环境)
大多数提示和评论位于代码中,所以请查看 GitHub 上的仓库!无论如何,最基本的用法如下
Cargo.toml
# by default feature "microfft-real" is used
[dependencies]
spectrum-analyzer = "<latest version, see crates.io>"
your_binary.rs
use spectrum_analyzer::{samples_fft_to_spectrum, FrequencyLimit};
use spectrum_analyzer::windows::hann_window;
use spectrum_analyzer::scaling::divide_by_N_sqrt;
/// Minimal example.
fn main() {
// YOU need to implement the samples source; get microphone input for example
let samples: &[f32] = &[0.0, 3.14, 2.718, -1.0, -2.0, -4.0, 7.0, 6.0];
// apply hann window for smoothing; length must be a power of 2 for the FFT
// 2048 is a good starting point with 44100 kHz
let hann_window = hann_window(&samples[0..8]);
// calc spectrum
let spectrum_hann_window = samples_fft_to_spectrum(
// (windowed) samples
&hann_window,
// sampling rate
44100,
// optional frequency limit: e.g. only interested in frequencies 50 <= f <= 150?
FrequencyLimit::All,
// optional scale
Some(÷_by_N_sqrt),
).unwrap();
for (fr, fr_val) in spectrum_hann_window.data().iter() {
println!("{}Hz => {}", fr, fr_val)
}
}
性能
在 i7-1165G7 @ 2.80GHz(单线程)上优化构建的测量结果
我测试了多个 FFT 实现。以下是你为什么决定使用 microfft::real
的原因。它不仅是最快的,而且可以在 no_std
环境中工作。
操作 | 时间 |
---|---|
4096 个样本的汉宁窗口 | ≈68µs |
4096 个样本的汉明窗口 | ≈118µs |
4096 个样本的 FFT(rustfft )到频谱 |
≈170µs |
4096 个样本的 FFT(microfft::real )到频谱 |
≈90µs |
4096 个样本的 FFT(microfft::complex )到频谱 |
≈250µs |
示例可视化
在以下示例中,您可以看到从 0 到 4000Hz
的频谱的基本可视化,用于 44100Hz 采样率下 50Hz、1000Hz 和 3777Hz 正弦波的分层信号。给定频率的峰值清晰可见。每个计算都是使用 2048
个样本完成的,即 ≈46ms 的音频信号。
噪声(错误峰值)也来自添加的正弦波的削顶!
样本上的无窗口函数频谱
峰值(50Hz、1000Hz、3777Hz)清晰可见,但也存在一些噪声。
在FFT之前的样本上使用Hann窗口函数的频谱
峰值(50Hz、1000Hz、3777Hz)清晰可见,Hann窗口函数略微减少了噪声。由于本例中噪声较少,您看不到太大的差异。
在FFT之前的样本上使用Hamming窗口函数的频谱
峰值(50Hz、1000Hz、3777Hz)清晰可见,Hamming窗口函数略微减少了噪声。由于本例中噪声较少,您看不到太大的差异。
实时音频加频谱可视化
执行示例 $ cargo run --release --example live-visualization
。它将向您展示如何实时可视化音频数据以及当前频谱。
构建和执行测试
要执行测试,您需要包libfreetype6-dev
(在Ubuntu/Debian上)。这是必需的,因为并非所有测试都是“自动单元测试”,还有需要通过查看生成的频谱图来视觉检查的测试。
趣味/常见问题解答
为什么使用f64而不是f32?
我测试了f64,但额外的精度并不足以抵消大约40%的计算开销(在x86_64上)。
我该如何对抗噪声?
应用窗口函数,例如Hann窗口或Hamming窗口。
更多信息的良好资源
- 解释FFT结果:https://www.gaussianwaves.com/2015/11/interpreting-fft-results-complex-dft-frequency-bins-and-fftshift/
- FFT基本概念:https://www.youtube.com/watch?v=z7X6jgFnB6Y
- “基于FFT的信号分析与测量的基础” https://www.sjsu.edu/people/burford.furman/docs/me120/FFT_tutorial_NI.pdf
- 快速傅里叶变换(FFTs)和窗口:https://www.youtube.com/watch?v=dCeHOf4cJE0
还可以查看我的博客文章。
依赖关系
~2MB
~97K SLoC