Example #1
0
void SoundSystem::StopAllSounds( SoundObjectId _id, char *_eventName )
{
    for( int i = 0; i < m_sounds.Size(); ++i )
    {
        if( m_sounds.ValidIndex(i) )
        {
            SoundInstance *instance = m_sounds[i];
            
            if( instance->m_objId == _id )
            {                    
                if( !_eventName || stricmp(instance->m_eventName, _eventName) == 0 )
                {
                    if( instance->IsPlaying() )
                    {
                        instance->BeginRelease(true);
                    }
                    else
                    {
                        ShutdownSound( instance );
                    }
                }
            }
        }
    }
}
Example #2
0
void SoundSystem::Advance()
{
    if( !m_channels )
	{
		return;
	}

    float timeNow = GetHighResTime();
    if( timeNow >= m_timeSync )
    {
        m_timeSync = timeNow + SOUNDSYSTEM_UPDATEPERIOD;
        
        START_PROFILE("SoundSystem");        
		
#ifndef TARGET_MSVC
		((SoundLibrary2dSDL *)g_soundLibrary2d)->m_callbackLock.Lock();
#endif
		
        //
        // Resync with blueprints (changed by editor)

        START_PROFILE("Propagate Blueprints" );
        if( m_propagateBlueprints )
        {
            PropagateBlueprints();
        }
        END_PROFILE("Propagate Blueprints" );


        //
		// First pass : Recalculate all Perceived Sound Volumes
		// Throw away sounds that have had their chance
        // Build a list of instanceIDs for sorting

        START_PROFILE("Allocate Sorted Array" );
        static int sortedArraySize = 128;
        static SoundInstanceId *sortedIds = NULL;
        if( m_sounds.NumUsed() > sortedArraySize )
        {
            delete [] sortedIds;
            sortedIds = NULL;
            while( sortedArraySize < m_sounds.NumUsed() )
                sortedArraySize *= 2;
        }
        if( !sortedIds )
        {            
            sortedIds = new SoundInstanceId[ sortedArraySize ];
        }

        int numSortedIds = 0;
        END_PROFILE("Allocate Sorted Array" );

        START_PROFILE("Perceived Volumes" );
        for( int i = 0; i < m_sounds.Size(); ++i )
        {
            if( m_sounds.ValidIndex(i) )
            {
                SoundInstance *instance = m_sounds[i];
                if( !instance->IsPlaying() && !instance->m_loopType ) instance->m_restartAttempts--;
                if( instance->m_restartAttempts < 0 )
                {
                    ShutdownSound( instance );
                }
                else if( instance->m_positionType == SoundInstance::Type3DAttachedToObject &&
                         !instance->GetAttachedObject().IsValid() )                
                {
                    ShutdownSound( instance );
                }
                else
                {
                    instance->CalculatePerceivedVolume();
                    sortedIds[numSortedIds] = instance->m_id;
                    numSortedIds++;
                }
            }
        }
        END_PROFILE("Perceived Volumes" );


        //        
		// Sort sounds into perceived volume order
        // NOTE : There are exactly numSortedId elements in sortedIds.  
        // NOTE : It isn't safe to assume numSortedIds == m_sounds.NumUsed()
        
        START_PROFILE("Sort Samples" );
        qsort( sortedIds, numSortedIds, sizeof(SoundInstanceId), SoundInstanceCompare );
        END_PROFILE("Sort Samples" );


        //
		// Second pass : Recalculate all Sound Priorities starting with the nearest sounds
        // Reduce priorities as more of the same sounds are played

        BTree<float> existingInstances;
        
                
        //                
        // Also look out for the highest priority new sound to swap in

        START_PROFILE("Recalculate Priorities" );

        LList<SoundInstance *> newInstances;
        SoundInstance *newInstance = NULL;
        float highestInstancePriority = 0.0f;

        for( int i = 0; i < numSortedIds; ++i )
        {
            SoundInstanceId id = sortedIds[i];
            SoundInstance *instance = GetSoundInstance( id );
            AppDebugAssert( instance );

            instance->m_calculatedPriority = instance->m_perceivedVolume;

            BTree<float> *existingInstance = existingInstances.LookupTree( instance->m_eventName );
            if( existingInstance )
            {
                instance->m_calculatedPriority *= existingInstance->data;
                existingInstance->data *= 0.75f;
            }
            else
            {
                existingInstances.PutData( instance->m_eventName, 0.75f );
            }

            if( !instance->IsPlaying() )
            {
                if( instance->m_positionType == SoundInstance::TypeMusic )
                {
                    newInstances.PutData( instance );
                }
                else if( instance->m_calculatedPriority > highestInstancePriority )
                {
                    newInstance = instance;
                    highestInstancePriority = instance->m_calculatedPriority;
                }
            }
        }

        if( newInstance )
        {
            newInstances.PutData( newInstance );
        }

        END_PROFILE("Recalculate Priorities" );
        
     
        for( int i = 0; i < newInstances.Size(); ++i )
        {            
            SoundInstance *newInstance = newInstances[i];
            bool isMusic = (newInstance->m_positionType == SoundInstance::TypeMusic);

            // Find worst old sound to get rid of  
            START_PROFILE("Find best Channel" );
            int bestAvailableChannel = FindBestAvailableChannel( isMusic );
            END_PROFILE("Find best Channel" );

			// FindBestAvailableChannel can return -1, so let's not access an invalid index later on.
			if ( bestAvailableChannel < 0 )
				continue;

            START_PROFILE("Stop Old Sound" );
			// Stop the old sound
            SoundInstance *existingInstance = GetSoundInstance( m_channels[bestAvailableChannel] );
            if( existingInstance && !existingInstance->m_loopType )
            {
                ShutdownSound( existingInstance );
            }
            else if( existingInstance )
            {
                existingInstance->StopPlaying();
            }            
            END_PROFILE("Stop Old Sound" );


            START_PROFILE( "Start New Sound" );
			// Start the new sound
            bool success = newInstance->StartPlaying( bestAvailableChannel );
            if( success )
            {
                m_channels[bestAvailableChannel] = newInstance->m_id;
            }
            else
            {
                // This is fairly bad, the sound failed to play
                // Which means it failed to load, or to go into a channel
                ShutdownSound( newInstance );
            }
            END_PROFILE("Start New Sound" );
            
            START_PROFILE("Reset Channel" );
            g_soundLibrary3d->ResetChannel( bestAvailableChannel);
            END_PROFILE("Reset Channel" );
        }


        //
        // Advance all sound channels

        START_PROFILE("Advance All Channels" );
        for( int i = 0; i < m_numChannels; ++i )
        {            
            SoundInstanceId soundId = m_channels[i];            
            SoundInstance *currentSound = GetSoundInstance( soundId );                         
            if( currentSound )
            {
                bool amIDone = currentSound->Advance();
                if( amIDone )
                {                    
			        START_PROFILE("Shutdown Sound" );
                    ShutdownSound( currentSound );
			        END_PROFILE("Shutdown Sound" );
                }    
            }
        }
        END_PROFILE("Advance All Channels" );


		//
        // Update our listener position

        START_PROFILE("UpdateListener" );    

        Vector3<float> camPos, camVel, camUp, camFront;
        bool cameraDefined = m_interface->GetCameraPosition( camPos, camFront, camUp, camVel );

        if( cameraDefined )
        {
            if( g_preferences->GetInt("SoundSwapStereo",0) == 0 )
            {
                camUp *= -1.0f;
            }

            g_soundLibrary3d->SetListenerPosition( camPos, camFront, camUp, camVel );
        }
        
        END_PROFILE("UpdateListener" );    


        //
        // Advance our sound library

        START_PROFILE("SoundLibrary3d Advance" );
        g_soundLibrary3d->Advance();
        END_PROFILE("SoundLibrary3d Advance" );
      
#ifdef SOUNDSYSTEM_VERIFY
        RuntimeVerify();
#endif

#ifndef TARGET_MSVC
		((SoundLibrary2dSDL *)g_soundLibrary2d)->m_callbackLock.Unlock();
#endif

        END_PROFILE("SoundSystem");                    
    }
}