Example #1
0
        /// <summary>
        /// Creates a new OpenALDataBuffer.
        /// </summary>
        /// <returns>OpenALDataBuffer</returns>
        public static OpenALDataBuffer CreateBuffer()
        {
            var bufferId = new uint[1];

            OpenAL.alGenBuffers(1, bufferId);
            return(new OpenALDataBuffer(bufferId[0]));
        }
        public void QueuePlayback(AudioSource audioSource, byte[] data)
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException("OpenALPlaybackProvider");
            }
            if (audioSource == null)
            {
                throw new ArgumentNullException("audioSource");
            }

            Stack <SourceBuffer> bufferStack;

            if (!this.buffers.TryGetValue(audioSource, out bufferStack))
            {
                this.buffers[audioSource] = bufferStack = new Stack <SourceBuffer>();
            }

            lock (this.pool.SyncRoot)
            {
                Source source = this.pool.RequestSource(audioSource);

                Tuple <float, float> gain;
                if (this.gains.TryGetValue(audioSource, out gain))
                {
                    source.Gain = gain.Item2;
                }
                else
                {
                    source.Gain = this.normalGain;
                }

                const int bufferLen = 4;

                if (data.Length == 0)
                {
                    return;
                }

                if (!source.IsPlaying)
                {
                    OpenAL.DebugFormat("{0} bound to {1} isn't playing, inserting silent buffers", audioSource, source);

                    RequireBuffers(bufferStack, source, bufferLen);
                    for (int i = 0; i < bufferLen; ++i)
                    {
                        OpenALAudioFormat format = audioSource.CodecSettings.ToOpenALFormat();
                        SourceBuffer      wait   = bufferStack.Pop();
                        wait.Buffer(new byte[format.GetBytes((uint)audioSource.CodecSettings.FrameSize)], format, (uint)audioSource.CodecSettings.SampleRate);
                        source.QueueAndPlay(wait);
                    }
                }

                RequireBuffers(bufferStack, source, 1);
                SourceBuffer buffer = bufferStack.Pop();

                buffer.Buffer(data, audioSource.CodecSettings.ToOpenALFormat(), (uint)audioSource.CodecSettings.SampleRate);
                source.QueueAndPlay(buffer);
            }
        }
        protected void Dispose(bool disposing)
        {
            if (this.isDisposed)
            {
                return;
            }

            OpenAL.DebugFormat("Freeing OpenALPlaybackProvider. Disposing: ", disposing);

            if (disposing)
            {
                this.pool.Dispose();

                if (this.device != null)
                {
                    this.device.Dispose();
                }
            }

            SourceBuffer.Clear();

            OpenALRunner.RemoveUser();
            OpenALRunner.RemovePlaybackProvider(this);
            this.pool       = null;
            this.device     = null;
            this.isDisposed = true;
        }
Example #4
0
        internal static void AddUser()
        {
            OpenAL.Debug("Adding OpenAL user");

            int now = Interlocked.Increment(ref counter);

            if (now != 1 || running)
            {
                return;
            }

            lock (SyncRoot)
            {
                if (running)
                {
                    return;
                }

                running = true;
                (runnerThread = new Thread(Runner)
                {
                    IsBackground = true,
                    Name = "OpenAL Runner"
                }).Start();
            }
        }
Example #5
0
        internal static void AddPlaybackProvider(OpenALPlaybackProvider provider)
        {
            OpenAL.Debug("Adding OpenAL Playback Provider");

            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }

            lock (PlaybackProviders)
                PlaybackProviders.Add(provider);
        }
Example #6
0
        internal static void RemoveCaptureProvider(OpenALCaptureProvider provider)
        {
            OpenAL.Debug("Removing OpenAL Capture Provider");

            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }

            lock (CaptureProviders)
                CaptureProviders.Remove(provider);
        }
Example #7
0
        void SoundThread()
        {
            Profiler.SetThread();

            OpenAL.Initialize();

            while (true)
            {
                Thread.Sleep(SleepTime);
                if (State.Terminated)
                {
                    break;
                }
                if (!DoSound())
                {
                    return;
                }
            }
        }
        public void FreeSource(AudioSource source)
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException("OpenALPlaybackProvider");
            }
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

            OpenAL.DebugFormat("Freeing source {0}", source);

            lock (this.gains)
                this.gains = this.gains.Where(kvp => kvp.Key != source).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            buffers.Remove(source);
            pool.FreeSource(source);
        }
Example #9
0
		protected void Dispose (bool disposing)
		{
			if (this.disposed)
				return;

			OpenAL.DebugFormat ("Freeing OpenALCaptureProvider. Disposing: {0}", disposing);

			if (disposing)
			{
				if (IsCapturing)
					EndCapture();

				if (this.device != null)
					this.device.Dispose();
			}

			this.device = null;
			this.disposed = true;
		}
Example #10
0
        internal static void RemoveUser()
        {
            OpenAL.Debug("Removing OpenAL user");

            int now = Interlocked.Decrement(ref counter);

            if (now != 0 || !running)
            {
                return;
            }

            lock (SyncRoot)
            {
                if (!running)
                {
                    return;
                }

                running = false;
            }
        }
Example #11
0
        void Sound()
        {
            Profiler.Start();
            try
            {
                WatchdogToken.Ping();

                var viewer = Game.RenderProcess.Viewer;
                if (viewer == null)
                {
                    return;
                }

                OpenAL.alListenerf(OpenAL.AL_GAIN, Program.Simulator.Paused ? 0 : (float)Game.Settings.SoundVolumePercent / 100f);

                // Update activity sounds
                if (viewer.Simulator.SoundNotify != Event.None)
                {
                    if (viewer.World.GameSounds != null)
                    {
                        viewer.World.GameSounds.HandleEvent(viewer.Simulator.SoundNotify);
                    }
                    viewer.Simulator.SoundNotify = Event.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() && viewer.Simulator.GameSpeed <= 1)
                                    {
                                        Trace.TraceInformation("Sound Update return False");
                                        // This doesn't seem to be needed - cleanup when a train is removed seems to do it anyway.
                                        //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)
                {
                    Console.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();
            }
        }
Example #12
0
 public IEnumerable <IAudioDevice> GetDevices()
 {
     return(OpenAL.GetPlaybackDevices());
 }
Example #13
0
        /// <summary>
        /// Updates the form content. Warning: Creates garbage - Not any more I hope  - Dennis
        /// </summary>
        void UpdateContent()
        {
            var soundSources = Viewer.SoundProcess.SoundSources;

            activeSoundList.BeginUpdate();
            inactiveSoundList.BeginUpdate();

            for (int i = 0; i < activeSoundList.Nodes.Count; i++)
            {
                activeSoundList.Nodes[i].Nodes.Clear();
            }
            for (int i = 0; i < inactiveSoundList.Nodes.Count; i++)
            {
                inactiveSoundList.Nodes[i].Nodes.Clear();
            }

            lock (Viewer.SoundProcess.SoundSources)
            {
                foreach (var src in soundSources.Values)
                {
                    foreach (var ssb in src)
                    {
                        if (ssb is SoundSource)
                        {
                            AddToForm((SoundSource)ssb);
                        }
                        else
                        if (ssb is TrackSoundSource)
                        {
                            var ts = (TrackSoundSource)ssb;
                            if (ts._activeInSource != null)
                            {
                                AddToForm(ts._activeInSource);
                            }
                            if (ts._activeOutSource != null)
                            {
                                AddToForm(ts._activeOutSource);
                            }
                        }
                    }
                }

                CleanUp(activeSoundList.Nodes);
                CleanUp(inactiveSoundList.Nodes);
                activeSoundList.EndUpdate();
                inactiveSoundList.EndUpdate();

                // Fill selected node's data
                if (activeSoundList.SelectedNode != lastActSelectedNode)
                {
                    selectedNode                   = activeSoundList.SelectedNode;
                    lastActSelectedNode            = activeSoundList.SelectedNode;
                    inactiveSoundList.SelectedNode = null;
                    lastInActSelectedNode          = null;
                }
                else
                if (inactiveSoundList.SelectedNode != lastInActSelectedNode)
                {
                    selectedNode                 = inactiveSoundList.SelectedNode;
                    lastInActSelectedNode        = inactiveSoundList.SelectedNode;
                    activeSoundList.SelectedNode = null;
                    lastActSelectedNode          = null;
                }

                if (selectedNode != null && selectedNode.Tag is SoundSource && (SoundSource)selectedNode.Tag != null)
                {
                    selectedSoundSource = (SoundSource)selectedNode.Tag;

                    int soundSourceID = -1;
                    int i             = -1;
                    if (selectedSoundSource.SoundStreams.Count > 0)
                    {
                        while (++i < selectedSoundSource.SoundStreams.Count)
                        {
                            soundSourceID = selectedSoundSource.SoundStreams[i].ALSoundSource.SoundSourceID;
                            if (soundSourceID != -1)
                            {
                                break;
                            }
                        }
                    }

                    if (selectedSoundSource.WorldLocation != WorldLocation.None && selectedSoundSource.SoundStreams.Count > 0)
                    {
                        //Source distance:
                        distance.Text = Math.Sqrt(selectedSoundSource.DistanceSquared).ToString("F1");

                        //Stream distance:
                        //float[] pos = new float[3];
                        //OpenAL.alGetSource3f(soundSourceID, OpenAL.AL_POSITION, out pos[0], out pos[1], out pos[2]);
                        //float[] lpos = new float[3];
                        //OpenAL.alGetListener3f(OpenAL.AL_POSITION, out lpos[0], out lpos[1], out lpos[2]);
                        //for (var j = 0; j < 3; j++)
                        //    pos[j] -= lpos[j];
                        //distance.Text = Math.Sqrt(pos[0] * pos[0] + pos[1] * pos[1] + pos[2] * pos[2]).ToString("F1");
                    }
                    else
                    {
                        distance.Text = "-";
                    }

                    int relative;
                    OpenAL.alGetSourcei(soundSourceID, OpenAL.AL_SOURCE_RELATIVE, out relative);
                    sound3D.Checked = relative == OpenAL.AL_FALSE;

                    if (selectedSoundSource.Car != null)
                    {
                        speed.Text = Math.Abs(selectedSoundSource.Car.SpeedMpS).ToString("F1");
                        var Variable1 = selectedSoundSource.Car.Variable1;
                        var Variable2 = selectedSoundSource.Car.Variable2;
                        var Variable3 = selectedSoundSource.Car.Variable3;

                        if (selectedSoundSource.Car is MSTSSteamLocomotive)
                        {
                            Variable1 /= 100f;
                            Variable2 /= 100f;
                            Variable3 /= 100f;
                        }
                        if (selectedSoundSource.Car is MSTSElectricLocomotive)
                        {
                            Variable1 /= 100f;
                            Variable2 /= 100f;
                        }

                        variable1.Text = Variable1.ToString("0.#%");
                        variable2.Text = Variable2.ToString("0.#%");
                        variable3.Text = Variable3.ToString("0.#%");
                    }
                    else
                    {
                        speed.Text     = "-";
                        variable1.Text = "-";
                        variable2.Text = "-";
                        variable3.Text = "-";
                    }

                    float gain;
                    OpenAL.alGetSourcef(soundSourceID, OpenAL.AL_GAIN, out gain);
                    smsVolume.Text = gain.ToString("0.#%");
                }
                else
                {
                    distance.Text  = "-";
                    speed.Text     = "-";
                    variable1.Text = "-";
                    variable2.Text = "-";
                    variable3.Text = "-";
                    smsVolume.Text = "-";
                    activeSoundList.SelectedNode   = null;
                    inactiveSoundList.SelectedNode = null;
                }

                waves.Text     = SoundItem.AllPieces.Count.ToString();
                alSources.Text = ALSoundSource.ActiveCount.ToString();
            }
        }
Example #14
0
        /// <summary>
        /// Updates the form content. Warning: Creates garbage
        /// </summary>
        void UpdateContent()
        {
            var soundSources = Viewer.SoundProcess.GetSoundSources();

            activeSoundList.BeginUpdate();
            inactiveSoundList.BeginUpdate();

            for (int i = 0; i < activeSoundList.Nodes.Count; i++)
            {
                activeSoundList.Nodes[i].Nodes.Clear();
            }
            for (int i = 0; i < inactiveSoundList.Nodes.Count; i++)
            {
                inactiveSoundList.Nodes[i].Nodes.Clear();
            }

            foreach (var src in soundSources.Values)
            {
                foreach (var ssb in src)
                {
                    if (ssb is SoundSource)
                    {
                        var      ss = (SoundSource)ssb;
                        TreeNode node;

                        var nodeString = String.Format("{0}: {1} ", ss.Car != null ? ss.Car.UiD.ToString() : "-", ss.SMSFileName);
                        var nodeKey    = nodeString + ss.GetHashCode().ToString();

                        if (ss.Active)
                        {
                            int index = activeSoundList.Nodes.IndexOfKey(nodeKey);
                            if (index == -1)
                            {
                                activeSoundList.Nodes.Add(nodeKey, nodeString);
                                index = activeSoundList.Nodes.IndexOfKey(nodeKey);
                            }
                            node = activeSoundList.Nodes[index];
                        }
                        else
                        {
                            int index = inactiveSoundList.Nodes.IndexOfKey(nodeKey);
                            if (index == -1)
                            {
                                inactiveSoundList.Nodes.Add(nodeKey, nodeString);
                                index = inactiveSoundList.Nodes.IndexOfKey(nodeKey);
                            }
                            node = inactiveSoundList.Nodes[index];
                        }
                        node.Tag = ss;

                        var activeSS = 0;
                        foreach (var soundStream in ss.SoundStreams)
                        {
                            var playingData = soundStream.ALSoundSource.GetPlayingData();
                            if (playingData[0] != "-1")
                            {
                                activeSS++;
                            }
                            var streamString = String.Format("{0} {1} (cue: {2}) {3}", playingData);
                            var streamKey    = streamString + soundStream.GetHashCode().ToString();
                            node.Nodes.Add(streamKey, streamString);
                            node.Nodes[streamKey].Tag = soundStream;
                        }
                        node.Text = string.Format("{0}({1}{2}", node.Text.Split('(')[0], activeSS, @"@");
                    }
                    else
                    {
                    }
                }
            }

            CleanUp(activeSoundList.Nodes);
            CleanUp(inactiveSoundList.Nodes);

            // Fill selected node's data
            var selectedNode = activeSoundList.SelectedNode;

            if (selectedNode == null)
            {
                selectedNode = inactiveSoundList.SelectedNode;
            }

            if (selectedNode != null && selectedNode.Tag is SoundSource)
            {
                selectedSoundSource = (SoundSource)selectedNode.Tag;
            }
            else
            {
                selectedSoundSource = null;
            }

            if (selectedSoundSource != null)
            {
                int soundSourceID = -1;
                int i             = -1;
                if (selectedSoundSource.SoundStreams.Count > 0)
                {
                    while (++i < selectedSoundSource.SoundStreams.Count)
                    {
                        soundSourceID = selectedSoundSource.SoundStreams[i].ALSoundSource.SoundSourceID;
                        if (soundSourceID != -1)
                        {
                            break;
                        }
                    }
                }

                if (selectedSoundSource.WorldLocation != WorldLocation.None && selectedSoundSource.SoundStreams.Count > 0)
                {
                    //Source distance:
                    //distance.Text = Math.Sqrt(selectedSoundSource.DistanceSquared).ToString("F1");

                    //Stream distance:
                    float[] pos = new float[3];
                    OpenAL.alGetSource3f(soundSourceID, OpenAL.AL_POSITION, out pos[0], out pos[1], out pos[2]);
                    float[] lpos = new float[3];
                    OpenAL.alGetListener3f(OpenAL.AL_POSITION, out lpos[0], out lpos[1], out lpos[2]);
                    for (var j = 0; j < 3; j++)
                    {
                        pos[j] -= lpos[j];
                    }
                    distance.Text = Math.Sqrt(pos[0] * pos[0] + pos[1] * pos[1] + pos[2] * pos[2]).ToString("F1");
                }
                else
                {
                    distance.Text = "-";
                }

                int relative;
                OpenAL.alGetSourcei(soundSourceID, OpenAL.AL_SOURCE_RELATIVE, out relative);
                sound3D.Checked = relative == OpenAL.AL_FALSE;

                if (selectedSoundSource.Car != null)
                {
                    speed.Text = Math.Abs(selectedSoundSource.Car.SpeedMpS).ToString("F1");
                    var Variable1 = selectedSoundSource.Car.Variable1;
                    var Variable2 = selectedSoundSource.Car.Variable2;
                    var Variable3 = selectedSoundSource.Car.Variable3;

                    if (selectedSoundSource.Car is MSTSSteamLocomotive)
                    {
                        Variable1 /= 100f;
                        Variable2 /= 100f;
                        Variable3 /= 100f;
                    }
                    if (selectedSoundSource.Car is MSTSElectricLocomotive)
                    {
                        Variable1 /= 100f;
                        Variable2 /= 100f;
                    }

                    variable1.Text = Variable1.ToString("0.#%");
                    variable2.Text = Variable2.ToString("0.#%");
                    variable3.Text = Variable3.ToString("0.#%");
                }
                else
                {
                    speed.Text     = "0";
                    variable1.Text = "-";
                    variable2.Text = "-";
                    variable3.Text = "-";
                }

                float gain;
                OpenAL.alGetSourcef(soundSourceID, OpenAL.AL_GAIN, out gain);
                smsVolume.Text = gain.ToString("0.#%");
            }

            activeSoundList.EndUpdate();
            inactiveSoundList.EndUpdate();

            waves.Text     = SoundItem.AllPieces.Count.ToString();
            alSources.Text = ALSoundSource.ActiveCount.ToString();
        }
Example #15
0
		public IEnumerable<IAudioDevice> GetDevices ()
		{
			return OpenAL.GetCaptureDevices();
		}
Example #16
0
        public void UpdateSoundPosition()
        {
            if (Car.SoundSourceIDs.Count == 0 || Viewer.Camera == null)
            {
                return;
            }

            if (Car.Train != null)
            {
                var realSpeedMpS = Car.SpeedMpS;
                //TODO Following if block is needed due to physics flipping when using rear cab
                // If such physics flipping is removed next block has to be removed.
                if (Car is MSTSLocomotive)
                {
                    var loco = Car as MSTSLocomotive;
                    if (loco.UsingRearCab)
                    {
                        realSpeedMpS = -realSpeedMpS;
                    }
                }
                Vector3 directionVector = Vector3.Multiply(Car.WorldPosition.XNAMatrix.Forward, realSpeedMpS);
                Velocity = new float[] { directionVector.X, directionVector.Y, -directionVector.Z };
            }
            else
            {
                Velocity = new float[] { 0, 0, 0 }
            };

            // TODO This entire block of code (down to TODO END) should be inside the SoundProcess, not here.
            SoundLocation = new WorldLocation(Car.WorldPosition.WorldLocation);
            SoundLocation.NormalizeTo(Camera.SoundBaseTile.X, Camera.SoundBaseTile.Y);
            float[] position = new float[] {
                SoundLocation.Location.X,
                SoundLocation.Location.Y,
                SoundLocation.Location.Z
            };

            // make a copy of SoundSourceIDs, but check that it didn't change during the copy; if it changed, try again up to 5 times.
            var sSIDsFinalCount = -1;
            var sSIDsInitCount  = -2;

            int[] soundSourceIDs = { 0 };
            int   trialCount     = 0;

            try
            {
                while (sSIDsInitCount != sSIDsFinalCount && trialCount < 5)
                {
                    sSIDsInitCount  = Car.SoundSourceIDs.Count;
                    soundSourceIDs  = Car.SoundSourceIDs.ToArray();
                    sSIDsFinalCount = Car.SoundSourceIDs.Count;
                    trialCount++;
                }
            }
            catch
            {
                Trace.TraceInformation("Skipped update of position and speed of sound sources");
                return;
            }
            if (trialCount >= 5)
            {
                return;
            }
            foreach (var soundSourceID in soundSourceIDs)
            {
                Viewer.Simulator.updaterWorking = true;
                if (OpenAL.alIsSource(soundSourceID))
                {
                    OpenAL.alSourcefv(soundSourceID, OpenAL.AL_POSITION, position);
                    OpenAL.alSourcefv(soundSourceID, OpenAL.AL_VELOCITY, Velocity);
                }
                Viewer.Simulator.updaterWorking = false;
            }
            // TODO END
        }
    }