我希望用本地频率内容显示每个部分的颜色编码的音频波形。基本上就是Serato / Traktor或任何其他DJ软件所做的事情,你可以看到声音并告诉它们有什么频率。它看起来像这样:
基本上,我会做一个FFT来获取我指定的任何bin宽度的频率,但是有人能引用我一些在实际绘制它时有用的代码(最好是c)吗?
答案 0 :(得分:2)
这次我们试试一个真正的答案。 : - )
问题太复杂了,无法提供此空间中所有代码的完整解决方案,但我会使用伪代码并假设您有一些可以窗口化样本块并计算FFT的库。
它类似于构建波形显示。在构建波形显示时,您可以确定适合的样本数量和#34;在当前缩放级别的单个水平像素中,它们开始给定您的X滚动位置,计算该段的最小和最大样本值,并为您提供该波形像素的最小/最大Y位置。 (这实际上有点简化,我在当天写回了波形渲染代码,但这是一个很好的近似值。)
要使用频率为波浪着色,您需要使用带有小间隔的短时间FFT对波形数据进行预处理,并为每个分区确定主要频率是什么,然后将其映射到从红色到紫色的光谱上的颜色
让我们在一个名为samples
的数组中说出你的音频样本,这里是伪代码。
// sample rate
float fS = 44100;
// size of frame for analysis, you may want to play with this
float frameMsec = 10;
// samples in a frame
int frameSamples = (int)(fS / (frameMsec * 1000));
// how much overlap each frame, you may want to play with this one too
int overlapSamples = (frameSamples / 2);
// number of samples in the sound file
int numSamples = ...;
// input array of samples
float inSamples[] = ...;
// color to use for each frame
RGB outColors[] = new float[(numSamples / frameOverlap) + 1];
// scratch buffers
float tmpWindow[frameSamples];
float tmpFFT[frameSamples];
// helper function to apply a windowing function to a frame of samples
void calcWindow(float* dst, const float* src, int size);
// helper function to compute FFT
void fft(float* dst, const float* src, int size);
// find the index of array element with the highest absolute value
// probably want to take some kind of moving average of buf[i]^2
// and return the maximum found
int maxFreqIndex(const float* buf, int size);
// map a frequency to a color, red = lower freq -> violet = high freq
RGB freqToColor(int i);
for (int i = 0, outptr = 0; i < numSamples; i += frameOverlap, outptr++)
{
// window another frame for FFT
calcWindow(tmpWindow, &inSamples[i], frameSamples);
// compute the FFT on the next frame
fft(tmpFFT, tmpWindow, frameSamples);
// which frequency is the highest?
int freqIndex = maxFreqIndex(tmpFFT, frameSamples);
// map to color
outColor[outptr] = freqToColor(freqIndex);
}
这将为您提供一个RGB数组,您可以放大和缩小波形显示的缩放比例。在缩放时,您可能希望平均相邻帧的RGB值,以便为您提供整体视图。
我希望这会有所帮助。