我试图了解如何将vDSP函数用于STFT。所以我使用来自apple的expamles的FFT代码,我可以获得前1024帧的FFT,但是如何获得下一个1024 - 2047帧的FFT,依此类推,直到文件结束..(在这种情况下,我想象文件的大小是int f = 10000)。
//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);
答案 0 :(得分:1)
如果您只想要接下来的1024个元素的FFT,请将nOver2添加到A.realp和A.imagp,然后执行另一个vDSP_fft_zripD和另一个vDSP_ztocD。您可能也想提前获得GettingReal,否则新结果将覆盖旧结果。
请注意,更改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中的相同空间。