Changeset 5896 for code/branches/core5/src/orxonox/sound/AmbientSound.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/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 }
Note: See TracChangeset
for help on using the changeset viewer.