about | download | documentation
     
 

Simple

This is a small program that just loads data from a WAV file into a buffer and plays it back. Before you run this program you should put an arbitrary WAV file named "test.wav" into the program's working directory. The source code for this program is simple.cpp.

The first step is to create an EvoAudioFile object so we can load the data from a file on disk. Since we are using a WAV file in this example, we create an EvoWaveAudioFile object. The constructor takes only one argument: the name of the file.

EvoWaveAudioFile file("test.wav");

The next step is to open the file by calling the open() function. This function has two parameters: a single character indicating what mode to open the file in ('r' for read, 'w' for write) and a pointer to an EvoFormatDescr object which is only required if we are opening in write mode. Since we are just reading the data we can omit the second argument:

if (!file.open('r')) {
    cout << "Failed opening file";
    return 0;
}

Now that the file is opened we can read the data into a buffer via the read() function. This function returns a pointer to a new EvoAudioBuffer object containing the requested data.

EvoAudioBuffer *audioBuffer = file.read();

Next we convert the buffer's sample format to 32-bit floating point. This step is not required to play the file but is generally recommended because it avoids the overhead of on-the-fly sample format conversion. You may want to skip this step if you really want to save memory by using a smaller sample format like 8 or 16-bit integer.

audioBuffer->setSampleFormat(paFloat32);

Before we can play the buffer we need an EvoAudioManager object. An EvoError e is passed to the constructor by reference and will have the value EVO_NOERROR if no error occurred during construction; otherwise it will have some other value as described in the API documentation for EvoAudioManager. We also need to specify what number of channels, sampling rate and frames per buffer we want the output device to have.

EvoError e;
EvoAudioManager manager(audioBuffer->getNumChannels(),  // number of channels
                        audioBuffer->getSampleRate(),  // sampling rate
                        1024,  // frames per buffer
                        e);
if (e != EVO_NOERROR) {
    cout << "Failed to initialize audio manager";
    return 0;
}

When the audio manager is created, it automatically creates an EvoOutputDevice object using the default output device ID as supplied by PortAudio. To get a pointer to this object we call the audio manager's getActiveOutputDevice() function. NOTE: The audio manager owns this default output device object and will delete the object when it is destroyed and therefore you do not need to delete the object if you switch to another output device that you create. Once we have a pointer to the active output device we can connect source lines to it (like an audio buffer in this case) by calling the connect() function inherited from EvoTargetLine. We need to supply a pointer to a source line, a source channel number and a target channel number, in that order.

for (int i = 0; i < audioBuffer->getNumChannels(); i++)
    manager.getActiveOutputDevice()->connect(audioBuffer, i, i);

Now we start the output device for playback:

e = manager.getActiveOutputDevice()->start();
if (e != EVO_NOERROR) {
    cout << "Failed to start output device";
    return 0;
}

We also need to play the audio buffer. The first parameter of the play() function indicates whether or not we want the sound to loop and the second indicates whether we want to reset all active play cursors before playing.

audioBuffer->play(false, false);

Finally, we need to make the main thread sleep for a bit so that we can actually hear something. We use the PortAudio utility function Pa_Sleep() for this. Note that this function should not be used for accurate timing and is primarily just for example programs.

Pa_Sleep(audioBuffer->getLengthMs());
return 0;



 
SourceForge.net Logo