diff --git a/OpenRA.Game/Sound/Sound.cs b/OpenRA.Game/Sound/Sound.cs index a4912aa065..32c8e64b17 100644 --- a/OpenRA.Game/Sound/Sound.cs +++ b/OpenRA.Game/Sound/Sound.cs @@ -45,10 +45,12 @@ namespace OpenRA ISound video; MusicInfo currentMusic; Dictionary currentSounds = new Dictionary(); + public bool DummyEngine { get; private set; } public Sound(IPlatform platform, SoundSettings soundSettings) { soundEngine = platform.CreateSound(soundSettings.Device); + DummyEngine = soundEngine.Dummy; if (soundSettings.Mute) MuteAudio(); diff --git a/OpenRA.Game/Sound/SoundDevice.cs b/OpenRA.Game/Sound/SoundDevice.cs index 148e6a87bd..0a8c819165 100644 --- a/OpenRA.Game/Sound/SoundDevice.cs +++ b/OpenRA.Game/Sound/SoundDevice.cs @@ -20,6 +20,7 @@ namespace OpenRA ISoundSource AddSoundSourceFromMemory(byte[] data, int channels, int sampleBits, int sampleRate); ISound Play2D(ISoundSource sound, bool loop, bool relative, WPos pos, float volume, bool attenuateVolume); ISound Play2DStream(Stream stream, int channels, int sampleBits, int sampleRate, bool loop, bool relative, WPos pos, float volume); + bool Dummy { get; } float Volume { get; set; } void PauseSound(ISound sound, bool paused); void StopSound(ISound sound); diff --git a/OpenRA.Mods.Common/Widgets/VqaPlayerWidget.cs b/OpenRA.Mods.Common/Widgets/VqaPlayerWidget.cs index cd840d1379..af50e477b4 100644 --- a/OpenRA.Mods.Common/Widgets/VqaPlayerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/VqaPlayerWidget.cs @@ -104,7 +104,7 @@ namespace OpenRA.Mods.Common.Widgets if (!stopped && !paused) { var nextFrame = 0; - if (video.HasAudio) + if (video.HasAudio && !Game.Sound.DummyEngine) nextFrame = (int)float2.Lerp(0, video.Frames, Game.Sound.VideoSeekPosition * invLength); else nextFrame = video.CurrentFrame + 1; diff --git a/OpenRA.Platforms.Default/DefaultPlatform.cs b/OpenRA.Platforms.Default/DefaultPlatform.cs index 59ae4c3c2e..8174c8a2a0 100644 --- a/OpenRA.Platforms.Default/DefaultPlatform.cs +++ b/OpenRA.Platforms.Default/DefaultPlatform.cs @@ -9,6 +9,7 @@ */ #endregion +using System; using OpenRA.Primitives; namespace OpenRA.Platforms.Default @@ -22,7 +23,15 @@ namespace OpenRA.Platforms.Default public ISoundEngine CreateSound(string device) { - return new OpenAlSoundEngine(device); + try + { + return new OpenAlSoundEngine(device); + } + catch (InvalidOperationException e) + { + Log.Write("sound", "Failed to initialize OpenAL device. Error was {0}", e); + return new DummySoundEngine(device); + } } public IFont CreateFont(byte[] data) diff --git a/OpenRA.Platforms.Default/DummySoundEngine.cs b/OpenRA.Platforms.Default/DummySoundEngine.cs new file mode 100644 index 0000000000..44cf889462 --- /dev/null +++ b/OpenRA.Platforms.Default/DummySoundEngine.cs @@ -0,0 +1,75 @@ +#region Copyright & License Information +/* + * Copyright 2007-2019 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System.IO; + +namespace OpenRA.Platforms.Default +{ + sealed class DummySoundEngine : ISoundEngine + { + public bool Dummy { get { return true; } } + + public SoundDevice[] AvailableDevices() + { + var defaultDevices = new[] + { + new SoundDevice(null, "Default Output"), + }; + + return defaultDevices; + } + + public DummySoundEngine(string deviceName) { } + + public ISoundSource AddSoundSourceFromMemory(byte[] data, int channels, int sampleBits, int sampleRate) + { + return new NullSoundSource(); + } + + public ISound Play2D(ISoundSource soundSource, bool loop, bool relative, WPos pos, float volume, bool attenuateVolume) + { + return new NullSound(); + } + + public ISound Play2DStream(Stream stream, int channels, int sampleBits, int sampleRate, bool loop, bool relative, WPos pos, float volume) + { + return null; + } + + public float Volume + { + get { return 0; } + set { } + } + + public void PauseSound(ISound sound, bool paused) { } + public void SetAllSoundsPaused(bool paused) { } + public void SetSoundVolume(float volume, ISound music, ISound video) { } + public void StopSound(ISound sound) { } + public void StopAllSounds() { } + public void SetListenerPosition(WPos position) { } + public void Dispose() { } + } + + class NullSoundSource : ISoundSource + { + public void Dispose() { } + } + + class NullSound : ISound + { + public float Volume { get; set; } + public float SeekPosition { get { return 0; } } + public bool Complete { get { return false; } } + + public void SetPosition(WPos position) { } + } +} diff --git a/OpenRA.Platforms.Default/OpenAlSoundEngine.cs b/OpenRA.Platforms.Default/OpenAlSoundEngine.cs index d2f1390ac4..ae3879614b 100644 --- a/OpenRA.Platforms.Default/OpenAlSoundEngine.cs +++ b/OpenRA.Platforms.Default/OpenAlSoundEngine.cs @@ -23,6 +23,8 @@ namespace OpenRA.Platforms.Default { sealed class OpenAlSoundEngine : ISoundEngine { + public bool Dummy { get { return false; } } + public SoundDevice[] AvailableDevices() { var defaultDevices = new[]