Having Glitches trying to use a Sinc Function Interpolation on a Signal, by chunks of 1024 samples I am trying to interpolate a signal using a third party lib that performs Sinc Function Interpolation on a signal. It works well if I input all the samples at once but introduce phase distortion if I try to perform by block of 1024 samples.

Some context:
I am trying to increase or reduce the playback speed of an audio loop.
The audio loop is a stereo interleaved samples with a total of 352,800 samples (176,400 stero frames).

It works flawlessly when I input all the 352,800 samples at once, but this can't be performed real time.
Instead, I try to feed it with chunks of 1024 samples as requested by the audio interface.

To do that, I first calculate how much I have to feed the interpolation function to get an interpolated result that fits this requirement:

// how much samples we need to prune in the original samples
let to_take = asked_size * playback_rate;


Then I pass theses samples to the interp function that spits out excaclty 'asked_size' samples, theses samples have been interpolated.

The interpolation function takes the following parametters:


samples: the samples buffer to be interpolated (1024*playback_rate)
sinc function (this is the sinc function as in the lib).
playback_rate
delay (which I set to 0.0)
wing (how many samples to looks from each sides for interpolation / convolution).


When the playback rate is 1, everything is smooth, but when I move this value, the global signal get distorded, because there is gaps between the first sample of the next buffer and the last sample of the previous buffer that I send to audio.

I suspect there is something to do with the phase, or something to do with the fact that the interp function miss some contexts on previous chunks of samples (blocks of 1024) for the outpout (concatenation of all the blocks of 1024) to be seemsless, and this results in nasty distorted audio.

How should I correct this behaviour ?

EDIT: Added implementation in Rust:

// block loop
pub fn next_block(&amp;mut self, size: usize) -&gt; Vec&lt;Stereo&lt;f32&gt;&gt; {

  // how much we need to prune
  let to_take = ((size as f64) * self.playback_rate) as usize;

  // to interleaved samples (original frame format is Vec&lt;[f32, 2]&gt;)
  let interleaved: Vec&lt;f32&gt; = self.take(to_take)
     .flat_map(|x| x.to_vec()).collect();

  // to complex DspVec data struct
  let mut complex = interleaved.to_complex_time_vec();

  // interpolation is HERE !
  complex.interpolatef(
    &amp;mut self.interp_buffer,
    &amp;self.sinc_function,
    (1.0 / self.playback_rate) as f32,
    0.0,
    16,
  );

  // re-frame the signal
  let chunked = complex.to_slice().chunks(2);
  let mut out = Vec::new();
  for chunk in chunked {
    let c = [chunk[0], chunk[1]];
    out.push(c);
  }

  // send full buffer
  return out;


}
Ah, that's interpolatef (it's in vector/src/vector_types/time_freq/interpolation.rs).

I'm not fluent in Rust, but I think it calculates the interpolation by:


Taking in a function (a real impulse response), and generating sampled vectors of that, with fractional offsets.
It uses that polyphase filterbank to do the arbitrary resampling


You could hence just "prepend" every chunk with conv_len samples, and then "throw away" the right amount of samples from the beginning of the result. 

However, that might be hard: Since this function allows for arbitrary real resampling ratios, conv_length * interpolation_factor might not be an integer.

So, the easiest thing would probably to restrict yourself to rational resampling ratios, here, and always transport a number of samples $n \ge \text{conv_len}$ with $\mathbb N \ni n = \frac m{\text{conv_len}}$ so that you can always throw away an integer amount of samples.