+ 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);
+ }
+
+
+ bool isPlaying() const
+ {
+ if (mIsPlaying) return true;
+
+ ALenum state;
+ alGetSourcei(mSource, AL_SOURCE_STATE, &state);
+
+ return state == AL_PLAYING;
+ }
+
+
+ void setLooping(bool looping)
+ {
+ mIsLooping = looping;
+
+ ALenum type;
+ alGetSourcei(mSource, AL_SOURCE_TYPE, &type);
+
+ if (type != AL_STREAMING)
+ {
+ alSourcei(mSource, AL_LOOPING, mIsLooping);
+ }
+ }
+
+
+ void streamUpdate(Timer& timer, Scalar t)
+ {
+ // don't let the music die!
+ update();
+ // TODO - might be nice to also allow using threads for streaming rather
+ // than a timer, probably as a compile-time option
+ }
+
+
+ ALuint mSource;
+ std::list<ALuint> mBuffers;
+
+ bool mIsLoaded;
+ bool mIsPlaying;
+ bool mIsLooping;
+
+ std::deque<BufferP> mQueue;
+
+ Timer mStreamTimer;