Playback of large wav files
When dealing with large wav files it is usually not a good idea to load the entire file into memory. This example shows how to use two buffers to continually load chunks of the file, thus allowing playback of very large files. While one buffer is being used for playback the other buffer is being filled with the next chunk of samples.
In order to do this, an AuxiliaryTask is used to load the file into the inactive buffer without interrupting the audio thread. We can set the global variable gDoneLoadingBuffer
to 1 each time the buffer has finished loading, allowing us to detect cases were the buffers havn't been filled in time. These cases can usually be mitigated by using a larger buffer size.
Try uploading a large wav file into the project and playing it back. You will need specify the amount of channels (#
define NUM_CHANNELS
) and the name of the file (gFilename
).
#include <libraries/AudioFile/AudioFile.h>
#include <vector>
#define BUFFER_LEN 22050 // BUFFER LENGTH
std::string gFilename = "waves.wav";
int gNumFramesInFile;
std::vector<std::vector<float> > gSampleBuf[2];
int gReadPtr = BUFFER_LEN;
int gBufferReadPtr = 0;
int gActiveBuffer = 0;
int gDoneLoadingBuffer = 1;
void fillBuffer(void*) {
gBufferReadPtr+=BUFFER_LEN;
if(gBufferReadPtr>=gNumFramesInFile)
gBufferReadPtr=0;
int endFrame = gBufferReadPtr + BUFFER_LEN;
int zeroPad = 0;
if((gBufferReadPtr+BUFFER_LEN)>=gNumFramesInFile-1) {
endFrame = gNumFramesInFile-1;
zeroPad = 1;
}
for(unsigned int ch = 0; ch < gSampleBuf[0].size(); ++ch) {
,gBufferReadPtr,endFrame);
if(zeroPad) {
int numFramesToPad = BUFFER_LEN - (endFrame-gBufferReadPtr);
for(int n=0;n<numFramesToPad;n++)
gSampleBuf[!gActiveBuffer][ch][n+(BUFFER_LEN-numFramesToPad)] = 0;
}
}
gDoneLoadingBuffer = 1;
}
{
return false;
if(gNumFramesInFile <= 0)
return false;
if(gNumFramesInFile <= BUFFER_LEN) {
printf("Sample needs to be longer than buffer size. This example is intended to work with long samples.");
return false;
}
gSampleBuf[1] = gSampleBuf[0];
return true;
}
{
for(
unsigned int n = 0; n < context->
audioFrames; n++) {
if(++gReadPtr >= BUFFER_LEN) {
if(!gDoneLoadingBuffer)
rt_printf("Couldn't load buffer in time :( -- try increasing buffer size!");
gDoneLoadingBuffer = 0;
gReadPtr = 0;
gActiveBuffer = !gActiveBuffer;
}
float out = gSampleBuf[gActiveBuffer][channel%gSampleBuf[0].size()][gReadPtr];
}
}
}
{
}