我正在为音频构建一个视觉均衡器,并且我对FFT的输出感到困惑。我的最终目标是将6个数字(1个低音,4个中音和1个高音)的简化数组发送到配备蓝牙的Arduino。这些数字表示每列中有多少个LED点亮(低音为1列,高音为1列等)。
第一步是将音频信号转换为数字表示。 为了做到这一点,我想要以规则的时间间隔将某些频率组合成离散的桶,即一个用于低音的60到250Hz。
我已经获得了一个300Hz的wav文件,我试图使用ruby FFTW3
gem来解卷积。我期望一个正弦波在1秒样本的过程中完成300个周期。当我传入300秒音调的1s样本时,fft.length = 1024
和fft[0] = 22528
。
我一直在使用这些对话Audio Equalizer in Ruby和Extract Fast Fourier Transform data from file作为我的主要参考点,因为ruby gem的文档令人困惑。
这是我的代码:
require "ruby-audio"
require "fftw3"
require "narray"
# Audio sample rate and block size:
SAMPLE_RATE = 44100
# break the audio into chunks (called windows, or frames)
# pass them sequentially to the FFT.
# gives a frequency profile that changes over time
# e.g. 1024, 2048, 4096, 8192, etc..
WINDOW = 2048
# samplerate/window => 44100/2048 = 10.7
# Updates about 11 times/second
# RESOLUTION = (1.0*SAMPLE_RATE/WINDOW)
filename = ARGV[0]
wave = Array.new # length is window size/2
fft = Array.new(WINDOW/2,[])
begin
# extracting audio from wav with ruby-audio
buf = RubyAudio::Buffer.float(WINDOW)
RubyAudio::Sound.open(filename) do |snd|
while snd.read(buf) != 0
wave.concat(buf.to_a)
na = NArray.to_na(buf.to_a)
fft_slice = FFTW3.fft(na).to_a[0, WINDOW/2]\
# na = array to be transformed
j=0
fft_slice.each do |x|
# getting the real part of the complex number
x = x.abs
fft[j] << x; j+=1
end
end
end
rescue => err
# log.error "error reading audio file: " + err
puts 'There was an error, exiting!'
exit
end
最内层的数组是表示频率,外部是表示时间的流逝,还是相反的方式。我如何知道哪个数组索引代表特定频率?
我不确定如何测试它以确定它是否准确地创建了正确的频率。是否有一种很好的方式来查看我在视觉上或其他方面遗漏的数据?
感谢您的任何指示!