我正在开发一个SDR程序,我有来自RTL2832加密狗的数据队列,另一个队列等待通过FFTW(在另一个线程中),另一个队列等待在另一个线程中显示。
我曾经使用静态计划数组,但现在我想切换到动态分配的计划。 喜欢:
//fftwf_plan fftplan[NUMFFT];
fftwf_plan *fftplan; // dynamic version
然后我就这么做了
fftplan = calloc(NUMFFT,sizeof(fftwf_plan));
为了填充数组,我这样做:
fftplan[i] = fftwf_plan_dft_1d(fftsize,fftin[i],fftout[i],FFTW_FORWARD,FFTW_ESTIMATE);
现在运行时会出现段错误,我有点无能为力。 我一年多前就弄清楚了 FFT 部分,但我还没有跟上它的速度。 它与静态数组一起使用。 我几乎不明白 **,现在我正在尝试用不透明指针填充动态数组。 我认为这主要是一个 C 问题,而不是 FFT 问题,但我认为我不能在这里使用 **,因为它是不透明的。
我的数据位于二维数组中,例如
fftwf_complex *fftin[NUMFFT], *fftout[NUMFFT];
基本的 AM 解调就像这样
dpybuf[i] = sqrt(((fftout[lochead][i][0]) * (fftout[lochead][i][0])) + \
((fftout[lochead][i][1]) * (fftout[lochead][i][1])));
也许我不需要为每个缓冲区的数据制定单独的计划。 lochead是循环队列中的位置,i是单个点,末尾的[0]或[1]是实部或虚部。
-------------- edit------------
在进行 SDR 时,通过进行 2 个相隔 90 度的 A/D 转换来数字化无线电波形。 这些被称为 I 和 Q,被视为实数和虚数。 负数没有实际的平方根。
好的,还有一些代码,但整个代码只有几个文件中的几千行。
fftwf_plan *fftplan; // dynamic version [global]
// I tried **fftplan above, it acts the same: compiles OK but segfaults
fftplan = calloc(NUMFFT,sizeof(fftwf_plan));
if (fftplan == NULL) {
fprintf(stderr,"Failed to allocate fftplan[]\n");
exit(1);
}
// fft init (NUMFFT is set at 10, the # of batches in the queue.)
for (i=0;i<NUMFFT; i++) {
fftin[i] = (fftwf_complex *) fftwf_malloc(sizeof(fftwf_complex) * fftsize);
if (fftin[i] == NULL) {
printf("malloc() of space for fftin failed.\n");
perror("malloc ");
exit(1);
}
fftout[i] = (fftwf_complex *) fftwf_malloc(sizeof(fftwf_complex) * fftsize);
if (fftout[i] == NULL) {
printf("malloc() of space for fftout failed.\n");
perror("malloc ");
fftwf_free(fftin);
exit(1);
}
aplan = fftwf_plan_dft_1d(fftsize,fftin[i],fftout[i],FFTW_FORWARD,\
FFTW_ESTIMATE);
printf("plan %i\n",i); // announce progress
fflush(stdout);
fftplan[i] = aplan; // see where it segfaults [here, storing plan 0]
}
fftwf 是 FFTW 的单精度浮点版本。 我只有来自加密狗的 8 位样本,我不需要双倍。
fftsize 现在是我的显示器 X 分辨率,我在这里运行的是 4096 点,现在是 1024
虽然我迟到了,但我在 SDR 申请中遇到了同样的问题。 就我而言,我在类 ctor 中为大小为 128 到 524288 的 FFT 创建多个计划 (fftw3f_plan mFftwfPlans[13])
CSdrClass::CSdrClass()
{
planner::scoped_lock lock(planner::mutex());
uint32_t FftSize = 128 * (1 << 0);
this->mFftwfPlans[0] = fftwf_plan_dft_1d(FftSize, this->mpInput, this->mpOutput, FFTW_FORWARD, FFTW_ESTIMATE);
FftSize = 128 * (1 << 1);
this->mFftwfPlans[1] = fftwf_plan_dft_1d(FftSize, this->mpInput, this->mpOutput, FFTW_FORWARD, FFTW_ESTIMATE);
FftSize = 128 * (1 << 2);
this->mFftwfPlans[2] = fftwf_plan_dft_1d(FftSize, this->mpInput, this->mpOutput, FFTW_FORWARD, FFTW_ESTIMATE);
...
FftSize = 128 * (1 << 12);
this->mFftwfPlans[12] = fftwf_plan_dft_1d(FftSize, this->mpInput, this->mpOutput, FFTW_FORWARD, FFTW_ESTIMATE);
}
...并且,在析构函数中:
CSdrClass::~CSdrClass()
{
planner::scoped_lock lock(planner::mutex());
fftwf_destroy_plan(this->mFftwfPlans[0]);
fftwf_destroy_plan(this->mFftwfPlans[1]);
...
fftwf_destroy_plan(this->mFftwfPlans[12]);
}
果然 - 分段错误,但通常是在销毁 this->mFftwfPlans[1] 时。 我通过将 dtor 中的每个 fftwf_destroy_plan 封装在其自己的作用域锁中来解决该问题:
// Destroy plans
{
planner::scoped_lock lock(planner::mutex());
fftwf_destroy_plan(this->mFftwfPlans[0]);
}
{
planner::scoped_lock lock(planner::mutex());
fftwf_destroy_plan(this->mFftwfPlans[1]);
}
...
{
planner::scoped_lock lock(planner::mutex());
fftwf_destroy_plan(this->mFftwfPlans[12]);
}
fftwf_destroy_plan 语句不再出现分段错误。