bmcfee / resampy

Efficient sample rate conversion in python
https://resampy.readthedocs.io
ISC License
253 stars 36 forks source link

Bringing import time back down #108

Closed bmcfee closed 2 years ago

bmcfee commented 2 years ago

The guvectorize implementation in 0.3.1 uses a full set of build targets for all supported dtypes:

https://github.com/bmcfee/resampy/blob/29d34876a61fcd74e72003ceb0775abaf6fdb961/resampy/interpn.py#L117-L142

This works to preserve dtypes of inputs, but it causes a huge compilation on every import. This could be amortized by using cache=True, but numba appears to have a pretty serious bug with guvectorize and cache that's causing SIGABRT on repeat runs.

The alternative here is to drop explicit signatures and JIT everything. This brings our import time back down to something reasonable. But it also has the effect of breaking integer resampling support.

Integer-valued resampling is rather dicey territory IMO. I actually don't think the way it's handled in 0.3.1 is "correct" because it will accumulate rounded (floored) values during convolution, rather than accumulate first and then round.

The way I see it, we have a few options here:

  1. Drop support for integer values entirely, and fail noisily.
  2. Accept integer input, but produce floating output (float32). This is what, eg, samplerate and scipy.signal resamplers do.
  3. Detect integer types and force-cast the output before returning. This would preserve dtypes at the cost of a second memory copy. AFAIK the only library that provides this kind of interface (aside from resampy 0.3.1) is soxr.

I'm currently leaning toward option (2), though it would technically cause API breakage and bump us to 0.4.