[英]EZAudio: How do you separate the buffersize from the FFT window size(desire higher frequency bin resolution).
https://github.com/syedhali/EZAudio
我已經成功使用了該音頻庫,但現在我想提高讀入的麥克風數據的分辨率,以使FFT分辨率或頻點大小降至10Hz。 為此,我需要8820而不是512的緩沖區大小。麥克風的緩沖區大小和FFT窗口大小是否可分離? 我看不到將其分開的方法。
如何設置音頻流描述,以便可以在更大的窗口中計算FFT?
任何幫助將非常感激。
FFT大小和音頻緩沖區大小應完全獨立。 您可以僅保存多個音頻輸入緩沖區(也許在循環FIFO或隊列中),而無需處理它們,直到您有足夠的樣本以達到所需的長度FFT。
通過這種方式保存音頻緩沖區,還可以對重疊的幀進行FFT,以獲得更高的時間分辨率。
瀏覽了鏈接項目的源之后,似乎音頻回調傳遞的緩沖區大小是麥克風設備的首選緩沖區大小。 我建議您在調用FFT之前緩沖所需數量的樣本。 以下代碼是從EZAudioFFTExample中的FFTViewController.m修改的:
#pragma mark - EZMicrophoneDelegate
-(void) microphone:(EZMicrophone *)microphone
hasAudioReceived:(float **)buffer
withBufferSize:(UInt32)bufferSize
withNumberOfChannels:(UInt32)numberOfChannels {
dispatch_async(dispatch_get_main_queue(), ^{
// Update time domain plot
[self.audioPlotTime updateBuffer:buffer[0]
withBufferSize:bufferSize];
// Setup the FFT if it's not already setup
if( !_isFFTSetup ){
[self createFFTWithBufferSize:bufferSize withAudioData:buffer[0]];
_isFFTSetup = YES;
}
int samplesRemaining = bufferSize;
while (samplesRemaining > 0)
{
int samplestoCopy = max(bufferSize, FFTLEN - _fftBufIndex);
memcpy(_fftBuf, buffer[0], samplesToCopy*sizeof(float));
_fftBufIndex += samplesToCopy;
samplesRemaining -= samplesToCopy;
if (_fftBufIndex == FFTLEN)
{
_fftBufIndex = 0;
[self updateFFTWithBufferSize:FFTLEN withAudioData:_fftBuf];
}
}
});
}
在修改后的程序中, FFTLEN
是您定義的值, _fftBuf
是您分配的浮點數組,它需要保存FFTLEN
元素,而_fftBufIndex
是一個整數以跟蹤寫入數組的位置。
另外,我建議您在調用異步委托之前復制buffer參數。 我說這的原因是因為查看EZMicrophone的來源似乎是在回收緩沖區,所以您將遇到競爭狀況。
感謝Jaket的建議。 緩沖區是必經之路,這是我現在具有可調FFT窗口的相同功能的有效實現:
-(void)microphone:(EZMicrophone *)microphone
hasAudioReceived:(float **)buffer
withBufferSize:(UInt32)bufferSize
withNumberOfChannels:(UInt32)numberOfChannels {
dispatch_async(dispatch_get_main_queue(),^{
[self.audioPlot updateBuffer:buffer[0] withBufferSize:bufferSize];
// Decibel Calculation.
float one = 1.0;
float meanVal = 0.0;
float tiny = 0.1;
vDSP_vsq(buffer[0], 1, buffer[0], 1, bufferSize);
vDSP_meanv(buffer[0], 1, &meanVal, bufferSize);
vDSP_vdbcon(&meanVal, 1, &one, &meanVal, 1, 1, 0);
// Exponential moving average to dB level to only get continous sounds.
float currentdb = 1.0 - (fabs(meanVal)/100);
if (lastdbValue == INFINITY || lastdbValue == -INFINITY || isnan(lastdbValue)) {
lastdbValue = 0.0;
}
dbValue = ((1.0 - tiny)*lastdbValue) + tiny*currentdb;
lastdbValue = dbValue;
// NSLog(@"dbval: %f",dbValue);
//
// Setup the FFT if it's not already setup
int samplestoCopy = fmin(bufferSize, FFTLEN - _fftBufIndex);
for ( size_t i = 0; i < samplestoCopy; i++ ) {
_fftBuf[_fftBufIndex+i] = buffer[0][i];
}
_fftBufIndex += samplestoCopy;
_samplesRemaining -= samplestoCopy;
if (_fftBufIndex == FFTLEN) {
if( !_isFFTSetup ){
[self createFFTWithBufferSize:FFTLEN withAudioData:_fftBuf];
_isFFTSetup = YES;
}
[self updateFFTWithBufferSize:FFTLEN withAudioData:_fftBuf];
_fftBufIndex = 0;
_samplesRemaining = FFTLEN;
}
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.