Add audio device selection. Fixes #3553.

This commit is contained in:
Paul Chote
2013-08-02 19:38:49 +12:00
parent 332759a5f5
commit 4009edfa96
7 changed files with 175 additions and 46 deletions

View File

@@ -77,6 +77,20 @@ namespace OpenRA
video = null;
}
public static SoundDevice[] AvailableDevices()
{
var defaultDevices = new []
{
new SoundDevice("AL", null, "Default Output"),
new SoundDevice("Null", null, "Output Disabled")
};
var alDevices = OpenAlSoundEngine.AvailableDevices()
.Select(d => new SoundDevice("AL", d, d));
return defaultDevices.Concat(alDevices).ToArray();
}
public static void SetListenerPosition(float2 position) { soundEngine.SetListenerPosition(position); }
static ISound Play(Player player, string name, bool headRelative, WPos pos, float volumeModifier)
@@ -348,6 +362,24 @@ namespace OpenRA
void SetSoundVolume(float volume, ISound music, ISound video);
}
public class SoundDevice
{
public readonly string Engine;
public readonly string Device;
public readonly string Label;
public SoundDevice(string engine, string device, string label)
{
Engine = engine;
Device = device;
Label = label;
// Limit label to 32 characters
if (Label.Length > 32)
Label = "..." + Label.Substring(Label.Length - 32);
}
}
interface ISoundSource { }
public interface ISound
@@ -372,13 +404,51 @@ namespace OpenRA
Dictionary<int, PoolSlot> sourcePool = new Dictionary<int, PoolSlot>();
const int POOL_SIZE = 32;
static string[] QueryDevices(string label, int type)
{
// Clear error bit
Al.alGetError();
var devices = Alc.alcGetStringv(IntPtr.Zero, type);
if (Al.alGetError() != Al.AL_NO_ERROR)
{
Log.Write("sound", "Failed to query OpenAL device list using {0}", label);
return new string[] {};
}
return devices;
}
public static string[] AvailableDevices()
{
// Returns all devices under windows vista and newer
if (Alc.alcIsExtensionPresent(IntPtr.Zero, "ALC_ENUMERATE_ALL_EXT") == Alc.ALC_TRUE)
return QueryDevices("ALC_ENUMERATE_ALL_EXT", Alc.ALC_ALL_DEVICES_SPECIFIER);
if (Alc.alcIsExtensionPresent(IntPtr.Zero, "ALC_ENUMERATION_EXT") == Alc.ALC_TRUE)
return QueryDevices("ALC_ENUMERATION_EXT", Alc.ALC_DEVICE_SPECIFIER);
return new string[] {};
}
public OpenAlSoundEngine()
{
Console.WriteLine("Using OpenAL sound engine");
//var str = Alc.alcGetString(IntPtr.Zero, Alc.ALC_DEFAULT_DEVICE_SPECIFIER);
var dev = Alc.alcOpenDevice(null);
if (Game.Settings.Sound.Device != null)
Console.WriteLine("Using device `{0}`", Game.Settings.Sound.Device);
else
Console.WriteLine("Using default device");
var dev = Alc.alcOpenDevice(Game.Settings.Sound.Device);
if (dev == IntPtr.Zero)
throw new InvalidOperationException("Can't create OpenAL device");
{
Console.WriteLine("Failed to open device. Falling back to default");
dev = Alc.alcOpenDevice(null);
if (dev == IntPtr.Zero)
throw new InvalidOperationException("Can't create OpenAL device");
}
var ctx = Alc.alcCreateContext(dev, IntPtr.Zero);
if (ctx == IntPtr.Zero)
throw new InvalidOperationException("Can't create OpenAL context");