However, more complicated processing is needed if there are more than 1 channels to process because SoundTouch wants interleaved audio buffers. The audio from the JUCE AudioBuffer needs to be interleaved into a helper buffer that is then passed into SoundTouch.
Good shout, I haven’t used SoundTouch myself. Can it do mono processing and you create two separate instances as multi-mono?
Otherwise there is no way around copying the samples around to a temporary buffer.
It’s of course possible to create multiple mono instances of SoundTouch but then the channels will drift apart in timing. So, using the helper/work buffer for stereo/multichannel is really the recommended way to implement it.
Add a std::vector<float> as a member of your AudioProcessor. Resize that to numChannels*samplesPerBlockExpected in prepareToPlay.
Then something like this in processBlock to interleave :
int numch = buffer.getNumChannels();
for (int i=0;i<numch;++i)
for (int j=0;j<buffer.getNumSamples();++j)
m_tempbuffer[j*numch+i]=buffer.getSample(i,j);
I think JUCE also has a helper function for that, that may be able to vectorize the operation to make it faster, but I don’t recall what it is named and how to use it right now.
It’s difficult to say based just on that what could be wrong. What else is going on in the code? Is the SoundTouch using code even in the AudioProcessor subclass? Have you initialized SoundTouch to work with the number of channels and sample rate required?
SoundTouch::flush clears the audio that is available from the stretcher, so you shouldn’t be calling it in processBlock. You might call it in prepareToPlay to clear the stretcher of the old audio.
Ah yea I put that in there testing different things and forgot to remove. Unfortunately thats not the issue. Removing flush from processBlock has no effect on the output not working.
Probably makes SoundTouch expect stereo audio, so the putSamples and receiveSamples get messed up when you are testing as mono. try setChannels(1);
Note if that gets the audio running, it may still be corrupt for example because receiveSamples didn’t produce enough output. You can check if that happens from the return value of receiveSamples. It may not always be how many samples you requested. You will likely have to let SoundTouch process additional audio before trying to get output from it. Which will cause latency…It’s not really the best library to use in a virtual instrument like you are trying to use it.
I see. I am still new to VST development and trying to patch my way together to a full instrument. What are best practices when looking for standardized algorithms for pitch shifting and bpm matching for example? I’ve found this repo to be quite resourceful. Id love to look at more like this if there are any buried.