View Single Post
Old 09-28-2014, 12:08 PM   #26
Human being with feelings
Join Date: Dec 2011
Posts: 402

I've found the solution to my problem. I wasn't taking the number of channels into account when incrementing the playhead. Here is the updated getBuffer function.

void AudioSample::getBuffer(double &sampleOutput, int channel, int sample, int nFrames)
  if (channel < mNumChannels)
    //Check if the current buffer index that is going to be played 
    //is greater than or equal to the size of the vector. If it is, 
    //reset the playhead so the sample repeats.
    if ((sample * mNumChannels + channel) + mPlayhead >= getSampleLength() * mNumChannels)
      mPlayhead = -(sample * mNumChannels);
    //Set the output value to the current buffer sample, which is offset
    //by the playhead.
    sampleOutput = mBuffer[(sample * mNumChannels + channel) + mPlayhead];
    //Increment the playhead every time we hit the end of the buffer.
    if (sample * mNumChannels + channel >= nFrames * mNumChannels - 1)
      mPlayhead += nFrames * mNumChannels;
    //If we make it to a channel that isn't present in the sample,
    //just set the output value to 0.
    sampleOutput = 0;
This gives me proper results now. I have a few questions though for anyone interested in answering. Is this usually how playing an audio file is handled? I couldn't think of any other way than having a playhead that lives beyond the function call.
I also want to start adding support for files with different bits per sample. I know that wave files that are 8 bits per sample are stored as unsigned bytes, and 16 bits per sample are 2's complement signed integers, but what happens after that? Are wave files 32 bit and above exclusively floating point? And what about 24 bit? 3 bytes per sample is really strange, and C++ doesn't have a type that is exactly 3 bytes to my knowledge. How is this usually dealt with?
Alkamist is offline   Reply With Quote