Как проверить результаты FFT в iphone? - PullRequest
3 голосов
/ 28 октября 2010

Я сделал БПФ для аудиофайла, используя OouraFFTl. Как проверить правильность или неправильность вывода сэмплирования. Какой лучший и простой способ проверить это. Это мой код.

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

Вам нужно нанести на график величину выходного сигнала БПФ.Я не знаком с вашим языком программирования, но в Python вы бы использовали что-то вроде plot(abs(fft(a))).Для тихого ввода на выходе должны быть все нули.Для синусоидального входа вы должны увидеть два пика:

alt text

Для реального сигнала, пики будут симметричны слева направо.Если вы делаете реальное БПФ , хотя (что более эффективно с точки зрения вычислений) вы получите только левую половину графика в качестве выходных данных, поскольку оно игнорирует избыточное зеркальное отображение.1010 * Если частота выше, шипы будут ближе к центру.Если частота идеально синхронизируется с размером фрагмента , шип будет иметь ширину всего в одну точку, а все остальное будет очень близко к 0. В противном случае у него будет сужающаяся «юбка», как указано выше.*

1 голос
/ 02 ноября 2010

Самый распространенный способ - взять БПФ, а затем преобразовать полученный частотный спектр с помощью iFFT (обратное быстрое преобразование Фурье) обратно во временную область. Затем вы должны сравнить ваш входной сигнал времени с полученным сигналом времени. Самый простой способ сравнения - это вычислить разницу между RMS.

Пример:

Дан временный сигнал x длины n. Найдите X=FFT(x), затем найдите y=iFFT(X). у будет такой же длины п. Затем, чтобы сравнить 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 голос
/ 28 октября 2010

Простой способ проверить БПФ - взять БПФ синусоидального сигнала. На выходе должны быть все нули, кроме десятка ненулевых значений.

...