所以我设置了一个AudioRecord,使用FFT来确定音符确定的频率。
在设置过程中,我要求
AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat)
然后我有一些if语句将它设置为下一个更大的2的幂。对于我的手机,通常为2048(2 ^ 11)。目的是我执行的下一件事是FFT,算法要求缓冲区长度为2的幂。
如果我错了,请纠正我,但我觉得你找到最小缓冲区大小的原因是因为它会减少延迟。
在我阅读之前,这一切都很好,为了准确地确定具体的音符,特别是那些频率较低的音符,你必须有更大的样本量来提供给FFT;优选样品大小大于16384(2 ^ 14)。
我猜我遇到的问题是。当我创建AudioRecord时:
AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT,
rate, channelConfig, audioFormat, bufferSize1);
我可以使用一个缓冲区大小,更小的延迟,然后当我读取缓冲区时:
AudioRecord().read(thisbuffer, 0, bufferSize2);
在将其发送到FFT之前,使用不同长度的缓冲区大小?或者有更好的方法吗?
答案 0 :(得分:2)
首先,对于“音符”判定来说,FFT是一个不好的选择,因为对于通常想要估计音高的音符,而不是频谱频率,这是由于心理声学导致的两个非常不同的事物。
对于加窗FFT,在FFT窗口中间附近最精确地确定频谱频率。因此,使用更长的FFT,即使在非常短的输入缓冲器大小之后通过重叠重复它们,也将产生大约FFT长度的一半的延迟。
但更频繁地重复FFT(通过在短输入缓冲延迟后重叠它们)将为您提供更好的时间分辨率,如果不是更快的延迟。为了实现更低的延迟,您需要使用更短的FFT,并丢失频率分辨率,或使用其他频率或音调估计器,这也将具有其他时间 - 频率 - 稳健性权衡。