Skip to content

File fft_core.h

FileList > fft > fft_core.h

Go to the source code of this file

Per-instance 1-D FFT using pocketfft directly. More...

  • #include "clib_common.h"
  • #include "pocketfft/pocketfft.h"

Classes

Type Name
struct fft_state_t

Public Functions

Type Name
fft_state_t * fft_create (size_t n, int sign, int nthreads)
Allocate a reusable 1-D FFT engine for a fixed length and sign. Two pocketfft plans are created at construction time — one for CF64 and one for CF32 — so execute calls carry no plan-setup overhead. The same instance may be called repeatedly for independent input vectors of the same length. nthreads is accepted for API parity but is ignored; pocketfft plans are single-threaded.
void fft_destroy (fft_state_t * state)
Destroy and free an fft instance.
size_t fft_execute_cf32 (fft_state_t * state, const float complex * in, size_t n_in, float complex * out)
Compute an out-of-place 1-D DFT on a single-precision complex input. Identical to fft_execute_cf64() but operates on float complex (CF32) buffers, halving memory bandwidth relative to the double-precision variant. Output is unnormalised;in andout must not alias.
size_t fft_execute_cf32_max_out (fft_state_t * state)
Maximum output samples for CF32 execute (always == n).
size_t fft_execute_cf64 (fft_state_t * state, const double complex * in, size_t n_in, double complex * out)
Compute an out-of-place 1-D DFT on a double-precision complex input. The output is written to a fresh caller-supplied buffer; in andout must not alias. The transform is unnormalised: the inverse DFT (sign=+1) does NOT divide by n. Both buffers must be exactly state->n elements long.
size_t fft_execute_cf64_max_out (fft_state_t * state)
Maximum output samples per execute call (always == n).
size_t fft_execute_ci16 (fft_state_t * state, const int16_t * in, size_t n_in, float complex * out)
Compute an out-of-place 1-D DFT directly on integer IQ (ci16). in is interleaved int16 I/Q (2 ints per complex sample, length 2*n); the result is float complex (CF32). The int->float scale (v/32768, full-scale ±1.0, matching the cvt module) is folded into the transform's input read, so this is a single fused pass — faster than a separate i16_to_f32 conversion followed byfft_execute_cf32() . Output is unnormalised.
size_t fft_execute_ci16_max_out (fft_state_t * state)
Maximum output samples for the ci16 execute (always == n).
size_t fft_execute_ci8 (fft_state_t * state, const int8_t * in, size_t n_in, float complex * out)
Compute an out-of-place 1-D DFT directly on integer IQ (ci8). As fft_execute_ci16() butin is interleaved int8 I/Q (scale v/128).
size_t fft_execute_ci8_max_out (fft_state_t * state)
Maximum output samples for the ci8 execute (always == n).
size_t fft_execute_inplace_cf32 (fft_state_t * state, const float complex * in, size_t n_in, float complex * out)
Copy in intoout , then transformout in-place (CF32). Single-precision variant offft_execute_inplace_cf64() . Copies state->n CF32 samples fromin toout , then transformsout with the CF32 pocketfft plan.in is left unmodified.
size_t fft_execute_inplace_cf32_max_out (fft_state_t * state)
Maximum output samples for inplace CF32 (always == n).
size_t fft_execute_inplace_cf64 (fft_state_t * state, const double complex * in, size_t n_in, double complex * out)
Copy in intoout , then transformout in-place (CF64). The copy step lets callers preserve their input while keeping the output buffer hot in cache. Semantically identical tofft_execute_cf64() for separatein /out pointers; use this variant when the caller already ownsout and wants the result there without a second allocation.
size_t fft_execute_inplace_cf64_max_out (fft_state_t * state)
Maximum output samples for inplace CF64 (always == n).
void fft_reset (fft_state_t * state)
No-op reset (plans are immutable after creation).

Detailed Description

Holds two pocketfft plans — one for CF64, one for CF32 — allocated at create time for the requested transform length and sign. nthreads is accepted for API compatibility but ignored; pocketfft is single-threaded.

Lifecycle:

fft_state_t *fft = fft_create(1024, -1, 1);
double complex out[1024];
fft_execute_cf64(fft, in, 1024, out);
fft_destroy(fft);

Public Functions Documentation

function fft_create

Allocate a reusable 1-D FFT engine for a fixed length and sign. Two pocketfft plans are created at construction time — one for CF64 and one for CF32 — so execute calls carry no plan-setup overhead. The same instance may be called repeatedly for independent input vectors of the same length. nthreads is accepted for API parity but is ignored; pocketfft plans are single-threaded.

fft_state_t * fft_create (
    size_t n,
    int sign,
    int nthreads
) 

Parameters:

  • n Transform length in samples (power of two recommended).
  • sign -1 for the forward DFT, +1 for the inverse DFT.
  • nthreads Accepted for API compatibility; ignored.

Returns:

Heap-allocated state, or NULL on allocation failure.

>>> from doppler.spectral import FFT
>>> import numpy as np
>>> fft = FFT(n=4, sign=-1, nthreads=1)
>>> fft.n, fft.sign
(4, -1)
>>> x = np.array([1, 0, 0, 0], dtype=np.complex64)
>>> fft.execute_cf32(x).tolist()
[(1+0j), (1+0j), (1+0j), (1+0j)]


function fft_destroy

Destroy and free an fft instance.

void fft_destroy (
    fft_state_t * state
) 

Parameters:

  • state May be NULL.

function fft_execute_cf32

Compute an out-of-place 1-D DFT on a single-precision complex input. Identical to fft_execute_cf64() but operates on float complex (CF32) buffers, halving memory bandwidth relative to the double-precision variant. Output is unnormalised;in andout must not alias.

size_t fft_execute_cf32 (
    fft_state_t * state,
    const float complex * in,
    size_t n_in,
    float complex * out
) 

Parameters:

  • state Allocated FFT engine (non-NULL).
  • in Input buffer of length state->n (CF32, row-major).
  • n_in Number of input samples; must equal state->n.
  • out Output buffer of length >= state->n (CF32, caller-allocated).

Returns:

n (number of samples written).

>>> from doppler.spectral import FFT
>>> import numpy as np
>>> fft = FFT(n=4, sign=-1)
>>> x = np.ones(4, dtype=np.complex64)
>>> fft.execute_cf32(x).tolist()
[(4+0j), 0j, 0j, 0j]


function fft_execute_cf32_max_out

Maximum output samples for CF32 execute (always == n).

size_t fft_execute_cf32_max_out (
    fft_state_t * state
) 


function fft_execute_cf64

Compute an out-of-place 1-D DFT on a double-precision complex input. The output is written to a fresh caller-supplied buffer; in andout must not alias. The transform is unnormalised: the inverse DFT (sign=+1) does NOT divide by n. Both buffers must be exactly state->n elements long.

size_t fft_execute_cf64 (
    fft_state_t * state,
    const double complex * in,
    size_t n_in,
    double complex * out
) 

Parameters:

  • state Allocated FFT engine (non-NULL).
  • in Input buffer of length state->n (CF64, row-major).
  • n_in Number of input samples; must equal state->n.
  • out Output buffer of length >= state->n (CF64, caller-allocated).

Returns:

n (number of samples written).

>>> from doppler.spectral import FFT
>>> import numpy as np
>>> fft = FFT(n=4, sign=-1)
>>> x = np.array([1, 0, 0, 0], dtype=np.complex128)
>>> fft.execute_cf64(x).tolist()
[(1+0j), (1+0j), (1+0j), (1+0j)]


function fft_execute_cf64_max_out

Maximum output samples per execute call (always == n).

size_t fft_execute_cf64_max_out (
    fft_state_t * state
) 


function fft_execute_ci16

Compute an out-of-place 1-D DFT directly on integer IQ (ci16). in is interleaved int16 I/Q (2 ints per complex sample, length 2*n); the result is float complex (CF32). The int->float scale (v/32768, full-scale ±1.0, matching the cvt module) is folded into the transform's input read, so this is a single fused pass — faster than a separate i16_to_f32 conversion followed byfft_execute_cf32() . Output is unnormalised.

size_t fft_execute_ci16 (
    fft_state_t * state,
    const int16_t * in,
    size_t n_in,
    float complex * out
) 

Parameters:

  • state Allocated FFT engine (non-NULL).
  • in Interleaved int16 I/Q, 2*state->n samples.
  • n_in Number of complex samples; must equal state->n.
  • out Output buffer of length >= state->n (CF32, caller-allocated).

Returns:

n (number of complex samples written).

>>> import numpy as np
>>> from doppler.spectral import FFT
>>> fft = FFT(n=4, sign=-1)
>>> iq = np.full(8, 32768 // 4, dtype=np.int16)   # ~0.25 + 0.25j, full-scale
>>> np.round(fft.execute_ci16(iq).real, 3).tolist()
[1.0, 0.0, 0.0, 0.0]


function fft_execute_ci16_max_out

Maximum output samples for the ci16 execute (always == n).

size_t fft_execute_ci16_max_out (
    fft_state_t * state
) 


function fft_execute_ci8

Compute an out-of-place 1-D DFT directly on integer IQ (ci8). As fft_execute_ci16() butin is interleaved int8 I/Q (scale v/128).

size_t fft_execute_ci8 (
    fft_state_t * state,
    const int8_t * in,
    size_t n_in,
    float complex * out
) 

Parameters:

  • state Allocated FFT engine (non-NULL).
  • in Interleaved int8 I/Q, 2*state->n samples.
  • n_in Number of complex samples; must equal state->n.
  • out Output buffer of length >= state->n (CF32, caller-allocated).

Returns:

n (number of complex samples written).

>>> import numpy as np
>>> from doppler.spectral import FFT
>>> fft = FFT(n=4, sign=-1)
>>> iq = np.full(8, 32, dtype=np.int8)            # 0.25 + 0.25j, full-scale
>>> np.round(fft.execute_ci8(iq).real, 3).tolist()
[1.0, 0.0, 0.0, 0.0]


function fft_execute_ci8_max_out

Maximum output samples for the ci8 execute (always == n).

size_t fft_execute_ci8_max_out (
    fft_state_t * state
) 


function fft_execute_inplace_cf32

Copy in intoout , then transformout in-place (CF32). Single-precision variant offft_execute_inplace_cf64() . Copies state->n CF32 samples fromin toout , then transformsout with the CF32 pocketfft plan.in is left unmodified.

size_t fft_execute_inplace_cf32 (
    fft_state_t * state,
    const float complex * in,
    size_t n_in,
    float complex * out
) 

Parameters:

  • state Allocated FFT engine (non-NULL).
  • in Source buffer, state->n CF32 samples; not modified.
  • n_in Number of input samples; must equal state->n.
  • out Destination buffer, length >= state->n; must not alias in.

Returns:

n (number of samples written).

>>> from doppler.spectral import FFT
>>> import numpy as np
>>> fft = FFT(n=4, sign=-1)
>>> x = np.array([1, 0, 0, 0], dtype=np.complex64)
>>> fft.execute_inplace_cf32(x).tolist()
[(1+0j), (1+0j), (1+0j), (1+0j)]


function fft_execute_inplace_cf32_max_out

Maximum output samples for inplace CF32 (always == n).

size_t fft_execute_inplace_cf32_max_out (
    fft_state_t * state
) 


function fft_execute_inplace_cf64

Copy in intoout , then transformout in-place (CF64). The copy step lets callers preserve their input while keeping the output buffer hot in cache. Semantically identical tofft_execute_cf64() for separatein /out pointers; use this variant when the caller already ownsout and wants the result there without a second allocation.

size_t fft_execute_inplace_cf64 (
    fft_state_t * state,
    const double complex * in,
    size_t n_in,
    double complex * out
) 

Parameters:

  • state Allocated FFT engine (non-NULL).
  • in Source buffer, state->n CF64 samples; not modified.
  • n_in Number of input samples; must equal state->n.
  • out Destination buffer, length >= state->n; must not alias in.

Returns:

n (number of samples written).

>>> from doppler.spectral import FFT
>>> import numpy as np
>>> fft = FFT(n=4, sign=-1)
>>> x = np.array([1, 0, 0, 0], dtype=np.complex128)
>>> fft.execute_inplace_cf64(x).tolist()
[(1+0j), (1+0j), (1+0j), (1+0j)]


function fft_execute_inplace_cf64_max_out

Maximum output samples for inplace CF64 (always == n).

size_t fft_execute_inplace_cf64_max_out (
    fft_state_t * state
) 


function fft_reset

No-op reset (plans are immutable after creation).

void fft_reset (
    fft_state_t * state
) 



The documentation for this class was generated from the following file native/inc/fft/fft_core.h