1

我试图了解如何将 vDSP 函数用于 STFT。所以我使用苹果示例中的 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);
4

1 回答 1

1

如果您只是想要接下来 1024 个元素的 FFT,请将 nOver2 添加到 A.realp 和 A.imagp,然后执行另一个 vDSP_fft_zripD 和另一个 vDSP_ztocD。您可能也希望提前获取真实值,否则新结果将覆盖旧结果。

请注意,更改 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 将数据移动到 gettingReal,然后使用 vDSP_ctozD 移动到下一个组以移动 1024 个新元素将元素放入之前使用的 A.realp 和 A.imagp 中的同一空间。

于 2012-07-13T14:35:45.307 回答