Ejemplo n.º 1
0
        Task ExecuteSafe(Func <Task> execution, OnError errorAction, string errorMessage)
        {
            var task = new TaskCompletionSource <bool>();

            AudioThread.Post(async() =>
            {
                try
                {
                    await execution();
                    task.TrySetResult(true);
                }
                catch (Exception ex)
                {
                    if (errorAction == OnError.Throw)
                    {
                        task.TrySetException(ex);
                    }
                    else
                    {
                        await errorAction.Apply(ex, "Failed to play audio file");
                        task.TrySetResult(false);
                    }
                }
            });

            return(task.Task);
        }
Ejemplo n.º 2
0
        public void TestThreads()
        {
            var a         = new AudioThread();
            var latency   = 10;
            var cpuUsage  = 1.0f;
            var underRuns = 1;

            var output = a.Update(TestHelper.Silence(1), out latency, out cpuUsage, out underRuns, false);

            float[] buf = new float[256];
            Thread.Sleep(200);
            Assert.IsNotNull(output);
            Assert.IsTrue(a.PlayBuffer.BufferedSamples > 0);
            output.Read(buf, 0, buf.Length);
            Assert.AreEqual(TestHelper.GenerateBuffer(new[] { 1.0f }, 256), buf);

            output = a.Update(null, out latency, out cpuUsage, out underRuns, false);
            Thread.Sleep(200);
            Assert.IsNotNull(output);
            Assert.IsTrue(a.PlayBuffer.BufferedSamples == 0);
            output.Read(buf, 0, buf.Length);
            Assert.AreEqual(TestHelper.GenerateBuffer(new[] { 0.0f }, 256), buf);

            var input = TestHelper.Silence(2);

            output = a.Update(input, out latency, out cpuUsage, out underRuns, true);
            Thread.Sleep(200);
            Assert.IsNull(output);
            Assert.IsTrue(a.PlayBuffer.BufferedSamples > 0);
            Assert.IsTrue(((LevelProcessor)input.Processor).ReadPos > 0);

            Thread.Sleep(200);
            a.Dispose();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Constructs an AudioManager given a track resource store, and a sample resource store.
        /// </summary>
        /// <param name="trackStore">The resource store containing all audio tracks to be used in the future.</param>
        /// <param name="sampleStore">The sample store containing all audio samples to be used in the future.</param>
        public AudioManager(ResourceStore <byte[]> trackStore, ResourceStore <byte[]> sampleStore)
        {
            AudioDevice.ValueChanged += onDeviceChanged;

            trackStore.AddExtension(@"mp3");

            sampleStore.AddExtension(@"wav");
            sampleStore.AddExtension(@"mp3");

            Thread = new AudioThread(Update, @"Audio");
            Thread.Start();

            scheduler.Add(() =>
            {
                globalTrackManager  = GetTrackManager(trackStore);
                globalSampleManager = GetSampleManager(sampleStore);

                try
                {
                    setAudioDevice();
                }
                catch
                {
                }
            });

            scheduler.AddDelayed(delegate
            {
                updateAvailableAudioDevices();
                checkAudioDeviceChanged();
            }, 1000, true);
        }
Ejemplo n.º 4
0
        private void StartRadioPlayerNew()
        {
            if (waveOut != null)
            {
                waveOut.Stop();
            }

            tokenSource.Cancel();
            tokenSource.Dispose();
            Console.WriteLine("AudioThread.Wait(); start");

            AudioThread.Wait();



            Console.WriteLine("AudioThread.Wait(); end");

            AudioThread.Dispose();

            bufferedWaveProvider = null;
            waveOut = null;

            tokenSource = new CancellationTokenSource();
            AudioThread = new Task(() =>
            {
                StreamMp3(tokenSource.Token);
            }, tokenSource.Token);

            AudioThread.Start();
        }
Ejemplo n.º 5
0
        /// <summary>
        /// This method calls <see cref="Bass.Init(int, int, DeviceInitFlags, IntPtr, IntPtr)"/>.
        /// It can be overridden for unit testing.
        /// </summary>
        protected virtual bool InitBass(int device)
        {
            if (Bass.CurrentDevice == device)
            {
                return(true);
            }

            // reduce latency to a known sane minimum.
            Bass.Configure(ManagedBass.Configuration.DeviceBufferLength, 10);
            Bass.Configure(ManagedBass.Configuration.PlaybackBufferLength, 100);

            // this likely doesn't help us but also doesn't seem to cause any issues or any cpu increase.
            Bass.Configure(ManagedBass.Configuration.UpdatePeriod, 5);

            // without this, if bass falls back to directsound legacy mode the audio playback offset will be way off.
            Bass.Configure(ManagedBass.Configuration.TruePlayPosition, 0);

            // Enable custom BASS_CONFIG_MP3_OLDGAPS flag for backwards compatibility.
            Bass.Configure((ManagedBass.Configuration) 68, 1);

            // For iOS devices, set the default audio policy to one that obeys the mute switch.
            Bass.Configure(ManagedBass.Configuration.IOSMixAudio, 5);

            // ensure there are no brief delays on audio operations (causing stream STALLs etc.) after periods of silence.
            Bass.Configure(ManagedBass.Configuration.DevNonStop, true);

            return(AudioThread.InitDevice(device));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// This method calls <see cref="Bass.Init(int, int, DeviceInitFlags, IntPtr, IntPtr)"/>.
        /// It can be overridden for unit testing.
        /// </summary>
        protected virtual bool InitBass(int device)
        {
            if (Bass.CurrentDevice == device)
            {
                return(true);
            }

            // reduce latency to a known sane minimum.
            Bass.Configure(ManagedBass.Configuration.DeviceBufferLength, 10);
            Bass.Configure(ManagedBass.Configuration.PlaybackBufferLength, 100);

            // this likely doesn't help us but also doesn't seem to cause any issues or any cpu increase.
            Bass.Configure(ManagedBass.Configuration.UpdatePeriod, 5);

            // without this, if bass falls back to directsound legacy mode the audio playback offset will be way off.
            Bass.Configure(ManagedBass.Configuration.TruePlayPosition, 0);

            // Enable custom BASS_CONFIG_MP3_OLDGAPS flag for backwards compatibility.
            Bass.Configure((ManagedBass.Configuration) 68, 1);

            // For iOS devices, set the default audio policy to one that obeys the mute switch.
            Bass.Configure(ManagedBass.Configuration.IOSMixAudio, 5);

            // ensure there are no brief delays on audio operations (causing stream STALLs etc.) after periods of silence.
            Bass.Configure(ManagedBass.Configuration.DevNonStop, true);

            // Always provide a default device. This should be a no-op, but we have asserts for this behaviour.
            Bass.Configure(ManagedBass.Configuration.IncludeDefaultDevice, true);

            // Disable BASS_CONFIG_DEV_TIMEOUT flag to keep BASS audio output from pausing on device processing timeout.
            // See https://www.un4seen.com/forum/?topic=19601 for more information.
            Bass.Configure((ManagedBass.Configuration) 70, false);

            return(AudioThread.InitDevice(device));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Constructs an AudioManager given a track resource store, and a sample resource store.
        /// </summary>
        /// <param name="audioThread">The host's audio thread.</param>
        /// <param name="trackStore">The resource store containing all audio tracks to be used in the future.</param>
        /// <param name="sampleStore">The sample store containing all audio samples to be used in the future.</param>
        public AudioManager(AudioThread audioThread, ResourceStore <byte[]> trackStore, ResourceStore <byte[]> sampleStore)
        {
            Thread = audioThread;

            Thread.RegisterManager(this);

            AudioDevice.ValueChanged += onDeviceChanged;

            trackStore.AddExtension(@"mp3");

            sampleStore.AddExtension(@"wav");
            sampleStore.AddExtension(@"mp3");

            globalTrackManager  = new Lazy <TrackManager>(() => GetTrackManager(trackStore));
            globalSampleManager = new Lazy <SampleManager>(() => GetSampleManager(sampleStore));

            scheduler.Add(() =>
            {
                try
                {
                    setAudioDevice();
                }
                catch
                {
                }
            });

            scheduler.AddDelayed(delegate
            {
                updateAvailableAudioDevices();
                checkAudioDeviceChanged();
            }, 1000, true);
        }
Ejemplo n.º 8
0
        public void Init()
        {
            AudioThread.PreloadBass();

            // Initialize bass with no audio to make sure the test remains consistent even if there is no audio device.
            Bass.Configure(ManagedBass.Configuration.UpdatePeriod, 5);
            Bass.Init(0);
        }
Ejemplo n.º 9
0
        public void SetUp()
        {
            thread = new AudioThread();
            store  = new NamespacedResourceStore <byte[]>(new DllResourceStore(new AssemblyName("osu.Framework")), @"Resources");

            manager = new AudioManager(thread, store, store);

            thread.Start();
        }
Ejemplo n.º 10
0
 public override void Stop()
 {
     tok.Cancel();
     VideoThread?.CloseSocket();
     AudioThread?.CloseSocket();
     VideoThread?.Join();
     AudioThread?.Join();
     base.Stop();
 }
Ejemplo n.º 11
0
 protected override void Dispose(bool Managed)
 {
     if (!Managed)
     {
         return;
     }
     VideoThread?.Dispose();
     AudioThread?.Dispose();
     base.Dispose(Managed);
 }
Ejemplo n.º 12
0
        public virtual void SetUp()
        {
            thread = new AudioThread();

            var store = new NamespacedResourceStore <byte[]>(new DllResourceStore(@"osu.Framework.Tests.dll"), @"Resources");

            Manager = new AudioManagerWithDeviceLoss(thread, store, store);

            thread.Start();
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Fires up the engine. And then it makes noise.
        /// </summary>
        public static void Start(EngineMode engineMode)
        {
#if DEBUG
            IsDebug = true;
#endif
            AppId = 480;
            Mode  = engineMode;

            LogService.ConfigureLoggers();

            Process      = Process.GetCurrentProcess();
            PlatformId   = PlatformId.Windows;
            PlatformType = PlatformType.Desktop;

            TempPath = Path.Combine(Path.GetTempPath(), "dEngine");
            if (Directory.Exists(TempPath))
            {
                ContentProvider.DeleteDirectory(TempPath);
            }
            // otherwise DeleteDirectory won't get called when stop debugging in VS.
            Directory.CreateDirectory(TempPath);

            Logger.Info("Log opened.");
            Logger.Info($"Command line args: {string.Join(" ", Environment.GetCommandLineArgs().Skip(1))})");
            Logger.Info($"Base directory: {Environment.CurrentDirectory}");

            Logger.Info($"Engine mode: {engineMode}");
            Logger.Info($"Graphics mode: {RenderSettings.GraphicsMode}");

            Logger.Info($"User: {Environment.UserName} on {Environment.MachineName}");
            Logger.Info($"CPU: {DebugSettings.CpuName} ({Environment.ProcessorCount} processors)");
            Logger.Info($"Memory: {((long)new ComputerInfo().TotalPhysicalMemory).ToPrettySize()}");

            CancelTokenSource = new CancellationTokenSource();

            Inst.Init();

            Logger.Info("Starting GraphicsThread...");
            StartThread(nameof(GraphicsThread), GraphicsThread.Start);
            GraphicsThread.Wait();
            Logger.Info("GraphicsThread started.");

            Logger.Info("Starting AudioThread...");
            StartThread(nameof(AudioThread), AudioThread.Start);
            AudioThread.Wait();
            Logger.Info("AudioThread started.");

            Logger.Info("Starting GameThread...");
            StartThread(nameof(GameThread), GameThread.Start);
            GameThread.Wait();
            Logger.Info("GameThread started.");

            AppDomain.CurrentDomain.ProcessExit += (s, e) => Shutdown(0);
        }
Ejemplo n.º 14
0
        public void SetUp()
        {
            Architecture.SetIncludePath();

            thread = new AudioThread();
            store  = new NamespacedResourceStore <byte[]>(new DllResourceStore(@"osu.Framework.dll"), @"Resources");

            manager = new AudioManager(thread, store, store);

            thread.Start();
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Constructs an AudioStore given a track resource store, and a sample resource store.
        /// </summary>
        /// <param name="audioThread">The host's audio thread.</param>
        /// <param name="trackStore">The resource store containing all audio tracks to be used in the future.</param>
        /// <param name="sampleStore">The sample store containing all audio samples to be used in the future.</param>
        public AudioManager(AudioThread audioThread, ResourceStore <byte[]> trackStore, ResourceStore <byte[]> sampleStore)
        {
            thread = audioThread;

            thread.RegisterManager(this);

            AudioDevice.ValueChanged += onDeviceChanged;

            globalTrackStore = new Lazy <TrackStore>(() =>
            {
                var store = new TrackStore(trackStore, TrackMixer);
                AddItem(store);
                store.AddAdjustment(AdjustableProperty.Volume, VolumeTrack);
                return(store);
            });

            globalSampleStore = new Lazy <SampleStore>(() =>
            {
                var store = new SampleStore(sampleStore, SampleMixer);
                AddItem(store);
                store.AddAdjustment(AdjustableProperty.Volume, VolumeSample);
                return(store);
            });

            AddItem(TrackMixer  = createAudioMixer(null, nameof(TrackMixer)));
            AddItem(SampleMixer = createAudioMixer(null, nameof(SampleMixer)));

            CancellationToken token = cancelSource.Token;

            scheduler.Add(() =>
            {
                // sync audioDevices every 1000ms
                new Thread(() =>
                {
                    while (!token.IsCancellationRequested)
                    {
                        try
                        {
                            syncAudioDevices();
                            Thread.Sleep(1000);
                        }
                        catch
                        {
                        }
                    }
                })
                {
                    IsBackground = true
                }.Start();
            });
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Constructs an AudioStore given a track resource store, and a sample resource store.
        /// </summary>
        /// <param name="audioThread">The host's audio thread.</param>
        /// <param name="trackStore">The resource store containing all audio tracks to be used in the future.</param>
        /// <param name="sampleStore">The sample store containing all audio samples to be used in the future.</param>
        public AudioManager(AudioThread audioThread, ResourceStore <byte[]> trackStore, ResourceStore <byte[]> sampleStore)
        {
            Thread = audioThread;

            Thread.RegisterManager(this);

            AudioDevice.ValueChanged += onDeviceChanged;

            globalTrackStore = new Lazy <TrackStore>(() =>
            {
                var store = new TrackStore(trackStore);
                AddItem(store);
                store.AddAdjustment(AdjustableProperty.Volume, VolumeTrack);
                return(store);
            });

            globalSampleStore = new Lazy <SampleStore>(() =>
            {
                var store = new SampleStore(sampleStore);
                AddItem(store);
                store.AddAdjustment(AdjustableProperty.Volume, VolumeSample);
                return(store);
            });

            // check for device validity every 100ms
            scheduler.AddDelayed(() =>
            {
                try
                {
                    if (!IsCurrentDeviceValid())
                    {
                        setAudioDevice();
                    }
                }
                catch
                {
                }
            }, 100, true);

            // enumerate new list of devices every second
            scheduler.AddDelayed(() =>
            {
                try
                {
                    setAudioDevice(AudioDevice.Value);
                }
                catch
                {
                }
            }, 1000, true);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// This method calls <see cref="Bass.Init(int, int, DeviceInitFlags, IntPtr, IntPtr)"/>.
        /// It can be overridden for unit testing.
        /// </summary>
        protected virtual bool InitBass(int device)
        {
            if (Bass.CurrentDevice == device)
            {
                return(true);
            }

            // reduce latency to a known sane minimum.
            Bass.Configure(ManagedBass.Configuration.DeviceBufferLength, 10);
            Bass.Configure(ManagedBass.Configuration.PlaybackBufferLength, 100);

            // this likely doesn't help us but also doesn't seem to cause any issues or any cpu increase.
            Bass.Configure(ManagedBass.Configuration.UpdatePeriod, 5);

            // without this, if bass falls back to directsound legacy mode the audio playback offset will be way off.
            Bass.Configure(ManagedBass.Configuration.TruePlayPosition, 0);

            // Enable custom BASS_CONFIG_MP3_OLDGAPS flag for backwards compatibility.
            Bass.Configure((ManagedBass.Configuration) 68, 1);

            // For iOS devices, set the default audio policy to one that obeys the mute switch.
            Bass.Configure(ManagedBass.Configuration.IOSMixAudio, 5);

            // ensure there are no brief delays on audio operations (causing stream STALLs etc.) after periods of silence.
            Bass.Configure(ManagedBass.Configuration.DevNonStop, true);

            var didInit = Bass.Init(device);

            // If the device was already initialised, the device can be used without much fuss.
            if (Bass.LastError == Errors.Already)
            {
                Bass.CurrentDevice = device;

                // Without this call, on windows, a device which is disconnected then reconnected will look initialised
                // but not work correctly in practice.
                AudioThread.FreeDevice(device);

                didInit = Bass.Init(device);
            }

            if (didInit)
            {
                thread.RegisterInitialisedDevice(device);
            }

            return(didInit);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Constructs an AudioStore given a track resource store, and a sample resource store.
        /// </summary>
        /// <param name="audioThread">The host's audio thread.</param>
        /// <param name="trackStore">The resource store containing all audio tracks to be used in the future.</param>
        /// <param name="sampleStore">The sample store containing all audio samples to be used in the future.</param>
        public AudioManager(AudioThread audioThread, ResourceStore <byte[]> trackStore, ResourceStore <byte[]> sampleStore)
        {
            Thread = audioThread;

            Thread.RegisterManager(this);

            AudioDevice.ValueChanged += onDeviceChanged;

            trackStore.AddExtension(@"mp3");

            sampleStore.AddExtension(@"wav");
            sampleStore.AddExtension(@"mp3");

            globalTrackStore = new Lazy <TrackStore>(() =>
            {
                var store = new TrackStore(trackStore);
                AddItem(store);
                store.AddAdjustment(AdjustableProperty.Volume, VolumeTrack);
                return(store);
            });

            globalSampleStore = new Lazy <SampleStore>(() =>
            {
                var store = new SampleStore(sampleStore);
                AddItem(store);
                store.AddAdjustment(AdjustableProperty.Volume, VolumeSample);
                return(store);
            });

            scheduler.Add(() =>
            {
                try
                {
                    setAudioDevice();
                }
                catch
                {
                }
            });

            scheduler.AddDelayed(delegate
            {
                updateAvailableAudioDevices();
                checkAudioDeviceChanged();
            }, 1000, true);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Constructs an AudioStore given a track resource store, and a sample resource store.
        /// </summary>
        /// <param name="audioThread">The host's audio thread.</param>
        /// <param name="trackStore">The resource store containing all audio tracks to be used in the future.</param>
        /// <param name="sampleStore">The sample store containing all audio samples to be used in the future.</param>
        public AudioManager(AudioThread audioThread, ResourceStore <byte[]> trackStore, ResourceStore <byte[]> sampleStore)
        {
            Thread = audioThread;

            Thread.RegisterManager(this);

            AudioDevice.ValueChanged += onDeviceChanged;

            globalTrackStore = new Lazy <TrackStore>(() =>
            {
                var store = new TrackStore(trackStore);
                AddItem(store);
                store.AddAdjustment(AdjustableProperty.Volume, VolumeTrack);
                return(store);
            });

            globalSampleStore = new Lazy <SampleStore>(() =>
            {
                var store = new SampleStore(sampleStore);
                AddItem(store);
                store.AddAdjustment(AdjustableProperty.Volume, VolumeSample);
                return(store);
            });

            // sync audioDevices every 200ms
            CancellationToken token = cancellationTokenSource.Token;

            Task.Factory.StartNew(() =>
            {
                while (!token.IsCancellationRequested)
                {
                    try
                    {
                        var task = Task.Delay(200, token);
                        syncAudioDevices();
                        task.Wait(token);
                    }
                    catch
                    {
                    }
                }
            }, token, TaskCreationOptions.None, TaskScheduler.Default);
        }
Ejemplo n.º 20
0
        public void ResetDevices()
        {
            // kill thread
            if (AudioThread != null)
            {
                ThreadRunning = false;
                AudioEvent.Set();
                AudioThread.Join(2000);
                AudioThread = null;
            }

            // deconstruct all record/play streams
            if (Recorder != null)
            {
                Recorder.Dispose();
                Recorder = null;
            }

            Players.ForEach(p => p.Dispose());
            Players.SafeClear();

            // will auto be recreated
        }
Ejemplo n.º 21
0
 public AudioManagerWithDeviceLoss(AudioThread audioThread, ResourceStore <byte[]> trackStore, ResourceStore <byte[]> sampleStore)
     : base(audioThread, trackStore, sampleStore)
 {
 }
Ejemplo n.º 22
0
 public override void Begin()
 {
     VideoThread?.Begin();
     AudioThread?.Begin();
     base.Begin();
 }
Ejemplo n.º 23
0
 public LevelAudioManager(AudioThread audioThread, ResourceStore <byte[]> trackStore, ResourceStore <byte[]> sampleStore)
     : base(audioThread, trackStore, sampleStore)
 {
 }