Changeset 5896
- Timestamp:
- Oct 6, 2009, 11:12:01 PM (15 years ago)
- Location:
- code/branches/core5
- Files:
-
- 9 edited
- 4 copied
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
code/branches/core5/data/levels/presentation_pong.oxw
r5891 r5896 46 46 gametype = Pong 47 47 > 48 <AmbientSound soundFile="ambient/mainmenu.wav" playOnLoad=true /> 49 48 50 <Scene 49 51 ambientlight = "0.5, 0.5, 0.5" … … 82 84 <ParticleSpawner name=scoreeffect_left position="-120,0,-30" source="Orxonox/BigExplosion1part2" lifetime=3.0 autostart=0 /> 83 85 <ParticleSpawner name=scoreeffect_left position="-120,0,-45" source="Orxonox/sparks2" lifetime=0.1 autostart=0 /> 86 87 <WorldSound name="scoreSound" position="0,0,0" soundFile="sounds/pong_score.wav" > 88 <events> 89 <play> 90 <EventListener event=pongcenter /> 91 </play> 92 </events> 93 </WorldSound> 84 94 85 95 <?lua -
code/branches/core5/src/orxonox/OrxonoxPrereqs.h
r5895 r5896 150 150 151 151 //sound 152 class SoundBase; 152 class AmbientSound; 153 class BaseSound; 153 154 class SoundManager; 154 class SoundMainMenu;155 class WorldSound; 155 156 156 157 // weaponsystem -
code/branches/core5/src/orxonox/controllers/HumanController.cc
r5813 r5896 36 36 #include "infos/PlayerInfo.h" 37 37 #include "overlays/Map.h" 38 #include "sound/SoundManager.h" 38 39 #include "Radar.h" 39 40 #include "Scene.h" … … 77 78 } 78 79 80 void HumanController::tick(float dt) 81 { 82 if (HumanController::localController_s && HumanController::localController_s->controllableEntity_) 83 { 84 if (GameMode::playsSound()) 85 { 86 // Update sound listener 87 SoundManager::getInstance().setListenerPosition(HumanController::localController_s->controllableEntity_->getPosition()); 88 SoundManager::getInstance().setListenerOrientation(HumanController::localController_s->controllableEntity_->getOrientation()); 89 } 90 } 91 } 92 79 93 void HumanController::moveFrontBack(const Vector2& value) 80 94 { -
code/branches/core5/src/orxonox/controllers/HumanController.h
r5813 r5896 31 31 32 32 #include "OrxonoxPrereqs.h" 33 34 #include "tools/interfaces/Tickable.h" 33 35 #include "Controller.h" 34 36 35 37 namespace orxonox 36 38 { 37 class _OrxonoxExport HumanController : public Controller 39 class _OrxonoxExport HumanController : public Controller, public Tickable 38 40 { 39 41 public: 40 42 HumanController(BaseObject* creator); 41 43 virtual ~HumanController(); 44 45 virtual void tick(float dt); 42 46 43 47 static void moveFrontBack(const Vector2& value); -
code/branches/core5/src/orxonox/gamestates/GSMainMenu.cc
r5892 r5896 39 39 #include "core/GUIManager.h" 40 40 #include "Scene.h" 41 #include "sound/ SoundBase.h"41 #include "sound/AmbientSound.h" 42 42 43 43 namespace orxonox … … 62 62 { 63 63 // Load sound 64 this->ambient_ = new SoundBase(0);65 this->ambient_-> loadFile("ambient/mainmenu.wav");64 this->ambient_ = new AmbientSound(0); 65 this->ambient_->setSoundFile("ambient/mainmenu.wav"); 66 66 } 67 67 } … … 96 96 if (GameMode::playsSound()) 97 97 { 98 this->ambient_->play(true); 98 this->ambient_->setLoop(true); 99 this->ambient_->play(); 99 100 } 100 101 } -
code/branches/core5/src/orxonox/gamestates/GSMainMenu.h
r5892 r5896 59 59 60 60 // ambient sound for the main menu 61 SoundBase*ambient_;61 AmbientSound* ambient_; 62 62 }; 63 63 } -
code/branches/core5/src/orxonox/sound/AmbientSound.cc
r5891 r5896 21 21 * 22 22 * Author: 23 * Erwin 'vaiursch' Herrsche23 * Reto Grieder 24 24 * Co-authors: 25 25 * ... … … 27 27 */ 28 28 29 #include " SoundBase.h"29 #include "AmbientSound.h" 30 30 31 #include <string> 32 #include <vector> 33 #include <AL/alut.h> 34 #include <vorbis/vorbisfile.h> 35 36 #include "util/Math.h" 37 #include "core/Resource.h" 38 #include "worldentities/WorldEntity.h" 39 #include "SoundManager.h" 31 #include "core/EventIncludes.h" 32 #include "core/XMLPort.h" 40 33 41 34 namespace orxonox 42 35 { 43 SoundBase::SoundBase(WorldEntity* entity) 36 CreateFactory(AmbientSound); 37 38 AmbientSound::AmbientSound(BaseObject* creator) 39 : BaseObject(creator) 44 40 { 45 this->source_ = 0; 46 this->buffer_ = 0; 47 this->entity_ = entity; 48 49 SoundManager::getInstance().addSound(this); 41 RegisterObject(AmbientSound); 50 42 } 51 43 52 SoundBase::~SoundBase()44 AmbientSound::~AmbientSound() 53 45 { 54 alSourcei(this->source_, AL_BUFFER, 0);55 alDeleteSources(1, &this->source_);56 alDeleteBuffers(1, &this->buffer_);57 46 } 58 47 59 void SoundBase::attachToEntity(WorldEntity* entity)48 void AmbientSound::XMLPort(Element& xmlelement, XMLPort::Mode mode) 60 49 { 61 this->entity_ = entity; 62 this->update(); 50 SUPER(AmbientSound, XMLPort, xmlelement, mode); 51 XMLPortParamExtern(AmbientSound, BaseSound, this, "soundFile", setSoundFile, getSoundFile, xmlelement, mode); 52 XMLPortParamExtern(AmbientSound, BaseSound, this, "loop", setLoop, getLoop, xmlelement, mode); 53 XMLPortParamExtern(AmbientSound, BaseSound, this, "playOnLoad", setPlayOnLoad, getPlayOnLoad, xmlelement, mode); 63 54 } 64 55 65 void SoundBase::update() { 66 if(this->entity_ != NULL && alIsSource(this->source_)) { 67 const Vector3& pos = this->entity_->getPosition(); 68 alSource3f(this->source_, AL_POSITION, pos.x, pos.y, pos.z); 69 ALenum error = alGetError(); 70 if(error == AL_INVALID_VALUE) 71 COUT(2) << "Sound: OpenAL: Invalid sound position" << std::endl; 72 73 const Vector3& vel = this->entity_->getVelocity(); 74 alSource3f(this->source_, AL_VELOCITY, vel.x, vel.y, vel.z); 75 error = alGetError(); 76 if(error == AL_INVALID_VALUE) 77 COUT(2) << "Sound: OpenAL: Invalid sound velocity" << std::endl; 78 79 const Quaternion& orient = this->entity_->getOrientation(); 80 Vector3 at = orient.zAxis(); 81 alSource3f(this->source_, AL_DIRECTION, at.x, at.y, at.z); 82 error = alGetError(); 83 if(error == AL_INVALID_VALUE) 84 COUT(2) << "Sound: OpenAL: Invalid sound direction" << std::endl; 85 } 56 void AmbientSound::XMLEventPort(Element& xmlelement, XMLPort::Mode mode) 57 { 58 SUPER(AmbientSound, XMLEventPort, xmlelement, mode); 59 XMLPortEventState(AmbientSound, BaseObject, "play", play, xmlelement, mode); 86 60 } 87 88 void SoundBase::play(bool loop) { 89 if(alIsSource(this->source_)) { 90 if(loop) 91 alSourcei(this->source_, AL_LOOPING, AL_TRUE); 92 else 93 alSourcei(this->source_, AL_LOOPING, AL_FALSE); 94 alSourcePlay(this->source_); 95 96 if(alGetError() != AL_NO_ERROR) 97 { 98 COUT(2) << "Sound: OpenAL: Error playin sound " << this->source_ << std::endl; 99 } 100 } 101 } 102 103 void SoundBase::stop() { 104 if(alIsSource(this->source_)) { 105 alSourceStop(this->source_); 106 } 107 } 108 109 void SoundBase::pause() { 110 if(alIsSource(this->source_)) { 111 alSourcePause(this->source_); 112 } 113 } 114 115 bool SoundBase::isPlaying() { 116 if(alIsSource(this->source_)) { 117 return getSourceState() == AL_PLAYING; 118 } 119 return false; 120 } 121 122 bool SoundBase::isPaused() { 123 if(alIsSource(this->source_)) { 124 return getSourceState() == AL_PAUSED; 125 } 126 return true; 127 } 128 129 bool SoundBase::isStopped() { 130 if(alIsSource(this->source_)) { 131 return getSourceState() == AL_INITIAL || getSourceState() == AL_STOPPED; 132 } 133 return true; 134 } 135 136 bool SoundBase::loadFile(const std::string& filename) { 137 if(!SoundManager::getInstance().isSoundAvailable()) 138 { 139 COUT(3) << "Sound: not available, skipping " << filename << std::endl; 140 return false; 141 } 142 143 COUT(3) << "Sound: OpenAL ALUT: loading file " << filename << std::endl; 144 // Get DataStream from the resources 145 shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(filename); 146 if (fileInfo == NULL) { 147 COUT(2) << "Warning: Sound file '" << filename << "' not found" << std::endl; 148 return false; 149 } 150 DataStreamPtr stream = Resource::open(filename); 151 // Read everything into a temporary buffer 152 char* buffer = new char[fileInfo->size]; 153 stream->read(buffer, fileInfo->size); 154 155 this->buffer_ = alutCreateBufferFromFileImage(buffer, fileInfo->size); 156 delete[] buffer; 157 158 if(this->buffer_ == AL_NONE) { 159 COUT(2) << "Sound: OpenAL ALUT: " << alutGetErrorString(alutGetError()) << std::endl; 160 if(filename.find("ogg", 0) != std::string::npos) 161 { 162 COUT(2) << "Sound: Trying fallback ogg loader" << std::endl; 163 this->buffer_ = loadOggFile(filename); 164 } 165 166 if(this->buffer_ == AL_NONE) 167 { 168 COUT(2) << "Sound: fallback ogg loader failed: " << alutGetErrorString(alutGetError()) << std::endl; 169 return false; 170 } 171 } 172 173 alGenSources(1, &this->source_); 174 alSourcei(this->source_, AL_BUFFER, this->buffer_); 175 if(alGetError() != AL_NO_ERROR) { 176 COUT(2) << "Sound: OpenAL: Error loading sample file: " << filename << std::endl; 177 return false; 178 } 179 return true; 180 } 181 182 ALint SoundBase::getSourceState() { 183 ALint state; 184 alGetSourcei(this->source_, AL_SOURCE_STATE, &state); 185 return state; 186 } 187 188 ALuint SoundBase::loadOggFile(const std::string& filename) 189 { 190 char inbuffer[4096]; 191 std::vector<char> outbuffer; 192 OggVorbis_File vf; 193 vorbis_info* vorbisInfo; 194 int eof = false; 195 int current_section; 196 ALuint buffer; 197 ALenum format; 198 199 FILE* f = fopen(filename.c_str(), "rb"); 200 201 if(ov_open(f, &vf, NULL, 0) < 0) 202 { 203 COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl; 204 ov_clear(&vf); 205 return AL_NONE; 206 } 207 208 while(!eof) 209 { 210 long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, ¤t_section); 211 if (ret == 0) 212 { 213 eof = true; 214 } 215 else if (ret < 0) 216 { 217 COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl; 218 ov_clear(&vf); 219 return AL_NONE; 220 } 221 else 222 { 223 outbuffer.insert(outbuffer.end(), inbuffer, inbuffer + sizeof(inbuffer)); 224 } 225 } 226 227 vorbisInfo = ov_info(&vf, -1); 228 if(vorbisInfo->channels == 1) 229 format = AL_FORMAT_MONO16; 230 else 231 format = AL_FORMAT_STEREO16; 232 233 alGenBuffers(1, &buffer); 234 alBufferData(buffer, format, &outbuffer[0], outbuffer.size(), vorbisInfo->rate); 235 ov_clear(&vf); 236 237 return buffer; 238 } 239 } // namespace: orxonox 61 } -
code/branches/core5/src/orxonox/sound/AmbientSound.h
r5891 r5896 21 21 * 22 22 * Author: 23 * Erwin 'vaiursch' Herrsche23 * Reto Grieder 24 24 * Co-authors: 25 25 * ... 26 26 * 27 27 */ 28 #ifndef _ SoundBase_H__29 #define _ SoundBase_H__28 #ifndef _AmbientSound_H__ 29 #define _AmbientSound_H__ 30 30 31 31 #include "OrxonoxPrereqs.h" 32 #include <cstring> // define NULL 32 33 #include "core/BaseObject.h" 34 #include "sound/BaseSound.h" 33 35 34 36 namespace orxonox 35 37 { 36 38 /** 37 * The SoundBaseclass is the base class for all sound file loader classes.39 * The AmbientSound class is the base class for all sound file loader classes. 38 40 * It server as main interface to the OpenAL library. 39 41 * 40 42 */ 41 class _OrxonoxExport SoundBase43 class _OrxonoxExport AmbientSound : public BaseSound, public BaseObject 42 44 { 43 45 public: 44 SoundBase(WorldEntity* entity = NULL);45 ~SoundBase();46 AmbientSound(BaseObject* creator); 47 virtual ~AmbientSound(); 46 48 47 void attachToEntity(WorldEntity* entity); 48 void update(); 49 void play(bool loop = false); 50 void stop(); 51 void pause(); 52 53 bool isPlaying(); 54 bool isPaused(); 55 bool isStopped(); 56 57 bool loadFile(const std::string& filename); 49 virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); 50 virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode); 58 51 59 52 private: 60 ALuint loadOggFile(const std::string& filename); 61 ALuint source_; 62 ALuint buffer_; 63 WorldEntity* entity_; 53 }; 54 } 64 55 65 ALint getSourceState(); 66 }; // class SoundBase 67 } // namepsace orxonox 68 69 #endif /* _SoundBase_H__ */ 56 #endif /* _AmbientSound_H__ */ -
code/branches/core5/src/orxonox/sound/BaseSound.cc
r5891 r5896 21 21 * 22 22 * Author: 23 * 23 * Erwin 'vaiursch' Herrsche 24 24 * Co-authors: 25 * ...25 * Reto Grieder 26 26 * 27 27 */ 28 28 29 #include "SoundBase.h" 30 31 #include <string> 29 #include "BaseSound.h" 30 32 31 #include <vector> 33 32 #include <AL/alut.h> 34 33 #include <vorbis/vorbisfile.h> 35 34 36 #include "util/Math.h" 35 #include "core/CoreIncludes.h" 36 #include "core/GameMode.h" 37 37 #include "core/Resource.h" 38 #include "worldentities/WorldEntity.h"39 #include "SoundManager.h"40 38 41 39 namespace orxonox 42 40 { 43 SoundBase::SoundBase(WorldEntity* entity) 44 { 45 this->source_ = 0; 46 this->buffer_ = 0; 47 this->entity_ = entity; 48 49 SoundManager::getInstance().addSound(this); 50 } 51 52 SoundBase::~SoundBase() 53 { 54 alSourcei(this->source_, AL_BUFFER, 0); 55 alDeleteSources(1, &this->source_); 56 alDeleteBuffers(1, &this->buffer_); 57 } 58 59 void SoundBase::attachToEntity(WorldEntity* entity) 60 { 61 this->entity_ = entity; 62 this->update(); 63 } 64 65 void SoundBase::update() { 66 if(this->entity_ != NULL && alIsSource(this->source_)) { 67 const Vector3& pos = this->entity_->getPosition(); 68 alSource3f(this->source_, AL_POSITION, pos.x, pos.y, pos.z); 69 ALenum error = alGetError(); 70 if(error == AL_INVALID_VALUE) 71 COUT(2) << "Sound: OpenAL: Invalid sound position" << std::endl; 72 73 const Vector3& vel = this->entity_->getVelocity(); 74 alSource3f(this->source_, AL_VELOCITY, vel.x, vel.y, vel.z); 75 error = alGetError(); 76 if(error == AL_INVALID_VALUE) 77 COUT(2) << "Sound: OpenAL: Invalid sound velocity" << std::endl; 78 79 const Quaternion& orient = this->entity_->getOrientation(); 80 Vector3 at = orient.zAxis(); 81 alSource3f(this->source_, AL_DIRECTION, at.x, at.y, at.z); 82 error = alGetError(); 83 if(error == AL_INVALID_VALUE) 84 COUT(2) << "Sound: OpenAL: Invalid sound direction" << std::endl; 85 } 86 } 87 88 void SoundBase::play(bool loop) { 89 if(alIsSource(this->source_)) { 90 if(loop) 41 BaseSound::BaseSound() 42 : source_(0) 43 , buffer_(0) 44 , bPlayOnLoad_(false) 45 , bLoop_(false) 46 { 47 RegisterRootObject(BaseSound); 48 } 49 50 BaseSound::~BaseSound() 51 { 52 this->setSoundFile(""); 53 } 54 55 void BaseSound::play() 56 { 57 if (alIsSource(this->source_)) 58 { 59 if (this->bLoop_) 91 60 alSourcei(this->source_, AL_LOOPING, AL_TRUE); 92 61 else … … 94 63 alSourcePlay(this->source_); 95 64 96 if (alGetError() != AL_NO_ERROR)65 if (alGetError() != AL_NO_ERROR) 97 66 { 98 67 COUT(2) << "Sound: OpenAL: Error playin sound " << this->source_ << std::endl; … … 101 70 } 102 71 103 void SoundBase::stop() { 104 if(alIsSource(this->source_)) { 72 void BaseSound::stop() 73 { 74 if (alIsSource(this->source_)) 105 75 alSourceStop(this->source_); 106 107 } 108 109 void SoundBase::pause(){110 if (alIsSource(this->source_)) {76 } 77 78 void BaseSound::pause() 79 { 80 if (alIsSource(this->source_)) 111 81 alSourcePause(this->source_); 112 113 } 114 115 bool SoundBase::isPlaying(){116 if (alIsSource(this->source_)) {82 } 83 84 bool BaseSound::isPlaying() 85 { 86 if (alIsSource(this->source_)) 117 87 return getSourceState() == AL_PLAYING; 118 }119 88 return false; 120 89 } 121 90 122 bool SoundBase::isPaused() { 123 if(alIsSource(this->source_)) { 91 bool BaseSound::isPaused() 92 { 93 if (alIsSource(this->source_)) 124 94 return getSourceState() == AL_PAUSED; 125 }126 95 return true; 127 96 } 128 97 129 bool SoundBase::isStopped() { 130 if(alIsSource(this->source_)) { 98 bool BaseSound::isStopped() 99 { 100 if (alIsSource(this->source_)) 131 101 return getSourceState() == AL_INITIAL || getSourceState() == AL_STOPPED; 132 }133 102 return true; 134 103 } 135 104 136 bool SoundBase::loadFile(const std::string& filename) { 137 if(!SoundManager::getInstance().isSoundAvailable()) 138 { 139 COUT(3) << "Sound: not available, skipping " << filename << std::endl; 140 return false; 141 } 142 143 COUT(3) << "Sound: OpenAL ALUT: loading file " << filename << std::endl; 105 void BaseSound::setPlayOnLoad(bool val) 106 { 107 this->bPlayOnLoad_ = true; 108 this->play(); 109 } 110 111 void BaseSound::setSoundFile(const std::string& soundFile) 112 { 113 this->soundFile_ = soundFile; 114 if (!GameMode::playsSound()) 115 return; 116 117 if (soundFile.empty() && alIsSource(this->source_)) 118 { 119 // Unload sound 120 alSourcei(this->source_, AL_BUFFER, 0); 121 alDeleteSources(1, &this->source_); 122 alDeleteBuffers(1, &this->buffer_); 123 return; 124 } 125 126 COUT(3) << "Sound: OpenAL ALUT: loading file " << soundFile << std::endl; 144 127 // Get DataStream from the resources 145 shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(filename); 146 if (fileInfo == NULL) { 147 COUT(2) << "Warning: Sound file '" << filename << "' not found" << std::endl; 148 return false; 149 } 150 DataStreamPtr stream = Resource::open(filename); 128 shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(soundFile); 129 if (fileInfo == NULL) 130 { 131 COUT(2) << "Warning: Sound file '" << soundFile << "' not found" << std::endl; 132 return; 133 } 134 DataStreamPtr stream = Resource::open(soundFile); 151 135 // Read everything into a temporary buffer 152 136 char* buffer = new char[fileInfo->size]; … … 156 140 delete[] buffer; 157 141 158 if(this->buffer_ == AL_NONE) { 142 if (this->buffer_ == AL_NONE) 143 { 159 144 COUT(2) << "Sound: OpenAL ALUT: " << alutGetErrorString(alutGetError()) << std::endl; 160 if(filename.find("ogg", 0) != std::string::npos) 161 { 162 COUT(2) << "Sound: Trying fallback ogg loader" << std::endl; 163 this->buffer_ = loadOggFile(filename); 164 } 165 166 if(this->buffer_ == AL_NONE) 167 { 168 COUT(2) << "Sound: fallback ogg loader failed: " << alutGetErrorString(alutGetError()) << std::endl; 169 return false; 170 } 145 return; 146 //if (filename.find("ogg", 0) != std::string::npos) 147 //{ 148 // COUT(2) << "Sound: Trying fallback ogg loader" << std::endl; 149 // this->buffer_ = loadOggFile(filename); 150 //} 151 152 //if (this->buffer_ == AL_NONE) 153 //{ 154 // COUT(2) << "Sound: fallback ogg loader failed: " << alutGetErrorString(alutGetError()) << std::endl; 155 // return; 156 //} 171 157 } 172 158 173 159 alGenSources(1, &this->source_); 174 160 alSourcei(this->source_, AL_BUFFER, this->buffer_); 175 if(alGetError() != AL_NO_ERROR) { 176 COUT(2) << "Sound: OpenAL: Error loading sample file: " << filename << std::endl; 177 return false; 178 } 179 return true; 180 } 181 182 ALint SoundBase::getSourceState() { 161 if (alGetError() != AL_NO_ERROR) 162 { 163 COUT(2) << "Sound: OpenAL: Error loading sample file: " << soundFile << std::endl; 164 return; 165 } 166 167 alSource3f(this->source_, AL_POSITION, 0, 0, 0); 168 169 if (this->bPlayOnLoad_) 170 this->play(); 171 } 172 173 ALint BaseSound::getSourceState() 174 { 183 175 ALint state; 184 176 alGetSourcei(this->source_, AL_SOURCE_STATE, &state); … … 186 178 } 187 179 188 ALuint SoundBase::loadOggFile(const std::string& filename) 180 #if 0 // Not yet supported because of missing resource implementation 181 ALuint BaseSound::loadOggFile(const std::string& filename) 189 182 { 190 183 char inbuffer[4096]; … … 199 192 FILE* f = fopen(filename.c_str(), "rb"); 200 193 201 if (ov_open(f, &vf, NULL, 0) < 0)194 if (ov_open(f, &vf, NULL, 0) < 0) 202 195 { 203 196 COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl; … … 206 199 } 207 200 208 while (!eof)201 while (!eof) 209 202 { 210 203 long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, ¤t_section); … … 226 219 227 220 vorbisInfo = ov_info(&vf, -1); 228 if (vorbisInfo->channels == 1)221 if (vorbisInfo->channels == 1) 229 222 format = AL_FORMAT_MONO16; 230 223 else … … 237 230 return buffer; 238 231 } 232 #endif 233 239 234 } // namespace: orxonox -
code/branches/core5/src/orxonox/sound/BaseSound.h
r5891 r5896 21 21 * 22 22 * Author: 23 * 23 * Erwin 'vaiursch' Herrsche 24 24 * Co-authors: 25 * ...25 * Reto Grieder 26 26 * 27 27 */ 28 #ifndef _ SoundBase_H__29 #define _ SoundBase_H__28 #ifndef _BaseSound_H__ 29 #define _BaseSound_H__ 30 30 31 31 #include "OrxonoxPrereqs.h" 32 #include <cstring> // define NULL 32 33 #include <string> 34 #include "core/OrxonoxClass.h" 33 35 34 36 namespace orxonox 35 37 { 36 38 /** 37 * The SoundBaseclass is the base class for all sound file loader classes.39 * The BaseSound class is the base class for all sound file loader classes. 38 40 * It server as main interface to the OpenAL library. 39 41 * 40 42 */ 41 class _OrxonoxExport SoundBase43 class _OrxonoxExport BaseSound : virtual public OrxonoxClass 42 44 { 43 45 public: 44 SoundBase(WorldEntity* entity = NULL);45 ~SoundBase();46 BaseSound(); 47 virtual ~BaseSound(); 46 48 47 void attachToEntity(WorldEntity* entity); 48 void update(); 49 void play(bool loop = false); 49 void play(); 50 50 void stop(); 51 51 void pause(); … … 55 55 bool isStopped(); 56 56 57 bool loadFile(const std::string& filename); 57 void setSoundFile(const std::string& soundFile); 58 const std::string& getSoundFile() { return this->soundFile_; } 59 60 bool getPlayOnLoad() { return this->bPlayOnLoad_; } 61 void setPlayOnLoad(bool val); 62 63 bool getLoop() { return this->bLoop_; } 64 void setLoop(bool val) { this->bLoop_ = val; } 65 66 protected: 67 //ALuint loadOggFile(const std::string& filename); 68 ALint getSourceState(); 69 70 ALuint source_; 71 ALuint buffer_; 58 72 59 73 private: 60 ALuint loadOggFile(const std::string& filename); 61 ALuint source_; 62 ALuint buffer_; 63 WorldEntity* entity_; 74 std::string soundFile_; 75 bool bPlayOnLoad_; 76 bool bLoop_; 77 }; 78 } 64 79 65 ALint getSourceState(); 66 }; // class SoundBase 67 } // namepsace orxonox 68 69 #endif /* _SoundBase_H__ */ 80 #endif /* _BaseSound_H__ */ -
code/branches/core5/src/orxonox/sound/CMakeLists.txt
r5892 r5896 1 1 ADD_SOURCE_FILES(ORXONOX_SRC_FILES 2 AmbientSound.cc 3 BaseSound.cc 2 4 SoundManager.cc 3 SoundBase.cc5 WorldSound.cc 4 6 ) 5 7 -
code/branches/core5/src/orxonox/sound/SoundManager.cc
r5881 r5896 36 36 #include "core/GameMode.h" 37 37 #include "core/ScopedSingletonManager.h" 38 #include "CameraManager.h"39 #include "graphics/Camera.h"40 #include "SoundBase.h"41 38 42 39 namespace orxonox … … 89 86 } 90 87 91 /** 92 * Add a SoundBase object to the list. Every SoundBase object should be in 93 * this list. 94 * 95 * @param sound Pointer to the SoundBase object to add 96 */ 97 void SoundManager::addSound(SoundBase* sound) 88 void SoundManager::setListenerPosition(const Vector3& position) 98 89 { 99 this->soundlist_.push_back(sound); 90 alListener3f(AL_POSITION, position.x, position.y, position.z); 91 ALenum error = alGetError(); 92 if (error == AL_INVALID_VALUE) 93 COUT(2) << "Sound: OpenAL: Invalid listener position" << std::endl; 100 94 } 101 95 102 /** 103 * Remove a SoundBase object from the list and destroy it. 104 */ 105 void SoundManager::removeSound(SoundBase* sound) 96 void SoundManager::setListenerOrientation(const Quaternion& orientation) 106 97 { 107 std::list<SoundBase*>::iterator pos = this->soundlist_.end(); 108 for(std::list<SoundBase*>::iterator i = this->soundlist_.begin(); i != this->soundlist_.end(); i++) 109 { 110 if((*i) == sound) 111 pos = i; 112 } 98 // update listener orientation 99 Vector3 up = orientation.xAxis(); // just a wild guess 100 Vector3 at = orientation.zAxis(); 113 101 114 delete (*pos); 115 this->soundlist_.erase(pos); 116 } 102 ALfloat orient[6] = { at.x, at.y, at.z, 103 up.x, up.y, up.z }; 117 104 118 /** 119 * Tick function, updates listener and registred SoundBase objects 120 * 121 * @param dt @see Orxonox::Tickable 122 */ 123 void SoundManager::tick(float dt) 124 { 125 if (!CameraManager::getInstancePtr()) 126 return; 127 128 // update listener position 129 Camera* camera = CameraManager::getInstance().getActiveCamera(); 130 if(camera == NULL) return; 131 Vector3 pos = camera->getPosition(); 132 alListener3f(AL_POSITION, pos.x, pos.y, pos.z); 105 alListenerfv(AL_POSITION, orient); 133 106 ALenum error = alGetError(); 134 if(error == AL_INVALID_VALUE) 135 COUT(2) << "Sound: OpenAL: Invalid listener position" << std::endl; 136 137 // update listener orientation 138 const Quaternion& orient = camera->getOrientation(); 139 Vector3 up = orient.xAxis(); // just a wild guess 140 Vector3 at = orient.zAxis(); 141 142 ALfloat orientation[6] = { at.x, at.y, at.z, 143 up.x, up.y, up.z }; 144 145 alListenerfv(AL_POSITION, orientation); 146 error = alGetError(); 147 if(error == AL_INVALID_VALUE) 107 if (error == AL_INVALID_VALUE) 148 108 COUT(2) << "Sound: OpenAL: Invalid listener orientation" << std::endl; 149 150 // update sounds151 for(std::list<SoundBase*>::iterator i = this->soundlist_.begin(); i != this->soundlist_.end(); i++)152 (*i)->update();153 }154 155 /**156 * Check if sound is available157 */158 bool SoundManager::isSoundAvailable()159 {160 return this->soundavailable_;161 109 } 162 110 } -
code/branches/core5/src/orxonox/sound/SoundManager.h
r5867 r5896 39 39 /** 40 40 * The SoundManager class manages the OpenAL device, context and listener 41 * position. It has a list of all SoundBase objects and calls their update 42 * function every tick. It is a singleton. 41 * position. It is a singleton. 43 42 * 44 43 */ 45 class _OrxonoxExport SoundManager : public Singleton<SoundManager> , public Tickable44 class _OrxonoxExport SoundManager : public Singleton<SoundManager> 46 45 { 47 46 friend class Singleton<SoundManager>; … … 49 48 SoundManager(); 50 49 ~SoundManager(); 51 void addSound(SoundBase* sound); 52 void removeSound(SoundBase* sound); 53 void tick(float dt); 54 bool isSoundAvailable(); 50 51 void setListenerPosition(const Vector3& position); 52 void setListenerOrientation(const Quaternion& orientation); 55 53 56 54 private: 57 55 ALCdevice* device_; 58 56 ALCcontext* context_; 59 std::list<SoundBase*> soundlist_;60 bool soundavailable_;61 57 62 58 static SoundManager* singletonPtr_s; 63 }; // class SoundManager64 } // namespace orxonox59 }; 60 } 65 61 66 62 #endif /* _SoundManager_H__ */ -
code/branches/core5/src/orxonox/sound/WorldSound.cc
r5891 r5896 21 21 * 22 22 * Author: 23 * Erwin 'vaiursch' Herrsche 23 * Erwin 'vaiursch' Herrsche 24 * Reto Grieder 24 25 * Co-authors: 25 26 * ... … … 27 28 */ 28 29 29 #include " SoundBase.h"30 #include "WorldSound.h" 30 31 31 #include <string>32 #include <vector>33 32 #include <AL/alut.h> 34 #include <vorbis/vorbisfile.h>35 36 33 #include "util/Math.h" 37 #include "core/Resource.h" 38 #include "worldentities/WorldEntity.h" 39 #include "SoundManager.h" 34 #include "core/EventIncludes.h" 35 #include "core/XMLPort.h" 40 36 41 37 namespace orxonox 42 38 { 43 SoundBase::SoundBase(WorldEntity* entity) 39 CreateFactory(WorldSound); 40 41 WorldSound::WorldSound(BaseObject* creator) 42 : StaticEntity(creator) 44 43 { 45 this->source_ = 0; 46 this->buffer_ = 0; 47 this->entity_ = entity; 48 49 SoundManager::getInstance().addSound(this); 44 RegisterObject(WorldSound); 50 45 } 51 46 52 SoundBase::~SoundBase()47 WorldSound::~WorldSound() 53 48 { 54 alSourcei(this->source_, AL_BUFFER, 0);55 alDeleteSources(1, &this->source_);56 alDeleteBuffers(1, &this->buffer_);57 49 } 58 50 59 void SoundBase::attachToEntity(WorldEntity* entity)51 void WorldSound::XMLPort(Element& xmlelement, XMLPort::Mode mode) 60 52 { 61 this->entity_ = entity; 62 this->update(); 53 SUPER(WorldSound, XMLPort, xmlelement, mode); 54 XMLPortParamExtern(WorldSound, BaseSound, this, "soundFile", setSoundFile, getSoundFile, xmlelement, mode); 55 XMLPortParamExtern(WorldSound, BaseSound, this, "loop", setLoop, getLoop, xmlelement, mode); 56 XMLPortParamExtern(WorldSound, BaseSound, this, "playOnLoad", setPlayOnLoad, getPlayOnLoad, xmlelement, mode); 63 57 } 64 58 65 void SoundBase::update() { 66 if(this->entity_ != NULL && alIsSource(this->source_)) { 67 const Vector3& pos = this->entity_->getPosition(); 59 void WorldSound::XMLEventPort(Element& xmlelement, XMLPort::Mode mode) 60 { 61 SUPER(WorldSound, XMLEventPort, xmlelement, mode); 62 XMLPortEventState(WorldSound, BaseObject, "play", play, xmlelement, mode); 63 } 64 65 void WorldSound::processEvent(Event& event) 66 { 67 SUPER(WorldSound, processEvent, event); 68 } 69 70 void WorldSound::tick(float dt) 71 { 72 if (alIsSource(this->source_)) 73 { 74 const Vector3& pos = this->getWorldPosition(); 68 75 alSource3f(this->source_, AL_POSITION, pos.x, pos.y, pos.z); 69 76 ALenum error = alGetError(); 70 if (error == AL_INVALID_VALUE)77 if (error == AL_INVALID_VALUE) 71 78 COUT(2) << "Sound: OpenAL: Invalid sound position" << std::endl; 72 79 73 const Vector3& vel = this-> entity_->getVelocity();80 const Vector3& vel = this->getVelocity(); 74 81 alSource3f(this->source_, AL_VELOCITY, vel.x, vel.y, vel.z); 75 82 error = alGetError(); 76 if (error == AL_INVALID_VALUE)83 if (error == AL_INVALID_VALUE) 77 84 COUT(2) << "Sound: OpenAL: Invalid sound velocity" << std::endl; 78 85 79 const Quaternion& orient = this-> entity_->getOrientation();86 const Quaternion& orient = this->getWorldOrientation(); 80 87 Vector3 at = orient.zAxis(); 81 88 alSource3f(this->source_, AL_DIRECTION, at.x, at.y, at.z); 82 89 error = alGetError(); 83 if (error == AL_INVALID_VALUE)90 if (error == AL_INVALID_VALUE) 84 91 COUT(2) << "Sound: OpenAL: Invalid sound direction" << std::endl; 85 92 } 86 93 } 87 94 88 void SoundBase::play(bool loop) { 89 if(alIsSource(this->source_)) { 90 if(loop) 91 alSourcei(this->source_, AL_LOOPING, AL_TRUE); 92 else 93 alSourcei(this->source_, AL_LOOPING, AL_FALSE); 94 alSourcePlay(this->source_); 95 96 if(alGetError() != AL_NO_ERROR) 97 { 98 COUT(2) << "Sound: OpenAL: Error playin sound " << this->source_ << std::endl; 99 } 100 } 101 } 102 103 void SoundBase::stop() { 104 if(alIsSource(this->source_)) { 105 alSourceStop(this->source_); 106 } 107 } 108 109 void SoundBase::pause() { 110 if(alIsSource(this->source_)) { 111 alSourcePause(this->source_); 112 } 113 } 114 115 bool SoundBase::isPlaying() { 116 if(alIsSource(this->source_)) { 117 return getSourceState() == AL_PLAYING; 118 } 119 return false; 120 } 121 122 bool SoundBase::isPaused() { 123 if(alIsSource(this->source_)) { 124 return getSourceState() == AL_PAUSED; 125 } 126 return true; 127 } 128 129 bool SoundBase::isStopped() { 130 if(alIsSource(this->source_)) { 131 return getSourceState() == AL_INITIAL || getSourceState() == AL_STOPPED; 132 } 133 return true; 134 } 135 136 bool SoundBase::loadFile(const std::string& filename) { 137 if(!SoundManager::getInstance().isSoundAvailable()) 138 { 139 COUT(3) << "Sound: not available, skipping " << filename << std::endl; 140 return false; 141 } 142 143 COUT(3) << "Sound: OpenAL ALUT: loading file " << filename << std::endl; 144 // Get DataStream from the resources 145 shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(filename); 146 if (fileInfo == NULL) { 147 COUT(2) << "Warning: Sound file '" << filename << "' not found" << std::endl; 148 return false; 149 } 150 DataStreamPtr stream = Resource::open(filename); 151 // Read everything into a temporary buffer 152 char* buffer = new char[fileInfo->size]; 153 stream->read(buffer, fileInfo->size); 154 155 this->buffer_ = alutCreateBufferFromFileImage(buffer, fileInfo->size); 156 delete[] buffer; 157 158 if(this->buffer_ == AL_NONE) { 159 COUT(2) << "Sound: OpenAL ALUT: " << alutGetErrorString(alutGetError()) << std::endl; 160 if(filename.find("ogg", 0) != std::string::npos) 161 { 162 COUT(2) << "Sound: Trying fallback ogg loader" << std::endl; 163 this->buffer_ = loadOggFile(filename); 164 } 165 166 if(this->buffer_ == AL_NONE) 167 { 168 COUT(2) << "Sound: fallback ogg loader failed: " << alutGetErrorString(alutGetError()) << std::endl; 169 return false; 170 } 171 } 172 173 alGenSources(1, &this->source_); 174 alSourcei(this->source_, AL_BUFFER, this->buffer_); 175 if(alGetError() != AL_NO_ERROR) { 176 COUT(2) << "Sound: OpenAL: Error loading sample file: " << filename << std::endl; 177 return false; 178 } 179 return true; 180 } 181 182 ALint SoundBase::getSourceState() { 183 ALint state; 184 alGetSourcei(this->source_, AL_SOURCE_STATE, &state); 185 return state; 186 } 187 188 ALuint SoundBase::loadOggFile(const std::string& filename) 189 { 190 char inbuffer[4096]; 191 std::vector<char> outbuffer; 192 OggVorbis_File vf; 193 vorbis_info* vorbisInfo; 194 int eof = false; 195 int current_section; 196 ALuint buffer; 197 ALenum format; 198 199 FILE* f = fopen(filename.c_str(), "rb"); 200 201 if(ov_open(f, &vf, NULL, 0) < 0) 202 { 203 COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl; 204 ov_clear(&vf); 205 return AL_NONE; 206 } 207 208 while(!eof) 209 { 210 long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, ¤t_section); 211 if (ret == 0) 212 { 213 eof = true; 214 } 215 else if (ret < 0) 216 { 217 COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl; 218 ov_clear(&vf); 219 return AL_NONE; 220 } 221 else 222 { 223 outbuffer.insert(outbuffer.end(), inbuffer, inbuffer + sizeof(inbuffer)); 224 } 225 } 226 227 vorbisInfo = ov_info(&vf, -1); 228 if(vorbisInfo->channels == 1) 229 format = AL_FORMAT_MONO16; 230 else 231 format = AL_FORMAT_STEREO16; 232 233 alGenBuffers(1, &buffer); 234 alBufferData(buffer, format, &outbuffer[0], outbuffer.size(), vorbisInfo->rate); 235 ov_clear(&vf); 236 237 return buffer; 238 } 239 } // namespace: orxonox 95 } -
code/branches/core5/src/orxonox/sound/WorldSound.h
r5891 r5896 21 21 * 22 22 * Author: 23 * Erwin 'vaiursch' Herrsche23 * Reto Grieder 24 24 * Co-authors: 25 25 * ... 26 26 * 27 27 */ 28 #ifndef _ SoundBase_H__29 #define _ SoundBase_H__28 #ifndef _WorldSound_H__ 29 #define _WorldSound_H__ 30 30 31 31 #include "OrxonoxPrereqs.h" 32 #include <cstring> // define NULL 32 33 #include "tools/interfaces/Tickable.h" 34 #include "sound/BaseSound.h" 35 #include "worldentities/StaticEntity.h" 33 36 34 37 namespace orxonox 35 38 { 36 /** 37 * The SoundBase class is the base class for all sound file loader classes. 38 * It server as main interface to the OpenAL library. 39 * 40 */ 41 class _OrxonoxExport SoundBase 39 /* 40 @brief 41 The WorldSound class is to be used for sounds with position and orientation. 42 */ 43 class _OrxonoxExport WorldSound : public StaticEntity, public BaseSound, public Tickable 42 44 { 43 45 public: 44 SoundBase(WorldEntity* entity = NULL);45 ~SoundBase();46 WorldSound(BaseObject* creator); 47 virtual ~WorldSound(); 46 48 47 void attachToEntity(WorldEntity* entity); 48 void update(); 49 void play(bool loop = false); 50 void stop(); 51 void pause(); 49 virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); 50 virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode); 52 51 53 bool isPlaying(); 54 bool isPaused(); 55 bool isStopped(); 52 virtual void tick(float dt); 56 53 57 bool loadFile(const std::string& filename);54 virtual void processEvent(Event& event); 58 55 59 56 private: 60 ALuint loadOggFile(const std::string& filename); 61 ALuint source_; 62 ALuint buffer_; 63 WorldEntity* entity_; 57 }; 58 } 64 59 65 ALint getSourceState(); 66 }; // class SoundBase 67 } // namepsace orxonox 68 69 #endif /* _SoundBase_H__ */ 60 #endif /* _WorldSound_H__ */
Note: See TracChangeset
for help on using the changeset viewer.