Example #1
0
        private static unsafe void Worker()
        {
            var toRemove = new List <DynamicSoundSource>();

            while (true)
            {
                toRemove.Clear();

                while (!NewSources.IsEmpty)
                {
                    if (!NewSources.TryTake(out var source))
                    {
                        continue;
                    }

                    if (!source.IsInitialized)
                    {
                        source.InitializeInternal();
                    }

                    if (source.IsInitialized)
                    {
                        Sources.Add(source);
                    }
                }

                foreach (var source in Sources)
                {
                    if (source.IsDisposed)
                    {
                        toRemove.Add(source);
                        continue;
                    }

                    source.UpdateInternal();

                    var seekRequested = false;

                    while (!source.Commands.IsEmpty)
                    {
                        AsyncCommand command;
                        if (!source.Commands.TryDequeue(out command))
                        {
                            continue;
                        }
                        switch (command)
                        {
                        case AsyncCommand.Play:
                            source.PlayInternal();
                            break;

                        case AsyncCommand.Pause:
                            source.PauseInternal();
                            break;

                        case AsyncCommand.Stop:
                            source.StopInternal();
                            break;

                        case AsyncCommand.Seek:
                            seekRequested = true;
                            break;

                        case AsyncCommand.SetRange:
                            source.RestartInternal();
                            break;

                        case AsyncCommand.Dispose:
                            source.DisposeInternal();
                            toRemove.Add(source);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }

                    if (source.IsDisposed)
                    {
                        continue;
                    }

                    source.isSourcePausedOrPlaying = (source.IsPausedOrPlaying && !source.Ended.Task.IsCompleted) || AudioLayer.SourceIsPlaying(source.SoundInstance.Source);

                    //Did we get a Seek request?
                    if (seekRequested)
                    {
                        source.SeekInternal();
                        continue;
                    }

                    if (source.CanFill)
                    {
                        source.ExtractAndFillData();
                    }
                }

                foreach (var source in toRemove)
                {
                    Sources.Remove(source);
                }

                var buffersShouldBeFill = false;
                foreach (var source in Sources)
                {
                    if (source.CanFill)
                    {
                        buffersShouldBeFill = true;
                        break;
                    }
                }

                if (!buffersShouldBeFill) // avoid active looping when no work is needed
                {
                    Utilities.Sleep(10);
                }
            }
        }