Skip to content

Latest commit

 

History

History
54 lines (33 loc) · 2.17 KB

File metadata and controls

54 lines (33 loc) · 2.17 KB

Four Ways To Write A Pitch-Shifter example code

This is the code used to produce the audio demos for the ADC22 presentation: Four Ways To Write A Pitch-Shifter. It aimes for simplicity rather than performance.

The ideas from this code are used in the Signalsmith Stretch library.

Organisation

All the different stretching methods are packed into one file. It definitely could be tidier, and I hope to get to that soon - in the meantime, do get in contact if you have any questions about it.

Each class uses a similar streaming-style API. You should be able to instantiate them simply:

HybridPhaseStretch stretch;

Configure them with channel-count and block sizes:

double blockMs = 120; 
int blockSamples = int(sampleRate*0.001*blockMs);
stretch.configure(channels, blockSamples, blockSamples/4);

Then process blocks:

stretch.setTimeFactor(timeFactor);
stretch.setFreqFactor(freqFactor);

// For `outputBufferSize` output samples, how many input samples should we have?
int inputBufferSize = processor.samplesForOutput(outputBufferSize);
processor.process(inputBufferSize, inputSamples, outputBuffers, outputBufferSize);

processBlocks(stretch, timeFactor);

If you're not performing a time-stretch, then inputBufferSize will always match outputBufferSize.

Dependencies

It depends on my DSP library for a couple of things (to get delay-buffers, FFT and Kaiser windows).

Building

The main logic is in shift-stretch.h.

If you use make, it compiles main.cpp which produces a command-line interface, with built-in help. (I wouldn't recommend focusing on that code - the main stuff is in shift-stretch.h).

FFTs

It's currently written to use a Modified Real FFT, which has a half-bin offset (so we have N complex bins/bands, instead of N-1 complex and 2 real ones). I'd like to change this in future because it's probably more confusing than necessary.

It should be easy to write adapt this to a more typical Real FFT - the main difference should be in bandToFreq(), and perhaps handling the fact that the 0Hz and Nyquist bands will be real.