resample function
Resamples the input
audio to the given outputLength
.
Returns a new array of length outputLength
containing the resampled
input
. Doesn't modify the input array.
This function FFTs the input, truncates or zero pads the frequencies to the output length, then IFFTs to get the output. This isn't the best way of resampling audio. It's intended to be simple and good enough for most purposes. A more typical approach is convolution with a windowed sinc function, which will often be more efficient and produce better results, but requires a bit more design work to match the parameters to the use case. If you just want something that works well enough, this function is a good starting point.
Implementation
Float64List resample(List<double> input, int outputLength) {
if (input.length == outputLength) {
return Float64List.fromList(input);
}
final inf = FFT(input.length).realFft(input).discardConjugates();
final outflen = ComplexArray.discardConjugatesLength(outputLength);
late Float64x2List outf;
if (outflen < inf.length) {
// Truncate.
outf = Float64x2List.sublistView(inf, 0, outflen);
} else {
// Zero pad.
outf = Float64x2List(outflen);
for (int i = 0; i < inf.length; ++i) {
outf[i] = inf[i];
}
}
final out =
FFT(outputLength).realInverseFft(outf.createConjugates(outputLength));
// Resampling like this changes the amplitude, so we need to fix that.
final ratio = outputLength.toDouble() / input.length;
for (int i = 0; i < out.length; ++i) {
out[i] *= ratio;
}
return out;
}