FFT是如何工作的?在Rust中似乎无法得到每一帧的频谱

py49o6xq  于 2023-01-26  发布在  其他
关注(0)|答案(1)|浏览(180)

我每0.03秒只能得到735个频率的音频数据。
我想弄清楚怎样才能得到每帧的频谱。下面的代码每帧只返回735个数据(因为samples_in_frame是735,这是每帧的样本数),但是我想得到0.03秒样本的整个~20,000 hz。我该怎么做呢?
path:波形文件的路径
second_start:以秒为单位的进程起始点,0
second_length:处理时间(秒),10
frame_rate:每秒多少帧,60

fn fft_this(mut buffer: Vec<Complex<f64>>, samples_in_frame: usize) -> Vec<f64> {
    let mut planner = FftPlanner::new();

    let fft = planner.plan_fft_forward(samples_in_frame);

    fft.process(&mut buffer[..]);

    let mut frame_data: Vec<f64> = Vec::with_capacity(samples_in_frame);

    for i in 0..samples_in_frame {
        frame_data.push(buffer[i].norm())
    }

    return frame_data;
}

#[tauri::command]
pub fn analyze(
    path: &str,
    second_start: f64,
    second_length: f64,
    frame_rate: f64,
) -> Vec<Vec<f64>> {
    let wave_file: Wave64 = Wave64::load(path).expect("Could not load wave.");

    let samples_start: f64 = second_start * wave_file.sample_rate();
    let samples_in_each_frame: usize = (wave_file.sample_rate() / frame_rate) as usize;

    let frames_in_length: usize = (second_length * frame_rate) as usize;

    let mut wave_buffer: Vec<Vec<f64>> = vec![];

    for frame_index in 0..frames_in_length {
        let mut frame_buffer: Vec<Complex<f64>> = vec![];

        for sample_index in 0..samples_in_each_frame {
            let buffer_index: usize = frame_index * sample_index + samples_start as usize;

            frame_buffer.push(Complex {
                re: wave_file.at(0, buffer_index),
                im: 0.0,
            });
        }

        let processed_frame: Vec<f64> = fft_this(frame_buffer, samples_in_each_frame);

        wave_buffer.push(processed_frame);
    }

    return wave_buffer;
}
cwdobuhd

cwdobuhd1#

我认为您需要更多关于FFT的一般背景信息。
如果有735个数据点,则此数据仅包含735个正交频率。
假设735点代表1秒,则:

  • 第一个FFT值是直流部分0 Hz,是所有值的平均值。
  • 第二个是1 Hz,最慢的包含频率,表示采样周期内的一个完整周期。
  • 下一个是2 Hz,表示采样周期内的两个完整周期。
  • ...
  • 367 Hz,表示367个完整周期
  • 368 Hz,表示368个完整周期。**重要提示:**由于混叠(参见“采样定理”),这与-367 Hz相同,表示367 Hz以相反方向旋转!
  • -366 Hz
  • -365 Hz
  • ...
  • -1 Hz

总共有735个频率。信号中没有更多的信息。
在您的情况下,由于时间周期不是1秒,而是0.03秒,因此需要将频率乘以1/0.03 = 33.33,从而得到:

  • 0 Hz
  • 33.33 Hz
  • 66.66 Hz
  • ...
  • 12200 Hz
  • 12233.33 Hz
  • -12233.33 Hz
  • -12200 Hz
  • ...
  • -66.66 Hz
  • x1米20英寸1x

你的样本里没有更多的信息。

其他重要信息:

对于FFT,它看起来像是你给予它的信号在无限重复,所以如果你的735个样本实际上没有重复(我猜它们不是),您需要应用窗口函数来减少奇数频率产生的伪像。例如,在1秒的情况下,干净的1.5 Hz信号将给予您一些奇怪的泛音,因为不应用窗口函数等同于应用矩形窗口函数,这有可怕的弦外之音。更多信息在这里。
对于视觉学习者,我可以强烈推荐videos of 3Blue1Brown about the fourier transform

相关问题