Changeset 5896 for code/branches/core5/src/orxonox/sound/WorldSound.cc
- Timestamp:
- Oct 6, 2009, 11:12:01 PM (15 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
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 }
Note: See TracChangeset
for help on using the changeset viewer.