diff --git a/OpenRA.Game/FileSystem/BagFile.cs b/OpenRA.Game/FileSystem/BagFile.cs index 351fa4ccd4..074b56024a 100644 --- a/OpenRA.Game/FileSystem/BagFile.cs +++ b/OpenRA.Game/FileSystem/BagFile.cs @@ -68,7 +68,7 @@ namespace OpenRA.FileSystem waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("WAVE")); waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("fmt ")); waveHeaderMemoryStream.Write(BitConverter.GetBytes(16)); - waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)WavReader.WaveType.Pcm)); + waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)1)); waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)channels)); waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.SampleRate)); waveHeaderMemoryStream.Write(BitConverter.GetBytes(2 * channels * entry.SampleRate)); @@ -90,7 +90,7 @@ namespace OpenRA.FileSystem waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("WAVE")); waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("fmt ")); waveHeaderMemoryStream.Write(BitConverter.GetBytes(20)); - waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)WavReader.WaveType.ImaAdpcm)); + waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)17)); waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)channels)); waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.SampleRate)); waveHeaderMemoryStream.Write(BitConverter.GetBytes(bytesPerSec)); diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 060a15d2ab..534f05ec3d 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -95,7 +95,6 @@ - @@ -266,13 +265,10 @@ - - - diff --git a/OpenRA.Mods.Common/AudioLoaders/AudLoader.cs b/OpenRA.Mods.Common/AudioLoaders/AudLoader.cs new file mode 100644 index 0000000000..5561f15400 --- /dev/null +++ b/OpenRA.Mods.Common/AudioLoaders/AudLoader.cs @@ -0,0 +1,88 @@ +#region Copyright & License Information +/* + * Copyright 2007-2016 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; +using System.IO; +using OpenRA.Mods.Common.FileFormats; + +namespace OpenRA.Mods.Common.AudioLoaders +{ + public class AudLoader : ISoundLoader + { + bool IsAud(Stream s) + { + var start = s.Position; + s.Position += 10; + var readFlag = s.ReadByte(); + var readFormat = s.ReadByte(); + s.Position = start; + + if (!Enum.IsDefined(typeof(SoundFlags), readFlag)) + return false; + + return Enum.IsDefined(typeof(SoundFormat), readFormat); + } + + bool ISoundLoader.TryParseSound(Stream stream, out ISoundFormat sound) + { + try + { + if (IsAud(stream)) + { + sound = new AudFormat(stream); + return true; + } + } + catch + { + // Not a supported AUD + } + + sound = null; + return false; + } + } + + public class AudFormat : ISoundFormat + { + public int Channels { get { return 1; } } + public int SampleBits { get { return 16; } } + public int SampleRate { get { return sampleRate; } } + public float LengthInSeconds { get { return AudReader.SoundLength(stream); } } + public Stream GetPCMInputStream() { return new MemoryStream(rawData.Value); } + + int sampleRate; + Lazy rawData; + + Stream stream; + + public AudFormat(Stream stream) + { + this.stream = stream; + + var position = stream.Position; + rawData = Exts.Lazy(() => + { + try + { + byte[] data; + if (!AudReader.LoadSound(stream, out data, out sampleRate)) + throw new InvalidDataException(); + return data; + } + finally + { + stream.Position = position; + } + }); + } + } +} diff --git a/OpenRA.Game/FileFormats/VocLoader.cs b/OpenRA.Mods.Common/AudioLoaders/VocLoader.cs similarity index 99% rename from OpenRA.Game/FileFormats/VocLoader.cs rename to OpenRA.Mods.Common/AudioLoaders/VocLoader.cs index e291d68bc8..142ad41069 100644 --- a/OpenRA.Game/FileFormats/VocLoader.cs +++ b/OpenRA.Mods.Common/AudioLoaders/VocLoader.cs @@ -14,7 +14,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; -namespace OpenRA.FileFormats +namespace OpenRA.Mods.Common.AudioLoaders { public class VocLoader : ISoundLoader { diff --git a/OpenRA.Mods.Common/AudioLoaders/WavLoader.cs b/OpenRA.Mods.Common/AudioLoaders/WavLoader.cs new file mode 100644 index 0000000000..e651c21083 --- /dev/null +++ b/OpenRA.Mods.Common/AudioLoaders/WavLoader.cs @@ -0,0 +1,85 @@ +#region Copyright & License Information +/* + * Copyright 2007-2016 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; +using System.IO; +using OpenRA.Mods.Common.FileFormats; + +namespace OpenRA.Mods.Common.AudioLoaders +{ + public class WavLoader : ISoundLoader + { + bool IsWave(Stream s) + { + var start = s.Position; + var type = s.ReadASCII(4); + s.Position += 4; + var format = s.ReadASCII(4); + s.Position = start; + + return type == "RIFF" && format == "WAVE"; + } + + bool ISoundLoader.TryParseSound(Stream stream, out ISoundFormat sound) + { + try + { + if (IsWave(stream)) + { + sound = new WavFormat(stream); + return true; + } + } + catch + { + // Not a (supported) WAV + } + + sound = null; + return false; + } + } + + public class WavFormat : ISoundFormat + { + public int Channels { get { return reader.Value.Channels; } } + public int SampleBits { get { return reader.Value.BitsPerSample; } } + public int SampleRate { get { return reader.Value.SampleRate; } } + public float LengthInSeconds { get { return WavReader.WaveLength(stream); } } + public Stream GetPCMInputStream() { return new MemoryStream(reader.Value.RawOutput); } + + Lazy reader; + + readonly Stream stream; + + public WavFormat(Stream stream) + { + this.stream = stream; + + var position = stream.Position; + reader = Exts.Lazy(() => + { + var wavReader = new WavReader(); + try + { + if (!wavReader.LoadSound(stream)) + throw new InvalidDataException(); + } + finally + { + stream.Position = position; + } + + return wavReader; + }); + } + } +} \ No newline at end of file diff --git a/OpenRA.Game/FileFormats/AudLoader.cs b/OpenRA.Mods.Common/FileFormats/AudReader.cs similarity index 74% rename from OpenRA.Game/FileFormats/AudLoader.cs rename to OpenRA.Mods.Common/FileFormats/AudReader.cs index 5ff08becd6..8e568fe4e2 100644 --- a/OpenRA.Game/FileFormats/AudLoader.cs +++ b/OpenRA.Mods.Common/FileFormats/AudReader.cs @@ -12,7 +12,7 @@ using System; using System.IO; -namespace OpenRA.FileFormats +namespace OpenRA.Mods.Common.FileFormats { [Flags] enum SoundFlags @@ -44,77 +44,6 @@ namespace OpenRA.FileFormats } } - public class AudLoader : ISoundLoader - { - bool IsAud(Stream s) - { - var start = s.Position; - s.Position += 10; - var readFlag = s.ReadByte(); - var readFormat = s.ReadByte(); - s.Position = start; - - if (!Enum.IsDefined(typeof(SoundFlags), readFlag)) - return false; - - return Enum.IsDefined(typeof(SoundFormat), readFormat); - } - - bool ISoundLoader.TryParseSound(Stream stream, out ISoundFormat sound) - { - try - { - if (IsAud(stream)) - { - sound = new AudFormat(stream); - return true; - } - } - catch - { - // Not a supported AUD - } - - sound = null; - return false; - } - } - - public class AudFormat : ISoundFormat - { - public int Channels { get { return 1; } } - public int SampleBits { get { return 16; } } - public int SampleRate { get { return sampleRate; } } - public float LengthInSeconds { get { return AudReader.SoundLength(stream); } } - public Stream GetPCMInputStream() { return new MemoryStream(rawData.Value); } - - int sampleRate; - Lazy rawData; - - Stream stream; - - public AudFormat(Stream stream) - { - this.stream = stream; - - var position = stream.Position; - rawData = Exts.Lazy(() => - { - try - { - byte[] data; - if (!AudReader.LoadSound(stream, out data, out sampleRate)) - throw new InvalidDataException(); - return data; - } - finally - { - stream.Position = position; - } - }); - } - } - public class AudReader { static readonly int[] IndexAdjust = { -1, -1, -1, -1, 2, 4, 6, 8 }; diff --git a/OpenRA.Game/FileFormats/ImaAdpcmLoader.cs b/OpenRA.Mods.Common/FileFormats/ImaAdpcmReader.cs similarity index 92% rename from OpenRA.Game/FileFormats/ImaAdpcmLoader.cs rename to OpenRA.Mods.Common/FileFormats/ImaAdpcmReader.cs index 3e110fbb70..7fb8c0a6a2 100644 --- a/OpenRA.Game/FileFormats/ImaAdpcmLoader.cs +++ b/OpenRA.Mods.Common/FileFormats/ImaAdpcmReader.cs @@ -11,7 +11,7 @@ using System.IO; -namespace OpenRA.FileFormats +namespace OpenRA.Mods.Common.FileFormats { struct ImaAdpcmChunk { @@ -29,7 +29,9 @@ namespace OpenRA.FileFormats } } - public static class ImaAdpcmLoader + // Mostly a duplicate of AudReader, with some difference when loading + // TODO: Investigate whether they can be fused to get rid of some duplication + public class ImaAdpcmReader { static readonly int[] IndexAdjust = { -1, -1, -1, -1, 2, 4, 6, 8 }; static readonly int[] StepTable = diff --git a/OpenRA.Game/FileFormats/WavLoader.cs b/OpenRA.Mods.Common/FileFormats/WavReader.cs similarity index 74% rename from OpenRA.Game/FileFormats/WavLoader.cs rename to OpenRA.Mods.Common/FileFormats/WavReader.cs index a5bbdc571a..1c3f5c2b38 100644 --- a/OpenRA.Game/FileFormats/WavLoader.cs +++ b/OpenRA.Mods.Common/FileFormats/WavReader.cs @@ -12,76 +12,8 @@ using System; using System.IO; -namespace OpenRA.FileFormats +namespace OpenRA.Mods.Common.FileFormats { - public class WavLoader : ISoundLoader - { - bool IsWave(Stream s) - { - var start = s.Position; - var type = s.ReadASCII(4); - s.Position += 4; - var format = s.ReadASCII(4); - s.Position = start; - - return type == "RIFF" && format == "WAVE"; - } - - bool ISoundLoader.TryParseSound(Stream stream, out ISoundFormat sound) - { - try - { - if (IsWave(stream)) - { - sound = new WavFormat(stream); - return true; - } - } - catch - { - // Not a (supported) WAV - } - - sound = null; - return false; - } - } - - public class WavFormat : ISoundFormat - { - public int Channels { get { return reader.Value.Channels; } } - public int SampleBits { get { return reader.Value.BitsPerSample; } } - public int SampleRate { get { return reader.Value.SampleRate; } } - public float LengthInSeconds { get { return WavReader.WaveLength(stream); } } - public Stream GetPCMInputStream() { return new MemoryStream(reader.Value.RawOutput); } - - Lazy reader; - - readonly Stream stream; - - public WavFormat(Stream stream) - { - this.stream = stream; - - var position = stream.Position; - reader = Exts.Lazy(() => - { - var wavReader = new WavReader(); - try - { - if (!wavReader.LoadSound(stream)) - throw new InvalidDataException(); - } - finally - { - stream.Position = position; - } - - return wavReader; - }); - } - } - public class WavReader { public int FileSize; @@ -220,7 +152,7 @@ namespace OpenRA.FileFormats { // Decode 4 bytes (to 16 bytes of output) per channel var chunk = s.ReadBytes(4); - var decoded = ImaAdpcmLoader.LoadImaAdpcmSound(chunk, ref index[c], ref predictor[c]); + var decoded = ImaAdpcmReader.LoadImaAdpcmSound(chunk, ref index[c], ref predictor[c]); // Interleave output, one sample per channel var outOffsetChannel = outOffset + (2 * c); @@ -245,4 +177,4 @@ namespace OpenRA.FileFormats return output; } } -} \ No newline at end of file +} diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index d9488d42f6..66c553c47d 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -146,6 +146,9 @@ + + + @@ -724,6 +727,9 @@ + + +