• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/audio/src/OpenAL_OGG.cpp

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

Generated on Fri Jun 18 2010 17:48:39 for Cannonball by  doxygen 1.7.0