Revision: 2489 http://rigsofrods.svn.sourceforge.net/rigsofrods/?rev=2489&view=rev Author: ulteq Date: 2012-05-02 05:08:50 +0000 (Wed, 02 May 2012) Log Message: ----------- -Fix: fixes a bug which crashes the game with many add-on packs (>200). Reason: m_audio_buffers_in_use_count became too big.
Modified Paths: -------------- trunk/source/main/audio/Sound.cpp trunk/source/main/audio/Sound.h trunk/source/main/audio/SoundManager.cpp trunk/source/main/audio/SoundManager.h Modified: trunk/source/main/audio/Sound.cpp =================================================================== --- trunk/source/main/audio/Sound.cpp 2012-04-30 02:21:21 UTC (rev 2488) +++ trunk/source/main/audio/Sound.cpp 2012-05-02 05:08:50 UTC (rev 2489) @@ -18,24 +18,25 @@ along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>. */ +#ifdef USE_OPENAL + #include "Sound.h" #include "SoundManager.h" using namespace Ogre; -#ifdef USE_OPENAL - -Sound::Sound(ALuint _buffer, SoundManager *_soundManager, int _sourceIndex) : +Sound::Sound(ALuint _buffer, SoundManager *soundManager, int sourceIndex) : buffer(_buffer) - , soundManager(_soundManager) - , sourceIndex(_sourceIndex) + , soundManager(soundManager) + , sourceIndex(sourceIndex) + , audibility(0.0f) + , enabled(true) + , gain(0.0f) , hardware_index(-1) - , gain(1) - , pitch(1) , loop(false) - , enabled(true) + , pitch(1.0f) + , position(Vector3::ZERO) , should_play(false) - , position(Vector3::ZERO) , velocity(Vector3::ZERO) { } @@ -45,23 +46,25 @@ // Disable sound? if (!enabled) { - audibility = 0.0; + audibility = 0.0f; return; } // First check if the sound is finished! if (!loop && should_play && hardware_index!=-1) { - int value; + int value = 0; alGetSourcei((ALuint)soundManager->getHardwareSource(hardware_index), AL_SOURCE_STATE, &value); if (value != AL_PLAYING) + { should_play = false; + } } // Should it play at all? - if (!should_play || gain == 0.0) + if (!should_play || gain == 0.0f) { - audibility = 0.0; + audibility = 0.0f; return; } @@ -69,7 +72,7 @@ if (distance > soundManager->MAX_DISTANCE) { - audibility = 0.0; + audibility = 0.0f; } else if (distance < soundManager->REFERENCE_DISTANCE) { audibility = gain; @@ -83,9 +86,9 @@ { if (hardware_index != -1) { - int value; + int value = 0; alGetSourcei((ALuint)soundManager->getHardwareSource(hardware_index), AL_SOURCE_STATE, &value); - return (value==AL_PLAYING); + return (value == AL_PLAYING); } return false; } @@ -122,7 +125,7 @@ void Sound::setLoop(bool loop) { this->loop = loop; - soundManager->recomputeSource(sourceIndex, REASON_LOOP, (loop)?1.0:0.0, NULL); + soundManager->recomputeSource(sourceIndex, REASON_LOOP, (loop) ? 1.0f : 0.0f, NULL); } void Sound::setPitch(float pitch) Modified: trunk/source/main/audio/Sound.h =================================================================== --- trunk/source/main/audio/Sound.h 2012-04-30 02:21:21 UTC (rev 2488) +++ trunk/source/main/audio/Sound.h 2012-05-02 05:08:50 UTC (rev 2489) @@ -27,7 +27,6 @@ #include "RoRPrerequisites.h" #include <AL/al.h> - class Sound { friend class SoundManager; @@ -47,7 +46,7 @@ bool getEnabled(); bool isPlaying(); - enum { REASON_PLAY, REASON_STOP, REASON_GAIN, REASON_LOOP, REASON_PTCH, REASON_POSN, REASON_VLCT }; + enum RecomputeSource { REASON_PLAY, REASON_STOP, REASON_GAIN, REASON_LOOP, REASON_PTCH, REASON_POSN, REASON_VLCT }; private: void computeAudibility(Ogre::Vector3 pos); Modified: trunk/source/main/audio/SoundManager.cpp =================================================================== --- trunk/source/main/audio/SoundManager.cpp 2012-04-30 02:21:21 UTC (rev 2488) +++ trunk/source/main/audio/SoundManager.cpp 2012-05-02 05:08:50 UTC (rev 2489) @@ -47,15 +47,15 @@ String soundRenderer = SSETTING("3D Sound renderer", "Default"); if (soundRenderer == "No sound") return; - char str[256]; - if (soundRenderer == "Default") - str[0]=0; - else + char str[256] = {}; + if (soundRenderer != "Default") + { sprintf(str, "DirectSound Software on %s", soundRenderer.c_str()); + } LOG("Opening Device: '"+String(str)+"'"); - master_volume = FSETTING("Sound Volume", 100) / 100.0f; + master_volume = FSETTING("Sound Volume", 100.0f) / 100.0f; for (int i=0; i<MAX_HARDWARE_SOURCES; i++) m_hardware_sources_map[i]=-1; @@ -100,7 +100,7 @@ alSourcef(m_hardware_sources[m_hardware_sources_num], AL_ROLLOFF_FACTOR, ROLLOFF_FACTOR); alSourcef(m_hardware_sources[m_hardware_sources_num], AL_MAX_DISTANCE, MAX_DISTANCE); } - alDopplerFactor(1.0); + alDopplerFactor(1.0f); alDopplerVelocity(343.0f); } @@ -112,12 +112,13 @@ // Destroy the sound context and device m_sound_context = alcGetCurrentContext(); - m_sound_device = alcGetContextsDevice(m_sound_context); + m_sound_device = alcGetContextsDevice(m_sound_context); alcMakeContextCurrent(NULL); alcDestroyContext(m_sound_context); if (m_sound_device) + { alcCloseDevice(m_sound_device); - + } LOG("SoundManager destroyed."); } @@ -162,7 +163,9 @@ // Sort first 'num_hardware_sources' sources by audibility // See: https://en.wikipedia.org/wiki/Selection_algorithm if ((m_audio_sources_in_use_count-1) > m_hardware_sources_num) + { std::nth_element(m_audio_sources_most_audible, m_audio_sources_most_audible+m_hardware_sources_num, m_audio_sources_most_audible+m_audio_sources_in_use_count-1, compareByAudibility); + } // Retire out of range sources first for (int i=0; i<m_audio_sources_in_use_count; i++) { @@ -192,10 +195,13 @@ m_audio_sources[source_index]->computeAudibility(camera_position); - if (m_audio_sources[source_index]->audibility == 0.0) + if (m_audio_sources[source_index]->audibility == 0.0f) { - if (m_audio_sources[source_index]->hardware_index != -1) // Retire the source if it is currently assigned + if (m_audio_sources[source_index]->hardware_index != -1) + { + // Retire the source if it is currently assigned retire(source_index); + } } else { @@ -215,22 +221,25 @@ case Sound::REASON_VLCT: alSource3f(m_hardware_sources[m_audio_sources[source_index]->hardware_index], AL_VELOCITY, vvec->x,vvec->y,vvec->z);break; default: break; } - } - else + } else { // Try to make it play by the hardware // Check if there is one free m_audio_sources[source_index] in the pool if (m_hardware_sources_in_use_count < m_hardware_sources_num) { for (int i=0; i<m_hardware_sources_num; i++) - if (m_hardware_sources_map[i] == -1) {assign(source_index, i);break;} - } - else + { + if (m_hardware_sources_map[i] == -1) + { + assign(source_index, i);break; + } + } + } else { // Now, compute who is the faintest // Note: we know the table m_hardware_sources_map is full! - float fv=1.0; - int al_faintest=0; + float fv = 1.0f; + int al_faintest = 0; for (int i=0; i<m_hardware_sources_num; i++) { if (m_hardware_sources_map[i] >= 0 && m_audio_sources[m_hardware_sources_map[i]]->audibility < fv) @@ -238,7 +247,7 @@ fv=m_audio_sources[m_hardware_sources_map[i]]->audibility; al_faintest=i; } - } + } // Find if the the faintest m_audio_sources[source_index] is louder or not if (fv < m_audio_sources[source_index]->audibility) { @@ -256,8 +265,8 @@ { if (!m_sound_device) return; - m_audio_sources[source_index]->hardware_index=hardware_index; - m_hardware_sources_map[hardware_index]=source_index; + m_audio_sources[source_index]->hardware_index = hardware_index; + m_hardware_sources_map[hardware_index] = source_index; // The hardware source is supposed to be stopped! alSourcei(m_hardware_sources[hardware_index], AL_BUFFER, m_audio_sources[source_index]->buffer); @@ -267,8 +276,9 @@ alSource3f(m_hardware_sources[hardware_index], AL_POSITION, m_audio_sources[source_index]->position.x,m_audio_sources[source_index]->position.y,m_audio_sources[source_index]->position.z); alSource3f(m_hardware_sources[hardware_index], AL_VELOCITY, m_audio_sources[source_index]->velocity.x,m_audio_sources[source_index]->velocity.y,m_audio_sources[source_index]->velocity.z); if (m_audio_sources[source_index]->should_play) + { alSourcePlay(m_hardware_sources[hardware_index]); - + } m_hardware_sources_in_use_count++; } @@ -278,15 +288,15 @@ if (m_audio_sources[source_index]->hardware_index == -1) return; alSourceStop(m_hardware_sources[m_audio_sources[source_index]->hardware_index]); - m_hardware_sources_map[m_audio_sources[source_index]->hardware_index]=-1; - m_audio_sources[source_index]->hardware_index=-1; + m_hardware_sources_map[m_audio_sources[source_index]->hardware_index] = -1; + m_audio_sources[source_index]->hardware_index = -1; m_hardware_sources_in_use_count--; } void SoundManager::pauseAllSounds() { if (!m_sound_device) return; - alListenerf(AL_GAIN, 0.0); + alListenerf(AL_GAIN, 0.0f); } void SoundManager::resumeAllSounds() @@ -305,6 +315,13 @@ Sound* SoundManager::createSound(String filename) { if (!m_sound_device) return NULL; + + if (m_audio_buffers_in_use_count >= MAX_AUDIO_BUFFERS) + { + LOG("SoundManager: Reached MAX_AUDIO_BUFFERS limit (" + TOSTRING(MAX_AUDIO_BUFFERS) + ")"); + return NULL; + } + ALuint buffer=0; // Is the file already loaded? @@ -312,30 +329,27 @@ { if (filename == m_audio_buffer_file_name[i]) { - buffer=m_audio_buffers[i]; + buffer = m_audio_buffers[i]; break; } } + if (!buffer) { // Load the file - if (m_audio_buffers_in_use_count >= MAX_AUDIO_BUFFERS) - return NULL; - alGenBuffers(1, &m_audio_buffers[m_audio_buffers_in_use_count]); if (loadWAVFile(filename, m_audio_buffers[m_audio_buffers_in_use_count])) { // There was an error! alDeleteBuffers(1, &m_audio_buffers[m_audio_buffers_in_use_count]); - m_audio_buffer_file_name[m_audio_buffers_in_use_count]=String(""); + m_audio_buffer_file_name[m_audio_buffers_in_use_count]=""; return NULL; } - buffer=m_audio_buffers[m_audio_buffers_in_use_count]; - m_audio_buffer_file_name[m_audio_buffers_in_use_count]=filename; + buffer = m_audio_buffers[m_audio_buffers_in_use_count]; + m_audio_buffer_file_name[m_audio_buffers_in_use_count] = filename; } - if (m_audio_buffers_in_use_count >= MAX_AUDIO_SOURCES) return NULL; - m_audio_sources[m_audio_buffers_in_use_count]=new Sound(buffer, this, m_audio_buffers_in_use_count); + m_audio_sources[m_audio_buffers_in_use_count] = new Sound(buffer, this, m_audio_buffers_in_use_count); return m_audio_sources[m_audio_buffers_in_use_count++]; } Modified: trunk/source/main/audio/SoundManager.h =================================================================== --- trunk/source/main/audio/SoundManager.h 2012-04-30 02:21:21 UTC (rev 2488) +++ trunk/source/main/audio/SoundManager.h 2012-05-02 05:08:50 UTC (rev 2489) @@ -52,8 +52,7 @@ static const float ROLLOFF_FACTOR; static const float REFERENCE_DISTANCE; static const unsigned int MAX_HARDWARE_SOURCES = 32; - static const unsigned int MAX_AUDIO_SOURCES = 8192; - static const unsigned int MAX_AUDIO_BUFFERS = 2048; + static const unsigned int MAX_AUDIO_BUFFERS = 8192; private: void recomputeAllSources(); @@ -73,18 +72,18 @@ // Audio sources int m_audio_sources_in_use_count; - Sound* m_audio_sources[MAX_AUDIO_SOURCES]; + Sound* m_audio_sources[MAX_AUDIO_BUFFERS]; // Helper for calculating the most audible sources - std::pair<int, float> m_audio_sources_most_audible[MAX_AUDIO_SOURCES]; + std::pair<int, float> m_audio_sources_most_audible[MAX_AUDIO_BUFFERS]; // Audio buffers: Array of AL buffers and filenames - int m_audio_buffers_in_use_count; - ALuint m_audio_buffers[MAX_AUDIO_BUFFERS]; + int m_audio_buffers_in_use_count; + ALuint m_audio_buffers[MAX_AUDIO_BUFFERS]; Ogre::String m_audio_buffer_file_name[MAX_AUDIO_BUFFERS]; - Ogre::Vector3 camera_position; - ALCdevice *m_sound_device; - ALCcontext *m_sound_context; + Ogre::Vector3 camera_position; + ALCdevice *m_sound_device; + ALCcontext *m_sound_context; float master_volume; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Rigsofrods-devel mailing list Rigsofrods-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rigsofrods-devel