Ticket #1223: new_sound_manager_1.diff
File new_sound_manager_1.diff, 75.5 KB (added by , 12 years ago) |
---|
-
build/premake/premake4.lua
519 519 "ps/Network", 520 520 "ps/GameSetup", 521 521 "ps/XML", 522 "sound", 522 "soundmanager", 523 "soundmanager/data", 524 "soundmanager/items", 525 "soundmanager/js", 523 526 "scripting", 524 527 "maths", 525 528 "maths/scripting", … … 533 536 "boost", 534 537 "enet", 535 538 "libcurl", 539 "vorbis", 540 "openal" 536 541 } 537 542 setup_static_lib_project("engine", source_dirs, extern_libs, {}) 538 543 … … 553 558 end 554 559 setup_static_lib_project("graphics", source_dirs, extern_libs, {}) 555 560 556 557 561 source_dirs = { 558 562 "tools/atlas/GameInterface", 559 563 "tools/atlas/GameInterface/Handlers" -
source/ps/GameSetup/Config.cpp
23 23 #include "lib/timer.h" 24 24 #include "lib/res/sound/snd_mgr.h" 25 25 #include "Config.h" 26 #include "soundmanager/CSoundManager.h" 26 27 27 28 28 // (these variables are documented in the header.) 29 29 30 30 CStrW g_CursorName = L"test"; … … 81 81 CFG_GET_USER_VAL("particles", Bool, g_Particles); 82 82 83 83 float gain = -1.0f; 84 float musicGain = -1.0f; 85 float ambientGain = -1.0f; 86 float actionGain = -1.0f; 87 int bufferCount = 50; 88 unsigned long bufferSize = 65536; 89 84 90 CFG_GET_USER_VAL("sound.mastergain", Float, gain); 85 if(gain >= 0.0f) 86 WARN_IF_ERR(snd_set_master_gain(gain)); 91 CFG_GET_USER_VAL("sound.musicgain", Float, musicGain); 92 CFG_GET_USER_VAL("sound.ambientgain", Float, ambientGain); 93 CFG_GET_USER_VAL("sound.actiongain", Float, actionGain); 94 95 CFG_GET_USER_VAL("sound.bufferCount", Int, bufferCount); 96 CFG_GET_USER_VAL("sound.bufferSize", UnsignedLong, bufferSize); 97 98 g_SoundManager->setMasterGain( gain ); 99 g_SoundManager->setMusicGain( musicGain ); 100 g_SoundManager->setAmbientGain( ambientGain ); 101 g_SoundManager->setActionGain( actionGain ); 102 103 g_SoundManager->setMemoryUsage( bufferSize, bufferCount); 87 104 } 88 105 89 106 -
source/ps/GameSetup/GameSetup.cpp
102 102 #include "tools/atlas/GameInterface/GameLoop.h" 103 103 #include "tools/atlas/GameInterface/View.h" 104 104 105 #include "soundmanager/CSoundManager.h" 105 106 106 107 #if !(OS_WIN || OS_MACOSX || OS_ANDROID) // assume all other platforms use X11 for wxWidgets 107 108 #define MUST_INIT_X11 1 … … 203 204 { 204 205 PROFILE3("render"); 205 206 207 g_SoundManager->idleTask(); 208 206 209 ogl_WarnIfError(); 207 210 208 211 g_Profiler2.RecordGPUFrameStart(); … … 330 333 { 331 334 // maths 332 335 JSI_Vector3D::init(); 333 336 337 CSoundManager::ScriptingInit(); 334 338 // graphics 335 339 CGameView::ScriptingInit(); 336 340 … … 338 342 CRenderer::ScriptingInit(); 339 343 340 344 // sound 341 JSI_Sound::ScriptingInit();345 // JSI_Sound::ScriptingInit(); 342 346 343 347 // ps 344 348 JSI_Console::init(); … … 476 480 g_VFS->Mount(L"", modLoosePath / modName/"", flags, priority); 477 481 g_VFS->Mount(L"", modArchivePath / modName/"", flags, priority); 478 482 } 483 484 OsPath apth = paths.RData()/"mods/public"; 485 g_SoundManager = new CSoundManager( apth ); 479 486 480 487 // note: don't bother with g_VFS->TextRepresentation - directories 481 488 // haven't yet been populated and are empty. … … 691 698 // resource 692 699 // first shut down all resource owners, and then the handle manager. 693 700 TIMER_BEGIN(L"resource modules"); 694 snd_shutdown();701 delete g_SoundManager; 695 702 696 703 g_VFS.reset(); 697 704 … … 930 937 // speed up startup by disabling all sound 931 938 // (OpenAL init will be skipped). 932 939 // must be called before first snd_open. 933 snd_disable(true);940 g_SoundManager->setEnabled( false ); 934 941 } 935 942 936 943 g_GUI = new CGUIManager(g_ScriptingHost.GetScriptInterface()); -
source/ps/Game.cpp
45 45 #include "simulation2/components/ICmpPlayerManager.h" 46 46 47 47 #include "gui/GUIManager.h" 48 #include "soundmanager/CSoundManager.h" 48 49 49 50 extern bool g_GameRestarted; 50 51 … … 299 300 if (doInterpolate) 300 301 { 301 302 m_TurnManager->Interpolate(deltaTime); 303 g_SoundManager->idleTask(); 302 304 } 303 305 304 306 // TODO: maybe we should add a CCmpParticleInterface that passes the interpolation commands -
source/soundmanager/items/CSoundItem.h
1 // 2 // CSoundItem.h 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/23/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 9 #ifndef SoundTester_CSoundItem_h 10 #define SoundTester_CSoundItem_h 11 12 #include "CSoundBase.h" 13 #include "soundmanager/data/CSoundData.h" 14 15 16 class CSoundItem :public CSoundBase 17 { 18 protected: 19 20 public: 21 CSoundItem (); 22 CSoundItem (CSoundData* sndData); 23 24 virtual ~CSoundItem (); 25 void attach ( CSoundData* itemData ); 26 bool idleTask (); 27 28 protected: 29 30 31 }; 32 33 34 35 36 37 38 #endif -
source/soundmanager/items/CBufferItem.h
1 // 2 // CMusicItem.h 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/23/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 9 #ifndef SoundTester_CBufferItem_h 10 #define SoundTester_CBufferItem_h 11 12 #include "CSoundBase.h" 13 14 class CBufferItem : public CSoundBase 15 { 16 public: 17 CBufferItem (CSoundData* sndData); 18 virtual ~CBufferItem (); 19 20 virtual void setLooping ( bool loops ); 21 virtual bool idleTask (); 22 23 protected: 24 virtual void attach ( CSoundData* itemData ); 25 26 27 }; 28 29 30 #endif -
source/soundmanager/items/CStreamItem.h
1 // 2 // CMusicItem.h 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/23/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 9 #ifndef SoundTester_CStreamItem_h 10 #define SoundTester_CStreamItem_h 11 12 #include "soundmanager/data/CSoundData.h" 13 #include "CSoundBase.h" 14 15 class CStreamItem : public CSoundBase 16 { 17 public: 18 CStreamItem (CSoundData* sndData); 19 virtual ~CStreamItem (); 20 21 virtual void setLooping ( bool loops ); 22 virtual bool idleTask (); 23 24 protected: 25 virtual void attach ( CSoundData* itemData ); 26 27 }; 28 29 #endif -
source/soundmanager/items/ISoundItem.h
1 2 // 3 // Header.h 4 // pyrogenesis 5 // 6 // Created by Steven Fuchs on 4/15/12. 7 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 8 // 9 #ifndef SoundTester_ISoundItem_h 10 #define SoundTester_ISoundItem_h 11 12 #include <string> 13 #include "lib/external_libraries/openal.h" 14 #include "maths/Vector3D.h" 15 16 17 class ISoundItem 18 { 19 20 public: 21 virtual ~ISoundItem(){}; 22 virtual bool getLooping () = 0; 23 virtual void setLooping (bool loop) = 0; 24 virtual bool isPlaying () = 0; 25 26 27 virtual std::string getName () = 0; 28 virtual bool idleTask () = 0; 29 30 virtual void play () = 0; 31 virtual void stop () = 0; 32 33 virtual void ensurePlay () = 0; 34 virtual void playAsMusic () = 0; 35 virtual void playAsAmbient () = 0; 36 37 virtual void playAndDelete () = 0; 38 virtual void stopAndDelete () = 0; 39 virtual void fadeToIn ( ALfloat newVolume, double fadeDuration) = 0; 40 virtual void fadeAndDelete ( double fadeTime ) = 0; 41 virtual void playLoop () = 0; 42 43 virtual void setCone (ALfloat innerCone, ALfloat outerCone, ALfloat coneGain) = 0; 44 virtual void setPitch (ALfloat pitch) = 0; 45 virtual void setGain (ALfloat gain) = 0; 46 virtual void setLocation (const CVector3D& position) = 0; 47 }; 48 49 50 #endif //SoundTester_ISoundItem_h 51 No newline at end of file -
source/soundmanager/items/CSoundBase.cpp
1 // 2 // CSoundBase.cpp 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/23/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 #include "CSoundBase.h" 9 #include "soundmanager/CSoundManager.h" 10 #include "soundmanager/data/CSoundData.h" 11 12 #include <iostream> 13 14 #include "lib/timer.h" 15 16 17 CSoundBase::CSoundBase() 18 { 19 resetVars(); 20 } 21 22 CSoundBase::~CSoundBase() 23 { 24 stop(); 25 if ( mALSource != 0 ) { 26 alDeleteSources( 1, &mALSource); 27 mALSource = 0; 28 } 29 if ( mSoundData != 0 ) { 30 CSoundData::releaseSoundData( mSoundData ); 31 mSoundData = 0; 32 } 33 if ( mName ) 34 delete mName; 35 } 36 37 void CSoundBase::resetVars() 38 { 39 mALSource = 0; 40 mSoundData = 0; 41 mLastPlay = false; 42 mLooping = false; 43 mStartFadeTime = 0; 44 mEndFadeTime = 0; 45 mStartVolume = 0; 46 mEndVolume = 0; 47 48 resetFade(); 49 mName = new std::string( "sound name" ); 50 } 51 52 void CSoundBase::resetFade() 53 { 54 mStartFadeTime = 0; 55 mEndFadeTime = 0; 56 mStartVolume = 0; 57 mEndVolume = 0; 58 mShouldBePlaying = false; 59 } 60 61 void CSoundBase::setGain(ALfloat gain) 62 { 63 alSourcef(mALSource, AL_GAIN, gain); 64 } 65 66 void CSoundBase::ensurePlay() 67 { 68 if ( mShouldBePlaying && !isPlaying() ) 69 play(); 70 } 71 72 void CSoundBase::setCone(ALfloat innerCone, ALfloat outerCone, ALfloat coneGain) 73 { 74 alSourcef( mALSource, innerCone, AL_CONE_INNER_ANGLE); 75 alSourcef( mALSource, outerCone, AL_CONE_OUTER_ANGLE); 76 alSourcef( mALSource, coneGain, AL_CONE_OUTER_GAIN); 77 } 78 79 void CSoundBase::setPitch(ALfloat pitch) 80 { 81 alSourcef( mALSource, AL_PITCH, pitch); 82 } 83 84 void CSoundBase::setDirection(const CVector3D& direction) 85 { 86 alSourcefv( mALSource, AL_DIRECTION, direction.GetFloatArray() ); 87 } 88 89 bool CSoundBase::initOpenAL() 90 { 91 alGetError(); /* clear error */ 92 alGenSources( 1, &mALSource); 93 long anErr = alGetError(); 94 if( anErr != AL_NO_ERROR) 95 { 96 printf("- Error creating sources %ld !!\n", anErr ); 97 } 98 else 99 { 100 ALfloat source0Pos[]={ -2.0, 0.0, 0.0}; 101 ALfloat source0Vel[]={ 0.0, 0.0, 0.0}; 102 103 alSourcef( mALSource,AL_PITCH,1.0f); 104 alSourcef( mALSource,AL_GAIN,1.0f); 105 alSourcefv( mALSource,AL_POSITION,source0Pos); 106 alSourcefv( mALSource,AL_VELOCITY,source0Vel); 107 alSourcei( mALSource,AL_LOOPING,AL_FALSE); 108 return true; 109 } 110 return false; 111 } 112 113 bool CSoundBase::isPlaying() 114 { 115 int proc_state; 116 alGetSourceiv( mALSource, AL_SOURCE_STATE, &proc_state); 117 118 return ( proc_state == AL_PLAYING ); 119 } 120 121 void CSoundBase::setLastPlay( bool last ) 122 { 123 mLastPlay = last; 124 } 125 126 bool CSoundBase::idleTask() 127 { 128 return true; 129 } 130 131 void CSoundBase::setLocation (const CVector3D& position) 132 { 133 // const float* loatArr = position.GetFloatArray(); 134 // debug_printf(L"do upload and play at location:%f, %f, %f\n\n", loatArr[0], loatArr[1], loatArr[2] ); 135 136 // alSourcefv( mALSource,AL_POSITION, position.GetFloatArray() ); 137 } 138 139 bool CSoundBase::handleFade() 140 { 141 if ( mStartFadeTime != 0 ) { 142 double currTime = timer_Time(); 143 double pctDone = std::min( 1.0, (currTime - mStartFadeTime) / (mEndFadeTime - mStartFadeTime) ); 144 pctDone = std::max( 0.0, pctDone ); 145 ALfloat curGain = ((mEndVolume - mStartVolume ) * pctDone) + mStartVolume; 146 147 if (curGain == 0 ) 148 stop(); 149 else if ( curGain == mEndVolume ) { 150 alSourcef( mALSource, AL_GAIN, curGain); 151 resetFade(); 152 } 153 else 154 alSourcef( mALSource, AL_GAIN, curGain); 155 } 156 return true; 157 } 158 159 bool CSoundBase::getLooping() 160 { 161 return mLooping; 162 } 163 void CSoundBase::setLooping( bool loops ) 164 { 165 mLooping = loops; 166 alSourcei( mALSource, AL_LOOPING, loops ? AL_TRUE : AL_FALSE ); 167 } 168 169 void CSoundBase::play() 170 { 171 mShouldBePlaying = true; 172 if ( mALSource != 0 ) 173 alSourcePlay( mALSource ); 174 } 175 void CSoundBase::playAndDelete() 176 { 177 setLastPlay( true ); 178 play(); 179 } 180 181 void CSoundBase::fadeAndDelete( double fadeTime ) 182 { 183 setLastPlay( true ); 184 fadeToIn( 0, fadeTime ); 185 } 186 187 void CSoundBase::stopAndDelete() 188 { 189 setLastPlay( true ); 190 stop(); 191 } 192 193 void CSoundBase::playLoop() 194 { 195 if ( mALSource != 0 ) { 196 setLooping( true ); 197 play(); 198 } 199 } 200 201 void CSoundBase::fadeToIn( ALfloat newVolume, double fadeDuration) 202 { 203 int proc_state; 204 alGetSourceiv( mALSource, AL_SOURCE_STATE, &proc_state); 205 if ( proc_state == AL_PLAYING ) { 206 mStartFadeTime = timer_Time(); 207 mEndFadeTime = mStartFadeTime + fadeDuration; 208 alGetSourcef( mALSource, AL_GAIN, &mStartVolume); 209 mEndVolume = newVolume; 210 } 211 212 } 213 214 void CSoundBase::playAsMusic() 215 { 216 g_SoundManager->setMusicItem( this ); 217 } 218 219 void CSoundBase::playAsAmbient() 220 { 221 g_SoundManager->setAmbientItem( this ); 222 } 223 224 void CSoundBase::stop() 225 { 226 mShouldBePlaying = false; 227 if ( mALSource != 0 ) { 228 int proc_state; 229 alSourcei( mALSource, AL_LOOPING, AL_FALSE ); 230 alGetSourceiv( mALSource, AL_SOURCE_STATE, &proc_state); 231 if ( proc_state == AL_PLAYING ) 232 alSourceStop( mALSource ); 233 } 234 } 235 236 const char* CSoundBase::Name() 237 { 238 return mName->c_str(); 239 } 240 241 std::string CSoundBase::getName() 242 { 243 return std::string( mName->c_str() ); 244 } 245 246 void CSoundBase::setNameFromPath( char* fileLoc ) 247 { 248 std::string anst( fileLoc ); 249 size_t pos = anst.find_last_of("/"); 250 if(pos != std::wstring::npos) 251 mName->assign(anst.begin() + pos + 1, anst.end()); 252 else 253 mName->assign(anst.begin(), anst.end()); 254 } 255 -
source/soundmanager/items/CSoundItem.cpp
1 // 2 // CSoundItem.cpp 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/23/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 #include "CSoundItem.h" 9 #include "soundmanager/data/CSoundData.h" 10 11 #include <iostream> 12 13 14 CSoundItem::CSoundItem() 15 { 16 resetVars(); 17 } 18 19 CSoundItem::CSoundItem(CSoundData* sndData) 20 { 21 resetVars(); 22 if ( initOpenAL() ) 23 attach( sndData ); 24 25 debug_printf(L"created SoundItem at: %ls\n\n", sndData->getFileName().c_str()); 26 } 27 28 CSoundItem::~CSoundItem() 29 { 30 ALuint al_buf; 31 32 stop(); 33 alSourceUnqueueBuffers(mALSource, 1, &al_buf); 34 } 35 36 bool CSoundItem::idleTask() 37 { 38 handleFade(); 39 40 if ( mLastPlay ) 41 { 42 int proc_state; 43 alGetSourceiv( mALSource, AL_SOURCE_STATE, &proc_state); 44 return ( proc_state != AL_STOPPED ); 45 } 46 return true; 47 } 48 49 void CSoundItem::attach( CSoundData* itemData ) 50 { 51 if ( itemData != NULL ) { 52 mSoundData = itemData->incrementCount(); 53 alSourcei( mALSource, AL_BUFFER, mSoundData->getBuffer() ); 54 } 55 } -
source/soundmanager/items/CBufferItem.cpp
1 // 2 // CBufferItem.cpp 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/23/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 #include "CBufferItem.h" 9 #include "soundmanager/data/CSoundData.h" 10 11 #include <iostream> 12 13 CBufferItem::CBufferItem(CSoundData* sndData) 14 { 15 resetVars(); 16 if ( initOpenAL() ) 17 attach( sndData ); 18 19 debug_printf(L"created BufferItem at: %ls\n\n", sndData->getFileName().c_str()); 20 } 21 22 23 CBufferItem::~CBufferItem() 24 { 25 stop(); 26 int num_processed; 27 alGetSourcei( mALSource, AL_BUFFERS_PROCESSED, &num_processed); 28 29 if (num_processed > 0) 30 { 31 ALuint al_buf[num_processed]; 32 alSourceUnqueueBuffers(mALSource, num_processed, al_buf); 33 } 34 } 35 36 37 bool CBufferItem::idleTask() 38 { 39 handleFade(); 40 41 if ( mLastPlay ) 42 { 43 int proc_state; 44 alGetSourceiv( mALSource, AL_SOURCE_STATE, &proc_state); 45 return ( proc_state != AL_STOPPED ); 46 } 47 48 if ( getLooping() ) { 49 int num_processed; 50 alGetSourcei( mALSource, AL_BUFFERS_PROCESSED, &num_processed); 51 52 for ( int i = 0; i < num_processed; i++ ) 53 { 54 ALuint al_buf; 55 alSourceUnqueueBuffers(mALSource, 1, &al_buf); 56 alSourceQueueBuffers(mALSource, 1, &al_buf); 57 } 58 } 59 60 return true; 61 } 62 63 void CBufferItem::attach( CSoundData* itemData ) 64 { 65 if ( itemData != NULL ) { 66 mSoundData = itemData->incrementCount(); 67 alSourceQueueBuffers(mALSource, mSoundData->getBufferCount(),(const ALuint *) mSoundData->getBufferPtr()); 68 } 69 } 70 71 void CBufferItem::setLooping( bool loops ) 72 { 73 mLooping = loops; 74 } 75 -
source/soundmanager/items/CSoundBase.h
1 // 2 // CSoundBase.h 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/23/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 9 #ifndef SoundTester_CSoundBase_h 10 #define SoundTester_CSoundBase_h 11 12 #include <string> 13 #include "lib/external_libraries/openal.h" 14 #include "soundmanager/items/ISoundItem.h" 15 #include "soundmanager/data/CSoundData.h" 16 17 18 class CSoundBase :public ISoundItem 19 { 20 protected: 21 22 ALuint mALSource; 23 CSoundData* mSoundData; 24 25 std::string* mName; 26 bool mLastPlay; 27 bool mLooping; 28 bool mShouldBePlaying; 29 30 double mStartFadeTime; 31 double mEndFadeTime; 32 ALfloat mStartVolume; 33 ALfloat mEndVolume; 34 35 public: 36 CSoundBase (); 37 38 virtual ~CSoundBase (); 39 40 virtual bool initOpenAL(); 41 virtual void resetVars(); 42 virtual void ensurePlay(); 43 44 virtual void setGain (ALfloat gain); 45 virtual void setPitch(ALfloat pitch); 46 virtual void setDirection(const CVector3D& direction); 47 virtual void setCone(ALfloat innerCone, ALfloat outerCone, ALfloat coneGain); 48 virtual void setLastPlay( bool last ); 49 50 void play (); 51 void playAndDelete (); 52 bool idleTask (); 53 void playLoop (); 54 void stop (); 55 void stopAndDelete (); 56 void fadeToIn ( ALfloat newVolume, double fadeDuration); 57 58 void playAsMusic (); 59 void playAsAmbient (); 60 61 const char* Name(); 62 std::string getName(); 63 64 virtual bool getLooping (); 65 virtual void setLooping ( bool loops ); 66 virtual bool isPlaying(); 67 virtual void setLocation (const CVector3D& position); 68 virtual void fadeAndDelete ( double fadeTime ); 69 70 protected: 71 72 void setNameFromPath( char* fileLoc ); 73 void resetFade(); 74 bool handleFade(); 75 76 77 }; 78 79 80 81 82 83 84 #endif -
source/soundmanager/items/CStreamItem.cpp
1 // 2 // CStreamItem.cpp 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/23/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 #include "CStreamItem.h" 9 #include "soundmanager/data/COggData.h" 10 11 #include <iostream> 12 13 CStreamItem::CStreamItem(CSoundData* sndData) 14 { 15 resetVars(); 16 if ( initOpenAL() ) 17 attach( sndData ); 18 19 debug_printf(L"created StreamItem at: %ls\n\n", sndData->getFileName().c_str()); 20 } 21 22 CStreamItem::~CStreamItem() 23 { 24 stop(); 25 26 int num_processed; 27 alGetSourcei( mALSource, AL_BUFFERS_PROCESSED, &num_processed); 28 29 if (num_processed > 0) 30 { 31 ALuint al_buf[num_processed]; 32 alSourceUnqueueBuffers(mALSource, num_processed, al_buf); 33 } 34 } 35 36 bool CStreamItem::idleTask() 37 { 38 handleFade(); 39 40 int proc_state; 41 alGetSourceiv( mALSource, AL_SOURCE_STATE, &proc_state); 42 43 if ( proc_state == AL_STOPPED ) { 44 if ( mLastPlay ) 45 return ( proc_state != AL_STOPPED ); 46 } 47 else { 48 COggData* tmp = (COggData*)mSoundData; 49 50 if ( ! tmp->isFileFinished() ) { 51 int num_processed; 52 alGetSourcei( mALSource, AL_BUFFERS_PROCESSED, &num_processed); 53 54 if (num_processed > 0) 55 { 56 ALuint al_buf[num_processed]; 57 alSourceUnqueueBuffers(mALSource, num_processed, al_buf); 58 int didWrite = tmp->fetchDataIntoBuffer( num_processed, al_buf); 59 alSourceQueueBuffers( mALSource, didWrite, al_buf); 60 } 61 } 62 else if ( getLooping() ) 63 { 64 tmp->resetFile(); 65 } 66 } 67 return true; 68 } 69 70 void CStreamItem::attach( CSoundData* itemData ) 71 { 72 if ( itemData != NULL ) { 73 mSoundData = itemData->incrementCount(); 74 alSourceQueueBuffers(mALSource, mSoundData->getBufferCount(), (const ALuint *)mSoundData->getBufferPtr()); 75 } 76 } 77 78 void CStreamItem::setLooping( bool loops ) 79 { 80 mLooping = loops; 81 } 82 -
source/soundmanager/CSoundManager.cpp
1 // 2 // CSoundManager.cpp 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/21/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 9 #include "CSoundManager.h" 10 #include "soundmanager/items/CSoundItem.h" 11 #include "soundmanager/items/CBufferItem.h" 12 #include "soundmanager/items/CStreamItem.h" 13 #include "soundmanager/js/JAmbientSound.h" 14 #include "soundmanager/js/JMusicSound.h" 15 #include "soundmanager/js/JSound.h" 16 #include "soundmanager/data/CSoundData.h" 17 18 19 CSoundManager* g_SoundManager; 20 21 void CSoundManager::ScriptingInit() 22 { 23 JAmbientSound::ScriptingInit(); 24 JMusicSound::ScriptingInit(); 25 JSound::ScriptingInit(); 26 } 27 28 CSoundManager::CSoundManager(OsPath& resourcePath) 29 { 30 mResourcePath = resourcePath; 31 32 mItems = new ItemsList; 33 mCurrentEnvirons = 0; 34 mCurrentTune = 0; 35 mGain = 1; 36 mMusicGain = 1; 37 mAmbientGain = 1; 38 mActionGain = 1; 39 mEnabled = true; 40 mBufferCount = 50; 41 mBufferSize = 65536; 42 43 debug_printf(L"initiate manager at: %ls\n\n", resourcePath.string().c_str()); 44 45 alc_init(); 46 } 47 48 CSoundManager::~CSoundManager() 49 { 50 ItemsList::iterator lstr = mItems->begin(); 51 while ( lstr != mItems->end() ) { 52 (*lstr)->stop(); 53 delete *lstr; 54 lstr++; 55 } 56 57 alcDestroyContext( mContext ); 58 alcCloseDevice( mDevice ); 59 60 delete mItems; 61 mItems = 0L; 62 mCurrentEnvirons = 0; 63 mCurrentTune = 0; 64 } 65 66 67 Status CSoundManager::alc_init() 68 { 69 Status ret = INFO::OK; 70 71 mDevice = alcOpenDevice(NULL); 72 if(mDevice) 73 { 74 mContext = alcCreateContext(mDevice, 0); // no attrlist needed 75 if(mContext) 76 alcMakeContextCurrent(mContext); 77 } 78 79 // check if init succeeded. 80 // some OpenAL implementations don't indicate failure here correctly; 81 // we need to check if the device and context pointers are actually valid. 82 ALCenum err = alcGetError(mDevice); 83 if(err != ALC_NO_ERROR || !mDevice || !mContext) 84 { 85 #if OS_UNIX 86 ret = INFO::OK; 87 #else 88 ret = ERR::FAIL; 89 #endif 90 } 91 92 const char* dev_name = (const char*)alcGetString(mDevice, ALC_DEVICE_SPECIFIER); 93 wchar_t buf[200]; 94 swprintf(buf, ARRAY_SIZE(buf), L"SND| alc_init: success, using %hs\n", dev_name); 95 96 return ret; 97 } 98 void CSoundManager::setMemoryUsage( long bufferSize, int bufferCount ) 99 { 100 mBufferCount = bufferCount; 101 mBufferSize = bufferSize; 102 } 103 long CSoundManager::getBufferCount() 104 { 105 return mBufferCount; 106 } 107 long CSoundManager::getBufferSize() 108 { 109 return mBufferSize; 110 } 111 112 113 void CSoundManager::setMasterGain( float gain) 114 { 115 mGain = gain; 116 } 117 void CSoundManager::setMusicGain( float gain) 118 { 119 mMusicGain = gain; 120 } 121 void CSoundManager::setAmbientGain( float gain) 122 { 123 mAmbientGain = gain; 124 } 125 void CSoundManager::setActionGain( float gain) 126 { 127 mActionGain = gain; 128 } 129 130 131 ISoundItem* CSoundManager::loadItem( OsPath* itemPath ) 132 { 133 debug_printf(L"initiate item at: %ls\n\n", itemPath->string().c_str()); 134 135 OsPath thePath = mResourcePath/ *itemPath; 136 137 CSoundData* itemData = CSoundData::soundDataFromFile( thePath ); 138 ISoundItem* answer = NULL; 139 140 if ( itemData != NULL ) { 141 if ( itemData->isOneShot() ) { 142 if ( itemData->getBufferCount() == 1 ) 143 answer = new CSoundItem( itemData ); 144 else 145 answer = new CBufferItem( itemData ); 146 } 147 else { 148 answer = new CStreamItem( itemData ); 149 } 150 151 if ( answer != NULL ) 152 mItems->push_back( answer ); 153 } 154 155 156 return answer; 157 } 158 159 unsigned long CSoundManager::count() 160 { 161 return mItems->size(); 162 } 163 164 void CSoundManager::idleTask() 165 { 166 if ( mItems ) 167 { 168 ItemsList::iterator lstr = mItems->begin(); 169 ItemsList deadItemList; 170 ItemsList* nextItemList = new ItemsList; 171 172 173 while ( lstr != mItems->end() ) { 174 if ( (*lstr)->idleTask() ) 175 nextItemList->push_back( *lstr ); 176 else 177 deadItemList.push_back( *lstr ); 178 lstr++; 179 } 180 delete mItems; 181 mItems = nextItemList; 182 183 ItemsList::iterator deadItems = deadItemList.begin(); 184 while ( deadItems != deadItemList.end() ) 185 { 186 delete *deadItems; 187 deadItems++; 188 } 189 } 190 if ( mCurrentTune ) 191 mCurrentTune->ensurePlay(); 192 if ( mCurrentEnvirons ) 193 mCurrentEnvirons->ensurePlay(); 194 } 195 196 void CSoundManager::deleteItem( long itemNum ) 197 { 198 ItemsList::iterator lstr = mItems->begin(); 199 lstr += itemNum; 200 201 delete *lstr; 202 203 mItems->erase( lstr ); 204 } 205 206 ISoundItem* CSoundManager::getSoundItem( unsigned long itemRow ) 207 { 208 return (*mItems)[itemRow]; 209 } 210 211 void CSoundManager::InitListener() 212 { 213 ALfloat listenerPos[]={0.0,0.0,4.0}; 214 ALfloat listenerVel[]={0.0,0.0,0.0}; 215 ALfloat listenerOri[]={0.0,0.0,1.0, 0.0,1.0,0.0}; 216 217 alListenerfv(AL_POSITION,listenerPos); 218 alListenerfv(AL_VELOCITY,listenerVel); 219 alListenerfv(AL_ORIENTATION,listenerOri); 220 } 221 void CSoundManager::setEnabled( bool doEnable ) 222 { 223 mEnabled = doEnable; 224 } 225 226 void CSoundManager::playActionItem( ISoundItem* anItem ) 227 { 228 if ( anItem ) 229 { 230 if ( mEnabled && ( mActionGain > 0 ) ) { 231 anItem->setGain( mGain * mActionGain ); 232 anItem->play(); 233 } 234 } 235 } 236 void CSoundManager::playGroupItem( ISoundItem* anItem, ALfloat groupGain) 237 { 238 if ( anItem ) 239 { 240 if ( mEnabled && ( mActionGain > 0 ) ) { 241 anItem->setGain( mGain * groupGain ); 242 anItem->play(); 243 } 244 } 245 } 246 void CSoundManager::setMusicItem( ISoundItem* anItem ) 247 { 248 if ( mCurrentTune ) { 249 mCurrentTune->fadeAndDelete(3.00); 250 mCurrentTune = 0L; 251 } 252 idleTask(); 253 if ( anItem ) 254 { 255 if ( mEnabled && ( mMusicGain > 0 ) ) { 256 mCurrentTune = anItem; 257 mCurrentTune->setGain( 0 ); 258 mCurrentTune->playLoop(); 259 mCurrentTune->fadeToIn( mGain * mMusicGain, 3.00 ); 260 } 261 } 262 } 263 264 void CSoundManager::setAmbientItem( ISoundItem* anItem ) 265 { 266 if ( mCurrentEnvirons ) { 267 mCurrentEnvirons->fadeAndDelete(3.00); 268 mCurrentEnvirons = 0L; 269 } 270 idleTask(); 271 272 if ( anItem ) 273 { 274 if ( mEnabled && ( mAmbientGain > 0 ) ) { 275 mCurrentEnvirons = anItem; 276 mCurrentEnvirons->setGain( 0 ); 277 mCurrentEnvirons->playLoop(); 278 mCurrentEnvirons->fadeToIn( mGain * mAmbientGain, 3.00 ); 279 } 280 } 281 } 282 -
source/soundmanager/data/COggData.h
1 // 2 // CSoundItem.h 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/23/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 9 #ifndef SoundTester_COggData_h 10 #define SoundTester_COggData_h 11 12 #include "CSoundData.h" 13 #include "vorbis/vorbisfile.h" 14 15 class COggData : public CSoundData 16 { 17 ALuint mFormat; 18 long mFrequency; 19 20 public: 21 COggData (); 22 virtual ~COggData (); 23 24 virtual bool InitOggFile( const wchar_t* fileLoc ); 25 virtual bool isFileFinished(); 26 virtual bool isOneShot(); 27 28 virtual int fetchDataIntoBuffer( int count, ALuint* buffers); 29 virtual void resetFile(); 30 31 protected: 32 OggVorbis_File m_vf; 33 int m_current_section; 34 bool mFileFinished; 35 bool mOneShot; 36 ALuint mBuffer[100]; 37 int mBuffersUsed; 38 39 bool addDataBuffer( char* data, long length); 40 void setFormatAndFreq( int form, ALsizei freq); 41 ALsizei getBufferCount(); 42 ALuint getBuffer(); 43 ALuint* getBufferPtr(); 44 }; 45 46 47 48 #endif -
source/soundmanager/data/CSoundData.cpp
1 // 2 // CSoundItem.cpp 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/23/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 9 #import "CSoundData.h" 10 11 12 #include <iostream> 13 #include "COggData.h" 14 15 DataMap* CSoundData::sSoundData = NULL; 16 17 CSoundData::CSoundData() 18 { 19 initProperties(); 20 } 21 22 CSoundData::~CSoundData() 23 { 24 if ( mALBuffer != 0 ) 25 alDeleteBuffers( 1, &mALBuffer ); 26 } 27 28 void CSoundData::initProperties() 29 { 30 mALBuffer = 0; 31 mRetentionCount = 0; 32 } 33 34 void CSoundData::releaseSoundData( CSoundData* theData ) 35 { 36 DataMap::iterator itemFind; 37 38 if ( theData->decrementCount() ) { 39 if ( ( itemFind = CSoundData::sSoundData->find( theData->getFileName() ) ) != sSoundData->end() ) 40 { 41 CSoundData* dier = itemFind->second; 42 CSoundData::sSoundData->erase( itemFind ); 43 delete dier; 44 } 45 } 46 } 47 48 CSoundData* CSoundData::soundDataFromFile( OsPath& itemPath ) 49 { 50 if ( CSoundData::sSoundData == NULL ) 51 CSoundData::sSoundData = new DataMap; 52 53 Path fExt = itemPath.Extension(); 54 DataMap::iterator itemFind; 55 CSoundData* answer; 56 57 58 debug_printf(L"creating data at: %ls\n\n", itemPath.string().c_str()); 59 60 if ( ( itemFind = CSoundData::sSoundData->find( itemPath.string() ) ) != sSoundData->end() ) 61 { 62 debug_printf(L"data found in cache at: %ls\n\n", itemPath.string().c_str()); 63 answer = itemFind->second; 64 } 65 else 66 { 67 if ( fExt == ".ogg" ) 68 answer = soundDataFromOgg( itemPath ); 69 // else if ( fExt == ".wav" ) 70 // answer = soundDataFromWAV( itemPath ); 71 72 if ( answer && answer->isOneShot() ) 73 (*CSoundData::sSoundData)[itemPath.string()] = answer; 74 75 } 76 return answer; 77 } 78 79 bool CSoundData::isOneShot() 80 { 81 return true; 82 } 83 84 85 CSoundData* CSoundData::soundDataFromOgg(OsPath& itemPath ) 86 { 87 CSoundData* answer = NULL; 88 COggData* oggAnswer = new COggData(); 89 if ( oggAnswer->InitOggFile( itemPath.string().c_str() ) ) { 90 answer = oggAnswer; 91 } 92 93 return answer; 94 } 95 96 97 ALsizei CSoundData::getBufferCount() 98 { 99 return 1; 100 } 101 102 std::wstring CSoundData::getFileName() 103 { 104 return mFileName; 105 } 106 107 108 109 110 111 112 113 114 115 CSoundData* CSoundData::incrementCount() 116 { 117 mRetentionCount++; 118 return this; 119 } 120 121 bool CSoundData::decrementCount() 122 { 123 mRetentionCount--; 124 125 return ( mRetentionCount <= 0 ); 126 } 127 128 ALuint CSoundData::getBuffer() 129 { 130 return mALBuffer; 131 } 132 ALuint* CSoundData::getBufferPtr() 133 { 134 return &mALBuffer; 135 } 136 -
source/soundmanager/data/COggData.cpp
1 // 2 // CSoundItem.cpp 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/23/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 9 #include "COggData.h" 10 11 12 #include <wchar.h> 13 #include <iostream> 14 #include "soundmanager/CSoundManager.h" 15 16 COggData::COggData() 17 { 18 mOneShot = false; 19 } 20 21 COggData::~COggData() 22 { 23 alDeleteBuffers( mBuffersUsed, mBuffer ); 24 ov_clear(&m_vf); 25 } 26 27 void COggData::setFormatAndFreq( int form, ALsizei freq) 28 { 29 mFormat = form; 30 mFrequency = freq; 31 } 32 33 bool COggData::InitOggFile( const wchar_t* fileLoc ) 34 { 35 int buffersToStart = g_SoundManager->getBufferCount(); 36 37 #ifdef _WIN32 38 _setmode( _fileno( stdin ), _O_BINARY ); 39 _setmode( _fileno( stdout ), _O_BINARY ); 40 #endif 41 42 // fprintf(stderr, "ready to open ogg file at:%ls \r\r", fileLoc); 43 44 char nameH[300]; 45 sprintf( nameH, "%ls", fileLoc ); 46 47 FILE* f = fopen( nameH, "rb"); 48 m_current_section = 0; 49 int err = ov_open_callbacks(f, &m_vf, NULL, 0, OV_CALLBACKS_DEFAULT); 50 if ( err < 0) { 51 fprintf(stderr,"Input does not appear to be an Ogg bitstream :%d :%d.\n", err, ferror(f) ); 52 return false; 53 } 54 55 mFileName = std::wstring(fileLoc); 56 57 mFileFinished = false; 58 setFormatAndFreq( (m_vf.vi->channels == 1)? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16 , (ALsizei)m_vf.vi->rate ); 59 60 alGetError(); /* clear error */ 61 alGenBuffers( buffersToStart, mBuffer); 62 63 if(alGetError() != AL_NO_ERROR) 64 { 65 printf("- Error creating initial buffer !!\n"); 66 return false; 67 } 68 else 69 { 70 mBuffersUsed = fetchDataIntoBuffer( buffersToStart, mBuffer); 71 if ( mFileFinished ) { 72 mOneShot = true; 73 if ( mBuffersUsed < buffersToStart ) { 74 debug_printf(L"one shot gave back %d buffers\n\n", buffersToStart - mBuffersUsed ); 75 alDeleteBuffers( buffersToStart - mBuffersUsed, &mBuffer[mBuffersUsed] ); 76 } 77 } 78 } 79 return true; 80 } 81 82 ALsizei COggData::getBufferCount() 83 { 84 return mBuffersUsed; 85 } 86 87 bool COggData::isFileFinished() 88 { 89 return mFileFinished; 90 } 91 92 void COggData::resetFile() 93 { 94 ov_time_seek( &m_vf, 0 ); 95 m_current_section = 0; 96 mFileFinished = false; 97 } 98 99 bool COggData::isOneShot() 100 { 101 return mOneShot; 102 } 103 104 int COggData::fetchDataIntoBuffer( int count, ALuint* buffers) 105 { 106 long bufferSize = g_SoundManager->getBufferSize(); 107 108 char pcmout[bufferSize + 5000]; 109 int buffersWritten = 0; 110 111 for(int i = 0; ( i < count ) && !mFileFinished; i++) { 112 char* readDest = pcmout; 113 long totalRet = 0; 114 while (totalRet < bufferSize ) 115 { 116 long ret=ov_read(&m_vf,readDest, 4096,0,2,1, &m_current_section); 117 if (ret == 0) { 118 mFileFinished=true; 119 break; 120 } else if (ret < 0) { 121 /* error in the stream. Not a problem, just reporting it in 122 case we (the app) cares. In this case, we don't. */ 123 } else { 124 totalRet += ret; 125 readDest += ret; 126 } 127 } 128 if ( totalRet > 0 ) 129 { 130 buffersWritten++; 131 alBufferData( buffers[i], mFormat, pcmout, (ALsizei)totalRet, (int)mFrequency); 132 } 133 } 134 135 return buffersWritten; 136 } 137 138 139 ALuint COggData::getBuffer() 140 { 141 return mBuffer[0]; 142 } 143 ALuint* COggData::getBufferPtr() 144 { 145 return mBuffer; 146 } 147 148 149 150 151 -
source/soundmanager/data/CSoundData.h
1 // 2 // CSoundItem.h 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/23/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 9 #ifndef SoundTester_CSoundData_h 10 #define SoundTester_CSoundData_h 11 #include "lib/os_path.h" 12 13 #include "lib/external_libraries/openal.h" 14 #include "string" 15 #include "map" 16 17 class CSoundData; 18 typedef std::map<std::wstring, CSoundData*> DataMap; 19 20 21 22 class CSoundData 23 { 24 public: 25 static CSoundData* soundDataFromFile( OsPath& itemPath ); 26 static CSoundData* soundDataFromOgg( OsPath& itemPath ); 27 // static CSoundData* soundDataFromWAV( OsPath& itemPath ); 28 29 static void releaseSoundData( CSoundData* theData ); 30 31 CSoundData (); 32 CSoundData (ALuint dataSource); 33 virtual ~CSoundData (); 34 35 CSoundData* incrementCount(); 36 bool decrementCount(); 37 void initProperties(); 38 virtual bool isOneShot(); 39 40 41 virtual ALuint getBuffer(); 42 virtual ALsizei getBufferCount(); 43 std::wstring getFileName(); 44 virtual ALuint* getBufferPtr(); 45 46 protected: 47 static DataMap* sSoundData; 48 49 ALuint mALBuffer; 50 int mRetentionCount; 51 std::wstring mFileName; 52 53 54 55 }; 56 57 58 59 60 61 62 #endif -
source/soundmanager/CSoundManager.h
1 // 2 // CSoundManager.h 3 // SoundTester 4 // 5 // Created by Steven Fuchs on 3/21/12. 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 // 8 9 #ifndef SoundTester_CSoundManager_h 10 #define SoundTester_CSoundManager_h 11 12 #include "vector" 13 #include "map" 14 #include "lib/external_libraries/openal.h" 15 16 #include "soundmanager/items/ISoundItem.h" 17 18 typedef std::vector<ISoundItem*> ItemsList; 19 20 21 class CSoundManager 22 { 23 protected: 24 25 ALuint mALEnvironment; 26 ALCcontext* mContext; 27 ALCdevice* mDevice; 28 ISoundItem* mCurrentTune; 29 ISoundItem* mCurrentEnvirons; 30 ItemsList* mItems; 31 OsPath mResourcePath; 32 float mGain; 33 float mMusicGain; 34 float mAmbientGain; 35 float mActionGain; 36 bool mEnabled; 37 long mBufferSize; 38 int mBufferCount; 39 40 public: 41 CSoundManager (OsPath& resourcePath); 42 virtual ~CSoundManager (); 43 44 ISoundItem* loadItem( OsPath* itemPath ); 45 46 static void ScriptingInit(); 47 48 49 50 ISoundItem* itemFromWAV ( OsPath& fname); 51 ISoundItem* itemFromOgg ( OsPath& fname); 52 53 ISoundItem* getSoundItem ( unsigned long itemRow ); 54 unsigned long count (); 55 void idleTask (); 56 void deleteItem ( long itemNum ); 57 58 void setMemoryUsage( long bufferSize, int bufferCount ); 59 long getBufferCount(); 60 long getBufferSize(); 61 62 void setMusicItem( ISoundItem* anItem ); 63 void setAmbientItem( ISoundItem* anItem ); 64 void playActionItem( ISoundItem* anItem ); 65 void playGroupItem( ISoundItem* anItem, ALfloat groupGain); 66 67 void setMasterGain( float gain); 68 void setMusicGain( float gain); 69 void setAmbientGain( float gain); 70 void setActionGain( float gain); 71 72 void setEnabled( bool doEnable ); 73 protected: 74 void InitListener(); 75 virtual Status alc_init(); 76 77 }; 78 79 80 81 extern CSoundManager* g_SoundManager; 82 83 84 85 86 87 88 89 #endif -
source/soundmanager/js/JAmbientSound.cpp
1 /* Copyright (C) 2009 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "JAmbientSound.h" 19 #include "maths/Vector3D.h" 20 21 #include "lib/utf8.h" 22 #include "lib/res/sound/snd_mgr.h" 23 #include "lib/res/h_mgr.h" // h_filename 24 #include "ps/Filesystem.h" 25 26 #include "soundmanager/CSoundManager.h" 27 28 JAmbientSound::JAmbientSound(const VfsPath& pathname) 29 { 30 mFileName = new OsPath( pathname.string().c_str() ); 31 } 32 33 JAmbientSound::~JAmbientSound() 34 { 35 } 36 37 38 // start playing the sound, all ambient sounds loop 39 bool JAmbientSound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) 40 { 41 ISoundItem* aSnd = g_SoundManager->loadItem( mFileName ); 42 43 aSnd->playAsAmbient(); 44 45 return true; 46 } 47 48 // start playing the sound, all ambient sounds loop 49 bool JAmbientSound::Loop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) 50 { 51 ISoundItem* aSnd = g_SoundManager->loadItem( mFileName ); 52 53 aSnd->playAsAmbient(); 54 return true; 55 } 56 bool JAmbientSound::Free(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) 57 { 58 g_SoundManager->setAmbientItem( 0L ); 59 60 return true; 61 } 62 63 // Script-bound functions 64 65 66 void JAmbientSound::ScriptingInit() 67 { 68 AddMethod<CStr, &JAmbientSound::ToString>("toString", 0); 69 AddMethod<bool, &JAmbientSound::Play>("play", 0); 70 AddMethod<bool, &JAmbientSound::Loop>("loop", 0); 71 AddMethod<bool, &JAmbientSound::Free>("free", 0); 72 73 CJSObject<JAmbientSound>::ScriptingInit("AmbientSound", &JAmbientSound::Construct, 1); 74 } 75 76 CStr JAmbientSound::ToString(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) 77 { 78 std::ostringstream stringStream; 79 stringStream << "[object AmbientSound: "; 80 stringStream << mFileName->string().c_str(); 81 82 return stringStream.str(); 83 } 84 85 JSBool JAmbientSound::Construct(JSContext* cx, uintN argc, jsval* vp) 86 { 87 // JSU_REQUIRE_MIN_PARAMS(1); 88 89 CStrW filename; 90 if (! ToPrimitive<CStrW>(cx, JS_ARGV(cx, vp)[0], filename)) 91 return JS_FALSE; 92 93 JAmbientSound* newObject = new JAmbientSound(filename); 94 newObject->m_EngineOwned = false; 95 96 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript())); 97 98 return JS_TRUE; 99 } -
source/soundmanager/js/JSound.cpp
1 /* Copyright (C) 2009 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "JSound.h" 19 #include "maths/Vector3D.h" 20 21 #include "lib/utf8.h" 22 #include "ps/Filesystem.h" 23 24 #include "soundmanager/CSoundManager.h" 25 26 27 JSound::JSound(const VfsPath& pathname) 28 { 29 OsPath itsPth = OsPath( pathname.string().c_str() ); 30 mSndItem = g_SoundManager->loadItem( &itsPth ); 31 } 32 33 JSound::~JSound() 34 { 35 if ( mSndItem ) { 36 mSndItem->fadeAndDelete(0.2); 37 mSndItem = 0; 38 } 39 } 40 41 bool JSound::clearSoundItem() 42 { 43 mSndItem = 0L; 44 } 45 46 bool JSound::SetGain(JSContext* cx, uintN UNUSED(argc), jsval* argv) 47 { 48 if (! mSndItem ) 49 return false; 50 51 float gain; 52 if (! ToPrimitive<float>(cx, argv[0], gain)) 53 return false; 54 55 mSndItem->setGain( gain ); 56 return true; 57 } 58 59 bool JSound::SetPitch(JSContext* cx, uintN UNUSED(argc), jsval* argv) 60 { 61 if (! mSndItem ) 62 return false; 63 64 float pitch; 65 if (! ToPrimitive<float>(cx, argv[0], pitch)) 66 return false; 67 68 mSndItem->setPitch( pitch ); 69 return true; 70 } 71 72 bool JSound::SetPosition(JSContext* cx, uintN argc, jsval* argv) 73 { 74 if (! mSndItem ) 75 return false; 76 77 ENSURE(argc >= 1); // FIXME 78 79 CVector3D pos; 80 // absolute world coords 81 if (!ToPrimitive<CVector3D>(cx, argv[0], pos)) 82 return false; 83 84 mSndItem->setLocation( pos ); 85 86 return true; 87 } 88 89 90 bool JSound::Fade(JSContext* cx, uintN argc, jsval* argv) 91 { 92 if (! mSndItem ) 93 return false; 94 95 // ENSURE(argc >= 3); // FIXME 96 float initial_gain, final_gain; 97 float length; 98 if (! (ToPrimitive<float>(cx, argv[0], initial_gain) 99 && ToPrimitive<float>(cx, argv[1], final_gain) 100 && ToPrimitive<float>(cx, argv[2], length))) 101 return false; 102 103 mSndItem->setGain( initial_gain ); 104 mSndItem->fadeToIn( final_gain, length ); 105 106 return true; 107 } 108 109 bool JSound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) 110 { 111 if (! mSndItem ) 112 return false; 113 114 mSndItem->play(); 115 116 return true; 117 } 118 119 bool JSound::Loop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) 120 { 121 if (! mSndItem ) 122 return false; 123 124 mSndItem->playLoop(); 125 126 return true; 127 } 128 129 bool JSound::Free(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) 130 { 131 if ( mSndItem ) { 132 mSndItem->fadeAndDelete(0.2); 133 mSndItem = 0; 134 } 135 136 return true; 137 } 138 139 void JSound::ScriptingInit() 140 { 141 AddMethod<CStr, &JSound::ToString>("toString", 0); 142 AddMethod<bool, &JSound::Play>("play", 0); 143 AddMethod<bool, &JSound::Loop>("loop", 0); 144 AddMethod<bool, &JSound::Free>("free", 0); 145 AddMethod<bool, &JSound::SetGain>("setGain", 0); 146 AddMethod<bool, &JSound::SetPitch>("setPitch", 0); 147 AddMethod<bool, &JSound::SetPosition>("setPosition", 0); 148 AddMethod<bool, &JSound::Fade>("fade", 0); 149 150 CJSObject<JSound>::ScriptingInit("Sound", &JSound::Construct, 1); 151 } 152 153 CStr JSound::ToString(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) 154 { 155 return "[object Sound: " + ( mSndItem ? mSndItem->getName() : "(null)" ) + "]"; 156 } 157 158 JSBool JSound::Construct(JSContext* cx, uintN argc, jsval* vp) 159 { 160 // JSU_REQUIRE_MIN_PARAMS(1); 161 162 CStrW filename; 163 if (! ToPrimitive<CStrW>(cx, JS_ARGV(cx, vp)[0], filename)) 164 return JS_FALSE; 165 166 JSound* newObject = new JSound(filename); 167 newObject->m_EngineOwned = false; 168 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript())); 169 170 return JS_TRUE; 171 } -
source/soundmanager/js/JMusicSound.cpp
1 /* Copyright (C) 2009 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "JMusicSound.h" 19 #include "maths/Vector3D.h" 20 21 #include "lib/utf8.h" 22 #include "ps/Filesystem.h" 23 24 #include "soundmanager/CSoundManager.h" 25 26 27 JMusicSound::JMusicSound(const VfsPath& pathname) 28 { 29 mFileName = new OsPath( pathname.string().c_str() ); 30 } 31 32 JMusicSound::~JMusicSound() 33 { 34 // disposing of music now handled by SoundManager 35 } 36 37 bool JMusicSound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) 38 { 39 ISoundItem* aSnd = g_SoundManager->loadItem( mFileName ); 40 aSnd->playAsMusic(); 41 42 return true; 43 } 44 45 // request the sound be played until free() is called. returns immediately. 46 bool JMusicSound::Loop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) 47 { 48 ISoundItem* aSnd = g_SoundManager->loadItem( mFileName ); 49 aSnd->playAsMusic(); 50 51 return true; 52 } 53 54 void JMusicSound::ScriptingInit() 55 { 56 AddMethod<CStr, &JMusicSound::ToString>("toString", 0); 57 AddMethod<bool, &JMusicSound::Play>("play", 0); 58 AddMethod<bool, &JMusicSound::Loop>("loop", 0); 59 60 CJSObject<JMusicSound>::ScriptingInit("MusicSound", &JMusicSound::Construct, 1); 61 } 62 63 CStr JMusicSound::ToString(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) 64 { 65 std::ostringstream stringStream; 66 stringStream << "[object MusicSound: "; 67 stringStream << mFileName->string().c_str(); 68 69 return stringStream.str(); 70 } 71 72 JSBool JMusicSound::Construct(JSContext* cx, uintN argc, jsval* vp) 73 { 74 // JSU_REQUIRE_MIN_PARAMS(1); 75 76 CStrW filename; 77 if (! ToPrimitive<CStrW>(cx, JS_ARGV(cx, vp)[0], filename)) 78 return JS_FALSE; 79 80 JMusicSound* newObject = new JMusicSound(filename); 81 newObject->m_EngineOwned = false; 82 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript())); 83 84 return JS_TRUE; 85 } -
source/soundmanager/js/SMSoundGroup.cpp
1 /* Copyright (C) 2010 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 /** 19 * ========================================================================= 20 * File : SoundGroup.cpp 21 * Project : 0 A.D. 22 * Description : Loads up a group of sound files with shared properties, 23 * and provides a simple interface for playing them. 24 * ========================================================================= 25 */ 26 27 #include "precompiled.h" 28 #include "soundmanager/CSoundManager.h" 29 #include "SMSoundGroup.h" 30 31 #include <algorithm> 32 33 #include "lib/rand.h" 34 35 #include "ps/XML/Xeromyces.h" 36 #include "ps/CLogger.h" 37 #include "ps/Filesystem.h" 38 #include "ps/Util.h" 39 40 41 static const bool DISABLE_INTENSITY = true; // disable for now since it's broken 42 43 void CSMSoundGroup::SetGain(float gain) 44 { 45 gain = std::min(gain, 1.0f); 46 m_Gain = gain; 47 } 48 49 void CSMSoundGroup::SetDefaultValues() 50 { 51 m_index = 0; 52 m_Flags = 0; 53 m_Intensity = 0; 54 m_CurTime = 0.0f; 55 56 // sane defaults; will probably be replaced by the values read during LoadSoundGroup. 57 SetGain(0.7f); 58 m_Pitch = 1.0f; 59 m_Priority = 60; 60 m_PitchUpper = 1.1f; 61 m_PitchLower = 0.9f; 62 m_GainUpper = 1.0f; 63 m_GainLower = 0.8f; 64 m_ConeOuterGain = 0.0f; 65 m_ConeInnerAngle = 360.0f; 66 m_ConeOuterAngle = 360.0f; 67 m_Decay = 3.0f; 68 m_IntensityThreshold = 3; 69 // WARNING: m_TimeWindow is currently unused and uninitialized 70 } 71 72 CSMSoundGroup::CSMSoundGroup() 73 { 74 SetDefaultValues(); 75 } 76 77 CSMSoundGroup::CSMSoundGroup(const VfsPath& pathnameXML) 78 { 79 SetDefaultValues(); 80 LoadSoundGroup(pathnameXML); 81 } 82 83 CSMSoundGroup::~CSMSoundGroup() 84 { 85 // clean up all the handles from this group. 86 ReleaseGroup(); 87 } 88 89 static float RandFloat(float min, float max) 90 { 91 return float(rand(min*100.0f, max*100.0f) / 100.0f); 92 } 93 94 void CSMSoundGroup::UploadPropertiesAndPlay(ISoundItem* hSound, const CVector3D& position) 95 { 96 hSound->setLocation( position ); 97 98 if( TestFlag(eRandPitch) ) 99 hSound->setPitch( RandFloat( m_PitchLower, m_PitchUpper ) ); 100 else 101 hSound->setPitch( m_Pitch ); 102 103 ALfloat theGain = m_Gain; 104 if( TestFlag(eRandGain) ) 105 theGain = RandFloat( m_GainLower, m_GainUpper); 106 107 hSound->setCone( m_ConeInnerAngle, m_ConeOuterAngle, m_ConeOuterGain); 108 109 110 g_SoundManager->playGroupItem( hSound, theGain ); 111 } 112 113 114 static void HandleError(const std::wstring& message, const VfsPath& pathname, Status err) 115 { 116 if(err == ERR::AGAIN) 117 return; // open failed because sound is disabled (don't log this) 118 LOGERROR(L"%ls: pathname=%ls, error=%ls", message.c_str(), pathname.string().c_str(), ErrorString(err)); 119 } 120 121 void CSMSoundGroup::PlayNext(const CVector3D& position) 122 { 123 // if no sounds, return 124 if (filenames.size() == 0) 125 return; 126 127 m_index = (size_t)rand(0, (size_t)filenames.size()); 128 UploadPropertiesAndPlay( snd_group[m_index], position); 129 } 130 131 void CSMSoundGroup::Reload() 132 { 133 m_index = 0; // reset our index 134 135 snd_group.clear(); 136 137 for(size_t i = 0; i < filenames.size(); i++) 138 { 139 OsPath thePath = OsPath( m_filepath/filenames[i] ); 140 ISoundItem* temp = g_SoundManager->loadItem( &thePath ); 141 snd_group.push_back(temp); 142 } 143 144 if(TestFlag(eRandOrder)) 145 random_shuffle(snd_group.begin(), snd_group.end()); 146 } 147 148 void CSMSoundGroup::ReleaseGroup() 149 { 150 151 for(size_t i = 0; i < filenames.size(); i++) 152 { 153 snd_group[i]->fadeAndDelete(0.2); 154 } 155 snd_group.clear(); 156 } 157 158 void CSMSoundGroup::Update(float TimeSinceLastFrame) 159 { 160 } 161 162 bool CSMSoundGroup::LoadSoundGroup(const VfsPath& pathnameXML) 163 { 164 // LOGERROR(L"loading new sound group '%ls'", pathnameXML.string().c_str()); 165 166 CXeromyces XeroFile; 167 if (XeroFile.Load(g_VFS, pathnameXML) != PSRETURN_OK) 168 return false; 169 170 // Define elements used in XML file 171 #define EL(x) int el_##x = XeroFile.GetElementID(#x) 172 #define AT(x) int at_##x = XeroFile.GetAttributeID(#x) 173 EL(soundgroup); 174 EL(gain); 175 EL(looping); 176 EL(omnipresent); 177 EL(pitch); 178 EL(priority); 179 EL(randorder); 180 EL(randgain); 181 EL(randpitch); 182 EL(conegain); 183 EL(coneinner); 184 EL(coneouter); 185 EL(sound); 186 EL(gainupper); 187 EL(gainlower); 188 EL(pitchupper); 189 EL(pitchlower); 190 EL(path); 191 EL(threshold); 192 EL(decay); 193 EL(replacement); 194 #undef AT 195 #undef EL 196 197 XMBElement root = XeroFile.GetRoot(); 198 199 if (root.GetNodeName() != el_soundgroup) 200 { 201 LOGERROR(L"Invalid SoundGroup format (unrecognised root element '%hs')", XeroFile.GetElementString(root.GetNodeName()).c_str()); 202 return false; 203 } 204 205 XERO_ITER_EL(root, child) 206 { 207 208 int child_name = child.GetNodeName(); 209 210 if(child_name == el_gain) 211 { 212 SetGain(child.GetText().ToFloat()); 213 } 214 else if(child_name == el_looping) 215 { 216 if(child.GetText().ToInt() == 1) 217 SetFlag(eLoop); 218 } 219 else if(child_name == el_omnipresent) 220 { 221 if(child.GetText().ToInt() == 1) 222 SetFlag(eOmnipresent); 223 } 224 else if(child_name == el_pitch) 225 { 226 this->m_Pitch = child.GetText().ToFloat(); 227 } 228 else if(child_name == el_priority) 229 { 230 this->m_Priority = child.GetText().ToFloat(); 231 } 232 else if(child_name == el_randorder) 233 { 234 if(child.GetText().ToInt() == 1) 235 SetFlag(eRandOrder); 236 } 237 else if(child_name == el_randgain) 238 { 239 if(child.GetText().ToInt() == 1) 240 SetFlag(eRandGain); 241 } 242 else if(child_name == el_gainupper) 243 { 244 this->m_GainUpper = child.GetText().ToFloat(); 245 } 246 else if(child_name == el_gainlower) 247 { 248 this->m_GainLower = child.GetText().ToFloat(); 249 } 250 else if(child_name == el_randpitch) 251 { 252 if(child.GetText().ToInt() == 1) 253 SetFlag(eRandPitch); 254 } 255 else if(child_name == el_pitchupper) 256 { 257 this->m_PitchUpper = child.GetText().ToFloat(); 258 } 259 else if(child_name == el_pitchlower) 260 { 261 this->m_PitchLower = child.GetText().ToFloat(); 262 } 263 else if(child_name == el_conegain) 264 { 265 this->m_ConeOuterGain = child.GetText().ToFloat(); 266 } 267 else if(child_name == el_coneinner) 268 { 269 this->m_ConeInnerAngle = child.GetText().ToFloat(); 270 } 271 else if(child_name == el_coneouter) 272 { 273 this->m_ConeOuterAngle = child.GetText().ToFloat(); 274 } 275 else if(child_name == el_sound) 276 { 277 this->filenames.push_back(child.GetText().FromUTF8()); 278 } 279 else if(child_name == el_path) 280 { 281 m_filepath = child.GetText().FromUTF8(); 282 } 283 else if(child_name == el_threshold) 284 { 285 m_IntensityThreshold = child.GetText().ToFloat(); 286 } 287 else if(child_name == el_decay) 288 { 289 m_Decay = child.GetText().ToFloat(); 290 } 291 } 292 293 Reload(); 294 return true; 295 } -
source/soundmanager/js/JAmbientSound.h
1 /* Copyright (C) 2009 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef INCLUDED_JAMBIENTSOUND 19 #define INCLUDED_JAMBIENTSOUND 20 21 #include "scripting/ScriptableObject.h" 22 #include "soundmanager/items/ISoundItem.h" 23 24 class JAmbientSound : public CJSObject<JAmbientSound> 25 { 26 public: 27 JAmbientSound (const VfsPath& pathname); 28 virtual ~JAmbientSound (); 29 30 31 CStr ToString(JSContext* cx, uintN argc, jsval* argv); 32 33 bool Play(JSContext* cx, uintN argc, jsval* argv); 34 35 bool Loop(JSContext* cx, uintN argc, jsval* argv); 36 bool Free(JSContext* cx, uintN argc, jsval* argv); 37 38 bool SetGain(JSContext* cx, uintN argc, jsval* argv); 39 bool SetPitch(JSContext* cx, uintN argc, jsval* argv); 40 bool Fade(JSContext* cx, uintN argc, jsval* argv); 41 42 static JSBool Construct(JSContext* cx, uintN argc, jsval* vp); 43 void clearSoundItem(); 44 static void ScriptingInit(); 45 protected: 46 47 OsPath* mFileName; 48 49 }; 50 51 #endif // #ifndef INCLUDED_JAMBIENTSOUND -
source/soundmanager/js/JSound.h
1 /* Copyright (C) 2009 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 // JS sound binding 19 20 // interface rationale: 21 // - can't just expose fire and forget playSound to script code: 22 // we sometimes need to loop until a certain condition is met 23 // (e.g. building is complete) => need means of access (Handle) to sound. 24 // 25 // - the current 64-bit Handle can't be stored as-is by JS code; 26 // we could make it 32 bit, but that limits its usefulness 27 // (barely enough tag bits). 28 // 29 // - instead, we provide a thin class wrapper (using scriptableobject.h) 30 // on top of the snd API that encapsulates the Handle. 31 32 #ifndef INCLUDED_JSOUND 33 #define INCLUDED_JSOUND 34 35 #include "scripting/ScriptableObject.h" 36 #include "soundmanager/items/ISoundItem.h" 37 38 class JSound : public CJSObject<JSound> 39 { 40 public: 41 42 // note: filename is stored by handle manager; no need to keep a copy here. 43 44 JSound(const VfsPath& pathname); 45 virtual ~JSound(); 46 47 CStr ToString(JSContext* cx, uintN argc, jsval* argv); 48 49 bool Play(JSContext* cx, uintN argc, jsval* argv); 50 bool Loop(JSContext* cx, uintN argc, jsval* argv); 51 52 bool Free(JSContext* cx, uintN argc, jsval* argv); 53 bool SetGain(JSContext* cx, uintN argc, jsval* argv); 54 bool SetPitch(JSContext* cx, uintN argc, jsval* argv); 55 bool SetPosition(JSContext* cx, uintN argc, jsval* argv); 56 bool clearSoundItem(); 57 58 bool Fade(JSContext* cx, uintN argc, jsval* argv); 59 60 static JSBool Construct(JSContext* cx, uintN argc, jsval* vp); 61 static void ScriptingInit(); 62 63 protected: 64 ISoundItem* mSndItem; 65 }; 66 67 #endif // #ifndef INCLUDED_JSOUND -
source/soundmanager/js/JMusicSound.h
1 /* Copyright (C) 2009 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 // JS sound binding 19 20 // interface rationale: 21 // - can't just expose fire and forget playSound to script code: 22 // we sometimes need to loop until a certain condition is met 23 // (e.g. building is complete) => need means of access (Handle) to sound. 24 // 25 // - the current 64-bit Handle can't be stored as-is by JS code; 26 // we could make it 32 bit, but that limits its usefulness 27 // (barely enough tag bits). 28 // 29 // - instead, we provide a thin class wrapper (using scriptableobject.h) 30 // on top of the snd API that encapsulates the Handle. 31 32 #ifndef INCLUDED_JMUSICSOUND 33 #define INCLUDED_JMUSICSOUND 34 35 #include "scripting/ScriptableObject.h" 36 #include "soundmanager/items/ISoundItem.h" 37 38 class JMusicSound : public CJSObject<JMusicSound> 39 { 40 public: 41 JMusicSound(const VfsPath& pathname); 42 virtual ~JMusicSound(); 43 44 // Script-bound functions 45 46 CStr ToString(JSContext* cx, uintN argc, jsval* argv); 47 48 bool Play(JSContext* cx, uintN argc, jsval* argv); 49 bool Loop(JSContext* cx, uintN argc, jsval* argv); 50 51 static JSBool Construct(JSContext* cx, uintN argc, jsval* vp); 52 53 static void ScriptingInit(); 54 55 protected: 56 OsPath* mFileName; 57 }; 58 59 #endif // #ifndef INCLUDED_JMUSICSOUND -
source/soundmanager/js/SMSoundGroup.h
1 /* Copyright (C) 2009 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 /** 19 * ========================================================================= 20 * File : SoundGroup.h 21 * Project : 0 A.D. 22 * Description : Loads up a group of sound files with shared properties, 23 * and provides a simple interface for playing them. 24 * ========================================================================= 25 */ 26 27 /* 28 Example usage: 29 30 31 Example SoundGroup.xml 32 <?xml version="1.0" encoding="utf-8"?> 33 <SoundGroup> 34 <Gain>1.0</Gain> 35 <Looping>0</Looping> 36 <Pitch>1.0</Pitch> 37 <Priority>100</Priority> 38 <RandOrder>0</RandOrder> 39 <RandGain>0</RandGain> 40 <RandPitch>0</RandPitch> 41 <ConeGain>1.0</ConeGain> 42 <ConeInner>360</ConeInner> 43 <ConeOuter>360</ConeOuter> 44 <Sound>audio/voice/hellenes/soldier/Attack_Attackx.ogg</Sound> 45 <Sound>audio/voice/hellenes/soldier/Attack_Chargex.ogg</Sound> 46 <Sound>audio/voice/hellenes/soldier/Attack_Engagex.ogg</Sound> 47 <Sound>audio/voice/hellenes/soldier/Attack_ForMyFamily.ogg</Sound> 48 </SoundGroup> 49 50 */ 51 52 #ifndef INCLUDED_SMSOUNDGROUP 53 #define INCLUDED_SMSOUNDGROUP 54 55 #include "lib/res/handle.h" 56 #include "lib/file/vfs/vfs_path.h" 57 #include "ps/CStr.h" 58 #include "maths/Vector3D.h" 59 #include "lib/res/sound/snd_mgr.h" 60 #include "soundmanager/items/ISoundItem.h" 61 62 #include <vector> 63 64 enum eSndGrpFlags 65 { 66 eRandOrder = 0x01, 67 eRandGain = 0x02, 68 eRandPitch = 0x04, 69 eLoop = 0x08, 70 eOmnipresent = 0x10 71 }; 72 73 74 class CSMSoundGroup 75 { 76 NONCOPYABLE(CSMSoundGroup); 77 public: 78 CSMSoundGroup(const VfsPath& pathnameXML); 79 CSMSoundGroup(void); 80 ~CSMSoundGroup(void); 81 82 // Play next sound in group 83 // @param position world position of the entity generating the sound 84 // (ignored if the eOmnipresent flag is set) 85 void PlayNext(const CVector3D& position); 86 87 // Load a group 88 bool LoadSoundGroup(const VfsPath& pathnameXML); 89 90 void Reload(); 91 92 // Release all remaining loaded handles 93 void ReleaseGroup(); 94 95 // Update SoundGroup, remove dead sounds from intensity count 96 void Update(float TimeSinceLastFrame); 97 98 // Set a flag using a value from eSndGrpFlags 99 inline void SetFlag(int flag) { m_Flags = (unsigned char)(m_Flags | flag); } 100 101 // Test flag, returns true if flag is set. 102 inline bool TestFlag(int flag) { return (m_Flags & flag) != 0; } 103 104 private: 105 void SetGain(float gain); 106 void UploadPropertiesAndPlay(ISoundItem* hSound, const CVector3D& position); 107 void SetDefaultValues(); 108 109 size_t m_index; // index of the next sound to play 110 111 Handle m_hReplacement; 112 113 std::vector<ISoundItem*> snd_group; // we store the handles so we can load now and play later 114 std::vector<std::wstring> filenames; // we need the filenames so we can reload when necessary. 115 116 VfsPath m_filepath; // the file path for the list of sound file resources 117 118 float m_CurTime; // Time elapsed since soundgroup was created 119 float m_TimeWindow; // The Intensity Threshold Window 120 size_t m_IntensityThreshold; // the allowable intensity before a sound switch 121 size_t m_Intensity; // our current intensity(number of sounds played since m_CurTime - m_TimeWindow) 122 float m_Decay; // 123 unsigned char m_Flags; // up to eight individual parameters, use with eSndGrpFlags. 124 125 float m_Gain; 126 float m_Pitch; 127 float m_Priority; 128 float m_ConeOuterGain; 129 float m_PitchUpper; 130 float m_PitchLower; 131 float m_GainUpper; 132 float m_GainLower; 133 float m_ConeInnerAngle; 134 float m_ConeOuterAngle; 135 }; 136 137 #endif //#ifndef INCLUDED_SOUNDGROUP -
source/main.cpp
383 383 // coincide in position and orientation. 384 384 float down[3] = { -up[0], -up[1], -up[2] }; 385 385 386 {387 PROFILE3("sound update");388 if (snd_update(pos, dir, down) < 0)389 debug_printf(L"snd_update failed\n");390 }386 // { 387 // PROFILE3("sound update"); 388 // if (snd_update(pos, dir, down) < 0) 389 // debug_printf(L"snd_update failed\n"); 390 // } 391 391 } 392 392 else 393 393 { 394 PROFILE3("sound update (0)");395 if (snd_update(0, 0, 0) < 0)396 debug_printf(L"snd_update (pos=0 version) failed\n");394 // PROFILE3("sound update (0)"); 395 // if (snd_update(0, 0, 0) < 0) 396 // debug_printf(L"snd_update (pos=0 version) failed\n"); 397 397 } 398 398 399 399 // Immediately flush any messages produced by simulation code … … 477 477 // run non-visual simulation replay if requested 478 478 if (args.Has("replay")) 479 479 { 480 snd_disable(true);481 482 480 Paths paths(args); 483 481 g_VFS = CreateVfs(20 * MiB); 484 482 g_VFS->Mount(L"cache/", paths.Cache(), VFS_MOUNT_ARCHIVABLE); -
source/simulation2/components/CCmpSoundManager.cpp
24 24 #include "simulation2/MessageTypes.h" 25 25 #include "simulation2/components/ICmpPosition.h" 26 26 #include "simulation2/components/ICmpRangeManager.h" 27 #include "sound /SoundGroup.h"27 #include "soundmanager/js/SMSoundGroup.h" 28 28 29 29 class CCmpSoundManager : public ICmpSoundManager 30 30 { … … 36 36 37 37 DEFAULT_COMPONENT_ALLOCATOR(SoundManager) 38 38 39 std::map<std::wstring, CS oundGroup*> m_SoundGroups;39 std::map<std::wstring, CSMSoundGroup*> m_SoundGroups; 40 40 41 41 static std::string GetSchema() 42 42 { … … 49 49 50 50 virtual void Deinit() 51 51 { 52 for (std::map<std::wstring, CS oundGroup*>::iterator it = m_SoundGroups.begin(); it != m_SoundGroups.end(); ++it)52 for (std::map<std::wstring, CSMSoundGroup*>::iterator it = m_SoundGroups.begin(); it != m_SoundGroups.end(); ++it) 53 53 delete it->second; 54 54 m_SoundGroups.clear(); 55 55 } … … 76 76 // or on some other timer? 77 77 const CMessageUpdate& msgData = static_cast<const CMessageUpdate&> (msg); 78 78 float t = msgData.turnLength.ToFloat(); 79 for (std::map<std::wstring, CS oundGroup*>::iterator it = m_SoundGroups.begin(); it != m_SoundGroups.end(); ++it)79 for (std::map<std::wstring, CSMSoundGroup*>::iterator it = m_SoundGroups.begin(); it != m_SoundGroups.end(); ++it) 80 80 if (it->second) 81 81 it->second->Update(t); 82 82 break; … … 87 87 virtual void PlaySoundGroup(std::wstring name, entity_id_t source) 88 88 { 89 89 // Make sure the sound group is loaded 90 CS oundGroup* group;90 CSMSoundGroup* group; 91 91 if (m_SoundGroups.find(name) == m_SoundGroups.end()) 92 92 { 93 group = new CS oundGroup();93 group = new CSMSoundGroup(); 94 94 if (!group->LoadSoundGroup(L"audio/" + name)) 95 95 { 96 96 LOGERROR(L"Failed to load sound group '%ls'", name.c_str()); -
binaries/data/mods/public/gui/session/session.js
408 408 // currentAmbient = newRandomSound("ambient", "temperate_", "dayscape"); 409 409 410 410 const AMBIENT = "audio/ambient/dayscape/day_temperate_gen_03.ogg"; 411 currentAmbient = new Sound(AMBIENT);411 currentAmbient = new AmbientSound(AMBIENT); 412 412 413 413 if (currentAmbient) 414 414 { 415 415 currentAmbient.loop(); 416 currentAmbient.setGain(0.8);417 416 } 418 417 break; 419 418 … … 428 427 { 429 428 if (currentAmbient) 430 429 { 431 currentAmbient.f ade(-1, 0.0, 5.0);430 currentAmbient.free(); 432 431 currentAmbient = null; 433 432 } 434 433 } -
binaries/data/mods/public/gui/common/music.js
72 72 switch (this.currentState) 73 73 { 74 74 case this.states.OFF: 75 if (this.isPlaying())76 {77 this.currentMusic.fade(-1, 0.0, 3.0);78 this.currentMusic = null;79 }80 75 break; 81 76 82 77 case this.states.MENU: … … 146 141 147 142 Music.prototype.switchMusic = function(track, fadeInPeriod, isLooping) 148 143 { 149 if (this.currentMusic) 150 { 151 this.currentMusic.fade(-1, 0.0, 5.0); 152 this.currentMusic = null; 153 } 144 this.currentMusic = new MusicSound(this.RELATIVE_MUSIC_PATH + track); 154 145 155 this.currentMusic = new Sound(this.RELATIVE_MUSIC_PATH + track);156 157 146 if (this.currentMusic) 158 147 { 159 148 if (isLooping) 160 149 this.currentMusic.loop(); 161 150 else 162 151 this.currentMusic.play(); 163 164 if (fadeInPeriod)165 this.currentMusic.fade(0.0, this.musicGain, fadeInPeriod);166 152 } 167 153 }; 168 154 -
binaries/data/mods/public/gui/common/functions_utility_music.js
66 66 67 67 //console.write("Playing " + randomSoundPath + " ..."); 68 68 69 switch (soundType) 70 { 71 case "music": 72 return new MusicSound(randomSoundPath); 73 break; 74 case "ambient": 75 return new AmbientSound(randomSoundPath); 76 break; 77 case "effect": 78 console.write ("am loading effect '*"+randomSoundPath+"*'"); 79 break; 80 default: 81 break; 82 } 69 83 return new Sound(randomSoundPath); 70 84 } 71 85 -
binaries/data/mods/public/hwdetect/hwdetect.js
213 213 } 214 214 215 215 // http://trac.wildfiregames.com/ticket/685 216 if (os_macosx)217 {218 warnings.push("Audio has been disabled, due to problems with OpenAL on OS X.");219 disable_audio = true;220 }216 // if (os_macosx) 217 // { 218 // warnings.push("Audio has been disabled, due to problems with OpenAL on OS X."); 219 // disable_audio = true; 220 // } 221 221 222 222 // http://trac.wildfiregames.com/ticket/684 223 223 // https://bugs.freedesktop.org/show_bug.cgi?id=24047 -
binaries/data/config/default.cfg
73 73 74 74 ; GENERAL PREFERENCES: 75 75 76 sound.mastergain = 0.5 76 sound.mastergain = 0.9 77 sound.musicgain = 0.2 78 sound.ambientgain = 0.6 79 sound.actiongain = 0.7 80 sound.bufferCount = 50 81 sound.bufferSize = 65536 77 82 78 83 ; Camera control settings 79 84 view.scroll.speed = 120.0