Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Mar 1, 2011, 5:10:29 AM (13 years ago)
Author:
rgrieder
Message:

Merged sound5 into sound6 branch.

Location:
code/branches/usability
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/branches/usability

  • code/branches/usability/src/orxonox/sound/AmbientSound.cc

    r7929 r8005  
    2323 *      Reto Grieder
    2424 *   Co-authors:
    25  *      ...
     25 *      Kevin Young
    2626 *
    2727 */
     
    3333#include "core/Resource.h"
    3434#include "SoundManager.h"
     35#include "SoundStreamer.h"
     36#include "util/Sleep.h"
     37
     38#include <AL/alut.h>
    3539
    3640namespace orxonox
    3741{
     42    // vorbis callbacks
     43    size_t readVorbis(void* ptr, size_t size, size_t nmemb, void* datasource);
     44    int seekVorbis(void* datasource, ogg_int64_t offset, int whence);
     45    long tellVorbis(void* datasource);
     46   
    3847    AmbientSound::AmbientSound()
    3948        : bPlayOnLoad_(false)
     
    4251
    4352        // Ambient sounds always fade in
    44         this->setVolume(0);
     53        //this->setVolume(0);
    4554    }
    4655
     
    5160            // Smoothly fade out by keeping a SmartPtr
    5261            SoundManager::getInstance().unregisterAmbientSound(this);
     62            this->soundstreamthread_.interrupt();
    5363        }
    5464    }
     
    6272    bool AmbientSound::stop()
    6373    {
    64         if (GameMode::playsSound())
     74        if (GameMode::playsSound()) 
    6575            SoundManager::getInstance().unregisterAmbientSound(this);
    6676        return false; // sound source not (yet) destroyed - return false
     
    92102            shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(path);
    93103            if (fileInfo != NULL)
    94                 this->setSource(path);
     104                this->setStreamSource(path);
    95105            else
    96106                COUT(3) << "Sound: " << this->ambientSource_ << ": Not a valid name! Ambient sound will not change." << std::endl;
     
    104114            this->play();
    105115    }
     116
     117    // hacky solution for file streaming
     118    void AmbientSound::setStreamSource(const std::string& source)
     119    {
     120        if (!GameMode::playsSound())
     121        {
     122            this->source_ = source;
     123            return;
     124        }
     125
     126        if(!alIsSource(this->audioSource_))
     127            this->audioSource_ = SoundManager::getInstance().getSoundSource(this);
     128
     129        if (this->source_ == source)
     130        {
     131            return;
     132        }
     133
     134        this->source_ = source;
     135        // Don't load ""
     136        if (source_.empty())
     137            return;
     138
     139        if (this->soundstreamthread_.get_id() != boost::thread::id())
     140        {
     141            this->soundstreamthread_.interrupt(); // terminate an old thread if necessary
     142        }
     143
     144        // queue some init buffers
     145        COUT(4) << "Sound: Creating thread for " << source << std::endl;
     146        // Get resource info
     147        shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(source);
     148        if (fileInfo == NULL)
     149        {
     150            COUT(2) << "Sound: Warning: Sound file '" << source << "' not found" << std::endl;
     151            return;
     152        }
     153        // Open data stream
     154        DataStreamPtr dataStream = Resource::open(fileInfo);
     155       
     156        alSourcei(this->audioSource_, AL_BUFFER, 0);
     157
     158        // Open file with custom streaming
     159        ov_callbacks vorbisCallbacks;
     160        vorbisCallbacks.read_func  = &readVorbis;
     161        vorbisCallbacks.seek_func  = &seekVorbis;
     162        vorbisCallbacks.tell_func  = &tellVorbis;
     163        vorbisCallbacks.close_func = NULL;
     164
     165        OggVorbis_File* vf = new OggVorbis_File();
     166        int ret = ov_open_callbacks(dataStream.get(), vf, NULL, 0, vorbisCallbacks);
     167        if (ret < 0)
     168        {
     169            COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl;
     170            ov_clear(vf);
     171            return;
     172        }
     173        vorbis_info* vorbisInfo;
     174        vorbisInfo = ov_info(vf, -1);
     175        ALenum format;
     176        if (vorbisInfo->channels == 1)
     177            format = AL_FORMAT_MONO16;
     178        else
     179            format = AL_FORMAT_STEREO16;
     180
     181        char inbuffer[4096];
     182        ALuint initbuffers[10];
     183        alGenBuffers(10, initbuffers);
     184        if (ALint error = alGetError()) {
     185            COUT(2) << "Sound: Streamer: Could not generate buffer:" << getALErrorString(error) << std::endl;
     186            return;
     187        }
     188        int current_section;
     189
     190        for(int i = 0; i < 10; i++)
     191        {
     192            long ret = ov_read(vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
     193            if (ret == 0)
     194            {
     195                break;
     196            }
     197            else if (ret < 0)
     198            {
     199                COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl;
     200                ov_clear(vf);
     201                return;
     202            }
     203
     204            alBufferData(initbuffers[i], format, &inbuffer, ret, vorbisInfo->rate);
     205            if(ALint error = alGetError()) {
     206                COUT(2) << "Sound: Could not fill buffer: " << getALErrorString(error) << std::endl;
     207                break;
     208             }
     209             alSourceQueueBuffers(this->audioSource_, 1, &initbuffers[i]);
     210             if (ALint error = alGetError()) {
     211                 COUT(2) << "Sound: Warning: Couldn't queue buffers: " << getALErrorString(error) << std::endl;
     212             }
     213        }
     214       
     215        this->soundstreamthread_ = boost::thread(SoundStreamer(), this->audioSource_, dataStream, vf, current_section);
     216        if(this->soundstreamthread_ == boost::thread())
     217            COUT(2) << "Sound: Failed to create thread." << std::endl;
     218        //SoundStreamer streamer;
     219        //streamer(this->audioSource_, dataStream);
     220
     221        alSource3f(this->audioSource_, AL_POSITION,  0, 0, 0);
     222        alSource3f(this->audioSource_, AL_VELOCITY,  0, 0, 0);
     223        alSource3f(this->audioSource_, AL_DIRECTION, 0, 0, 0);
     224        if (ALint error = alGetError())
     225            COUT(2) << "Sound: Warning: Setting source parameters to 0 failed: " << getALErrorString(error) << std::endl;
     226    }
     227
     228    bool AmbientSound::doStop()
     229    {
     230        bool result = BaseSound::doStop();
     231        this->soundstreamthread_.interrupt();
     232        return result;
     233    }
     234
     235    void AmbientSound::doPlay()
     236    {
     237        BaseSound::doPlay();
     238
     239        if(GameMode::playsSound() && this->getSourceState() != AL_PLAYING)
     240        {
     241            if(!alIsSource(this->audioSource_))
     242            {
     243                this->audioSource_ = SoundManager::getInstance().getSoundSource(this);
     244                if(!alIsSource(this->audioSource_))
     245                    return;
     246                this->initialiseSource();
     247            }
     248
     249            alSourcePlay(this->audioSource_);
     250            if(int error = alGetError())
     251                COUT(2) << "Sound: Error playing sound: " << getALErrorString(error) << std::endl;
     252        }
     253    }
    106254}
Note: See TracChangeset for help on using the changeset viewer.