diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj
index 80e5bc199f..a6969166d8 100644
--- a/OpenRa.Game/OpenRa.Game.csproj
+++ b/OpenRa.Game/OpenRa.Game.csproj
@@ -63,10 +63,6 @@
False
..\Ijw.DirectX\Ijw.Framework\IjwFramework\bin\Debug\IjwFramework.dll
-
- False
- ..\thirdparty\irrKlang.NET2.0.dll
-
3.5
@@ -75,6 +71,7 @@
+
diff --git a/OpenRa.Game/Sound.cs b/OpenRa.Game/Sound.cs
index 537d4b59f6..c1c2202e1a 100644
--- a/OpenRa.Game/Sound.cs
+++ b/OpenRa.Game/Sound.cs
@@ -1,7 +1,8 @@
using IjwFramework.Collections;
-using IrrKlang;
using OpenRa.FileFormats;
using OpenRa.Game.GameRules;
+using Tao.OpenAl;
+using System;
namespace OpenRa.Game
{
@@ -14,49 +15,42 @@ namespace OpenRa.Game
//TODO: read these from somewhere?
static float soundVolume;
static float musicVolume;
- static bool paused;
+ // static bool paused;
static ISoundSource LoadSound(string filename)
{
var data = AudLoader.LoadSound(FileSystem.Open(filename));
- return soundEngine.AddSoundSourceFromPCMData(data, filename,
- new AudioFormat()
- {
- ChannelCount = 1,
- FrameCount = data.Length / 2,
- Format = SampleFormat.Signed16Bit,
- SampleRate = 22050
- });
+ return soundEngine.AddSoundSourceFromMemory(data, 1, 16, 22050);
}
public static void Initialize()
{
- soundEngine = new ISoundEngine();
+ soundEngine = new OpenAlSoundEngine();
sounds = new Cache(LoadSound);
music = null;
- soundVolume = soundEngine.SoundVolume;
- musicVolume = soundEngine.SoundVolume;
+ soundVolume = soundEngine.Volume;
+ musicVolume = soundEngine.Volume;
}
public static void Play(string name)
{
var sound = sounds[name];
// todo: positioning
- soundEngine.Play2D(sound, false /* loop */, false, false);
+ soundEngine.Play2D(sound, false);
}
-
+
public static void PlayMusic(string name)
{
var sound = sounds[name];
- music = soundEngine.Play2D(sound, true /* loop */, false, false);
+ music = soundEngine.Play2D(sound, true);
music.Volume = musicVolume;
}
- public static bool Paused
- {
- get { return paused; }
- set { paused = value; soundEngine.SetAllSoundsPaused(paused); }
- }
+ //public static bool Paused
+ //{
+ // get { return paused; }
+ // set { paused = value; soundEngine.SetAllSoundsPaused(paused); }
+ //}
public static float Volume
{
@@ -64,29 +58,30 @@ namespace OpenRa.Game
set
{
soundVolume = value;
- soundEngine.SoundVolume = value;
+ soundEngine.Volume = value;
}
}
-
+
public static float MusicVolume
{
get { return musicVolume; }
- set {
+ set
+ {
musicVolume = value;
if (music != null)
music.Volume = value;
}
}
- public static void SeekMusic(uint delta)
- {
- if (music != null)
- {
- music.PlayPosition += delta;
- if (music.PlayPosition < 0 || music.PlayPosition > music.PlayLength)
- music.PlayPosition = 0;
- }
- }
+ //public static void SeekMusic(uint delta)
+ //{
+ // if (music != null)
+ // {
+ // music.PlayPosition += delta;
+ // if (music.PlayPosition < 0 || music.PlayPosition > music.PlayLength)
+ // music.PlayPosition = 0;
+ // }
+ //}
public static void PlayVoice(string phrase, Actor voicedUnit)
{
@@ -115,4 +110,91 @@ namespace OpenRa.Game
Play(clip + variant);
}
}
+
+ interface ISoundEngine
+ {
+ ISoundSource AddSoundSourceFromMemory(byte[] data, int channels, int sampleBits, int sampleRate);
+ ISound Play2D(ISoundSource sound, bool loop);
+ float Volume { get; set; }
+ }
+
+ interface ISoundSource {}
+ interface ISound
+ {
+ float Volume { get; set; }
+ }
+
+ class OpenAlSoundEngine : ISoundEngine
+ {
+ float volume = 1f;
+
+ public OpenAlSoundEngine()
+ {
+ var str = Alc.alcGetString(IntPtr.Zero, Alc.ALC_DEFAULT_DEVICE_SPECIFIER);
+ var dev = Alc.alcOpenDevice(str);
+ if (dev == IntPtr.Zero)
+ throw new InvalidOperationException("Can't create OpenAL device");
+ var ctx = Alc.alcCreateContext(dev, (int[]) null);
+ Alc.alcMakeContextCurrent(ctx);
+ }
+
+ public ISoundSource AddSoundSourceFromMemory(byte[] data, int channels, int sampleBits, int sampleRate)
+ {
+ return new OpenAlSoundSource(data, channels, sampleBits, sampleRate);
+ }
+
+ public ISound Play2D(ISoundSource sound, bool loop)
+ {
+ return new OpenAlSound((sound as OpenAlSoundSource).buffer, loop);
+ }
+
+ public float Volume
+ {
+ get { return volume; }
+ set { Al.alListenerf(Al.AL_GAIN, volume = value); }
+ }
+ }
+
+ class OpenAlSoundSource : ISoundSource
+ {
+ public readonly int buffer;
+
+ static int MakeALFormat(int channels, int bits)
+ {
+ if (channels == 1)
+ return bits == 16 ? Al.AL_FORMAT_MONO16 : Al.AL_FORMAT_MONO8;
+ else
+ return bits == 16 ? Al.AL_FORMAT_STEREO16 : Al.AL_FORMAT_STEREO8;
+ }
+
+ public OpenAlSoundSource(byte[] data, int channels, int sampleBits, int sampleRate)
+ {
+ Al.alGenBuffers(1, out buffer);
+ Al.alBufferData(buffer, MakeALFormat(channels, sampleBits), data, data.Length, sampleRate);
+ }
+ }
+
+ class OpenAlSound : ISound
+ {
+ public readonly int source;
+ float volume = 1f;
+
+ public OpenAlSound(int buffer, bool looping)
+ {
+ Al.alGenSources(1, out source);
+ Al.alSourcef(source, Al.AL_PITCH, 1f);
+ Al.alSourcef(source, Al.AL_GAIN, 1f);
+ Al.alSource3f(source, Al.AL_POSITION, 0f, 0f, 0f);
+ Al.alSource3f(source, Al.AL_VELOCITY, 0f, 0f, 0f);
+ Al.alSourcei(source, Al.AL_BUFFER, buffer);
+ Al.alSourcei(source, Al.AL_LOOPING, looping ? Al.AL_TRUE : Al.AL_FALSE);
+ Al.alSourcePlay(source);
+ }
+
+ public float Volume
+ {
+ get { return volume; }
+ set { Al.alSourcef(source, Al.AL_GAIN, volume = value); }
+ }
+ }
}
diff --git a/thirdparty/irrKlang.NET2.0.dll b/thirdparty/irrKlang.NET2.0.dll
deleted file mode 100644
index a558e4fb00..0000000000
Binary files a/thirdparty/irrKlang.NET2.0.dll and /dev/null differ
diff --git a/thirdparty/irrKlang.txt b/thirdparty/irrKlang.txt
deleted file mode 100644
index 92648dec0d..0000000000
--- a/thirdparty/irrKlang.txt
+++ /dev/null
@@ -1 +0,0 @@
-irrKlang library is from http://www.ambiera.com/irrklang/
\ No newline at end of file