Example #1
0
        private void Sound()
        {
            Profiler.Start();
            try
            {
                var viewer = Game.RenderProcess.Viewer;
                if (viewer == null)
                {
                    return;
                }

                OpenAL.Listenerf(OpenAL.AL_GAIN, Simulator.Instance.GamePaused ? 0 : (float)Game.Settings.SoundVolumePercent / 100f);

                // Update activity sounds
                if (viewer.Simulator.SoundNotify != TrainEvent.None)
                {
                    if (viewer.World.GameSounds != null)
                    {
                        viewer.World.GameSounds.HandleEvent(viewer.Simulator.SoundNotify);
                    }
                    viewer.Simulator.SoundNotify = TrainEvent.None;
                }

                // Update all sound in our list
                //float UpdateInterrupts = 0;
                StartUpdateTime = viewer.RealTime;
                int RetryUpdate  = 0;
                int restartIndex = -1;

                while (RetryUpdate >= 0)
                {
                    bool updateInterrupted = false;
                    lock (SoundSources)
                    {
                        UpdateCounter++;
                        UpdateCounter %= FULLUPDATECYCLE;
                        var removals = new List <KeyValuePair <object, SoundSourceBase> >();
#if DEBUG_SOURCE_SOURCES
                        SoundSrcBaseCount += SoundSources.Count;
#endif
                        foreach (var sources in SoundSources)
                        {
                            restartIndex++;
#if DEBUG_SOURCE_SOURCES
                            SoundSrcCount += sources.Value.Count;
                            if (sources.Value.Count < 1)
                            {
                                NullSoundSrcBaseCount++;
                                //Trace.TraceInformation("Null SoundSourceBase {0}", sources.Key.ToString());
                            }
#endif
                            if (restartIndex >= RetryUpdate)
                            {
                                for (int i = 0; i < sources.Value.Count; i++)
                                {
                                    if (!sources.Value[i].NeedsFrequentUpdate && UpdateCounter > 0)
                                    {
                                        continue;
                                    }

                                    if (!sources.Value[i].Update())
                                    {
                                        removals.Add(new KeyValuePair <object, SoundSourceBase>(sources.Key, sources.Value[i]));
                                    }
                                }
                            }
                            // Check if Add or Remove Sound Sources is waiting to get in - allow it if so.
                            // Update can be a (relatively) long process.
                            if (ASyncUpdatePending > 0)
                            {
                                updateInterrupted = true;
                                RetryUpdate       = restartIndex;
                                //Trace.TraceInformation("Sound Source Updates Interrupted: {0}, Restart Index:{1}", UpdateInterrupts, restartIndex);
                                break;
                            }
                        }
                        if (!updateInterrupted)
                        {
                            RetryUpdate = -1;
                        }
#if DEBUG_SOURCE_SOURCES
                        Trace.TraceInformation("SoundProcess: sound source self-removal on " + Thread.CurrentThread.Name);
#endif
                        // Remove Sound Sources for train no longer active.  This doesn't seem to be necessary -
                        // cleanup when a train is removed seems to do it anyway with hardly any delay.
                        foreach (var removal in removals)
                        {
                            // If either of the key or value no longer exist, we can't remove them - so skip over them.
                            if (SoundSources.ContainsKey(removal.Key) && SoundSources[removal.Key].Contains(removal.Value))
                            {
                                removal.Value.Uninitialize();
                                SoundSources[removal.Key].Remove(removal.Value);
                                if (SoundSources[removal.Key].Count == 0)
                                {
                                    SoundSources.Remove(removal.Key);
                                }
                            }
                        }
                    }

                    //Update check for activity sounds
                    if (ORTSActSoundSourceList != null)
                    {
                        ORTSActSoundSourceList.Update();
                    }
                }
                //if (UpdateInterrupts > 1)
                //    Trace.TraceInformation("Sound Source Update Interrupted more than once: {0}", UpdateInterrupts);

                // <CSComment> the block below could provide better sound response but is more demanding in terms of CPU time, especially for slow CPUs

/*              int resptime = (int)((viewer.RealTime - StartUpdateTime) * 1000);
 *              SleepTime = 50 - resptime;
 *              if (SleepTime < 5)
 *                  SleepTime = 5;*/
#if DEBUG_SOURCE_SOURCES
                SoundTime += (int)((viewer.RealTime - StartUpdateTime) * 1000);
                if (viewer.RealTime - ConsoleWriteTime >= 15f)
                {
                    Trace.WriteLine("SoundSourceBases (Null): {0} ({1}), SoundSources: {2}, Time: {3}ms",
                                    (int)(SoundSrcBaseCount / UpdateCounter), (int)(NullSoundSrcBaseCount / UpdateCounter), (int)(SoundSrcCount / UpdateCounter), (int)(SoundTime / UpdateCounter));
                    ConsoleWriteTime      = viewer.RealTime;
                    SoundTime             = 0;
                    UpdateCounter         = 0;
                    SoundSrcCount         = 0;
                    SoundSrcBaseCount     = 0;
                    NullSoundSrcBaseCount = 0;
                }
#endif
            }
            finally
            {
                Profiler.Stop();
            }
        }