1

我编写了一个函数来对 1024 个样本的数组执行 FFT。我正在尝试使用此函数的输出来绘制频谱图。

该图的输入非常不一致,大部分时间都在 0 处,而当它显示某些内容时,似乎与音乐几乎没有关系。我已经包含了两个屏幕截图来演示。

我已经包含了几个屏幕截图,以及用于执行 FFT 的代码。有没有人对为什么产生的输出如此糟糕有任何想法?

另外,我注意到频谱图的低端是“尖峰”,因为它喜欢跳跃很多。

奇怪的输出:

有时一些输出是,但幅度看起来不正确

无输出(出现在所有绘制帧的 1/2 到 2/3 之间):

可能有 1/2 到 2/3 的时间没有显示输出

编码:

// Get the samples

AudioSampleType *samples = [_songModel nextSamplesWithLength: _fftN];
if (samples == nil)
    return nil;

// Convert AudioSampleTypes (SInt16s) into floats between -1.0 and 1.0 
// (required by the DSP library).

for (int i = 0; i < _fftN; i++)
    _inputReal[i] = (samples[i] + 0.5) / 32767.5;

// Window the input

vDSP_vmul(_inputReal, 1, _hanningWindow, 1, _windowedReal, 1, _fftN);

// Convert our real input into even-odd form

vDSP_ctoz((COMPLEX *)_windowedReal, 2, &_fourierOutput, 1, _fftHalfN);

// Perform the fast fourier transform

vDSP_fft_zrip(_fftSetup, &_fourierOutput, 1, _fftLog2n, FFT_FORWARD);

// Calculate magnitudes (will output to the real part of the COMPLEX_SPLIT)

vDSP_zvmags(&_fourierOutput, 1, _fourierOutput.realp, 1, _fftHalfN);

// Build and return the input and output of the analysis

return [[FrequencyData alloc] initWithSignal:_inputReal 
                                signalLength:_fftN  
                         frequencyMagnitudes:_fourierOutput.realp
                             magnitudeLength:_fftHalfN];

编辑

设置代码:

_fftN = 1 << _fftLog2n;
_fftHalfN = _fftN / 2;
_stride = 1;

_fourierOutput.realp = (float *) malloc(_fftHalfN * sizeof(float));
_fourierOutput.imagp = (float *) malloc(_fftHalfN * sizeof(float));

_hanningWindow = (float *) malloc(_fftN * sizeof(float));    
vDSP_hann_window(_hanningWindow, _fftN, 0);

_inputReal = (float *) malloc(_fftN * sizeof(float));
_windowedReal = (float *) malloc(_fftN * sizeof(float));
_fftSetup = vDSP_create_fftsetup(_fftLog2n, FFT_RADIX2);
4

1 回答 1

0

没有输出的结果可能是由于代码中其他地方的错误(可能在歌曲阅读或绘图代码中)。

“奇怪的输出”可能是录制音乐的正确 FFT 结果,因为有趣的发声乐器和声音的完整音频频谱可能与仅标注的音高频率有很大不同。

于 2012-03-08T02:01:05.977 回答