搞了搞音频的频率动效,一次应该用多少长度的采样数据进行 fft 计算合适
还有就是为啥每次计算出的数据前面一截(低 hz 的)总是一柱擎天呢
1
billlee 2023-08-21 21:29:54 +08:00 via Android
第一个柱子是直流分量,是不是值域映射错了,应该是 [-1.0, 1.0].
|
2
horou OP @billlee 不只是第一个数据,前面几个都是,值我检查了,没映射错,传的采样数据是 -1.0 到 1.0 ,计算出来的 FrequencyValue 是 0.0 到 1.0
|
3
horou OP |
4
billlee 2023-08-21 23:15:22 +08:00 via Android
图上没有坐标轴,用的是对数坐标吗?
|
5
ranaanna 2023-08-22 00:30:21 +08:00
取决于你的计算平台的能力吧,计算时间限制下当然是越多越好喽。另外最好是加个 Hamming 窗来减少旁瓣。另外结果似乎也不对吧,如果画出的是频谱的幅值,不管怎么样应该是个偶函数吧,各频点幅度一般也不应该都落在 0 到 1 之间
|
6
xiangyuecn 2023-08-22 00:43:35 +08:00 1
根据需求来,每次计算输入的采样数记为 fftSize ,比如 fftSize=1024 ; fft 计算后的结果只需要取一半,共 512 个分频率
音频的采样率决定了频率上限,比如 sampleRate=48000 ,最大频率为 sampleRate/2=24KHz ; 512 个分频率均分这 24K ,绘制频谱图的时候相当于 x 轴,每个刻度间隔为 24000/512=46.875Hz 所以,固定了一个 fftSize 的时候,sampleRate 变来变去时会影响 x 轴,48000 中间位置是 12KHz ,换做 16000 时中间位置是 4KHz ,因此 fftSize 的大小得根据 sampleRate 大小来定 fftSize 具体取多大,看你需求,fftSize 越大绘制的频谱越精细,每次输入的时域数据越长(时间越长),可以使用滑动窗口来解决新数据量不够的问题,比如每次只取 50ms 新数据和老数据一起计算,很大的 fftSize 可以做到很高的帧率 ------- 前面一截总是一柱擎天,大部分情况下属正常,声音能量主要集中在低频部分,高频部分比较少。但也不排除你的 fft 代码有问题,算出来的结果是错的。 |
8
horou OP @ranaanna 用了 hann window
@xiangyuecn 感谢大佬详细解答,还有个问题,你第二点说的意思是只固定取那些 hz 的数据吗,还是计算这个 hz 周围的平均值 口头说不是很能表达明白意思,我直接上我的代码吧 代码地址: https://gist.github.com/rust-play/44f0864a5855d164e919aaa0ff367b8f 打包好的程序:链接: https://pan.baidu.com/s/1Tn-NWmTjIU3kLe-NnSNesw?pwd=oct6 提取码:oct6 直接把音乐文件拖到 exe 上执行 大佬帮我看看到底效果到底是差在哪个地方 |
9
xiangyuecn 2023-08-22 11:52:01 +08:00
自己研究研究吧,fft 是比较难学,现在看到代码就脑壳疼😂 相同的 fftSize+sampleRate 每次计算出来的每一位结果都对应固定的频率值,相当于 x 轴( Hz ),y 轴为每一位的值(振幅),每次计算出每个频率的振幅会发生变化,就形成了动画
|
10
bug123 2023-08-22 12:41:13 +08:00
你那个图没啥问题的,每次计算最近的 512 采样点就可以,另外可以把幅度值转成 dbfs ,另外用 Hanning 窗比较好吧,不是 Hamming
|
11
horou OP @xiangyuecn 好的,感谢大佬的解答加深了我对这部分的理解。
|