Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 5896


Ignore:
Timestamp:
Oct 6, 2009, 11:12:01 PM (14 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.

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  
    4646 gametype     = Pong
    4747>
     48  <AmbientSound soundFile="ambient/mainmenu.wav" playOnLoad=true />
     49
    4850  <Scene
    4951   ambientlight = "0.5, 0.5, 0.5"
     
    8284          <ParticleSpawner name=scoreeffect_left position="-120,0,-30" source="Orxonox/BigExplosion1part2" lifetime=3.0 autostart=0 />
    8385          <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>
    8494
    8595<?lua
  • code/branches/core5/src/orxonox/OrxonoxPrereqs.h

    r5895 r5896  
    150150
    151151    //sound
    152     class SoundBase;
     152    class AmbientSound;
     153    class BaseSound;
    153154    class SoundManager;
    154     class SoundMainMenu;
     155    class WorldSound;
    155156
    156157    // weaponsystem
  • code/branches/core5/src/orxonox/controllers/HumanController.cc

    r5813 r5896  
    3636#include "infos/PlayerInfo.h"
    3737#include "overlays/Map.h"
     38#include "sound/SoundManager.h"
    3839#include "Radar.h"
    3940#include "Scene.h"
     
    7778    }
    7879
     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
    7993    void HumanController::moveFrontBack(const Vector2& value)
    8094    {
  • code/branches/core5/src/orxonox/controllers/HumanController.h

    r5813 r5896  
    3131
    3232#include "OrxonoxPrereqs.h"
     33
     34#include "tools/interfaces/Tickable.h"
    3335#include "Controller.h"
    3436
    3537namespace orxonox
    3638{
    37     class _OrxonoxExport HumanController : public Controller
     39    class _OrxonoxExport HumanController : public Controller, public Tickable
    3840    {
    3941        public:
    4042            HumanController(BaseObject* creator);
    4143            virtual ~HumanController();
     44
     45            virtual void tick(float dt);
    4246
    4347            static void moveFrontBack(const Vector2& value);
  • code/branches/core5/src/orxonox/gamestates/GSMainMenu.cc

    r5892 r5896  
    3939#include "core/GUIManager.h"
    4040#include "Scene.h"
    41 #include "sound/SoundBase.h"
     41#include "sound/AmbientSound.h"
    4242
    4343namespace orxonox
     
    6262        {
    6363            // 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");
    6666        }
    6767    }
     
    9696        if (GameMode::playsSound())
    9797        {
    98             this->ambient_->play(true);
     98            this->ambient_->setLoop(true);
     99            this->ambient_->play();
    99100        }
    100101    }
  • code/branches/core5/src/orxonox/gamestates/GSMainMenu.h

    r5892 r5896  
    5959
    6060        // ambient sound for the main menu
    61         SoundBase*        ambient_;
     61        AmbientSound*     ambient_;
    6262    };
    6363}
  • code/branches/core5/src/orxonox/sound/AmbientSound.cc

    r5891 r5896  
    2121 *
    2222 *   Author:
    23  *       Erwin 'vaiursch' Herrsche
     23 *      Reto Grieder
    2424 *   Co-authors:
    2525 *      ...
     
    2727 */
    2828
    29 #include "SoundBase.h"
     29#include "AmbientSound.h"
    3030
    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"
    4033
    4134namespace orxonox
    4235{
    43     SoundBase::SoundBase(WorldEntity* entity)
     36    CreateFactory(AmbientSound);
     37
     38    AmbientSound::AmbientSound(BaseObject* creator)
     39        : BaseObject(creator)
    4440    {
    45         this->source_ = 0;
    46         this->buffer_ = 0;
    47         this->entity_ = entity;
    48 
    49         SoundManager::getInstance().addSound(this);
     41        RegisterObject(AmbientSound);
    5042    }
    5143
    52     SoundBase::~SoundBase()
     44    AmbientSound::~AmbientSound()
    5345    {
    54         alSourcei(this->source_, AL_BUFFER, 0);
    55         alDeleteSources(1, &this->source_);
    56         alDeleteBuffers(1, &this->buffer_);
    5746    }
    5847
    59     void SoundBase::attachToEntity(WorldEntity* entity)
     48    void AmbientSound::XMLPort(Element& xmlelement, XMLPort::Mode mode)
    6049    {
    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);
    6354    }
    6455
    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);
    8660    }
    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, &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
     61}
  • code/branches/core5/src/orxonox/sound/AmbientSound.h

    r5891 r5896  
    2121 *
    2222 *   Author:
    23  *       Erwin 'vaiursch' Herrsche
     23 *      Reto Grieder
    2424 *   Co-authors:
    2525 *      ...
    2626 *
    2727 */
    28 #ifndef _SoundBase_H__
    29 #define _SoundBase_H__
     28#ifndef _AmbientSound_H__
     29#define _AmbientSound_H__
    3030
    3131#include "OrxonoxPrereqs.h"
    32 #include <cstring> // define NULL
     32
     33#include "core/BaseObject.h"
     34#include "sound/BaseSound.h"
    3335
    3436namespace orxonox
    3537{
    3638    /**
    37      * The SoundBase class is the base class for all sound file loader classes.
     39     * The AmbientSound class is the base class for all sound file loader classes.
    3840     * It server as main interface to the OpenAL library.
    3941     *
    4042     */
    41     class _OrxonoxExport SoundBase
     43    class _OrxonoxExport AmbientSound : public BaseSound, public BaseObject
    4244    {
    4345    public:
    44         SoundBase(WorldEntity* entity = NULL);
    45         ~SoundBase();
     46        AmbientSound(BaseObject* creator);
     47        virtual ~AmbientSound();
    4648
    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);
    5851
    5952    private:
    60         ALuint loadOggFile(const std::string& filename);
    61         ALuint source_;
    62         ALuint buffer_;
    63         WorldEntity* entity_;
     53    };
     54}
    6455
    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  
    2121 *
    2222 *   Author:
    23  *       Erwin 'vaiursch' Herrsche
     23 *      Erwin 'vaiursch' Herrsche
    2424 *   Co-authors:
    25  *      ...
     25 *      Reto Grieder
    2626 *
    2727 */
    2828
    29 #include "SoundBase.h"
    30 
    31 #include <string>
     29#include "BaseSound.h"
     30
    3231#include <vector>
    3332#include <AL/alut.h>
    3433#include <vorbis/vorbisfile.h>
    3534
    36 #include "util/Math.h"
     35#include "core/CoreIncludes.h"
     36#include "core/GameMode.h"
    3737#include "core/Resource.h"
    38 #include "worldentities/WorldEntity.h"
    39 #include "SoundManager.h"
    4038
    4139namespace orxonox
    4240{
    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_)
    9160                alSourcei(this->source_, AL_LOOPING, AL_TRUE);
    9261            else
     
    9463            alSourcePlay(this->source_);
    9564
    96             if(alGetError() != AL_NO_ERROR)
     65            if (alGetError() != AL_NO_ERROR)
    9766            {
    9867                 COUT(2) << "Sound: OpenAL: Error playin sound " << this->source_ << std::endl;
     
    10170    }
    10271
    103     void SoundBase::stop() {
    104         if(alIsSource(this->source_)) {
     72    void BaseSound::stop()
     73    {
     74        if (alIsSource(this->source_))
    10575            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_))
    11181            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_))
    11787            return getSourceState() == AL_PLAYING;
    118         }
    11988        return false;
    12089    }
    12190
    122     bool SoundBase::isPaused() {
    123         if(alIsSource(this->source_)) {
     91    bool BaseSound::isPaused()
     92    {
     93        if (alIsSource(this->source_))
    12494            return getSourceState() == AL_PAUSED;
    125         }
    12695        return true;
    12796    }
    12897
    129     bool SoundBase::isStopped() {
    130         if(alIsSource(this->source_)) {
     98    bool BaseSound::isStopped()
     99    {
     100        if (alIsSource(this->source_))
    131101            return getSourceState() == AL_INITIAL || getSourceState() == AL_STOPPED;
    132         }
    133102        return true;
    134103    }
    135104
    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;
    144127        // 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);
    151135        // Read everything into a temporary buffer
    152136        char* buffer = new char[fileInfo->size];
     
    156140        delete[] buffer;
    157141
    158         if(this->buffer_ == AL_NONE) {
     142        if (this->buffer_ == AL_NONE)
     143        {
    159144            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            //}
    171157        }
    172158
    173159        alGenSources(1, &this->source_);
    174160        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    {
    183175        ALint state;
    184176        alGetSourcei(this->source_, AL_SOURCE_STATE, &state);
     
    186178    }
    187179
    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)
    189182    {
    190183        char inbuffer[4096];
     
    199192        FILE* f = fopen(filename.c_str(), "rb");
    200193
    201         if(ov_open(f, &vf, NULL, 0) < 0)
     194        if (ov_open(f, &vf, NULL, 0) < 0)
    202195        {
    203196            COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl;
     
    206199        }
    207200
    208         while(!eof)
     201        while (!eof)
    209202        {
    210203            long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
     
    226219
    227220        vorbisInfo = ov_info(&vf, -1);
    228         if(vorbisInfo->channels == 1)
     221        if (vorbisInfo->channels == 1)
    229222            format = AL_FORMAT_MONO16;
    230223        else
     
    237230        return buffer;
    238231    }
     232#endif
     233
    239234} // namespace: orxonox
  • code/branches/core5/src/orxonox/sound/BaseSound.h

    r5891 r5896  
    2121 *
    2222 *   Author:
    23  *       Erwin 'vaiursch' Herrsche
     23 *      Erwin 'vaiursch' Herrsche
    2424 *   Co-authors:
    25  *      ...
     25 *      Reto Grieder
    2626 *
    2727 */
    28 #ifndef _SoundBase_H__
    29 #define _SoundBase_H__
     28#ifndef _BaseSound_H__
     29#define _BaseSound_H__
    3030
    3131#include "OrxonoxPrereqs.h"
    32 #include <cstring> // define NULL
     32
     33#include <string>
     34#include "core/OrxonoxClass.h"
    3335
    3436namespace orxonox
    3537{
    3638    /**
    37      * The SoundBase class is the base class for all sound file loader classes.
     39     * The BaseSound class is the base class for all sound file loader classes.
    3840     * It server as main interface to the OpenAL library.
    3941     *
    4042     */
    41     class _OrxonoxExport SoundBase
     43    class _OrxonoxExport BaseSound : virtual public OrxonoxClass
    4244    {
    4345    public:
    44         SoundBase(WorldEntity* entity = NULL);
    45         ~SoundBase();
     46        BaseSound();
     47        virtual ~BaseSound();
    4648
    47         void attachToEntity(WorldEntity* entity);
    48         void update();
    49         void play(bool loop = false);
     49        void play();
    5050        void stop();
    5151        void pause();
     
    5555        bool isStopped();
    5656
    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_;
    5872
    5973    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}
    6479
    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  
    11ADD_SOURCE_FILES(ORXONOX_SRC_FILES
     2    AmbientSound.cc
     3    BaseSound.cc
    24    SoundManager.cc
    3     SoundBase.cc
     5    WorldSound.cc
    46)
    57
  • code/branches/core5/src/orxonox/sound/SoundManager.cc

    r5881 r5896  
    3636#include "core/GameMode.h"
    3737#include "core/ScopedSingletonManager.h"
    38 #include "CameraManager.h"
    39 #include "graphics/Camera.h"
    40 #include "SoundBase.h"
    4138
    4239namespace orxonox
     
    8986    }
    9087
    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)
    9889    {
    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;
    10094    }
    10195
    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)
    10697    {
    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();
    113101
    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 };
    117104
    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);
    133106        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)
    148108            COUT(2) << "Sound: OpenAL: Invalid listener orientation" << std::endl;
    149 
    150         // update sounds
    151         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 available
    157     */
    158     bool SoundManager::isSoundAvailable()
    159     {
    160         return this->soundavailable_;
    161109    }
    162110}
  • code/branches/core5/src/orxonox/sound/SoundManager.h

    r5867 r5896  
    3939    /**
    4040     * 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.
    4342     *
    4443     */
    45     class _OrxonoxExport SoundManager : public Singleton<SoundManager>, public Tickable
     44    class _OrxonoxExport SoundManager : public Singleton<SoundManager>
    4645    {
    4746        friend class Singleton<SoundManager>;
     
    4948        SoundManager();
    5049        ~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);
    5553
    5654    private:
    5755        ALCdevice* device_;
    5856        ALCcontext* context_;
    59         std::list<SoundBase*> soundlist_;
    60         bool soundavailable_;
    6157
    6258        static SoundManager* singletonPtr_s;
    63     }; // class SoundManager
    64 } // namespace orxonox
     59    };
     60}
    6561
    6662#endif /* _SoundManager_H__ */
  • 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}
  • code/branches/core5/src/orxonox/sound/WorldSound.h

    r5891 r5896  
    2121 *
    2222 *   Author:
    23  *       Erwin 'vaiursch' Herrsche
     23 *      Reto Grieder
    2424 *   Co-authors:
    2525 *      ...
    2626 *
    2727 */
    28 #ifndef _SoundBase_H__
    29 #define _SoundBase_H__
     28#ifndef _WorldSound_H__
     29#define _WorldSound_H__
    3030
    3131#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"
    3336
    3437namespace orxonox
    3538{
    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
    4244    {
    4345    public:
    44         SoundBase(WorldEntity* entity = NULL);
    45         ~SoundBase();
     46        WorldSound(BaseObject* creator);
     47        virtual ~WorldSound();
    4648
    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);
    5251
    53         bool isPlaying();
    54         bool isPaused();
    55         bool isStopped();
     52        virtual void tick(float dt);
    5653
    57         bool loadFile(const std::string& filename);
     54        virtual void processEvent(Event& event);
    5855
    5956    private:
    60         ALuint loadOggFile(const std::string& filename);
    61         ALuint source_;
    62         ALuint buffer_;
    63         WorldEntity* entity_;
     57    };
     58}
    6459
    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.