From 87b92b53a45697a4622c9df1c62e54f7275d7f87 Mon Sep 17 00:00:00 2001 From: penev92 Date: Tue, 4 Jan 2022 23:13:56 +0200 Subject: [PATCH] Reworked ISoundFormat.LengthInSeconds implementations --- OpenRA.Mods.Cnc/AudioLoaders/AudLoader.cs | 7 ++--- OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs | 2 +- OpenRA.Mods.Cnc/FileFormats/AudReader.cs | 30 ++++---------------- OpenRA.Mods.Common/AudioLoaders/Mp3Loader.cs | 8 +++--- OpenRA.Mods.Common/AudioLoaders/OggLoader.cs | 3 +- OpenRA.Mods.Common/AudioLoaders/WavLoader.cs | 7 ++--- OpenRA.Mods.Common/FileFormats/WavReader.cs | 23 ++------------- 7 files changed, 21 insertions(+), 59 deletions(-) diff --git a/OpenRA.Mods.Cnc/AudioLoaders/AudLoader.cs b/OpenRA.Mods.Cnc/AudioLoaders/AudLoader.cs index df7546461b..37d4df9309 100644 --- a/OpenRA.Mods.Cnc/AudioLoaders/AudLoader.cs +++ b/OpenRA.Mods.Cnc/AudioLoaders/AudLoader.cs @@ -52,7 +52,7 @@ namespace OpenRA.Mods.Cnc.AudioLoaders public int Channels => channels; public int SampleBits => sampleBits; public int SampleRate => sampleRate; - public float LengthInSeconds { get; } + public float LengthInSeconds => lengthInSeconds; public Stream GetPCMInputStream() { return audStreamFactory(); } public void Dispose() { sourceStream.Dispose(); } @@ -61,15 +61,14 @@ namespace OpenRA.Mods.Cnc.AudioLoaders readonly int channels; readonly int sampleBits; readonly int sampleRate; + readonly float lengthInSeconds; public AudFormat(Stream stream) { sourceStream = stream; - if (!AudReader.LoadSound(stream, out audStreamFactory, out sampleRate, out sampleBits, out channels)) + if (!AudReader.LoadSound(stream, out audStreamFactory, out sampleRate, out sampleBits, out channels, out lengthInSeconds)) throw new InvalidDataException(); - - LengthInSeconds = AudReader.SoundLength(sourceStream); } } } diff --git a/OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs b/OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs index 261bc79765..4867d012e5 100644 --- a/OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs +++ b/OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs @@ -40,7 +40,7 @@ namespace OpenRA.Mods.Cnc.AudioLoaders { public int SampleBits => 8; public int Channels => 1; - public int SampleRate { get; private set; } + public int SampleRate { get; } public float LengthInSeconds => (float)totalSamples / SampleRate; public Stream GetPCMInputStream() { return new VocStream(new VocFormat(this)); } public void Dispose() { stream.Dispose(); } diff --git a/OpenRA.Mods.Cnc/FileFormats/AudReader.cs b/OpenRA.Mods.Cnc/FileFormats/AudReader.cs index 292c020624..622ad3f18c 100644 --- a/OpenRA.Mods.Cnc/FileFormats/AudReader.cs +++ b/OpenRA.Mods.Cnc/FileFormats/AudReader.cs @@ -32,28 +32,7 @@ namespace OpenRA.Mods.Cnc.FileFormats public static class AudReader { - public static float SoundLength(Stream s) - { - var originalPosition = s.Position; - - var sampleRate = s.ReadUInt16(); - /*var dataSize = */ s.ReadInt32(); - var outputSize = s.ReadInt32(); - var flags = (SoundFlags)s.ReadByte(); - - var samples = outputSize; - if ((flags & SoundFlags.Stereo) != 0) - samples /= 2; - - if ((flags & SoundFlags._16Bit) != 0) - samples /= 2; - - s.Seek(originalPosition, SeekOrigin.Begin); - - return (float)samples / sampleRate; - } - - public static bool LoadSound(Stream s, out Func result, out int sampleRate, out int sampleBits, out int channels) + public static bool LoadSound(Stream s, out Func result, out int sampleRate, out int sampleBits, out int channels, out float lengthInSeconds) { result = null; var startPosition = s.Position; @@ -62,9 +41,10 @@ namespace OpenRA.Mods.Cnc.FileFormats sampleRate = s.ReadUInt16(); var dataSize = s.ReadInt32(); var outputSize = s.ReadInt32(); - var readFlag = s.ReadByte(); - sampleBits = (readFlag & (int)SoundFlags._16Bit) == 0 ? 8 : 16; - channels = (readFlag & (int)SoundFlags.Stereo) == 0 ? 1 : 2; + var audioFlags = (SoundFlags)s.ReadByte(); + sampleBits = (audioFlags & SoundFlags._16Bit) == 0 ? 8 : 16; + channels = (audioFlags & SoundFlags.Stereo) == 0 ? 1 : 2; + lengthInSeconds = (float)(outputSize * 8) / (channels * sampleBits * sampleRate); var readFormat = s.ReadByte(); if (!Enum.IsDefined(typeof(SoundFormat), readFormat)) diff --git a/OpenRA.Mods.Common/AudioLoaders/Mp3Loader.cs b/OpenRA.Mods.Common/AudioLoaders/Mp3Loader.cs index 745330bb43..0df368f9a4 100644 --- a/OpenRA.Mods.Common/AudioLoaders/Mp3Loader.cs +++ b/OpenRA.Mods.Common/AudioLoaders/Mp3Loader.cs @@ -37,10 +37,10 @@ namespace OpenRA.Mods.Common.AudioLoaders public sealed class Mp3Format : ISoundFormat { - public int Channels { get { return mp3.ChannelCount; } } - public int SampleBits { get { return 16; } } - public int SampleRate { get { return mp3.Frequency; } } - public float LengthInSeconds { get; private set; } + public int Channels => mp3.ChannelCount; + public int SampleBits => 16; + public int SampleRate => mp3.Frequency; + public float LengthInSeconds { get; } public Stream GetPCMInputStream() { return new MP3Stream(Clone(this)); } public void Dispose() { mp3.Dispose(); } diff --git a/OpenRA.Mods.Common/AudioLoaders/OggLoader.cs b/OpenRA.Mods.Common/AudioLoaders/OggLoader.cs index 9257326774..c4c11fe84a 100644 --- a/OpenRA.Mods.Common/AudioLoaders/OggLoader.cs +++ b/OpenRA.Mods.Common/AudioLoaders/OggLoader.cs @@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.AudioLoaders public int SampleBits => 16; public int Channels => reader.Channels; public int SampleRate => reader.SampleRate; - public float LengthInSeconds => (float)reader.TotalTime.TotalSeconds; + public float LengthInSeconds { get; } public Stream GetPCMInputStream() { return new OggStream(new OggFormat(this)); } public void Dispose() { reader.Dispose(); } @@ -51,6 +51,7 @@ namespace OpenRA.Mods.Common.AudioLoaders { this.stream = stream; reader = new VorbisReader(stream); + LengthInSeconds = (float) reader.TotalTime.TotalSeconds; } OggFormat(OggFormat cloneFrom) diff --git a/OpenRA.Mods.Common/AudioLoaders/WavLoader.cs b/OpenRA.Mods.Common/AudioLoaders/WavLoader.cs index 0e904b5ef5..54244e07e2 100644 --- a/OpenRA.Mods.Common/AudioLoaders/WavLoader.cs +++ b/OpenRA.Mods.Common/AudioLoaders/WavLoader.cs @@ -53,7 +53,7 @@ namespace OpenRA.Mods.Common.AudioLoaders public int Channels => channels; public int SampleBits => sampleBits; public int SampleRate => sampleRate; - public float LengthInSeconds { get; } + public float LengthInSeconds => lengthInSeconds; public Stream GetPCMInputStream() { return wavStreamFactory(); } public void Dispose() { sourceStream.Dispose(); } @@ -62,15 +62,14 @@ namespace OpenRA.Mods.Common.AudioLoaders readonly short channels; readonly int sampleBits; readonly int sampleRate; + readonly float lengthInSeconds; public WavFormat(Stream stream) { sourceStream = stream; - if (!WavReader.LoadSound(stream, out wavStreamFactory, out channels, out sampleBits, out sampleRate)) + if (!WavReader.LoadSound(stream, out wavStreamFactory, out channels, out sampleBits, out sampleRate, out lengthInSeconds)) throw new InvalidDataException(); - - LengthInSeconds = WavReader.WaveLength(sourceStream); } } } diff --git a/OpenRA.Mods.Common/FileFormats/WavReader.cs b/OpenRA.Mods.Common/FileFormats/WavReader.cs index 69cdb806c2..bc99e28c2c 100644 --- a/OpenRA.Mods.Common/FileFormats/WavReader.cs +++ b/OpenRA.Mods.Common/FileFormats/WavReader.cs @@ -20,12 +20,13 @@ namespace OpenRA.Mods.Common.FileFormats { enum WaveType { Pcm = 0x1, MsAdpcm = 0x2, ImaAdpcm = 0x11 } - public static bool LoadSound(Stream s, out Func result, out short channels, out int sampleBits, out int sampleRate) + public static bool LoadSound(Stream s, out Func result, out short channels, out int sampleBits, out int sampleRate, out float lengthInSeconds) { result = null; channels = -1; sampleBits = -1; sampleRate = -1; + lengthInSeconds = -1; var type = s.ReadASCII(4); if (type != "RIFF") @@ -65,6 +66,7 @@ namespace OpenRA.Mods.Common.FileFormats s.ReadInt32(); // Byte Rate blockAlign = s.ReadInt16(); sampleBits = s.ReadInt16(); + lengthInSeconds = (float)(s.Length * 8) / (channels * sampleRate * sampleBits); s.ReadBytes(fmtChunkSize - 16); break; case "fact": @@ -107,25 +109,6 @@ namespace OpenRA.Mods.Common.FileFormats return true; } - public static float WaveLength(Stream s) - { - s.Position = 12; - var fmt = s.ReadASCII(4); - - if (fmt != "fmt ") - return 0; - - s.Position = 22; - var channels = s.ReadInt16(); - var sampleRate = s.ReadInt32(); - - s.Position = 34; - var bitsPerSample = s.ReadInt16(); - var length = s.Length * 8; - - return (float)length / (channels * sampleRate * bitsPerSample); - } - sealed class WavStreamImaAdpcm : ReadOnlyAdapterStream { readonly short channels;