Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.