Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 11, 2009, 2:15:43 PM (15 years ago)
Author:
rgrieder
Message:

Added audio source management. This should reduce the problems when loading too many sounds.
However if there are too many players shooting at the same time, some sounds may still not play.

Location:
code/branches/presentation2/src/orxonox/sound
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • code/branches/presentation2/src/orxonox/sound/AmbientSound.cc

    r6320 r6322  
    119119    float AmbientSound::getVolumeGain()
    120120    {
     121        assert(GameMode::playsSound());
    121122        return SoundManager::getInstance().getVolume(SoundType::ambient);
    122123    }
  • code/branches/presentation2/src/orxonox/sound/AmbientSound.h

    r6307 r6322  
    5050    public:
    5151        AmbientSound(BaseObject* creator);
    52         virtual ~AmbientSound();
     52        ~AmbientSound();
    5353
    54         virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
    55         virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
    56         virtual void changedActivity();
     54        void XMLPort(Element& xmlelement, XMLPort::Mode mode);
     55        void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
     56        void changedActivity();
    5757
    58         virtual void play();
    59         virtual void stop();
    60         virtual void pause();
     58        void play();
     59        void stop();
     60        void pause();
    6161       
    62         virtual float getVolumeGain();
     62        float getVolumeGain();
    6363
    64         virtual void setAmbientSource(const std::string& source);
     64        void setAmbientSource(const std::string& source);
    6565        const std::string& getAmbientSource() const { return this->ambientSource_; }
    6666        inline void ambientSourceChanged(){ this->setAmbientSource(this->ambientSource_); }
  • code/branches/presentation2/src/orxonox/sound/BaseSound.cc

    r6320 r6322  
    4343{
    4444    BaseSound::BaseSound()
    45         : audioSource_(0)
    46         , bPooling_(false)
     45        : bPooling_(false)
    4746        , volume_(1.0)
    4847        , bLooping_(false)
     
    5251        RegisterRootObject(BaseSound);
    5352
    54         if (GameMode::playsSound())
    55         {
    56             alGenSources(1, &this->audioSource_);
    57             if (!alIsSource(this->audioSource_))
    58                 COUT(1) << "Sound: Source generation failed: " << SoundManager::getALErrorString(alGetError()) << std::endl;
    59 
    60             if (alIsSource(this->audioSource_))
    61             {
    62                 alSourcei(this->audioSource_, AL_REFERENCE_DISTANCE, 20);
    63                 alSourcei(this->audioSource_, AL_MAX_DISTANCE, 10000);
    64             }
    65         }
     53        // Initialise audioSource_ to a value that is not a source
     54        // 0 is unfortunately not guaranteed to be no source ID.
     55        this->audioSource_ = 123456789;
     56        while (alIsSource(++this->audioSource_));
    6657    }
    6758
    6859    BaseSound::~BaseSound()
    6960    {
    70         this->setSource(std::string());
    71         if (GameMode::playsSound() && alIsSource(this->audioSource_))
    72             alDeleteSources(1, &this->audioSource_);
     61        this->stop();
    7362    }
    7463
     
    8473    {
    8574        this->state_ = Playing;
    86         if (GameMode::playsSound() && alIsSource(this->audioSource_) && this->getSourceState() != AL_PLAYING)
    87         {
     75        if (GameMode::playsSound() && this->getSourceState() != AL_PLAYING && this->soundBuffer_ != NULL)
     76        {
     77            if (!alIsSource(this->audioSource_))
     78                this->audioSource_ = SoundManager::getInstance().getSoundSource();
     79            if (!alIsSource(this->audioSource_))
     80                return;
     81            this->initialiseSource();
     82
    8883            alSourcePlay(this->audioSource_);
    89 
    9084            if (int error = alGetError())
    91                 COUT(2) << "Sound: Error playing sound: " << error << std::endl;
     85                COUT(2) << "Sound: Error playing sound: " << SoundManager::getALErrorString(error) << std::endl;
    9286        }
    9387    }
     
    9690    {
    9791        this->state_ = Stopped;
    98         if (GameMode::playsSound() && alIsSource(this->audioSource_))
     92        if (alIsSource(this->audioSource_))
     93        {
    9994            alSourceStop(this->audioSource_);
     95            // Release buffer
     96            alSourcei(this->audioSource_, AL_BUFFER, AL_NONE);
     97            // Release source again
     98            SoundManager::getInstance().releaseSoundSource(this->audioSource_);
     99            // Get a no source ID
     100            this->audioSource_ += 123455;
     101            while (alIsSource(++this->audioSource_));
     102        }
    100103    }
    101104
     
    105108            return;
    106109        this->state_ = Paused;
    107         if (GameMode::playsSound() && alIsSource(this->audioSource_))
     110        if (alIsSource(this->audioSource_))
    108111            alSourcePause(this->audioSource_);
    109112    }
     
    111114    ALint BaseSound::getSourceState() const
    112115    {
    113         if (GameMode::playsSound() && alIsSource(this->audioSource_))
     116        if (alIsSource(this->audioSource_))
    114117        {
    115118            ALint state;
     
    121124    }
    122125
     126    void BaseSound::initialiseSource()
     127    {
     128        this->updateVolume();
     129        this->setPitch(this->getPitch());
     130        this->setLooping(this->getLooping());
     131        alSource3f(this->audioSource_, AL_POSITION,  0, 0, 0);
     132        alSource3f(this->audioSource_, AL_VELOCITY,  0, 0, 0);
     133        alSource3f(this->audioSource_, AL_DIRECTION, 0, 0, 0);
     134        alSourcei(this->audioSource_, AL_REFERENCE_DISTANCE, 20);
     135        alSourcei(this->audioSource_, AL_MAX_DISTANCE, 10000);
     136        if (ALint error = alGetError())
     137            COUT(2) << "Sound Warning: Setting source parameters to 0 failed: "
     138                    << SoundManager::getALErrorString(error) << std::endl;
     139        assert(this->soundBuffer_ != NULL);
     140        alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
     141        if (ALuint error = alGetError())
     142            COUT(1) << "Sound Error: Could not set buffer \"" << this->source_ << "\": " << SoundManager::getALErrorString(error) << std::endl;
     143    }
     144
    123145    void BaseSound::setVolume(float vol)
    124146    {
     
    136158    float BaseSound::getVolumeGain()
    137159    {
     160        assert(GameMode::playsSound());
    138161        return SoundManager::getInstance().getVolume(SoundType::none);
    139162    }
     
    143166        if (alIsSource(this->audioSource_))
    144167        {
    145             alSourcef(this->audioSource_, AL_GAIN, this->volume_*this->getVolumeGain());
     168            float volume = this->volume_ * this->getVolumeGain();
     169            alSourcef(this->audioSource_, AL_GAIN, volume);
    146170            if (int error = alGetError())
    147                 COUT(2) << "Sound: Error setting volume: " << error << std::endl;
     171                COUT(2) << "Sound: Error setting volume to " << volume
     172                        << ": " << SoundManager::getALErrorString(error) << std::endl;
    148173        }
    149174    }
     
    152177    {
    153178        this->bLooping_ = val;
    154         if (GameMode::playsSound() && alIsSource(this->audioSource_))
     179        if (alIsSource(this->audioSource_))
    155180            alSourcei(this->audioSource_, AL_LOOPING, (val ? AL_TRUE : AL_FALSE));
    156181    }
     
    165190        }       
    166191        this->pitch_ = pitch;
    167         if (GameMode::playsSound() && alIsSource(this->audioSource_))
     192        if (alIsSource(this->audioSource_))
    168193        {
    169194            if (int error = alGetError())
    170                 COUT(2) << "Sound: Error setting pitch: " << error << std::endl;
     195                COUT(2) << "Sound: Error setting pitch: " << SoundManager::getALErrorString(error) << std::endl;
    171196            alSourcef(this->audioSource_, AL_PITCH, pitch);
    172197        }
     
    183208        if (this->soundBuffer_ != NULL)
    184209        {
     210            // Stopping is imperative here!
    185211            if (alIsSource(this->audioSource_))
    186212            {
    187213                alSourceStop(this->audioSource_);
    188                 // Unload old buffer first
    189                 alSourcei(this->audioSource_, AL_BUFFER, 0);
     214                alSourcei(this->audioSource_, AL_BUFFER, AL_NONE);
    190215            }
    191216            SoundManager::getInstance().releaseSoundBuffer(this->soundBuffer_, this->bPooling_);
     
    194219
    195220        this->source_ = source;
    196         if (source_.empty() || !alIsSource(this->audioSource_))
     221        if (source_.empty())
    197222            return;
    198223
     
    201226            return;
    202227
    203         alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
    204         if (ALuint error = alGetError())
    205         {
    206             COUT(1) << "Sound Error: Could not load file \"" << source << "\": " << SoundManager::getALErrorString(error) << std::endl;
    207             return;
    208         }
    209 
    210         alSource3f(this->audioSource_, AL_POSITION,  0, 0, 0);
    211         this->updateVolume();
    212         this->setPitch(this->getPitch());
    213         this->setLooping(getLooping());
    214         if (this->isPlaying() || this->isPaused())
    215         {
    216             alSourcePlay(this->audioSource_);
    217             if (int error = alGetError())
    218                 COUT(2) << "Sound: Error playing sound: " << error << std::endl;
    219         }
    220         if (this->isPaused())
    221             alSourcePause(this->audioSource_);
     228        if (alIsSource(this->audioSource_))
     229        {
     230            alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
     231            if (ALuint error = alGetError())
     232            {
     233                COUT(1) << "Sound Error: Could not set buffer \"" << source << "\": " << SoundManager::getALErrorString(error) << std::endl;
     234                return;
     235            }
     236
     237            if (this->isPlaying() || this->isPaused())
     238            {
     239                alSourcePlay(this->audioSource_);
     240                if (int error = alGetError())
     241                    COUT(2) << "Sound: Error playing sound: " << SoundManager::getALErrorString(error) << std::endl;
     242            }
     243            if (this->isPaused())
     244                alSourcePause(this->audioSource_);
     245        }
    222246    }
    223247   
  • code/branches/presentation2/src/orxonox/sound/BaseSound.h

    r6320 r6322  
    9696            Paused
    9797        };
     98        virtual void initialiseSource();
    9899        ALint getSourceState() const;
    99100
  • code/branches/presentation2/src/orxonox/sound/SoundManager.cc

    r6298 r6322  
    8787            COUT(1) << "Sound: Just getting the DLL with the dependencies is not enough for Windows (esp. Windows 7)!" << std::endl;
    8888#endif
    89             ThrowException(InitialisationFailed, "Sound: OpenAL error: Could not open sound device.");
     89            ThrowException(InitialisationFailed, "Sound Error: Could not open sound device.");
    9090        }
    9191        Loki::ScopeGuard closeDeviceGuard = Loki::MakeGuard(&alcCloseDevice, this->device_);
     
    100100
    101101        GameMode::setPlaysSound(true);
     102        Loki::ScopeGuard resetPlaysSoundGuard = Loki::MakeGuard(&GameMode::setPlaysSound, false);
    102103
    103104        // Get some information about the sound
     
    110111        else
    111112            COUT(2) << "Sound Warning: MIME Type retrieval failed: " << alutGetErrorString(alutGetError()) << std::endl;
     113       
     114        this->setVolumeInternal(1.0, SoundType::none);
     115        this->setVolumeInternal(1.0, SoundType::ambient);
     116        this->setVolumeInternal(1.0, SoundType::effects);
     117       
     118        this->mute_[SoundType::none] = false;
     119        this->mute_[SoundType::ambient] = false;
     120        this->mute_[SoundType::effects] = false;
     121
     122        this->setConfigValues();
     123
     124        // Try to get at least one source
     125        ALuint source;
     126        alGenSources(1, &source);
     127        if (!alGetError() && alIsSource(source))
     128            this->soundSources_.push_back(source);
     129        else
     130            ThrowException(InitialisationFailed, "Sound Error: Could not even create a single source");
     131        // Get the rest of the sources
     132        alGenSources(1, &source);
     133        unsigned int count = 1;
     134        while (alIsSource(source) && !alGetError() && count <= this->maxSources_)
     135        {
     136            this->soundSources_.push_back(source);
     137            alGenSources(1, &source);
     138            ++count;
     139        }
    112140
    113141        // Disarm guards
     
    115143        closeDeviceGuard.Dismiss();
    116144        desroyContextGuard.Dismiss();
    117        
    118         this->setVolumeInternal(1.0, SoundType::none);
    119         this->setVolumeInternal(1.0, SoundType::ambient);
    120         this->setVolumeInternal(1.0, SoundType::effects);
    121        
    122         this->mute_[SoundType::none] = false;
    123         this->mute_[SoundType::ambient] = false;
    124         this->mute_[SoundType::effects] = false;
    125 
    126         this->setConfigValues();
     145        resetPlaysSoundGuard.Dismiss();
    127146
    128147        COUT(4) << "Sound: Initialisation complete" << std::endl;
     
    164183            .description("Determines how fast sounds should fade, per second.")
    165184            .callback(this, &SoundManager::checkFadeStepValidity);
    166            
     185
    167186        SetConfigValue(soundVolume_, 1.0f)
    168187            .description("Defines the overall volume.")
    169188            .callback(this, &SoundManager::checkSoundVolumeValidity);
    170            
     189
    171190        SetConfigValue(ambientVolume_, 1.0f)
    172191            .description("Defines the ambient volume.")
    173192            .callback(this, &SoundManager::checkAmbientVolumeValidity);
    174            
     193
    175194        SetConfigValue(effectsVolume_, 1.0f)
    176195            .description("Defines the effects volume.")
    177196            .callback(this, &SoundManager::checkEffectsVolumeValidity);
     197
     198        SetConfigValue(maxSources_, 1024)
     199            .description("Maximum number of sources to be made available");
    178200    }
    179201
     
    595617        }
    596618    }
     619
     620    ALuint SoundManager::getSoundSource()
     621    {
     622        if (!this->soundSources_.empty())
     623        {
     624            ALuint source = this->soundSources_.back();
     625            this->soundSources_.pop_back();
     626            return source;
     627        }
     628        else
     629        {
     630            // Return no source ID
     631            ALuint source = 123456789;
     632            while (alIsSource(++source));
     633            return source;
     634        }
     635    }
     636
     637    void SoundManager::releaseSoundSource(ALuint source)
     638    {
     639#ifndef NDEBUG
     640        for (std::vector<ALuint>::const_iterator it = this->soundSources_.begin(); it != this->soundSources_.end(); ++it)
     641            assert((*it) != source);
     642#endif
     643        this->soundSources_.push_back(source);
     644    }
    597645}
  • code/branches/presentation2/src/orxonox/sound/SoundManager.h

    r6278 r6322  
    102102        void releaseSoundBuffer(const shared_ptr<SoundBuffer>& buffer, bool bPoolBuffer);
    103103
     104        ALuint getSoundSource();
     105        void releaseSoundSource(ALuint source);
     106
    104107        static std::string getALErrorString(ALenum error);
    105108
     
    144147        typedef std::map<std::string, shared_ptr<SoundBuffer> > SoundBufferMap;
    145148        SoundBufferMap soundBuffers_;
     149
     150        unsigned int maxSources_;
     151        std::vector<ALuint> soundSources_;
    146152       
    147153        static SoundManager* singletonPtr_s;
  • code/branches/presentation2/src/orxonox/sound/WorldSound.cc

    r6320 r6322  
    7676    }
    7777
     78    void WorldSound::initialiseSource()
     79    {
     80        BaseSound::initialiseSource();
     81        this->tick(0); // update position, orientation and velocity
     82    }
     83
    7884    void WorldSound::tick(float dt)
    7985    {
  • code/branches/presentation2/src/orxonox/sound/WorldSound.h

    r6307 r6322  
    5858    private:
    5959        void registerVariables();
     60        void initialiseSource();
    6061    };
    6162}
Note: See TracChangeset for help on using the changeset viewer.