+
+ Buffer::StreamStatus status = buffer_->stream(buffer);
+
+ if (status == Buffer::STREAM_OK)
+ {
+ alSourceQueueBuffers(source_, 1, &buffer);
+ }
+ else if (status == Buffer::STREAM_EOF)
+ {
+ if (!queue_.empty())
+ {
+ // begin the next buffer in the queue
+ expired_.push_back(buffer_);
+ buffer_ = queue_.front();
+ queue_.pop();
+ buffer_->beginStream(source_, 1);
+ }
+ else if (looping_)
+ {
+ // restart from the beginning
+ buffer_->rewind();
+ buffer_->stream(buffer);
+ alSourceQueueBuffers(source_, 1, &buffer);
+ }
+ }
+ else if (status == Buffer::STREAM_WRONG)
+ {
+ clear();
+ buffer_->beginStream(source_, 1);
+ }
+ }
+
+ ALenum state;
+ alGetSourcei(source_, 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 (playing_ && state != AL_PLAYING)
+ {
+ alSourcePlay(source_);
+ }
+ }
+
+ inline void clear()
+ {
+ // try to remove expired buffers
+ std::vector<BufferP>::iterator it;
+ for (it = expired_.end() - 1; it >= expired_.begin(); --it)
+ {
+ if ((*it)->clear()) expired_.erase(it);