lugre_sound_fmod.cpp

Go to the documentation of this file.
00001 #ifdef USE_FMOD
00002 #include "lugre_sound.h"
00003 
00004 
00005 
00006 #include <fmod.h>
00007 #include <fmod_errors.h>
00008 
00009 namespace Lugre {
00010 
00011     
00012 // ################## global stuff #######################
00013 FMOD_RESULT result;
00014 
00015 void ERRCHECK(FMOD_RESULT result){
00016     if (result != FMOD_OK){
00017         printf("FMOD error! (%d) %s\n", (int)result, FMOD_ErrorString(result));
00018     }
00019 }
00020 // #################################################
00021 
00022 class cSoundSourceFmod;
00023 
00024 class cSoundSystemFmod : public cSoundSystem {
00025 friend class Lugre::cSoundSourceFmod;
00026 public:
00027     cSoundSystemFmod(const int frequency, const int maxchannels);
00028     virtual ~cSoundSystemFmod();
00029     virtual void SetListenerPosition(const float x, const float y, const float z);
00030     virtual void SetListenerVelocity(const float x, const float y, const float z);
00031     virtual void GetListenerPosition(float &x, float &y, float &z);
00032     virtual void GetListenerVelocity(float &x, float &y, float &z);
00033     virtual void SetVolume(const float volume);
00034     virtual const float GetVolume();
00035     virtual void SetDistanceFactor(const float s);
00036     virtual const float GetDistanceFactor();
00037     virtual cSoundSource *CreateSoundSource(const char *filename);
00038     virtual cSoundSource *CreateSoundSource(const char *buffer, const int size, const int channels, const int bitrate, const int frequency);
00039     virtual cSoundSource *CreateSoundSource3D(const float x, const float y, const float z, const char *filename);
00040     virtual cSoundSource *CreateSoundSource3D(const float x, const float y, const float z, const char *buffer, const int size, const int channels, const int bitrate, const int frequency);
00041     virtual void Step();
00042 
00043 private:
00045     void UpdatePositionAndVelocity();
00046 
00048     int miMaxChannels;
00050     float mfDistanceFactor;
00052     FMOD_VECTOR mlPos;
00053     FMOD_VECTOR mlVel;
00054     
00056     FMOD_SYSTEM *mpSystem;
00057 };
00058 
00060 class cSoundSourceFmod : public cSoundSource {
00061 public:
00062     cSoundSourceFmod(cSoundSystemFmod *soundsystem, const char *filename) : mSoundSystem(soundsystem), mpChannel(0), mb3D(false), mpSound(0), mfMinDistance(100.0f), mfMaxDistance(100000.0f) {
00063         if(mSoundSystem && mSoundSystem->mpSystem){
00064             result = FMOD_System_CreateStream(mSoundSystem->mpSystem,filename, (FMOD_MODE)(FMOD_SOFTWARE | FMOD_2D), 0, &mpSound);
00065             ERRCHECK(result);
00066             
00067             SetPosition(0.0f,0.0f,0.0f);
00068             SetVelocity(0.0f,0.0f,0.0f);
00069         }
00070     }
00071     cSoundSourceFmod(cSoundSystemFmod *soundsystem, const char *buffer, const int size, const int channels, const int bitrate, const int frequency) : mSoundSystem(soundsystem), mpChannel(0), mb3D(false), mpSound(0), mfMinDistance(100.0f), mfMaxDistance(100000.0f) {
00072         if(mSoundSystem && mSoundSystem->mpSystem){
00073             FMOD_CREATESOUNDEXINFO exinfo;
00074             
00075             memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
00076             exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
00077             exinfo.length = size;
00078             exinfo.numchannels = channels;
00079             exinfo.defaultfrequency = frequency;
00080             
00081             switch(bitrate){
00082                 case 8:exinfo.format = FMOD_SOUND_FORMAT_PCM8;break;
00083                 case 16:exinfo.format = FMOD_SOUND_FORMAT_PCM16;break;
00084                 case 24:exinfo.format = FMOD_SOUND_FORMAT_PCM24;break;
00085                 case 32:exinfo.format = FMOD_SOUND_FORMAT_PCM32;break;
00086             }
00087             
00088             result = FMOD_System_CreateStream(mSoundSystem->mpSystem, buffer, (FMOD_MODE)(FMOD_OPENRAW | FMOD_OPENMEMORY | FMOD_SOFTWARE | FMOD_2D), &exinfo, &mpSound);
00089             ERRCHECK(result);
00090         }
00091         
00092         SetPosition(0.0f,0.0f,0.0f);
00093         SetVelocity(0.0f,0.0f,0.0f);
00094     }
00095 
00096     cSoundSourceFmod(cSoundSystemFmod *soundsystem, const float x, const float y, const float z, const char *filename) : mSoundSystem(soundsystem), mpChannel(0), mb3D(true), mpSound(0), mfMinDistance(100.0f), mfMaxDistance(100000.0f) {
00097         if(mSoundSystem && mSoundSystem->mpSystem){
00098             result = FMOD_System_CreateStream(mSoundSystem->mpSystem, filename, (FMOD_MODE)(FMOD_SOFTWARE | FMOD_3D), 0, &mpSound);
00099             ERRCHECK(result);
00100             
00101             SetPosition(x,y,z);
00102             SetVelocity(0,0,0);
00103         }
00104     }
00105 
00106     cSoundSourceFmod(cSoundSystemFmod *soundsystem, const float x, const float y, const float z, const char *buffer, const int size, const int channels, const int bitrate, const int frequency) : mSoundSystem(soundsystem), mpChannel(0), mb3D(true), mpSound(0), mfMinDistance(100.0f), mfMaxDistance(100000.0f) {
00107         if(mSoundSystem && mSoundSystem->mpSystem){
00108             FMOD_CREATESOUNDEXINFO exinfo;
00109             
00110             memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
00111             exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
00112             exinfo.length = size;
00113             exinfo.numchannels = channels;
00114             exinfo.defaultfrequency = frequency;
00115             
00116             switch(bitrate){
00117                 case 8:exinfo.format = FMOD_SOUND_FORMAT_PCM8;break;
00118                 case 16:exinfo.format = FMOD_SOUND_FORMAT_PCM16;break;
00119                 case 24:exinfo.format = FMOD_SOUND_FORMAT_PCM24;break;
00120                 case 32:exinfo.format = FMOD_SOUND_FORMAT_PCM32;break;
00121             }
00122             
00123             result = FMOD_System_CreateStream(mSoundSystem->mpSystem, buffer, (FMOD_MODE)(FMOD_OPENRAW | FMOD_OPENMEMORY | FMOD_SOFTWARE | FMOD_3D), &exinfo, &mpSound);
00124             ERRCHECK(result);
00125         }
00126         
00127         SetPosition(x,y,z);
00128         SetVelocity(0.0f,0.0f,0.0f);
00129     }
00130 
00131     virtual ~cSoundSourceFmod(){
00132         if(mpSound){
00133             // free buffer
00134             FMOD_Sound_Release(mpSound);
00135             mpSound = 0;
00136         }
00137     }
00138 
00140     virtual const bool Play(){
00141         if(IsPlaying())return true;
00142         if(IsPaused()){
00143             // unpause sound
00144             if(mpChannel){
00145                 result = FMOD_Channel_SetPaused(mpChannel,false);
00146                 ERRCHECK(result);
00147             }
00148         } else {
00149             // start playing
00150             mpChannel = 0;
00151             // alloc channel
00152             if(mpSound && mSoundSystem && mSoundSystem->mpSystem){
00153                 result = FMOD_System_PlaySound(mSoundSystem->mpSystem, FMOD_CHANNEL_FREE, mpSound, true, &mpChannel);
00154                 ERRCHECK(result);
00155             }
00156             
00157             // channel free and working?
00158             if(mpChannel){
00159                 
00160                 if(mb3D){
00161                     // set 3d position and velocity data
00162                     result = FMOD_Channel_Set3DAttributes(mpChannel, &mlPos, &mlVel);
00163                     ERRCHECK(result);
00164                     // set currently set minmax distances
00165                     SetMinMaxDistance(mfMinDistance,mfMaxDistance);
00166                 } 
00167                 
00168                 result = FMOD_Channel_SetPaused(mpChannel,false);
00169                 ERRCHECK(result);
00170                 
00171                 return true;
00172             } else return false;
00173         }
00174         return false;
00175     }
00176 
00178     virtual const bool IsPlaying(){
00179         FMOD_BOOL b;
00180         if(mpChannel == 0)return false;
00181         else {
00182             FMOD_Channel_IsPlaying(mpChannel,&b);
00183             if(b)return true;
00184             else return false;
00185         }
00186     }
00188     virtual const bool IsPaused(){
00189         FMOD_BOOL b;
00190         if(mpChannel == 0)return false;
00191         else {
00192             FMOD_Channel_GetPaused(mpChannel,&b);
00193             if(b)return true;
00194             else return false;
00195         }
00196     }
00197     
00199     virtual void Stop(){
00200         if(mpChannel == 0)return;
00201         
00202         result = FMOD_Channel_Stop(mpChannel);
00203         ERRCHECK(result);
00204     }
00205 
00207     virtual void Pause(){
00208         if(mpChannel == 0)return;
00209         
00210         result = FMOD_Channel_SetPaused(mpChannel, true);
00211         ERRCHECK(result);
00212     }
00213 
00215     virtual void SetVolume(const float volume){
00216         if(mpChannel == 0)return;
00217         
00218         result = FMOD_Channel_SetVolume(mpChannel, volume);
00219         ERRCHECK(result);
00220     }
00221     
00222     virtual const float GetVolume(){
00223         float b;
00224         if(mpChannel == 0)return 0.0f;
00225         else {
00226             FMOD_Channel_GetVolume(mpChannel, &b);
00227             return b;
00228         }
00229     }
00230 
00232     virtual void SetMinMaxDistance(const float min, const float max){
00233         mfMinDistance = min;
00234         mfMaxDistance = max;
00235 
00236         if(mpChannel == 0 || !Is3D())return;
00237         
00238         result = FMOD_Channel_Set3DMinMaxDistance(mpChannel, min * mSoundSystem->mfDistanceFactor,max * mSoundSystem->mfDistanceFactor);
00239         ERRCHECK(result);
00240     }
00241     
00242     virtual void GetMinMaxDistance(float &min, float &max){
00243         if(mpChannel == 0 || !Is3D())return;
00244         //result = FMOD_Channel_Get3DMinMaxDistance(mpChannel, &min,&max);
00245         //ERRCHECK(result);
00246             
00247         min = mfMinDistance;
00248         max = mfMaxDistance;
00249             
00250         //min /= mSoundSystem->mfDistanceFactor;
00251         //max /= mSoundSystem->mfDistanceFactor;
00252     }
00253 
00254     
00256 
00258     virtual bool Is3D(){return mb3D;}
00259     
00261     virtual void SetPosition(const float x, const float y, const float z){
00262         if(!Is3D())return;
00263         mlPos.x = x * mSoundSystem->mfDistanceFactor;
00264         mlPos.y = y * mSoundSystem->mfDistanceFactor;
00265         mlPos.z = z * mSoundSystem->mfDistanceFactor;
00266         if(mpChannel == 0)return;
00267         
00268         result = FMOD_Channel_Set3DAttributes(mpChannel, &mlPos, &mlVel);
00269         ERRCHECK(result);
00270     }
00271 
00273     virtual void SetVelocity(const float x, const float y, const float z){
00274         if(!Is3D())return;
00275         mlVel.x = x * mSoundSystem->mfDistanceFactor;
00276         mlVel.y = y * mSoundSystem->mfDistanceFactor;
00277         mlVel.z = z * mSoundSystem->mfDistanceFactor;
00278         if(mpChannel == 0)return;
00279 
00280         result = FMOD_Channel_Set3DAttributes(mpChannel, &mlPos, &mlVel);
00281         ERRCHECK(result);
00282     }
00283 
00285     virtual void GetPosition(float &x, float &y, float &z){
00286         if(!Is3D())return;
00287         x = mlPos.x / mSoundSystem->mfDistanceFactor;
00288         y = mlPos.y / mSoundSystem->mfDistanceFactor;
00289         z = mlPos.z / mSoundSystem->mfDistanceFactor;
00290     }
00291     
00293     virtual void GetVelocity(float &x, float &y, float &z){
00294         if(!Is3D())return;
00295         x = mlVel.x / mSoundSystem->mfDistanceFactor;
00296         y = mlVel.y / mSoundSystem->mfDistanceFactor;
00297         z = mlVel.z / mSoundSystem->mfDistanceFactor;
00298     }
00299 
00300 private:
00301     FMOD_SOUND     *mpSound;
00302     FMOD_CHANNEL   *mpChannel;
00303     
00305     cSoundSystemFmod *mSoundSystem;
00307     bool mb3D;
00308     
00310     float mfMinDistance,mfMaxDistance;
00311     
00313     FMOD_VECTOR mlPos;
00314     FMOD_VECTOR mlVel;
00315 };
00316 
00317 // ------------------------------------------------------------------------------------------
00318 // ------------------------------------------------------------------------------------------
00319 
00320 cSoundSystemFmod::cSoundSystemFmod(const int frequency, const int maxchannels) : mpSystem(0), miMaxChannels(maxchannels), mfDistanceFactor(1.0f) {
00321     result = FMOD_System_Create(&mpSystem);
00322     ERRCHECK(result);
00323 
00324     if(mpSystem){
00325         unsigned int version;
00326         result = FMOD_System_GetVersion(mpSystem, &version);
00327         ERRCHECK(result);
00328 
00329         if (version < FMOD_VERSION){
00330             printf("Error!  You are using an old version of FMOD %08x.  This program requires %08x\n", version, FMOD_VERSION);
00331         }
00332 
00333         result = FMOD_System_Init(mpSystem, miMaxChannels, FMOD_INIT_NORMAL, 0);
00334         ERRCHECK(result);
00335     }
00336 
00337     SetListenerPosition(0.0f,0.0f,0.0f);
00338     SetListenerVelocity(0.0f,0.0f,0.0f);
00339 }
00340 
00341 cSoundSystemFmod::~cSoundSystemFmod(){
00342     if(mpSystem){
00343         result = FMOD_System_Close(mpSystem);
00344         ERRCHECK(result);
00345         result = FMOD_System_Release(mpSystem);
00346         ERRCHECK(result);
00347     }
00348 }
00349 
00350 
00351 void cSoundSystemFmod::UpdatePositionAndVelocity(){
00352     if(mpSystem){
00353         result = FMOD_System_Set3DListenerAttributes(mpSystem, 0, &mlPos, &mlVel, 0, 0);//&forward, &up);
00354         ERRCHECK(result);
00355     }
00356 }
00357 
00358 
00360 void cSoundSystemFmod::SetListenerPosition(const float x, const float y, const float z){
00361     mlPos.x = x * mfDistanceFactor;
00362     mlPos.y = y * mfDistanceFactor;
00363     mlPos.z = z * mfDistanceFactor;
00364 
00365     UpdatePositionAndVelocity();
00366 }
00367 
00369 void cSoundSystemFmod::SetListenerVelocity(const float x, const float y, const float z){
00370     mlVel.x = x * mfDistanceFactor;
00371     mlVel.y = y * mfDistanceFactor;
00372     mlVel.z = z * mfDistanceFactor;
00373 
00374     UpdatePositionAndVelocity();
00375 }
00376 
00378 void cSoundSystemFmod::GetListenerPosition(float &x, float &y, float &z){
00379     //float v[3];
00380     x = mlPos.x / mfDistanceFactor;
00381     y = mlPos.y / mfDistanceFactor;
00382     z = mlPos.z / mfDistanceFactor;
00383 }
00384 
00386 void cSoundSystemFmod::GetListenerVelocity(float &x, float &y, float &z){
00387     //float v[3];
00388     x = mlVel.x / mfDistanceFactor;
00389     y = mlVel.y / mfDistanceFactor;
00390     z = mlVel.z / mfDistanceFactor;
00391 }
00392 
00394 void cSoundSystemFmod::SetVolume(const float volume){/* TODO */}
00395 const float cSoundSystemFmod::GetVolume(){return 1.0f;}
00396 
00399 void cSoundSystemFmod::SetDistanceFactor(const float s){
00400     // adjust the current coordinates
00401     for(int i = 0;i < 3;++i){
00402         mlPos.x = mlPos.x / mfDistanceFactor * s;
00403         mlPos.y = mlPos.y / mfDistanceFactor * s;
00404         mlPos.z = mlPos.z / mfDistanceFactor * s;
00405         mlVel.x = mlVel.x / mfDistanceFactor * s;
00406         mlVel.y = mlVel.y / mfDistanceFactor * s;
00407         mlVel.z = mlVel.z / mfDistanceFactor * s;
00408     }
00409 
00410     mfDistanceFactor = s;   
00411 }
00412 const float cSoundSystemFmod::GetDistanceFactor(){return mfDistanceFactor;}
00413 
00415 cSoundSource *cSoundSystemFmod::CreateSoundSource(const char *filename){
00416     return new cSoundSourceFmod(this,filename);
00417 }
00419 cSoundSource *cSoundSystemFmod::CreateSoundSource(const char *buffer, const int size, const int channels, const int bitrate, const int frequency){
00420     return new cSoundSourceFmod(this,buffer,size,channels,bitrate,frequency);
00421 }
00422 
00424 cSoundSource *cSoundSystemFmod::CreateSoundSource3D(const float x, const float y, const float z, const char *filename){
00425     return new cSoundSourceFmod(this,x,y,z,filename);
00426 }
00428 cSoundSource *cSoundSystemFmod::CreateSoundSource3D(const float x, const float y, const float z, const char *buffer, const int size, const int channels, const int bitrate, const int frequency){
00429     return new cSoundSourceFmod(this,x,y,z,buffer,size,channels,bitrate,frequency);
00430 }
00431 
00433 void cSoundSystemFmod::Step(){if(mpSystem)FMOD_System_Update(mpSystem);}
00434 
00435 // ------------------------------------------------------------------------------------------
00436 // ------------------------------------------------------------------------------------------
00437     
00438 cSoundSystem *CreateSoundSystemFmod(const int frequency){
00439     // TODO dont need frequency????
00440     int channels = 64;
00441     return new cSoundSystemFmod(frequency,channels);
00442 }
00443 
00444 };
00445 #endif

Generated on Wed May 23 06:00:15 2012 for cpp by  doxygen 1.5.6