FFTW 复数到实数分段错误

FFTW Complex to Real Segmentation Fault

我正在尝试使用连续的 FFT 帧及时编写短时傅里叶变换的简单实现,使用 FFTW 库计算,但我得到了 Segmentation fault 并且无法弄清楚原因。

我的代码如下:

// load in audio
AudioFile<double> audioFile;    
audioFile.load ("assets/example-audio/file_example_WAV_1MG.wav");
int N = audioFile.getNumSamplesPerChannel();

// make stereo audio mono
double fileDataMono[N];
if (audioFile.isStereo())
    for (int i = 0; i < N; i++)
        fileDataMono[i] = ( audioFile.samples[0][i] + audioFile.samples[1][i] ) / 2;

// setup stft
//              (test transform, presently unoptimized)
int stepSize = 512;
int M = 2048;       // fft size
int noOfFrames = (N-(M-stepSize))/stepSize;

// create Hamming window vector

double w[M];
for (int m = 0; m < M; m++) {
    w[m] = 0.53836 - 0.46164 * cos( 2*M_PI*m / M );
}

double* input;

// (pads input array if necessary)
if ( (N-(M-stepSize))%stepSize != 0) {
    noOfFrames += 1;
    int amountOfZeroPadding = stepSize - (N-(M-stepSize))%stepSize;
    double ipt[N + amountOfZeroPadding];

    for (int i = 0; i < N; i++)         // copy values from fileDataMono into input
        ipt[i] = fileDataMono[i];
    for (int i = 0; i < amountOfZeroPadding; i++)
        ipt[N + i] = 0;
    input = ipt;
} else {
    input = fileDataMono;
}

// compute stft

fftw_complex* stft[noOfFrames];
double frames[noOfFrames][M];

fftw_plan fftPlan;

for (int i = 0; i < noOfFrames; i++) {
    stft[i] = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * M);
    for (int m = 0; m < M; m++)
        frames[i][m] = input[i*stepSize + m] * w[m];
    fftPlan = fftw_plan_dft_r2c_1d(M, frames[i], stft[i], FFTW_ESTIMATE);
    fftw_execute(fftPlan);
}

// compute istft

double* outputFrames[noOfFrames];
double output[N];

for (int i = 0; i < noOfFrames; i++) {
    outputFrames[i] = (double*)fftw_malloc(sizeof(double) * M);
    fftPlan = fftw_plan_dft_c2r_1d(M, stft[i], outputFrames[i], FFTW_ESTIMATE);
    fftw_execute(fftPlan);
    for (int m = 0; i < M; m++) {
        output[i*stepSize + m] += outputFrames[i][m];
    }
}

fftw_destroy_plan(fftPlan);
for (int i = 0; i < noOfFrames; i++) {
    fftw_free(stft[i]);
    fftw_free(outputFrames[i]);
}

// output audio
AudioFile<double>::AudioBuffer outputBuffer;
outputBuffer.resize (1);
outputBuffer[0].resize(N);
outputBuffer[0].assign(output, output+N);
bool ok = audioFile.setAudioBuffer(outputBuffer);

audioFile.setAudioBufferSize (1, N);
audioFile.setBitDepth (16);
audioFile.setSampleRate (8000);
audioFile.save ("out/audioOutput.wav");

在计算正向 STFT 时,第一个 fftw_malloc 似乎引发了段错误。

提前致谢!

相关的代码是:

double* input;
if ( (N-(M-stepSize))%stepSize != 0) {
    double ipt[N + amountOfZeroPadding];
    //...
    input = ipt;
}
//...
input[i*stepSize + m];

您的 input 指针指向仅存在于 if 语句中的内存。右大括号表示 ipt 数组的生命周期结束。稍后取消引用指针时,您正在寻址不再存在的内存。