提取快速傅立叶从文件转换数据(Extract Fast Fourier Transform data

2019-07-20 09:31发布

我建立这应该在服务器上运行,并分析声音文件的工具。 我想为我的其他所有工具都写在红宝石以及为此在红宝石。 但我无法找到实现这一点的一个好方法。

很多的例子,我发现一直在做可视化工具和图形化的东西。 我只需要FFT数据,仅此而已。 我需要都得到了音频数据,并做就可以了FFT。 我的最终目标是要计算一些东西,如平均/中位数/模式,第25百分位,和第75百分位在所有频率(加权幅度),BPM的,也许还有一些其他好的特性以后能够聚集类似的声音混合在一起。

首先,我试图用红宝石的音频fftw3但我从来没有去两个真的一起工作。 该文档是也不好,所以我真的不知道什么样的数据正在抛去。 接下来,我试图用bplay / BREC和限制我的Ruby脚本只使用STDIN和对(仍然使用fftw3)执行FFT。 但我不能让bplay / BREC工作,因为服务器没有声卡,我没能只是直接将音频输出到标准输出而不去音频设备第一。

下面是我得到的最接近:

# extracting audio from wav with ruby-audio
buf = RubyAudio::Buffer.float(1024)
RubyAudio::Sound.open(fname) do |snd|
    while snd.read(buf) != 0
        # ???
    end
end

# performing FFT on audio
def get_fft(input, window_size)
    data = input.read(window_size).unpack("s*")
    na = NArray.to_na(data)
    fft = FFTW3.fft(na).to_a[0, window_size/2]
    return fft
end

所以,现在我被卡住,无法找到谷歌什么比较好的结果。 因此,也许你这样的家伙能帮助我吗?

谢谢!

Answer 1:

下面是什么,我想实现最终的解决方案,非常感谢兰德尔库克的有益的建议。 该代码提取红宝石WAV文件的声波和FFT:

require "ruby-audio"
require "fftw3"

fname = ARGV[0]
window_size = 1024
wave = Array.new
fft = Array.new(window_size/2,[])

begin
    buf = RubyAudio::Buffer.float(window_size)
    RubyAudio::Sound.open(fname) 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_size/2]
            j=0
            fft_slice.each { |x| fft[j] << x; j+=1 }
        end
    end

rescue => err
    log.error "error reading audio file: " + err
    exit
end

# now I can work on analyzing the "fft" and "wave" arrays...


Answer 2:

我觉得这里有两个问题。 一个是获得样本,另一个是执行FFT。

要获取样本,主要有两个步骤:解码和缩混。 为了解码WAV文件,你只需要解析头,所以你可以知道如何解释样本。 对于MP3文件,你需要做一个全解码。 一旦音频已经被解码,如果是不感兴趣的单独地处理立体声信道,则可能需要将其缩混成单,由于FFT需要一个单个信道作为输入。 如果你不介意冒险红宝石之外,在SOX工具让一切变得简单。 例如sox song.mp3 -b 16 song.raw channels 1应一个MP3转换为纯PCM样本(即16位整数)的单文件。 BTW,快速搜索揭示了红宝石/音频库(也许是在你的文章中提到的)。 它看起来相当不错,特别是因为它包装libsndfile。

为了执行FFT,我看到三个选项。 一种是使用此代码段的代码执行FFT。 我不是红宝石的专家,但它看起来像它可能是确定。 第二个选择是使用NArray 。 它有一吨的数学方法,包括FFTW,可在一个单独的模块,一个压缩包供其在NArray页面中间的链接。 第三个选项是编写自己的代码FFT。 这不是一个特别复杂的算法,并可以给你很好的与数字处理红宝石(如果你需要)。

你也许是意识到了这一点,但FFT预计复杂的输入,并产生复杂的输出。 音频信号是真实的,当然,所以输入的虚分量应该总是零( a + 0*i )。 由于您的输入是真实的,输出将是对称输出数组的中点。 您可以放心地忽略的上半部分。 如果你想在一个特定频率上的能量(它们间隔线性多达一半的采样率),你需要计算复数值(幅度sqrt(real*real + imag*imag)

一两件事:由于频率零(信号的DC偏移)和奈奎斯特频率(采样率的一半)具有无相位分量,一些FFT实现把它们放在一起成相同的复杂的容器(一个在实分量,一个在的虚分量,通常第一仓的)。 你可以创建一些简单的信号(全1的只是一个直流信号,并交替+ 1,-1的奈奎斯特信号),看到FFT输出的样子。



文章来源: Extract Fast Fourier Transform data from file