2012-07-13 117 views
0

我試圖瞭解如何使用STFT的vDSP函數。所以我使用蘋果expamles的FFT代碼,我可以得到前1024幀的FFT,但我怎麼能得到接下來的1024 - 2047幀的FFT等等,直到文件結尾..(在這種情況下,我想象文件的大小是int f = 10000)。如何使用vDSP函數進行短時傅立葉變換?

//vDSP variables 
DOUBLE_COMPLEX_SPLIT A; 
FFTSetupD setupReal; 
uint32_t log2n; 
uint32_t n, nOver2; 
int32_t stride; 
double *obtainedReal; 
double scale; 

log2n = N; 
n = 1 << log2n; 

stride = 1; 
nOver2 = n/2; 

int f = 10000; 

buffer = malloc(f *sizeof(double)); 
obtainedReal = malloc(f *sizeof(double)); 
A.realp = malloc(f *sizeof(double)); 
A.imagp = malloc(f *sizeof(double)); 

vDSP_ctozD((DOUBLE_COMPLEX*) buffer, 2, &A, 1, nOver2); 
setupReal = vDSP_create_fftsetupD(log2n, FFT_RADIX2); 

if (setupReal == NULL) { 
    NSLog(@"fft_setup failed to allocate enough memory for real FFT\n"); 
return 0 ; 
    } 

vDSP_fft_zripD(setupReal, &A, stride, log2n, FFT_FORWARD); 

scale = (double) 1.0/(2 * n); 

vDSP_vsmulD(A.realp, 1, &scale, A.realp, 1, nOver2); 
     vDSP_vsmulD(A.imagp, 1, &scale, A.imagp, 1, nOver2); 

vDSP_ztocD(&A, 1, (DOUBLE_COMPLEX *) obtainedReal, 2, nOver2); 

回答

1

如果您只是想下一個1024元的FFT,加nOver2到A.realp和A.imagp,然後執行另一個vDSP_fft_zripD和另一vDSP_ztocD。您可能還想提前獲取RealReal,否則新結果將覆蓋舊結果。

請注意,更改A.realp和A.imagp會丟失起始地址,因此除非您在更改A.realp和A.imagp之前重新計算起始地址或將它們保存在別處,否則將無法釋放此內存。

此外,10,000不是1024的整數倍,因此您的最後一部分不會有1024個元素,因此您需要找出一個替代方案,例如獲取更多數據或用零填充數據。

您正在爲A.realp和A.imagp分配太多內存。它們中的每一個接收緩衝區中的一半元素,所以它們每個只需要一半的內存。

即使那麼多的內存是不需要的。您可以使用vDSP_ctozD僅將1024個元素移動到A.realp和A.imagp(每個512個)中,然後執行FFT,然後使用vDSP_ztocD將數據移動到obtainReal,然後使用vDSP_ctozD將1024個新元素移動到下一個組元素放入以前使用的A.realp和A.imagp中的相同空間中。

+0

謝謝!如何將nOver2添加到A.realp和A.imagp。你可以在代碼中顯示這個嗎? :-) – andrey 2012-07-13 19:39:49

+0

'A.realp + = nOver2; A.imagp + = nOver2;' – 2012-07-13 19:40:46

+0

非常感謝! – andrey 2012-07-13 20:00:04