irfft static method
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);
}
}