Matching input buffer size to opus frame size

I am working on an audio effect that passes it's input though the opus codec. I want the effect to be a VST, so I don't have control of the input buffer size and the sample rate. However, opus requires a sample rate of 48Khz and frames of 120, 240, 480, 960, 1920, or 2880 samples. What is the best way to convert from an arbitrary frame size and sample rate to a known one? A loss of fidelity is OK.

Here is the signal chain as I understand it:

1. Audio comes from a VST host application such as Ableton Live.
2. I'm using JUCE as a library for creating the plugin so the audio is then past to the internals of JUCE.
3. JUCE calls the processBlock method on my plugin with an audio buffer. When testing I can force this audio buffer to be a certain size, but I want to support hosts with arbitrary sized buffers.
4. I need to somehow convert from the host buffer size, back to a frame size supported by opus. This is where my question resides.
5. I call opus_encode_float on the buffer to compress the data. This introduces sonic artifacts I want to keep.
6. I call opus_decode_float on the compressed data. This gives me back a buffer the size of a valid opus frame.
7. I need to then convert this back to a size the host is expecting (same size as the input buffer).
• Is it possible to mention more details about your setup? Typically, the signal chain that involves the VST plug-in would be independent of the signal chain that involves the codec. So, the two can operate independently.
– A_A
Jul 7 '20 at 11:53
• @A_A I added the information you suggested. Jul 7 '20 at 13:25
• Thank you. I am sorry, I think I misread the question in the first place where it is clearly mentioned that the codec and the VST have to work in syncrhonisation. The additional information helps anyway. This is not impossible but it will take some effort.
– A_A
Jul 7 '20 at 14:02

1 Answer

I ended up solving the problem. Because the input buffer was smaller than 1 frame, I was able to write the input to a circular buffer, wait until I have enough data, then do the processing. The result was the written to a second circular buffer, that would be read every block.