00001 #include "../h/OpenAL.h"
00002
00003 #define BUFFER_SIZE (4096 * 4)
00004 #define CHECK (alGetError() == AL_NO_ERROR)
00005
00006 ogg_stream::ogg_stream(bool& _loop, bool& _play) :
00007 m_loop(_loop), m_play(_play)
00008 {
00009 oggFile = 0;
00010 source = 0;
00011 buffers[0] = 0;
00012 buffers[1] = 0;
00013 }
00014
00015 bool ogg_stream::create(rchar* path, float volume)
00016 {
00017 if(FOPEN(&oggFile, path, _T("rb")) == false)
00018 return false;
00019
00020 if(ov_open(oggFile, &oggStream, NULL, 0) < 0)
00021 {
00022 FCLOSE(oggFile);
00023 oggFile = 0;
00024 return false;
00025 }
00026
00027 vorbisInfo = ov_info(&oggStream, -1);
00028
00029 format = (vorbisInfo->channels == 1) ?
00030 AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
00031
00032 alGenBuffers(2, buffers);
00033 if(CHECK == false)
00034 return false;
00035 alGenSources(1, &source);
00036 if(CHECK == false)
00037 return false;
00038
00039 alSource3f(source, AL_POSITION, 0.0, 0.0, 0.0);
00040 alSource3f(source, AL_VELOCITY, 0.0, 0.0, 0.0);
00041 alSource3f(source, AL_DIRECTION, 0.0, 0.0, 0.0);
00042 alSourcef (source, AL_ROLLOFF_FACTOR, 0.0 );
00043 alSourcei (source, AL_SOURCE_RELATIVE, AL_TRUE );
00044 alSourcei (source, AL_LOOPING, AL_FALSE );
00045 return true;
00046 }
00047
00048 bool ogg_stream::recreate(void)
00049 {
00050 if(oggFile == 0)
00051 return false;
00052 FSEEK(oggFile, 0, SEEK_SET);
00053 return true;
00054 }
00055
00056 void ogg_stream::free()
00057 {
00058 if(source)
00059 {
00060 alSourceStop(source);
00061 alDeleteSources(1, &source);
00062 source = 0;
00063 }
00064 if(buffers[0])
00065 {
00066 alDeleteBuffers(2, buffers);
00067 buffers[0] = 0;
00068 buffers[1] = 0;
00069 }
00070
00071 ov_clear(&oggStream);
00072 if(oggFile)
00073 {
00074 FCLOSE(oggFile);
00075 oggFile = 0;
00076 }
00077 }
00078
00079 void ogg_stream::play()
00080 {
00081 if((isPlaying()) ||
00082 (stream(buffers[0]) == false) ||
00083 (stream(buffers[1]) == false) ||
00084 (recreate() == false))
00085 return;
00086
00087 alSourceQueueBuffers(source, 2, buffers);
00088 alSourcePlay(source);
00089 m_play = true;
00090 m_release = false;
00091 }
00092
00093 void ogg_stream::stop()
00094 {
00095 m_play = false;
00096 alSourceStop(source);
00097 empty();
00098 }
00099
00100 void ogg_stream::pause()
00101 {
00102 m_play = false;
00103 alSourcePause(source);
00104 }
00105
00106 void ogg_stream::resume()
00107 {
00108 m_play = true;
00109 alSourcePlay(source);
00110 }
00111
00112 bool ogg_stream::isPlaying()
00113 {
00114 ALenum state;
00115 alGetSourcei(source, AL_SOURCE_STATE, &state);
00116 return (state == AL_PLAYING);
00117 }
00118
00119 void ogg_stream::update()
00120 {
00121 ALuint buffer;
00122 int processed;
00123
00124 if(m_release){
00125 if(isPlaying() == false)
00126 stop();
00127 }else{
00128 alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
00129
00130 while(processed--)
00131 {
00132 alSourceUnqueueBuffers(source, 1, &buffer);
00133 stream(buffer);
00134 alSourceQueueBuffers(source, 1, &buffer);
00135 if(CHECK == false)
00136 return;
00137 }
00138 }
00139 }
00140
00141 bool ogg_stream::stream(ALuint buffer)
00142 {
00143 char data[BUFFER_SIZE];
00144 int size = 0;
00145 int section;
00146 int result;
00147
00148 while(size < BUFFER_SIZE)
00149 {
00150 result = ov_read(&oggStream, data + size, BUFFER_SIZE - size, 0, 2, 1, §ion);
00151
00152 if(result > 0){
00153 size += result;
00154 }else if(result == 0){
00155 FSEEK(oggFile, 0, SEEK_SET);
00156 if(m_loop){
00157 if(size >= BUFFER_SIZE)
00158 break;
00159 }else{
00160 m_release = true;
00161 break;
00162 }
00163 }else{}
00164 }
00165
00166 if(size == 0)
00167 return false;
00168
00169 alBufferData(buffer, format, data, size, vorbisInfo->rate);
00170
00171 return CHECK;
00172 }
00173
00174 void ogg_stream::empty()
00175 {
00176 ALuint buffer;
00177 int queued;
00178
00179 alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
00180
00181 while(queued--)
00182 alSourceUnqueueBuffers(source, 1, &buffer);
00183 }
00184
00185 #undef CHECK