如何将音频与功率谱同步并选择帧长度 N(执行 fft)
How to syncronize audio with the power spectrum and choose frame length N (to do fft)?
我正在用C++做一个音乐可视化程序。它给出了音频输入的频谱。我使用Aquila-dsp获取音频样本,使用Kiss-fft进行FFT,SMFL播放音频。输入采用 (.wav) 格式。OpenGL用于绘制图形。
使用的算法:
1. *framePointer = 0, N = 10000;*
2. Load audio file and play it using SFML.
3. For *i* = framePointer to --> *framePointer* + *N* < *total_samples_count*
Collect audio samples.
4. Apply Window Function (Hann window)
5. Apply *FFT*
6. Calculate magnitude of first N/2 *FFT* data
*Magnitude* = sqrt( re * re + im * im)
7. Convert to dB(log) scale (optional)
10*log(magnitude)
8. Plot N/2, log(magnitude) values
9. If *framaPointer* >= *toatl_samples_count - N*
Exit
Else go to step 3.
#define N 10000
int framePointer = 0;
void getData()
{
int i,j,x;
Aquila::WaveFile wav(fileName);
double mag[N/2];
double roof = wav.getSamplesCount();
//Get first N samples
for( i = framePointer, j = 0; i < (framePointer + N)
&& framePointer < roof - N ; i++,j++ ){
//Apply window function on the sample
double multiplier = 0.5 * (1 - cos(2*M_PI*j/(N-1)));
in[j].r = multiplier * wav.sample(i);
in[j].i = 0; //stores N samples
}
if(framePointer < roof-N -1){
framePointer = i;
}
else {
printf("Frame pointer > roof - N n");
printf("Framepointer = %dn",framePointer );
//get total time and exit
timestamp_t t1 = get_timestamp();
double secs = (t1 - tmain) / 1000000.0L;
std::cout<<"Program exit.nTotal time: "<<secs<<std::endl;
exit(0);
}
// Apply FFT
getFft(in,out);
// calculate magnitude of first N/2 FFT
for(i = 0; i < N/2; i++ ){
mag[i] = sqrt((out[i].r * out[i].r) + (out[i].i * out[i].i));
graph[i] = log(mag[i]) *10;
}
}
我使用 OpenGL 绘制图形。 完整源代码
我遇到的问题是选择帧长度(N 值)。
对于一定长度的音频,具有:
Length: 237191 ms
Sample frequency: 44100 Hz
Channels: 2
Byte rate: 172 kB/s
Bits per sample: 16b
如果我选择 N = 10000,则图形与音频同步。或者至少它在音频结束时停止。
如何选择N(帧长度),以便音频与频谱同步。音频是双声道的,这个算法能用吗?
首先确定您希望可视化工具更新的频率。假设我们希望它每秒更新 25 次(类似于电视或电影帧速率)。这意味着每 1/25 秒或每 40 毫秒。在 44.1 kHz 的采样率下,这意味着 44100/25 = 1764 个样本。由于我们通常需要 2 FFT 大小的幂,那么让我们选择 N = 2048。
这给出了频率轴上的分辨率为 44100/2048 = 21.5 Hz。如果你想要更高的分辨率,那么你可以重叠连续的FFT窗口,例如保持相同的更新率和重叠50%,那么你可以有N = 4096的分辨率为10.75 Hz。
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- C++,系统无法执行指定的程序
- 使用C++中的模板和运算符重载执行矩阵运算
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 执行函数时导致崩溃的变量
- 无论条件是否为true,if总是在c++中执行
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 在C++中对T*类型执行std::move的意外行为
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如何在没有信号的情况下从C++执行QML插槽
- 如何确认我的constexpr表达式实际上已经在编译时执行
- C++17中的并行执行策略
- QML按钮点击功能执行顺序
- 程序在执行程序的其余部分之前退出
- 为什么catch中的代码没有被执行
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 将执行、作业和WinAPI相乘
- 如何在SDL2音频流数据上执行实时FFT
- 执行FFT计划后,FFTW输出矢量大小错误
- 如何将音频与功率谱同步并选择帧长度 N(执行 fft)