2017-01-27 2 views
1

J'utilise FFTW3 pour effectuer un fft sur plusieurs colonnes de données (c'est-à-dire l'audio multicanal, où je désire la transformation de chaque canal). Cela fonctionne bien sur OSX, mais le portage du code sur Linux me donne un défaut de seg.Faute de segmentation de plan FFTW

const int fftwFlags = FFTW_PRESERVE_INPUT|FFTW_PATIENT; 

struct fft { 
    fftw_complex **complexSig; 
    double **realSig; 
    fftw_plan forwardR2C; 
    int fftLen; 
    int numChan; 
} 

void create FFT(struct fft *fft) { 

int bufLen = 1024; 
int numChan = 4; 
fft->fftLen = bufLen; 
fft->numChan = numChan; 

fft->realSig = fftw_malloc(sizeof(double *) * numChan); 
for(int i = 0; i < numChan; i++) { 
    fft->realSig[i] = fftw_malloc(sizeof(double) * bufLen); 
} 

fft->complexSig = fftw_malloc(sizeof(fftw_complex *) * numChan); 
for(int i = 0; i < numChan; i++) { 
    fft->complexSig[i] = fftw_malloc(sizeof(fftw_complex) * bufLen); 
} 

fft->forwardR2C = fftw_plan_many_dft_r2c(1, &fft->fftLen, fft->numChan, *fft->realSig, &fft->fftLen, 1, fft->fftLen, *fft->complexSig, &fft->fftLen, 1, fft->fftLen, fftwFlags); 

} 

valgrind montre que le planificateur de fftw tente d'accéder après la fin de cette matrice (par 8 octets, un échantillon), ce qui entraîne une erreur de segmentation. Lorsque vous augmentez la quantité de mémoire allouée à realSig à bufLen * 2, cette erreur est absente.

Je suis sûr que c'est une erreur dans la façon dont je dis à FFTW de lire mes données, mais je ne peux pas le voir!

+0

tant de variables inconnues .... ce qui est fftLen et buflen et numCha et et et –

+0

juste la question :) éditables La les variables sont automatiquement définies en fonction de ce que le périphérique d'entrée est, donc j'ai oublié de clarifier! – Rampartisan

Répondre

1

Vous semblez supposer que les appels malloc successifs seront contigus, ce qui est bien sûr peu probable (vous avez probablement "eu de la chance" sur OS X). Vous pouvez résoudre ce problème assez facilement en effectuant une allocation importante, par ex.

void createFFT(struct fft *fft) 
{ 
    const int bufLen = 1024; 
    const int numChan = 4; 

    fft->fftLen = bufLen; 
    fft->numChan = numChan; 

    fft->realSig = fftw_malloc(sizeof(double *) * numChan); 
            // array of numChan pointers 
    fft->realSig[0] = fftw_malloc(sizeof(double) * numChan * bufLen); 
            // one large contiguous block of size `numChan * bufLen` 
    for(int i = 1; i < numChan; i++) // init pointers 
    { 
     fft->realSig[i] = fft->realSig[i - 1] + bufLen; 
    } 

    // ... 

} 

Remarque: lorsque vous avez fini avez juste besoin:

fftw_free(fft->realSig[0]); 
+1

Excellente réponse, je supposais en effet que les appels malloc successifs donneraient une mémoire contiguë. Et en revenant sur le fftw doc [ici] (http://www.fftw.org/doc/Advanced-Complex-DFTs.html) j'informais aussi le planificateur fftw que ma "matrice" était contiguë, avec istride/ostride de 1. – Rampartisan