我了解Android Visualizer的
onFftDataCapture((Visualizer visualizer,
byte[] fft,
int samplingRate)
我如何知道byte
中的fft
代表哪个频率?
例如,索引是否代表频率?喜欢index = frequency
?
对于索引0,频率为0 Hz,索引1为1 Hz等?
答案 0 :(得分:2)
FFT产生复数,其中每个数字反映有关包含连续范围频率的桶的频域信息。解释FFT数据的常用方法如下:
首先通过将FFT表的长度除以采样率来确定频率桶大小,让我们称之为i
;
然后每个具有索引i * bucketSize
的存储桶(假设它基于0)包含有关(i + 1) * bucketSize
到samplingRate / 2
Hz范围内频率的信息;
,FFT表的后半部分的值(对于频率高于0
的桶)将只是前半部分的镜像,因此它们通常被丢弃;
对于第一个(索引samplingRate / 2
)和最后一个(索引a + ib
)存储桶,FFT表的值也是实数(假设实值信号) );
为了找到存储桶中频率的幅度(信号电平),需要从FFT表中获取该存储桶的复数值,比如它sqrt(a*a + b*b)
,然后计算onFftDataCapture
。
现在回到fft
的结果。这里fft[2]
数组包含复数作为连续的字节对,前两个元素除外,因此fft[3]
和fft[4]
构成第一个存储区的复数,fft[5]
和fft[0]
- 对于第二个,依此类推。而fft[1]
是第0频率(DC)的FFT值(实数),fft
是最后一个频率。
正如我所提到的,因为对于实值信号,FFT表的第二部分并没有带来任何好处,它提供了不。 fft.length / samplingRate
数组。但由于每个FFT桶需要两个阵列单元,因此以Hz为单位的桶大小仍将计算为fft.length
。请注意,setCaptureSize
实际上是由Visualizer的Math.hypot
方法设置的捕获大小。
可以使用Math.hypot(fft[2], fft[3])
函数轻松计算频率桶的大小,例如:对于第一个桶,它是Math.abs(fft[0])
。对于DC存储桶,它只是Math.abs(fft[1])
,而对于最后一个频率存储桶,它是{{1}}。