如何在iPhone上对WAV文件执行FFT?

5
我需要在iPhone应用程序中对.wav文件执行FFT。 我看到了一些FFT算法,但我该如何解析WAV文件并在这种算法中使用呢?
我应该将WAV文件转换为NSData或其他格式吗?
有人在iPhone上成功地对WAV文件执行过FFT吗? 我尝试使用iPhoneFFT进行此操作,但没有成功。
例如,那里的代码说明:
 // 2. Then fill up an array with data with your own function
   fillUpInputSignalWithMyData(myFFT.inputData);

我该如何将WAV文件中的数据提供给类似于这样的东西?

3个回答

6
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];
for (int i=0;i<=8192;i++) {
NSLog(@"the spectrum data %d is  %f ",i,myFFT.spectrumData[i]);

}

我创建了一个名为 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;
}

就是这样。我得到了功率谱数组。我已经用样例正弦波进行了检查,一切都工作正常。


你好,战士。谢谢你的代码,我解决了我的问题,但是我发现它只适用于静态文件。如果我将该文件路径转换为TSLibraryImport类,应用程序会崩溃并且无法显示输出。请尽力帮助我。 - Kartik
1
@Warrior,请问我该如何使用你的类?MyAudioFile类是什么类型?packerCount、mAudioFile、mASBD等是什么意思?抱歉提出这样混乱的问题。 - majorl3oat

4

学习C语言数据类型。

FFT通常可以将数据作为C数组的一种形式进行处理,其中包括iOS 4内置的加速框架FFT。这些类型可能是short int、long int、float或double的数组。在大多数最近的iOS设备上,使用short float执行FFT通常是最快的。检查所选FFT需要哪种数据类型。许多需要实向量和虚向量作为复杂输入。

最常见的wav文件只有一个44字节的头块,然后是原始PCM数据,作为短整数数组,可以是单声道或立体声交错。只需将此数组转换为FFT所需的数据类型即可。对于单声道数据,可以使用以下简单方法:

for (i=0;i<n;i++) { 
    myFloatArray_RealPart[i] = wavInts[i+22]; 
    myFloatArray_ImaginaryPart[i] = 0.0; 
}

(但是您需要验证您拥有的波形文件类型和所需的FFT参数,以确保正确!)

请详细说明代码。我卡住了。如何将.wav文件作为输入。 - Warrior

1

我不懂C语言,你能给一些打开wav文件并获取双精度数组的代码吗? - Warrior

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