+ ALuint bufferObj;
+ alSourceUnqueueBuffers(mSource, 1, &bufferObj);
+
+ BufferP buffer = mQueue.front();
+ bool streamed = buffer->stream(bufferObj);
+
+ if (streamed)
+ {
+ alSourceQueueBuffers(mSource, 1, &bufferObj);
+ }
+ else
+ {
+ // the buffer couldn't be streamed, so get rid of it
+ mQueue.pop_front();
+
+ if (!mQueue.empty())
+ {
+ // begin the next buffer in the queue
+ mQueue.front()->rewind();
+ mQueue.front()->stream(bufferObj);
+ alSourceQueueBuffers(mSource, 1, &bufferObj);
+ logInfo("loading new buffer");
+
+ // queue up any unused buffers
+ bufferStream();
+ }
+ else if (mIsLooping)
+ {
+ // reload the same buffer
+ mQueue.push_back(buffer);
+ buffer->rewind();
+ buffer->stream(bufferObj);
+ alSourceQueueBuffers(mSource, 1, &bufferObj);
+ logInfo("looping same buffer");
+ }
+ else
+ {
+ // nothing more to play, stopping...
+ mIsPlaying = false;
+ std::remove(mBuffers.begin(), mBuffers.end(),
+ bufferObj);
+ }
+ }
+ }
+
+ ALenum state;
+ alGetSourcei(mSource, AL_SOURCE_STATE, &state);
+
+ // restart playing if we're stopped but supposed to be playing...
+ // this means we didn't queue enough and the audio skipped :-(
+ if (mIsPlaying && state != AL_PLAYING)
+ {
+ alSourcePlay(mSource);
+ }
+ }
+
+
+ void stop()
+ {
+ alSourceStop(mSource);
+ mIsPlaying = false;
+
+ mStreamTimer.invalidate();
+ }
+
+ void pause()
+ {
+ alSourcePause(mSource);
+ mIsPlaying = false;
+
+ mStreamTimer.invalidate();
+ }
+
+
+ void setSample(const std::string& name)
+ {
+ stop();
+ alSourcei(mSource, AL_BUFFER, AL_NONE);
+
+ mQueue.clear();
+ mIsLoaded = false;
+
+ enqueue(name);
+
+ while (!mBuffers.empty())
+ {
+ alDeleteBuffers(1, &mBuffers.back());
+ mBuffers.pop_back();
+ }
+ }
+
+ void enqueue(const std::string& name)
+ {
+ BufferP buffer = Buffer::getInstance(name);
+ mQueue.push_back(buffer);
+ }
+