JUCE and soundtouch

Hi,
I try to work with JUCE. Just do some examples from the internet by myself. And now I have the first problem.
I want to change pitch of input audio with soundtouch library. I use
pehrtree/juce_pitcher as a reference. But nothing happened.
Could you help me?

My code is here:
const auto numSamples = buffer.getNumSamples();
auto numOfChannels = buffer.getNumChannels();

auto pSoundTouch1 = new soundtouch::SoundTouch();
pSoundTouch1->setChannels(1);
pSoundTouch1->setSampleRate(44100);
pSoundTouch1->setPitchSemiTones(12.0f);

auto pSoundTouch2 = new soundtouch::SoundTouch();
pSoundTouch2->setChannels(1);
pSoundTouch2->setSampleRate(44100);
pSoundTouch2->setPitchSemiTones(12.0f);

AudioSampleBuffer buffer0 = buffer;
AudioSampleBuffer buffer1 = AudioSampleBuffer(1, numSamples);
buffer1.copyFrom(0, 0, buffer0, 0, 0, numSamples);

float* in_0 = buffer0.getWritePointer(0, 0);
float* in_1 = buffer1.getWritePointer(0, 0);

pSoundTouch1->putSamples(in_0, numSamples);
pSoundTouch1->receiveSamples(in_0, numSamples);

pSoundTouch2->putSamples(in_1, numSamples);
pSoundTouch2->receiveSamples(in_1, numSamples);

//Channel-specific gain
buffer0.applyGain(0, 0, buffer0.getNumSamples(), 0.5);
buffer1.applyGain(0, 0, buffer1.getNumSamples(), 0.5);


//Combine into output buffer (buffer == buffer0 already)
buffer.addFrom(0, 0, buffer1, 0, 0, numSamples);
buffer.copyFrom(1, 0, buffer, 1, 0, numSamples);

buffer.applyGain(0, 0, buffer.getNumSamples(), 1); //apply overall gain

Are you really doing all that inside your processBlock method? If yes, that is wrong because of at least 3 reasons :

-You are creating a new soundtouch instance each time processBlock is called. That is not going to work because soundtouch needs to retain its state between the audio processing calls. You need to have the soundtouch instance as a class member of your AudioProcessor.

-By using “new” in processBlock, you are going to cause realtime audio processing problems. You should do everything possible to avoid memory allocations during the actual audio processing. Prepare your memory buffers and objects beforehand. The problem isn’t exclusive to when using “new”, objects allocated in other ways can also be problematic because they may for example internally allocate on the heap using “new” or malloc().

-You are memory leaking the soundtouch instances. If you need to use objects via pointers, use smart pointers instead of raw pointers.

The pehrtree plugin project you have been looking at is extremely old. Juce has gone quite a lot of changes since that time. (Nevertheless, it does get some things more or less right, like allocating the soundtouch object outside the processBlock call.)

1 Like

You absolutely right! Now it works. Thank you!

Hi Trickster2, I’m hoping to get this working also to be able to simulate DJ scratching. From you experiences do you think this library would be suitable?

Thanks!

The scratching sound is done by “simple” resampling of the audio. SoundTouch is aimed at doing independent pitch and tempo changes. (Slow down the sound without the pitch going down etc.) It does also allow doing the varispeed/resampling sound, though. But you could do that with Juce’s classes too.

1 Like