diff --git a/OpenRA.FileFormats/FileFormats/WavLoader.cs b/OpenRA.FileFormats/FileFormats/WavLoader.cs
new file mode 100644
index 0000000000..42820cada5
--- /dev/null
+++ b/OpenRA.FileFormats/FileFormats/WavLoader.cs
@@ -0,0 +1,78 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2013 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. For more information,
+ * see COPYING.
+ */
+#endregion
+
+using System;
+using System.IO;
+using System.Text;
+
+namespace OpenRA.FileFormats
+{
+ public class WavLoader
+ {
+ public readonly int FileSize;
+ public readonly string Format;
+
+ public readonly int FmtChunkSize;
+ public readonly int AudioFormat;
+ public readonly int Channels;
+ public readonly int SampleRate;
+ public readonly int ByteRate;
+ public readonly int BlockAlign;
+ public readonly int BitsPerSample;
+
+ public readonly int DataSize;
+ public readonly byte[] RawOutput;
+
+ public readonly int ListChunkSize;
+
+ public WavLoader(Stream s)
+ {
+ while (s.Position < s.Length)
+ {
+ if ((s.Position & 1) == 1)
+ s.ReadByte(); // Alignment
+
+ var type = s.ReadASCII(4);
+ switch (type)
+ {
+ case "RIFF":
+ FileSize = s.ReadInt32();
+ Format = s.ReadASCII(4);
+ if (Format != "WAVE")
+ throw new NotSupportedException("Not a canonical WAVE file.");
+ break;
+ case "fmt ":
+ FmtChunkSize = s.ReadInt32();
+ if (FmtChunkSize != 16)
+ throw new NotSupportedException("{0} fmt chunk size is not a supported encoding scheme.".F(FmtChunkSize));
+ AudioFormat = s.ReadInt16();
+ if (AudioFormat != 1)
+ throw new NotSupportedException("Non-PCM compression is not supported.");
+ Channels = s.ReadInt16();
+ SampleRate = s.ReadInt32();
+ ByteRate = s.ReadInt32();
+ BlockAlign = s.ReadInt16();
+ BitsPerSample = s.ReadInt16();
+ break;
+ case "data":
+ DataSize = s.ReadInt32();
+ RawOutput = s.ReadBytes(DataSize);
+ break;
+ case "LIST":
+ ListChunkSize = s.ReadInt32();
+ s.ReadBytes(ListChunkSize); // Ignore annotation meta data.
+ break;
+ default:
+ throw new NotSupportedException("{0} chunks are not supported.".F(type));
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenRA.FileFormats/OpenRA.FileFormats.csproj b/OpenRA.FileFormats/OpenRA.FileFormats.csproj
index 1c4f6b8767..89b9dcb1ff 100644
--- a/OpenRA.FileFormats/OpenRA.FileFormats.csproj
+++ b/OpenRA.FileFormats/OpenRA.FileFormats.csproj
@@ -144,6 +144,7 @@
+
diff --git a/OpenRA.Game/Sound.cs b/OpenRA.Game/Sound.cs
index dc47dc0871..fda10c5e55 100644
--- a/OpenRA.Game/Sound.cs
+++ b/OpenRA.Game/Sound.cs
@@ -35,7 +35,15 @@ namespace OpenRA
return null;
}
- return LoadSoundRaw(AudLoader.LoadSound(FileSystem.Open(filename)));
+ if (filename.ToLowerInvariant().EndsWith("wav"))
+ return LoadWave(new WavLoader(FileSystem.Open(filename)));
+ else
+ return LoadSoundRaw(AudLoader.LoadSound(FileSystem.Open(filename)));
+ }
+
+ static ISoundSource LoadWave(WavLoader wave)
+ {
+ return soundEngine.AddSoundSourceFromMemory(wave.RawOutput, wave.Channels, wave.BitsPerSample, wave.SampleRate);
}
static ISoundSource LoadSoundRaw(byte[] rawData)