gpt4 book ai didi

IOS 和 FFT (vDSP_fft_zrip) : frequencies below appr. 100 Hz 被切断 - 为什么?

转载 作者:行者123 更新时间:2023-11-29 01:55:20 25 4
gpt4 key购买 nike

我正在使用 Novocaine 框架来执行音调检测。一切运行良好 - 仅使用图形 FFT 表示,存在一些麻烦。

当我使用音频文件作为输入时,FFT 工作正常 - 低于 100 Hz 的频率可以完美显示。

相反,当我使用麦克风作为输入时,低于 100 Hz 的频率根本不会显示 - 我不明白为什么!请参阅下面的屏幕截图:

正确显示较高频率(例如 1000 Hz)!

以下是 FFT 过程的源代码:

- (NSMutableArray*)performFFT: (float*) data  withFrames: (int) numSamples {
// 1. init
float bufferSize = numSamples;
uint32_t maxFrames = numSamples;
displayData = (float*)malloc(maxFrames*sizeof(float));
bzero(displayData, maxFrames*sizeof(float));
int log2n = log2f(maxFrames);
int n = 1 << log2n;
assert(n == maxFrames);
float nOver2 = maxFrames/2;


A.realp = (float*)malloc(nOver2 * sizeof(float));
A.imagp = (float*)malloc(nOver2 * sizeof(float));
fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);

// 2. calcuate
bufferSize = numSamples;
float ln = log2f(numSamples);
vDSP_ctoz((COMPLEX*)data, 2, &A, 1, numSamples/2);

//fft
vDSP_fft_zrip(fftSetup, &A, 1, ln, FFT_FORWARD);

// Absolute square (equivalent to mag^2)
vDSP_zvmags(&A, 1, A.realp, 1, numSamples/2);
// make imaginary part to zero in order to filter them out in the following loop
bzero(A.imagp, (numSamples/2) * sizeof(float));

//convert complex split to real
vDSP_ztoc(&A, 1, (COMPLEX*)displayData, 2, numSamples/2);

// Normalize
float scale = 1.f/displayData[0];
vDSP_vsmul(displayData, 1, &scale, displayData, 1, numSamples);


//scale fft
Float32 mFFTNormFactor = 1.0/(2*numSamples);
vDSP_vsmul(A.realp, 1, &mFFTNormFactor, A.realp, 1, numSamples/2);
vDSP_vsmul(A.imagp, 1, &mFFTNormFactor, A.imagp, 1, numSamples/2);

...
}

对于进一步的图形问题,我使用displayData

由于我对较低频率感兴趣(有一个单独的音调检测算法可以正常工作),因此我将采样率降低到 11.025(而不是 44100)。

在 Novocaine 中,我进行了以下调用:

1) 输入

[audioManager setInputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) {

// frequency analysis
vDSP_rmsqv(data, 1, &magnitude, numFrames*numChannels);
self->ringBuffer->AddNewInterleavedFloatData(data, numFrames, numChannels);
...
}

2)输出:

[audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels)
{
self->ringBuffer->FetchInterleavedData(data, numFrames, numChannels);
....
[fft performFFT:data withFrames:numFrames];
...
}

有人有想法吗?

最佳答案

这是因为内置麦克风是电容麦克风,并且具有高通滤波器,可以消除信号上的直流偏置。

可以禁用 HPF。 DC 偏置并不是什么大问题,因为它只会出现在 FFT 的 bin #0 中。

[[AVAudioSession sharedInstance] setMode: AVAudioSessionModeMeasurement error:NULL];

另请注意,FFT 的加窗也会影响 FFT 低频箱的准确性。对于任何给定频率,窗口中至少需要 2*PI 的样本。

关于IOS 和 FFT (vDSP_fft_zrip) : frequencies below appr. 100 Hz 被切断 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30934971/

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