如何在iPhone上检查FFT结果?

3

我使用OouraFFTl对音频文件进行了快速傅里叶变换(FFT)。如何检查采样输出是否正确?有什么更好、更容易的方法来检查?这是我的代码。

MyAudioFile  *audioFile = [[MyAudioFile alloc]init];
OSStatus result = [audioFile open:var ofType:@"wav"];
int numFrequencies=16384;
int kNumFFTWindows=10;

OouraFFT *myFFT = [[OouraFFT alloc] initForSignalsOfLength:numFrequencies*2    andNumWindows:kNumFFTWindows];
for(long i=0; i<myFFT.dataLength; i++)
 {
myFFT.inputData[i] = (double)audioFile.audioData[i];
} 
 [myFFT calculateWelchPeriodogramWithNewSignalSegment];
NSLog(@"the spectrum data 1 is  %f ",myFFT.spectrumData[1]);
NSLog(@"the spectrum data 2 is  %f",myFFT.spectrumData[2]);
NSLog(@"the spectrum data 8192 is  %f ",myFFT.spectrumData[8192]);

我已经创建了一个名为MyAudioFile的类,其中包含:
    -(OSStatus)open:(NSString *)fileName ofType:(NSString *)fileType{
OSStatus result = -1;

 CFStringRef filePath=fileName;

  CFURLRef audioFileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,      (CFStringRef)filePath, kCFURLPOSIXPathStyle, false);
 //open audio file
 result = AudioFileOpenURL (audioFileURL, kAudioFileReadPermission, 0, &mAudioFile);
 if (result == noErr) {
 //get  format info
 UInt32 size = sizeof(mASBD);

result = AudioFileGetProperty(mAudioFile, kAudioFilePropertyDataFormat, &size, &mASBD);

UInt32 dataSize = sizeof packetCount;
result = AudioFileGetProperty(mAudioFile, kAudioFilePropertyAudioDataPacketCount, &dataSize, &packetCount);
NSLog([NSString stringWithFormat:@"File Opened, packet Count: %d", packetCount]);

UInt32 packetsRead = packetCount;
UInt32 numBytesRead = -1;
if (packetCount > 0) { 
    //allocate  buffer
    audioData = (SInt16*)malloc( 2 *packetCount);
    //read the packets
    result = AudioFileReadPackets (mAudioFile, false, &numBytesRead, NULL, 0, &packetsRead,  audioData); 
    NSLog([NSString stringWithFormat:@"Read %d  bytes,  %d packets", numBytesRead, packetsRead]);
}
}
  else
  NSLog([NSString stringWithFormat:@"Could not open file: %@", filePath]);


CFRelease (audioFileURL);     
return result;
 }
3个回答

3
您需要绘制FFT输出的幅度。我不熟悉您所使用的编程语言,但在Python中,您可以使用类似于plot(abs(fft(a)))的代码。对于无声输入,输出应全部为零。对于正弦波输入,您应该看到两个峰值:

alt text

对于实际信号,峰值将从左至右对称。如果您正在进行实际FFT(这更加高效),则仅会将图形的左半部分作为输出返回,因为它忽略了冗余的镜像。
如果频率更高,则峰值将靠近中心。如果频率与块大小完全同步,则峰值仅为一个点宽,其他所有内容都非常接近0。否则,它将像上面那样具有逐渐变窄的“裙子”。

1

最常见的方法是使用FFT(快速傅里叶变换)对信号进行频谱分析,然后使用iFFT(逆快速傅里叶变换)将结果频谱转换回时域。接下来,您需要将输入的时间信号与结果时间信号进行比较。最简单的比较方法是计算两个RMS之间的差异。

例如:

给定长度为n的时间信号x。找到X=FFT(x),然后找到y=iFFT(X)。y的长度也为n。然后,为了将x与y进行比较,请计算

RMS_x=sqrt(x[0]*x[0] + x[1]*x[1] + ... + x[n]*x[n])
RMS_y=sqrt(y[0]*y[0] + y[1]*y[1] + ... + y[n]*y[n])

最后,

Error=abs(RMS_x - RMS_y)

这个错误越少,FFT/iFFT 的质量就越好。


1

检查FFT的简单方法是对正弦信号进行FFT变换。输出应该是除了一些非零值之外全部为零。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接