Implementing audio effects using pitch shifters in C++

In the world of audio processing, pitch shifting is a widely used technique to alter the pitch of a sound without changing its duration. This allows developers to create interesting audio effects, such as harmonization, time stretching, and special sound effects in digital audio applications.

What is a Pitch Shifter?

A pitch shifter is an audio effect that changes the frequency content of an audio signal, resulting in a higher or lower pitch. It works by modifying the playback speed of the audio signal while maintaining its original duration.

Implementing a Simple Pitch Shifter in C++

To implement a pitch shifter in C++, we can make use of libraries such as PortAudio and SoundTouch. PortAudio provides the necessary platform-agnostic audio I/O functionality, while SoundTouch offers audio processing algorithms, including pitch shifting.

Here’s an example code snippet demonstrating the implementation of a simple pitch shifter using PortAudio and SoundTouch:

#include <portaudio.h>
#include <SoundTouch.h>

using namespace soundtouch;

// Define the pitch shifting factor
float pitchShiftFactor = 1.5f; // Increase by 50% to raise the pitch

// SoundTouch instance for pitch shifting
SoundTouch soundTouch;

// PortAudio's callback function
static int audioCallback(const void* inputBuffer, void* outputBuffer,
                         unsigned long framesPerBuffer,
                         const PaStreamCallbackTimeInfo* timeInfo,
                         PaStreamCallbackFlags statusFlags,
                         void* userData)
{
    // Cast the buffer pointers to float*
    float* inBuffer = (float*)inputBuffer;
    float* outBuffer = (float*)outputBuffer;
    
    // Process the audio samples
    soundTouch.putSamples(inBuffer, framesPerBuffer);
    soundTouch.receiveSamples(outBuffer, framesPerBuffer);
    
    return paContinue;
}

int main()
{
    // Initialize PortAudio
    PaError err = Pa_Initialize();
    if (err != paNoError) {
        // Handle error
        return false;
    }
    
    // Open the audio stream
    PaStream* stream;
    err = Pa_OpenDefaultStream(&stream, 0, 1, paFloat32, 44100, 512, audioCallback, nullptr);
    if (err != paNoError) {
        // Handle error
        return false;
    }
    
    // Initialize SoundTouch
    soundTouch.setSampleRate(44100);
    soundTouch.setChannels(1);
    soundTouch.setPitchSemiTones(pitchShiftFactor);
    
    // Start the audio stream
    err = Pa_StartStream(stream);
    if (err != paNoError) {
        // Handle error
        return false;
    }
    
    // Let the audio stream play for some time
    Pa_Sleep(5000);
    
    // Stop and close the audio stream
    err = Pa_StopStream(stream);
    if (err != paNoError) {
        // Handle error
        return false;
    }
    err = Pa_CloseStream(stream);
    if (err != paNoError) {
        // Handle error
        return false;
    }
    
    // Terminate PortAudio
    Pa_Terminate();
    
    return 0;
}

Conclusion

Pitch shifting is a powerful audio effect that allows developers to manipulate the pitch of audio signals. By implementing a pitch shifter using libraries like PortAudio and SoundTouch in C++, you can bring unique audio effects to your digital audio applications. Experiment with different pitch shifting factors and explore the possibilities of audio manipulation! #AudioEffects #PitchShifting