Warning: this page refers to an old version of SFML. Click here to switch to the latest version.

Capturing audio data

Introduction

This tutorial will show how to easily capture audio data from your microphone, and apply custom processing to it like saving it to a sound buffer, or sending it through the network.

Creating a custom recorder

The class that defines the capture interface in SFML is sf::SoundRecorder. As it doesn't know what to do with the captured samples (and it doesn't have to), it is only a base class for your own custom recorder(s). sf::SoundRecorder provides you with the captured audio samples, all you have to do is... whatever you want : send them through the network, copy them into a sound buffer, etc.

Here are the functions to override by your derived recorder:

class MyCustomSoundRecorder : public sf::SoundRecorder
{
    virtual bool OnStart()
    {
        ...

        return true;
    }

    virtual bool OnProcessSamples(const sf::Int16* Samples, std::size_t SamplesCount)
    {
        ...

        return true;
    }

    virtual void OnStop()
    {
        ...
    }
};

OnStart is called once each time the capture starts (call to Start). It's optional, and won't do anything if you don't override it. If you override it, the return value must be true to start the capture, or false to abort it (e.g. after en error).

OnProcessSamples is called each time the recorder has captured enough data, so, many times during the capture. This function is mandatory (a recorder without a function to process audio data wouldn't make sense), so you have to override it in your custom recorders. Like OnStart, the return value means "should we continue capturing data?".
The Samples parameter is a pointer to the array of captured audio samples, and SamplesCount is the number of samples in this array.

OnStop is called once each time the capture stops. Like OnStart, it's optional and won't do anything if you don't override it.

Usage

The sf::SoundRecorder interface is quite simple. First, you must check that your system supports audio capture. This can be done with the static function CanCapture :

if (!sf::SoundRecorder::CanCapture())
{
    // Don't even try to capture audio...
}

This should be checked before any use of sf::SoundRecorder.

Then, to start the capture you call Start, and to stop it you call Stop.

MyCustomSoundRecorder Recorder;

Recorder.Start(96000);

// Wait a while...

Recorder.Stop();

When you call Start, you can pass a custom sample rate that will be used for the capture. By default, 44100 will be used (CD quality). If you need to get it back later, you can call the GetSampleRate function.

unsigned int SampleRate = Recorder.GetSampleRate();

Recording data into a sound buffer

The most common use is probably to save audio data to a sound buffer, so that you can save it to a file or play it immediately. SFML has a built-in specialization of sf::SoundRecorder for this : sf::SoundBufferRecorder. It copies the captured audio samples to a sf::SoundBuffer, that you can access through the GetBuffer function :

sf::SoundBufferRecorder Recorder;

Recorder.Start();

// Wait a while...

Recorder.Stop();

sf::SoundBuffer Buffer = Recorder.GetBuffer();

Multi-threading

For the same reasons as sf::SoundStream, sf::SoundRecorder runs the capture in a new thread, so that the main thread is not blocked. So, once again, you have to take care of synchronization issues that can arise if you share data between both threads.
For more detailed explanations, you can have a look at the SoundStream tutorial.

Conclusion

That's all for the basics of the audio package. You can play sounds and musics, stream audio from any source, and capture sounds from your microphone.
Let's now explore a more advanced feature: sound spatialization.