我讀過這些問題:iOS的FFT頻譜抽獎
Using the Apple FFT and Accelerate Framework
How do I set up a buffer when doing an FFT using the Accelerate framework?
iOS FFT Accerelate.framework draw spectrum during playback
他們都描述瞭如何設置FFT與加速框架。在他們的幫助下,我能夠設置fft並獲得基本的頻譜分析儀。現在,我顯示了我從fft獲得的所有值。但是,我只想顯示10-15,或者可變數字的條形圖,重現某些頻率。就像iTunes或WinAmp液位計一樣。 1.我是否需要平均一系列頻率的幅度值?或者他們只是告訴你一個特定頻率的大小? 2.另外,我是否需要將我的量值轉換爲db? 3.如何將我的數據映射到特定範圍。我是否會針對最大分貝範圍映射我的聲音bitdepth?獲取箱的最大值將導致跳躍最大映射值。
我RenderCallback:
static OSStatus PlaybackCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
UInt32 maxSamples = kAudioBufferNumFrames;
UInt32 log2n = log2f(maxSamples); //bins
UInt32 n = 1 << log2n;
UInt32 stride = 1;
UInt32 nOver2 = n/2;
COMPLEX_SPLIT A;
float *originalReal, *obtainedReal, *frequencyArray, *window, *in_real;
in_real = (float *) malloc(maxSamples * sizeof(float));
A.realp = (float *) malloc(nOver2 * sizeof(float));
A.imagp = (float *) malloc(nOver2 * sizeof(float));
memset(A.imagp, 0, nOver2 * sizeof(float));
obtainedReal = (float *) malloc(n * sizeof(float));
originalReal = (float *) malloc(n * sizeof(float));
frequencyArray = (float *) malloc(n * sizeof(float));
//-- window
UInt32 windowSize = maxSamples;
window = (float *) malloc(windowSize * sizeof(float));
memset(window, 0, windowSize * sizeof(float));
// vDSP_hann_window(window, windowSize, vDSP_HANN_DENORM);
vDSP_blkman_window(window, windowSize, 0);
vDSP_vmul(ioBuffer, 1, window, 1, in_real, 1, maxSamples);
//-- window
vDSP_ctoz((COMPLEX*)in_real, 2, &A, 1, maxSamples/2);
vDSP_fft_zrip(fftSetup, &A, stride, log2n, FFT_FORWARD);
vDSP_fft_zrip(fftSetup, &A, stride, log2n, FFT_INVERSE);
float scale = (float) 1.0/(2 * n);
vDSP_vsmul(A.realp, 1, &scale, A.realp, 1, nOver2);
vDSP_vsmul(A.imagp, 1, &scale, A.imagp, 1, nOver2);
vDSP_ztoc(&A, 1, (COMPLEX *) obtainedReal, 2, nOver2);
vDSP_zvmags(&A, 1, obtainedReal, 1, nOver2);
Float32 one = 1;
vDSP_vdbcon(obtainedReal, 1, &one, obtainedReal, 1, nOver2, 0);
for (int i = 0; i < nOver2; i++) {
frequencyArray[i] = obtainedReal[i];
}
// Extract the maximum value
double fftMax = 0.0;
vDSP_maxmgvD((double *)obtainedReal, 1, &fftMax, nOver2);
float max = sqrt(fftMax);
}
播放一些音樂,我從-96dB值到0dB。
CGPointMake(i, kMaxSpectrumHeight * (1 - frequencyArray[i]/-96.));
是給我的一個相當圓潤的曲線: 在繪製一個點
如果我不轉換爲DB我可以通過我的10000陣列值乘以繪製並獲得好的山峯。
我做得完全錯誤的?我怎樣才能顯示可變數量的酒吧?
只是想知道:但是你有最終的代碼,呈現酒吧?我很難從下面的答案中知道要去哪裏。 – kezi 2014-08-14 04:30:13