Time ratio should be constrained, out-of-range ratios can cause division-by-zero

(Formerly Bitbucket issue 4, filed by RJ Skerry-Ryan)

RJ writes:

Using librubberband 1.8.1 and current tip in realtime mode with all default settings (sample rate 44100) I can reliably cause a zero-division SIGFPE by setting the time ratio appropriately high.

An example time ratio is 6400. The input increment becomes 0. Since lots of places in the code divide by the input increment without checking for zero, this causes division-by-zero SIGFPEs.

Looking through RubberBandStretcher::Impl::calculateSizes():464, the input increment is assigned to be the output increment divided by the effective time ratio. For default settings, 44.1kHz and pitch ratio of 1.0 inputIncrement becomes 0 for a time ratio of 256 and higher. Using a larger FFT window size doubles this to 512 (since the FFT window size is in the numerator of the increment calculation).

I don't see any mention in the documentation of a maximum value for the time ratio or a way to check what the maximum value is given the window size. Is there a way to detect what the max time ratio should be? I could hack some heuristics in but since the maximum value is affected by the pitch ratio and the FFT window size I would end up having to build assumptions about RB's implementation into my code. I can also check for 0 inputIncrement and do a scan upwards to find the lowest value but this is also something I'd rather not do in an audio callback :).

For more info, here's the bug in our project: https://bugs.launchpad.net/ubuntu/+bug/1263233

Assigned to
8 months ago
8 months ago
No labels applied.

~breakfastquay 8 months ago

Added a check (in commit:f9a50353f998) for inputIncrement < 1 and to increase the input and output increments and window size accordingly.

We should still check & at least document a maximum stretch factor anyway, as the windowing doesn't work correctly for such extreme values - a factor of 640 works well but 6400 still does not, this fix notwithstanding.