irfft static method

Float32List irfft(
  1. Float32List real,
  2. Float32List imag, {
  3. int? n,
})

Computes the inverse real FFT from a packed positive-frequency spectrum.

real and imag must contain the non-redundant rfft spectrum: DC, positive frequencies, and Nyquist when n is even.

If n is omitted, the output length is inferred as 2 * (bins - 1), where bins == real.length. This matches the common FFT convention for reconstructing a real signal from an rfft result.

If n is provided, it is interpreted as the real-domain output length. The expected packed spectrum length then becomes n ~/ 2 + 1. Inputs are truncated or zero-padded to that packed length before the inverse transform.

Returns a real-valued time-domain signal of length n.

Implementation

static Float32List irfft(Float32List real, Float32List imag, {int? n}) {
  if (real.length != imag.length) {
    throw ArgumentError('real and imag must have the same length');
  }

  final inputBins = real.length;
  final outLen = n ?? (2 * (inputBins - 1));
  final bins = yl_rfft_bins(outLen);

  final plan = yl_fft_plan_c2r_create(outLen);
  if (plan == ffi.nullptr) {
    throw StateError('yl_fft_plan_c2r_create($outLen) returned nullptr');
  }

  ffi.Pointer<ffi.Float> realInPtr = ffi.nullptr;
  ffi.Pointer<ffi.Float> imagInPtr = ffi.nullptr;
  ffi.Pointer<ffi.Float> realOutPtr = ffi.nullptr;

  try {
    realInPtr = calloc<ffi.Float>(bins);
    imagInPtr = calloc<ffi.Float>(bins);
    realOutPtr = calloc<ffi.Float>(outLen);

    final copyLen = math.min(real.length, bins);
    realInPtr.asTypedList(bins).setRange(0, copyLen, real);
    imagInPtr.asTypedList(bins).setRange(0, copyLen, imag);

    final outReal = Float32List(outLen);

    yl_fft_plan_execute_c2r(plan, realInPtr, imagInPtr, realOutPtr);

    outReal.setAll(0, realOutPtr.asTypedList(outLen));

    return outReal;
  } finally {
    if (realInPtr != ffi.nullptr) calloc.free(realInPtr);
    if (imagInPtr != ffi.nullptr) calloc.free(imagInPtr);
    if (realOutPtr != ffi.nullptr) calloc.free(realOutPtr);
    yl_fft_plan_destroy(plan);
  }
}