主要参考资料:
深入浅出的讲解傅里叶变换(真正的通俗易懂): https://zhuanlan.zhihu.com/p/19763358
推荐开源项目:KISS FFT: https://blog.csdn.net/gitblog_00031/article/details/138840117
数字硅麦数据的处理(傅里叶FFT):https://blog.csdn.net/shayk/article/details/130305761
目录
- 概念
- 傅里叶变换
- 汉明窗
- C++代码实现
概念
傅里叶变换
傅里叶变换是一种数学变换,用于将信号从时间域(或空间域)转换到频率域。这种变换揭示了信号的频率成分,是信号处理和系统分析中非常重要的工具。以下是傅里叶变换的一些基本概念:
汉明窗
汉明窗(Hamming Window)是一种常用的窗函数,主要用于信号处理领域,特别是在傅里叶分析中。它是由理查德·汉明(Richard Hamming)提出的,因此得名汉明窗。
汉明窗的目的是减少信号在进行离散傅里叶变换(DFT)时的频谱泄露现象。频谱泄露是由于信号在时间上被截断而产生的,它会导致频谱分析中的误差。使用窗函数可以对信号的边缘进行平滑处理,从而减少这种误差。
C++代码实现
//得到频谱
void AudioProcessor::get_spectrogram(int16_t *audio, float *output) {
// 初始化一个浮点数mean,用于存储音频样本的平均值。
float mean = 0;
for (int i = 0; i < audio_length; i++) {
mean += audio[i];
}
mean /= audio_length;
// 初始化一个浮点数max,用于存储样本与平均值之差的绝对最大值。
float max = 0;
for (int i = 0; i < audio_length; i++) {
max = std::max(max, fabsf((float)audio[i] - mean));
}
// 通过步长step_size在音频长度范围内移动,每次提取window_size大小的窗口。
// 将当前窗口的样本复制到快速傅里叶变换(FFT)的输入缓冲区fft_input中,并减去平均值mean,然后除以最大值max进行归一化。
// 对于FFT输入缓冲区中窗口之外的部分,填充0。
for (int i = 0; i < audio_length - window_size; i += step_size) {
// Copy the samples into the FFT input buffer.
for (int j = 0; j < window_size; j++) {
fft_input[j] = ((float)audio[i + j] - mean) / max;
}
for (int j = window_size; j < fft_size; j++) {
fft_input[j] = 0;
}
// 对每个窗口调用spectrogram_segment函数,并将计算得到的频谱图数据存储到输出数组output中。输出数组的索引由当前窗口的
// 位置和池化能量大小pooled_energy_size决定。
spectrogram_segment(output + i / step_size * pooled_energy_size);
}
}