+ //unsigned decoded = Sound_DecodeAll(soundFile);
+ for (;;)
+ {
+ int section;
+ int result = ov_read(&oggStream, data + size,
+ BUFFER_SIZE - size, 0, 2, 1, §ion);
+
+ if (result > 0)
+ {
+ size += result;
+ }
+ else
+ {
+ if (result < 0) logWarning("vorbis playback error");
+ break;
+ }
+ }
+ if (size == 0)
+ {
+ logWarning("decoded no bytes from %s", getName().c_str());
+ //throw Exception(Exception::FILE_NOT_FOUND);
+ return;
+ }
+
+ ALuint obj;
+ alGenBuffers(1, &obj);
+
+ alBufferData(obj, audioFormat, data, size, audioFreq);
+
+ objects.push_back(obj);
+
+ alSourcei(source, AL_BUFFER, obj);
+
+ // don't need this anymore
+ ov_clear(&oggStream);
+ soundFile = 0;
+ }
+
+
+ void beginStream(ALuint source, int nBuffers = 4)
+ {
+ if (!soundFile) openFile();
+ if (!soundFile) return;
+
+ ALuint objs[nBuffers];
+ alGenBuffers(nBuffers, objs);
+
+ for (int i = 0; i < nBuffers; ++i)
+ {
+ objects.push_back(objs[i]);
+ stream(objs[i]);
+ }
+
+ alSourceQueueBuffers(source, nBuffers, objs);
+ }
+
+ enum StreamStatus
+ {
+ STREAM_OK = 0,
+ STREAM_EOF = 1,
+ STREAM_WRONG = 2
+ };
+
+ StreamStatus stream(ALuint buffer)
+ {
+ std::vector<ALuint>::iterator it =
+ std::find(objects.begin(), objects.end(), buffer);
+
+ // that buffer doesn't belong to us
+ if (it == objects.end()) return STREAM_WRONG;
+
+ char data[BUFFER_SIZE];
+ int size = 0;
+
+ //unsigned bytes = Sound_Decode(soundFile);
+ while (size < BUFFER_SIZE)
+ {
+ int section;
+ int result = ov_read(&oggStream, data + size,
+ BUFFER_SIZE - size, 0, 2, 1, §ion);
+
+ if (result > 0)
+ {
+ size += result;
+ }
+ else
+ {
+ if (result < 0) logWarning("vorbis playback error");
+ break;
+ }
+ }
+
+ if (size == 0) return STREAM_EOF;
+
+ alBufferData(buffer, audioFormat, data, size, audioFreq);
+
+ return STREAM_OK;
+ }
+
+ inline void rewind()
+ {
+ if (!soundFile) openFile();
+ else ov_raw_seek(&oggStream, 0);
+ }
+
+
+ // delete unused buffers, return true if all buffers deleted
+ inline bool clear()
+ {
+ // clear any openal errors
+ alGetError();
+
+ while (!objects.empty())
+ {
+ ALuint buffer = objects.back();
+ alDeleteBuffers(1, &buffer);
+
+ // if an error occured, the buffer was not deleted because it's
+ // still in use by some source
+ if (alGetError() != AL_NO_ERROR) return false;
+
+ objects.pop_back();
+ }
+
+ return true;
+ }