Change sample loop tempo without pitch change?

I have a drum loop and am wondering if it’s possible to change its rate ( tempo ) dynamically without changing its pitch? I’m thinking of something similar to the timestretching that can be done in DAWs like Cubase or Live to change the bpm of loops while preserving the pitch. I’m wondering if this could be done on the fly in real time in SC.

I’ve tried PlayBuf, BufRd, GrainBuf, and Warp1, but changing the rate changes the pitch. I’ve also tried using FFT PV_PlayBuf/PV_RecordBuf to do timestretching as explained in Eli Fieldsteel’s video ( https://youtu.be/L5aBpliR2h4?si=AMVHAINwuBpNoc3O ), but changing the rate has a smearing/washed out effect on the drum sounds so doesn’t preserve the integrity of the sound.

Thanks for any info!

In granular time stretching, you should change not rate, but rather the speed at which the grain position moves. rate is grain pitch; the grain position input controls the movement of time through the buffer. That is, if the loop is 1.5 seconds, the GrainBuf pos input could be driven by LFSaw.kr(1/1.5).range(0, 1). The time stretch factor goes into the LFSaw frequency. If you want the same loop to play in 1.1 seconds, I think it should be LFSaw.kr(1/1.1).range(0, 1).

GrainBuf, TGrains etc should fairly easily give you that 90s jittery time stretching effect.

DAW time stretchers usually have a percussion, drum or transient mode, which detects the attack portion and plays it as is, and switches to granulation or other to stretch out the body of the sound. I’m not aware of a SC implementation of this, though.

hjh

1 Like

I haven’t used Sam Pluta’s BufFFT Library, but that has a time stretch function for Buffers. It looks like it only has a MacOS build, so you may need to build for other platforms.
Best,
Paul

1 Like

Great thanks @jamshark70 , that helps!

Also a good suggestion (one which i had forgotten about). It doesn’t do transient detection, though. I tried it briefly on a drum loop, and snare drum sounds turn into very clean snare roll-type sounds.

So there’s currently:

  • Time domain granulation: As the grains overlap, drum attacks will acquire a 90s slap-echo type of smearing.
  • BufFFT: The PV_AccumPhase operation smooths out the stretching of the transients (and it sounds very smooth!), but the transients still get stretched.
  • PV_RecordBuf / PV_PlayBuf: Interpolation of the frame data produces a watery type of sound, which is interesting for some uses but not a realistic stretch.

Out of curiosity, I found a couple of papers:

Possibly someone more clever in c++ than I could make a UGen.

Short of that, one could probably also use FluCoMa to pre-analyze the frame positions of the transients in the drum loop, and use that to build an envelope to crossfade between granular time stretching and simple playback of the transient itself (like, each drum hit would play… 50-100 ms of transient without stretching, and then the envelope would switch the output to a granular timestretch for the drum body). I don’t have time to dig into that right now, though.

hjh

1 Like

DAWs have probably licensed Elastique or Rubber Band, which are algorithms with optimizations for percussion. Rubber Band is open source, so it could be incorporated into a UGen.

An issue with transients and time stretching is that the transient will seep into FFT frames temporally very far from where you want them. A possible solution is to do source separation ahead of time and to stretch the harmonic and percussive signals with different settings.

1 Like