LagrangeInterpolator with fractional ratio

I am doing sample rate conversion on an audio stream. The input to the stream is at s1 sample rate and the output of the stream should be at s2 sample rate. The ratio to the LagrangeInterpolator is s2/s1. I am receiving a fixed number of samples periodically on the input. If the ratio is fractional, this will produce a varying number of samples on the output. But, the LagrangeInterpolator requires that I specify the number of output samples, instead of the number of input samples. Does this mean I have to be stateful and manage the “extra” sample that should occur every once in a while? Seems like the LagrangeInterpolator is already stateful and should manage this?
Ex: s1 = 44100, s2 = 48000. I am getting, say, 100 samples on the input periodically. Shouldn’t the interface be “here is 100 samples and an oversized output buffer, let me know how many actual output samples you give me?”.

Yes it is. If your stream is interrupted, you should call reset() to reset the 4 last samples, that make the state for interpolation.

The JUCE pipeline model is a pulling model, so it will rather know, how many samples are needed. The process method returns the number of consumed samples. Because you usually don’t know the inter sample position, you cannot exactly predict the number of needed samples.

That’s the reason, why there is an overload, where you can limit the number of samples. That way you avoid to “overread” your input array. It will be filled up with silence, or if you supply the “wrapAround” parameter, it jumps n samples back, which allows to feed from a circular buffer.

Yes it is. If your stream is interrupted, you should call reset() to reset the 4 last samples, that make the state for interpolation.

OK, I understand the reset function.

Let’s expand the example. I have a continuous stream of audio coming in 100 sample chunks. Since I have to specify the output number of samples, I calculate I need 100 * (48000 / 44100) = 108.84 samples in the output buffer. I can ask for 108, and my input buffer of 100 should cover that. So, I move on using asking for 108 every iteration and I get my output samples. But now my actual output sample rate is 44100 * (108 / 100) = 47628. So, that won’t work. Similarly, I can’t use 109 every time. So, I have to sometimes ask for 108, and sometimes ask for 109, and when I ask for 109 I need to come up with another input sample because 100 won’t cover it. This is the problem.

I am using SRC today and it takes care of the above problem inside its state. I am exploring whether I can instead use the Juce LagrangeInterpolator, so maybe the answer is simply “no” for “streams with a fractional ratio”.

You are right, with the design of JUCE’s LagrangeInterpolator you cannot predict, how many samples will be consumed. There is always the +/- 1 uncertainty.
What you can do, is put the 100 samples into a fifo and allow one extra sample to be in the fifo, so it should always have enough samples to succeed.

It is just the design, that works from a consumer perspective, not from a producer perspective, so it’s just unlucky for your use case.

I remember playing with this a while ago. I found that converting a smooth sine wave from 80000 to 48000 Hz caused the odd glitchy spike, every block, even though i was NOT resetting it. I gave up and used something else, sorry I can’t give details.

same here, did my own implementation in the end…

I’ve heard someone else say that too. I went for a 2X oversampling and then a half-band filter which actually made sense for my synth, plus it turned out much faster.

@Daniel Found this use of LagrangeInterpolator for resampling.

Apparently it works if it is applied to the whole file not buffering. In the case of realtime are you suggesting using an AbstractFIFO?

Many thanks in advance.