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)