gpt4 book ai didi

c++ - 如何将音频与功率谱同步并选择帧长度 AND(做 fft)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:13:15 25 4
gpt4 key购买 nike

我正在用 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 = %d\n",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 绘制图表。 Full source code

我遇到的问题是在选择帧长度(N 值)时。

对于具有一定长度的音频:

Length: 237191 ms
Sample frequency: 44100 Hz
Channels: 2
Byte rate: 172 kB/s
Bits per sample: 16b

如果我选择 N = 10000,图表将与音频同步。或者至少它会在音频结束时停止。

如何选择 N(帧长)以使音频与频谱同步。音频是双 channel 的,这个算法适用吗?

最佳答案

首先确定您希望可视化工具更新的频率。假设我们希望它每秒更新 25 次(类似于电视或电影的帧速率)。这意味着每 1/25 秒或每 40 毫秒。在 44.1 kHz 的采样率下,这转换为 44100/25 = 1764 个样本。由于我们通常需要 2 的 FFT 大小的幂,因此让我们选择 N = 2048。

这给出了 44100/2048 = 21.5 Hz 的频率轴分辨率。如果你想要更高的分辨率,那么你可以重叠连续的 FFT 窗口,例如保持相同的更新率并重叠 50%,那么对于 10.75 Hz 的分辨率,您可以得到 N = 4096。

关于c++ - 如何将音频与功率谱同步并选择帧长度 AND(做 fft)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37415263/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com