Как вы выполняете БПФ файла WAV на iPhone? - PullRequest
5 голосов
/ 21 октября 2010

Я должен выполнить БПФ для файла .wav в приложении iPhone. Я видел там алгоритмы FFT, но как мне разобрать файл WAV и использовать его в таком алгоритме?

Должен ли я преобразовать WAV-файл в NSData или что-то еще?

Кто-нибудь ранее успешно выполнил БПФ файла WAV на iPhone? Я пытался использовать iPhoneFFT для этого, но безуспешно.

Например, код там гласит

 // 2. Then fill up an array with data with your own function
   fillUpInputSignalWithMyData(myFFT.inputData);

Как бы я передал данные из файла WAV что-то вроде этого?

Ответы [ 3 ]

6 голосов
/ 29 октября 2010
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;
}

Вот так. Я получаю массив спектра мощности. Я проверил образец синусоидальной волны. Работает нормально.

4 голосов
/ 21 октября 2010

Изучите ваши типы данных Си.

БПФ обычно может принимать данные в виде массива C одного из нескольких типов данных C (не NSArray) ... это включает в себя встроенные в iOS 4 встроенные FFT Accelerate Framework.Типы могут быть массивом коротких, длинных, плавающих или двойных чисел.Выполнение FFT с использованием коротких операций с плавающей точкой обычно является самым быстрым на большинстве последних устройств iOS.Проверьте, какой тип данных требует выбранный вами БПФ.Многие требуют, чтобы реальный вектор и мнимый вектор использовались в качестве комплексных входных данных.

В наиболее распространенном файле wav есть только 1 блок с 44-байтовым заголовком, а затем необработанные данные PCM в виде массива коротких целых чисел, с чередованием моно или стерео.,Просто преобразуйте этот массив в тип данных, требуемый БПФ.Для монофонических данных может сработать что-то простое:

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

(Но вам необходимо проверить тип имеющегося у вас волнового файла и параметры FFT, необходимые для этого!)

1 голос
/ 21 октября 2010

Ну, согласно: http://github.com/alexbw/iPhoneFFT/blob/master/OouraFFT.h

Вы используете:

double *inputData;

Итак, вы откроете () файл wav, избавитесь от заголовков и получите двойной массив.

...