Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 6203


Ignore:
Timestamp:
Dec 2, 2009, 4:57:24 PM (15 years ago)
Author:
rgrieder
Message:

Added buffer buffering: Sounds are only loaded into one buffer and then reused.

Location:
code/branches/presentation2/src
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • code/branches/presentation2/src/libraries/core/Resource.h

    r5929 r6203  
    8686            bool bSearchGroupsIfNotFound = false);
    8787
     88        //! Similar to open(string, string, bool), but with a fileInfo struct
     89        static DataStreamPtr open(shared_ptr<ResourceInfo> fileInfo,
     90            bool bSearchGroupsIfNotFound = false)
     91        {
     92            return open(fileInfo->filename, fileInfo->group, bSearchGroupsIfNotFound);
     93        }
     94
    8895        /**
    8996        @brief
  • code/branches/presentation2/src/orxonox/sound/AmbientSound.cc

    r6186 r6203  
    7171        if (GameMode::playsSound())
    7272        {
    73             COUT(3) << "Sound: " << this->getSource() << ": Playing" << std::endl;
    7473            SoundManager::getInstance().registerAmbientSound(this);
    7574        }
  • code/branches/presentation2/src/orxonox/sound/BaseSound.cc

    r6202 r6203  
    3131#include <cassert>
    3232#include <vector>
    33 #include <AL/alut.h>
    34 #include <vorbis/vorbisfile.h>
     33#include <al.h>
    3534
    3635#include "core/CoreIncludes.h"
     
    3837#include "core/Resource.h"
    3938#include "core/XMLPort.h"
     39#include "SoundBuffer.h"
    4040#include "SoundManager.h"
    4141
     
    4444    BaseSound::BaseSound()
    4545        : audioSource_(0)
    46         , audioBuffer_(0)
     46        , volume_(1.0)
    4747        , bLoop_(false)
    4848        , state_(Stopped)
     
    8282            alSourcePlay(this->audioSource_);
    8383
    84             if (alGetError() != AL_NO_ERROR)
    85                  COUT(2) << "Sound: OpenAL: Error playing sound " << this->audioSource_ << std::endl;
     84            if (int error = alGetError())
     85                COUT(2) << "Sound: Error playing sound: " << error << std::endl;
    8686        }
    8787    }
     
    155155        }
    156156
    157         if (this->audioBuffer_ != 0 && alIsBuffer(this->audioBuffer_))
     157        if (this->soundBuffer_ != NULL)
    158158        {
    159159            alSourceStop(this->audioSource_);
    160160            // Unload old sound first
    161161            alSourcei(this->audioSource_, AL_BUFFER, 0);
    162             alDeleteBuffers(1, &this->audioBuffer_);
    163             this->audioBuffer_ = 0;
     162            this->soundBuffer_.reset();
    164163        }
    165164
     
    168167            return;
    169168
    170         COUT(3) << "Sound: OpenAL ALUT: loading file " << source << std::endl;
    171169        // Get DataStream from the resources
    172170        shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(source);
     
    176174            return;
    177175        }
    178         dataStream_ = Resource::open(source);
    179         // Read everything into a temporary buffer
    180         char* buffer = new char[fileInfo->size];
    181         dataStream_->read(buffer, fileInfo->size);
    182         dataStream_->seek(0);
    183 
    184         this->audioBuffer_ = alutCreateBufferFromFileImage(buffer, fileInfo->size);
    185         delete[] buffer;
    186 
    187         if (this->audioBuffer_ == AL_NONE)
    188         {
    189             COUT(2) << "Sound: OpenAL ALUT: " << alutGetErrorString(alutGetError()) << std::endl;
    190             if (source.find("ogg", 0) != std::string::npos)
    191             {
    192                 COUT(2) << "Sound: Trying fallback ogg loader" << std::endl;
    193                 this->audioBuffer_ = this->loadOggFile();
    194             }
    195 
    196             if (this->audioBuffer_ == AL_NONE)
    197             {
    198                 COUT(2) << "Sound: fallback ogg loader failed: " << alutGetErrorString(alutGetError()) << std::endl;
    199                 return;
    200             }
    201         }
    202 
    203         alSourcei(this->audioSource_, AL_BUFFER, this->audioBuffer_);
     176
     177        this->soundBuffer_ = SoundManager::getInstance().getSoundBuffer(fileInfo);
     178        if (this->soundBuffer_ == NULL)
     179            return;
     180
     181        alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
    204182        if (alGetError() != AL_NO_ERROR)
    205183        {
     
    217195            alSourcePause(this->audioSource_);
    218196
    219         if (alGetError() != AL_NO_ERROR)
    220             COUT(2) << "Sound: OpenAL: Error playing sound " << this->audioSource_ << std::endl;
    221     }
    222 
    223     size_t readVorbis(void* ptr, size_t size, size_t nmemb, void* datasource)
    224     {
    225         return static_cast<Ogre::DataStream*>(datasource)->read(ptr, size * nmemb);
    226     }
    227 
    228     int seekVorbis(void* datasource, ogg_int64_t offset, int whence)
    229     {
    230         Ogre::DataStream* stream = static_cast<Ogre::DataStream*>(datasource);
    231         int offset_beg = offset;
    232         if (whence == SEEK_CUR)
    233             offset_beg = stream->tell() + offset;
    234         else if (whence == SEEK_END)
    235             offset_beg = stream->size() + offset;
    236         else if (whence != SEEK_SET)
    237             return -1;
    238         stream->seek(offset_beg);
    239         return 0;
    240     }
    241 
    242     long tellVorbis(void* datasource)
    243     {
    244         return static_cast<long>(static_cast<Ogre::DataStream*>(datasource)->tell());
    245     }
    246 
    247     ALuint BaseSound::loadOggFile()
    248     {
    249         char inbuffer[256*1024];
    250         std::vector<char> outbuffer;
    251         outbuffer.reserve(80*1024*1024);
    252         OggVorbis_File vf;
    253         vorbis_info* vorbisInfo;
    254         int eof = false;
    255         int current_section;
    256         ALuint buffer;
    257         ALenum format;
    258 
    259         // Open file with custom streaming
    260         ov_callbacks vorbisCallbacks;
    261         vorbisCallbacks.read_func  = &readVorbis;
    262         vorbisCallbacks.seek_func  = &seekVorbis;
    263         vorbisCallbacks.tell_func  = &tellVorbis;
    264         vorbisCallbacks.close_func = NULL;
    265 
    266         int ret = ov_open_callbacks(dataStream_.get(), &vf, NULL, 0, vorbisCallbacks);
    267         if (ret < 0)
    268         {
    269             COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl;
    270             ov_clear(&vf);
    271             return AL_NONE;
    272         }
    273 
    274         while (!eof)
    275         {
    276             long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
    277             if (ret == 0)
    278             {
    279                 eof = true;
    280             }
    281             else if (ret < 0)
    282             {
    283                 COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl;
    284                 ov_clear(&vf);
    285                 return AL_NONE;
    286             }
    287             else
    288             {
    289                 outbuffer.insert(outbuffer.end(), inbuffer, inbuffer + ret);
    290             }
    291         }
    292 
    293         vorbisInfo = ov_info(&vf, -1);
    294         if (vorbisInfo->channels == 1)
    295             format = AL_FORMAT_MONO16;
    296         else
    297             format = AL_FORMAT_STEREO16;
    298 
    299         alGenBuffers(1, &buffer);
    300         alBufferData(buffer, format, &outbuffer[0], outbuffer.size(), vorbisInfo->rate);
    301         ov_clear(&vf);
    302 
    303         return buffer;
     197        if (int error = alGetError())
     198            COUT(2) << "Sound: OpenAL: Error playing sound: " << error << std::endl;
    304199    }
    305200}
  • code/branches/presentation2/src/orxonox/sound/BaseSound.h

    r6202 r6203  
    3333
    3434#include <string>
     35#include <boost/shared_ptr.hpp>
    3536#include <OgreDataStream.h>
    3637#include "core/OrxonoxClass.h"
     
    3839namespace orxonox
    3940{
     41    // forward declaration
     42    class SoundBuffer;
     43
    4044    /**
    4145     * The BaseSound class is the base class for all sound file loader classes.
     
    8387
    8488        ALuint audioSource_;
    85         ALuint audioBuffer_;
     89        shared_ptr<SoundBuffer> soundBuffer_;
    8690
    8791    private:
  • code/branches/presentation2/src/orxonox/sound/CMakeLists.txt

    r5929 r6203  
    22    AmbientSound.cc
    33    BaseSound.cc
     4    SoundBuffer.cc
    45    SoundManager.cc
    56    WorldSound.cc
  • code/branches/presentation2/src/orxonox/sound/SoundManager.cc

    r6197 r6203  
    3838#include "util/StringUtils.h"
    3939#include "util/Clock.h"
     40#include "core/ConfigValueIncludes.h"
    4041#include "core/GameMode.h"
    4142#include "core/ScopedSingletonManager.h"
    42 #include "core/ConfigValueIncludes.h"
     43#include "core/Resource.h"
     44#include "SoundBuffer.h"
    4345#include "BaseSound.h"
    4446#include "AmbientSound.h"
     
    473475        }
    474476    }
     477
     478    shared_ptr<SoundBuffer> SoundManager::getSoundBuffer(shared_ptr<ResourceInfo> fileInfo)
     479    {
     480        std::map<std::string, weak_ptr<SoundBuffer> >::const_iterator it
     481            = this->soundBuffers_.find(fileInfo->group + '/' + fileInfo->filename);
     482        if (it != this->soundBuffers_.end())
     483            return it->second.lock();
     484        else
     485        {
     486            shared_ptr<SoundBuffer> buffer(new SoundBuffer(fileInfo));
     487            this->soundBuffers_[fileInfo->group + '/' + fileInfo->filename] = buffer;
     488            return buffer;
     489        }
     490    }
     491
     492    void SoundManager::removeBuffer(shared_ptr<ResourceInfo> fileInfo)
     493    {
     494        std::map<std::string, weak_ptr<SoundBuffer> >::const_iterator it
     495            = this->soundBuffers_.find(fileInfo->group + '/' + fileInfo->filename);
     496        if (it == this->soundBuffers_.end())
     497            this->soundBuffers_.erase(it);
     498    }
    475499}
  • code/branches/presentation2/src/orxonox/sound/SoundManager.h

    r6194 r6203  
    3333
    3434#include <list>
     35#include <map>
    3536#include <string>
    36 #include <map>
     37#include <boost/weak_ptr.hpp>
     38
    3739#include "util/Singleton.h"
    3840#include "core/OrxonoxClass.h"
     
    4143namespace orxonox
    4244{
     45    // forward declaration
     46    class SoundBuffer;
    4347   
    4448    //! Enum for the sound type.
     
    8690        bool getMute(SoundType::Value type); // tolua_export
    8791
     92        shared_ptr<SoundBuffer> getSoundBuffer(shared_ptr<ResourceInfo> fileInfo);
     93        void removeBuffer(shared_ptr<ResourceInfo> fileInfo);
     94
    8895    private:
    8996        void processCrossFading(float dt);
     
    118125        float effectsVolume_;
    119126        std::map<SoundType::Value, bool> mute_;
     127
     128        std::map<std::string, weak_ptr<SoundBuffer> > soundBuffers_;
    120129       
    121130        static SoundManager* singletonPtr_s;
Note: See TracChangeset for help on using the changeset viewer.