pytorch / audio

Data manipulation and transformation for audio signal processing, powered by PyTorch
https://pytorch.org/audio
BSD 2-Clause "Simplified" License
2.5k stars 644 forks source link

Resampling at arbitrary time steps #3725

Open pfeatherstone opened 8 months ago

pfeatherstone commented 8 months ago

🚀 The feature

Currently, torchaudio.functional.resample can only resample at regular time points and the period is determined by orig_freq and new_freq.

Is it possible to resample at arbitrary time steps? So rather than specifying a resampling ratio, we specify a array of time steps.

Motivation, pitch

I would like to be able to model jitter in an ADC which can be modelled by a slightly varying sample rate. If you integrate a sample rate curve (which isn't constant), you get irregular time steps. A function such as the one suggested above would allow me to resample using these time steps and model a jittery ADC.

Alternatives

I've rolled out my own function but it's not super efficient. Some experts might do a better job.

Additional context

No response

yoyololicon commented 8 months ago

Does your jitter effect change the sample rate periodically? If so, I think it's possible to reuse part of the resampling algorithm we have. resample finds the lcm of orig_freq and new_freq to pre-compute the since filters and apply them periodically. You can apply the same logic to get the needed since filters between the orig_freq and your modulation frequency (let's name it mod_freq).

If you want something that's more general, like np.interp, unfortunately, we don't have a similar function so far.

pfeatherstone commented 8 months ago

Does your jitter effect change the sample rate periodically? If so, I think it's possible to reuse part of the resampling algorithm we have. resample finds the lcm of orig_freq and new_freq to pre-compute the since filters and apply them periodically. You can apply the same logic to get the needed since filters between the orig_freq and your modulation frequency (let's name it mod_freq).

If you want something that's more general, like np.interp, unfortunately, we don't have a similar function so far.

The jitter is gaussian random and so the sample rate is slightly different at every sample. You can model jitter (I think) as a sample rate that's undergoing a very small gaussian random walk between a minimum and upper bound. You can then calculate the time points by integrating the sample rate over time. Then I need to resample using those time points. So yes, something like np.interp but using a user defined filter, such as kaiser - sinc filter would be appropriate. Currently i'm using a polyphase filter. This works but I think we could do better.

faroit commented 8 months ago

@pfeatherstone You can use https://github.com/aliutkus/torchinterp1d for that purpose. In fact it's exactly what I used it for, implementing differentiable time warping.

pfeatherstone commented 8 months ago

Nice. Except you can't set the filter...

pfeatherstone commented 8 months ago

I'll post the code I have tomorrow. To be honest, it would be great for someone to review