00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <sound/SoundBufferDynamicOVSourceInstance.h>
00022 #include <sound/SoundBufferOV.h>
00023 #include <common/Defines.h>
00024 #include <common/Logger.h>
00025
00026 #ifdef HAVE_OGG
00027
00028 SoundBufferDynamicOVSourceInstance::SoundBufferDynamicOVSourceInstance(
00029 unsigned int source, const char *fileName) :
00030 SoundBufferSourceInstance(source)
00031 {
00032
00033 if (!SoundBufferOV::openStream(fileName, oggStream_)) return;
00034 vorbisInfo_ = ov_info(&oggStream_, -1);
00035
00036 alGenBuffers(2, buffers_);
00037 if (alGetError() != AL_NO_ERROR) return;
00038 }
00039
00040 SoundBufferDynamicOVSourceInstance::~SoundBufferDynamicOVSourceInstance()
00041 {
00042 if (buffers_[0])
00043 {
00044 if (alIsBuffer(buffers_[0]) ||
00045 alIsBuffer(buffers_[1]))
00046 {
00047 stop();
00048
00049 alGetError();
00050 alDeleteBuffers(2, buffers_);
00051
00052 int errorNum = alGetError();
00053 if(errorNum != AL_NO_ERROR)
00054 {
00055 Logger::log("ERROR deleting AL buffers");
00056 }
00057 }
00058 }
00059 ov_clear(&oggStream_);
00060 }
00061
00062 void SoundBufferDynamicOVSourceInstance::play(bool repeat)
00063 {
00064 ov_raw_seek(&oggStream_, 0);
00065
00066 if (!addDataToBuffer(buffers_[0], repeat)) return;
00067 if (!addDataToBuffer(buffers_[1], repeat)) return;
00068
00069 alSourcei(source_, AL_BUFFER, 0);
00070 alSourcei(source_, AL_LOOPING, AL_FALSE);
00071
00072 int error = 0;
00073 alSourceQueueBuffers(source_, 2, buffers_);
00074 if ((error = alGetError()) != AL_NO_ERROR) return;
00075 alSourcePlay(source_);
00076 if ((error = alGetError()) != AL_NO_ERROR) return;
00077 }
00078
00079 void SoundBufferDynamicOVSourceInstance::stop()
00080 {
00081 alSourceStop(source_);
00082
00083 int queued = 2;
00084 while(queued--)
00085 {
00086 ALuint buffer;
00087 alSourceUnqueueBuffers(source_, 1, &buffer);
00088 alGetError();
00089 }
00090 }
00091
00092 void SoundBufferDynamicOVSourceInstance::simulate(bool repeat)
00093 {
00094 int processed = 0;
00095 alGetSourcei(source_, AL_BUFFERS_PROCESSED, &processed);
00096 if (processed == 2)
00097 {
00098 Logger::log("Warning: OGG falling behind");
00099 }
00100 while(processed--)
00101 {
00102
00103
00104 ALuint buffer;
00105 alSourceUnqueueBuffers(source_, 1, &buffer);
00106 if (addDataToBuffer(buffer, repeat))
00107 {
00108 alSourceQueueBuffers(source_, 1, &buffer);
00109 }
00110 }
00111 }
00112
00113 bool SoundBufferDynamicOVSourceInstance::addDataToBuffer(unsigned int buffer, bool loop)
00114 {
00115 static char data[OGG_BUFFER_SIZE];
00116 int size = SoundBufferOV::readData(oggStream_, data, OGG_BUFFER_SIZE);
00117 if(size == 0)
00118 {
00119 if (!loop) return false;
00120 else
00121 {
00122 ov_raw_seek(&oggStream_, 0);
00123 return addDataToBuffer(buffer, false);
00124 }
00125 }
00126
00127 SoundBufferOV::addDataToBuffer(vorbisInfo_, buffer, data, size);
00128 return true;
00129 }
00130
00131 #endif // HAVE_OGG
00132