Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Oct 6, 2009, 11:12:01 PM (15 years ago)
Author:
rgrieder
Message:

Added some basic sound classes: WorldSound (to be used for 3D sound, is a WorldEntity) and AmbientSound (BaseObject, just add it somewhere and it will play with playOnLoad=true).
Also moved the sound listener device updating to the HumanController. We might want to modify this again so that the listener is at the camera position again, not at the space ship.

File:
1 copied

Legend:

Unmodified
Added
Removed
  • code/branches/core5/src/orxonox/sound/WorldSound.cc

    r5891 r5896  
    2121 *
    2222 *   Author:
    23  *       Erwin 'vaiursch' Herrsche
     23 *      Erwin 'vaiursch' Herrsche
     24 *      Reto Grieder
    2425 *   Co-authors:
    2526 *      ...
     
    2728 */
    2829
    29 #include "SoundBase.h"
     30#include "WorldSound.h"
    3031
    31 #include <string>
    32 #include <vector>
    3332#include <AL/alut.h>
    34 #include <vorbis/vorbisfile.h>
    35 
    3633#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"
    4036
    4137namespace orxonox
    4238{
    43     SoundBase::SoundBase(WorldEntity* entity)
     39    CreateFactory(WorldSound);
     40
     41    WorldSound::WorldSound(BaseObject* creator)
     42        : StaticEntity(creator)
    4443    {
    45         this->source_ = 0;
    46         this->buffer_ = 0;
    47         this->entity_ = entity;
    48 
    49         SoundManager::getInstance().addSound(this);
     44        RegisterObject(WorldSound);
    5045    }
    5146
    52     SoundBase::~SoundBase()
     47    WorldSound::~WorldSound()
    5348    {
    54         alSourcei(this->source_, AL_BUFFER, 0);
    55         alDeleteSources(1, &this->source_);
    56         alDeleteBuffers(1, &this->buffer_);
    5749    }
    5850
    59     void SoundBase::attachToEntity(WorldEntity* entity)
     51    void WorldSound::XMLPort(Element& xmlelement, XMLPort::Mode mode)
    6052    {
    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);
    6357    }
    6458
    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();
    6875            alSource3f(this->source_, AL_POSITION, pos.x, pos.y, pos.z);
    6976            ALenum error = alGetError();
    70             if(error == AL_INVALID_VALUE)
     77            if (error == AL_INVALID_VALUE)
    7178                COUT(2) << "Sound: OpenAL: Invalid sound position" << std::endl;
    7279
    73             const Vector3& vel = this->entity_->getVelocity();
     80            const Vector3& vel = this->getVelocity();
    7481            alSource3f(this->source_, AL_VELOCITY, vel.x, vel.y, vel.z);
    7582            error = alGetError();
    76             if(error == AL_INVALID_VALUE)
     83            if (error == AL_INVALID_VALUE)
    7784                COUT(2) << "Sound: OpenAL: Invalid sound velocity" << std::endl;
    7885
    79             const Quaternion& orient = this->entity_->getOrientation();
     86            const Quaternion& orient = this->getWorldOrientation();
    8087            Vector3 at = orient.zAxis();
    8188            alSource3f(this->source_, AL_DIRECTION, at.x, at.y, at.z);
    8289            error = alGetError();
    83             if(error == AL_INVALID_VALUE)
     90            if (error == AL_INVALID_VALUE)
    8491                COUT(2) << "Sound: OpenAL: Invalid sound direction" << std::endl;
    8592        }
    8693    }
    8794
    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, &current_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.