From abea3a0f74fc921c5b9bb42ecc25345c65ac9e5e Mon Sep 17 00:00:00 2001 From: penev92 Date: Sun, 21 Feb 2021 15:10:59 +0200 Subject: [PATCH] Fixed AudFormat and WavFormat implementations of ISoundFormat.LengthInSeconds - Fixed a rounding issue in `WavReader.WaveLength()`. - Fixed `AudReader.SoundLength()` not resetting the stream position. - Fixed crashes caused by disposed streams because `LengthInSeconds` would try and calculate the length on the fly. It is now precalculated and cached (making it consistent across all 5 current `ISoundFormat` implementations). - Fixed a crash in `AudReader.LoadSound()`'s `out Func result` because that func would try and access the disposed stream's `Length` property. That works for `SegmentStream`, but not for `FileStream`. - Fixed frameCount/soundLength label positioning in the AssetBrowser window to avoid text clipping . --- OpenRA.Mods.Cnc/AudioLoaders/AudLoader.cs | 4 +++- OpenRA.Mods.Cnc/FileFormats/AudReader.cs | 8 +++++++- OpenRA.Mods.Common/AudioLoaders/WavLoader.cs | 4 +++- OpenRA.Mods.Common/FileFormats/WavReader.cs | 2 +- mods/cnc/chrome/assetbrowser.yaml | 2 +- mods/common/chrome/assetbrowser.yaml | 2 +- 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/OpenRA.Mods.Cnc/AudioLoaders/AudLoader.cs b/OpenRA.Mods.Cnc/AudioLoaders/AudLoader.cs index 1f6fe461bd..df7546461b 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 => AudReader.SoundLength(sourceStream); + public float LengthInSeconds { get; } public Stream GetPCMInputStream() { return audStreamFactory(); } public void Dispose() { sourceStream.Dispose(); } @@ -68,6 +68,8 @@ namespace OpenRA.Mods.Cnc.AudioLoaders if (!AudReader.LoadSound(stream, out audStreamFactory, out sampleRate, out sampleBits, out channels)) throw new InvalidDataException(); + + LengthInSeconds = AudReader.SoundLength(sourceStream); } } } diff --git a/OpenRA.Mods.Cnc/FileFormats/AudReader.cs b/OpenRA.Mods.Cnc/FileFormats/AudReader.cs index bac715bdd7..292c020624 100644 --- a/OpenRA.Mods.Cnc/FileFormats/AudReader.cs +++ b/OpenRA.Mods.Cnc/FileFormats/AudReader.cs @@ -34,6 +34,8 @@ namespace OpenRA.Mods.Cnc.FileFormats { public static float SoundLength(Stream s) { + var originalPosition = s.Position; + var sampleRate = s.ReadUInt16(); /*var dataSize = */ s.ReadInt32(); var outputSize = s.ReadInt32(); @@ -46,6 +48,8 @@ namespace OpenRA.Mods.Cnc.FileFormats if ((flags & SoundFlags._16Bit) != 0) samples /= 2; + s.Seek(originalPosition, SeekOrigin.Begin); + return (float)samples / sampleRate; } @@ -70,10 +74,12 @@ namespace OpenRA.Mods.Cnc.FileFormats throw new NotImplementedException(); var offsetPosition = s.Position; + var streamLength = s.Length; + var segmentLength = (int)(streamLength - offsetPosition); result = () => { - var audioStream = SegmentStream.CreateWithoutOwningStream(s, offsetPosition, (int)(s.Length - offsetPosition)); + var audioStream = SegmentStream.CreateWithoutOwningStream(s, offsetPosition, segmentLength); return new AudStream(audioStream, outputSize, dataSize); }; } diff --git a/OpenRA.Mods.Common/AudioLoaders/WavLoader.cs b/OpenRA.Mods.Common/AudioLoaders/WavLoader.cs index 7da4512dcb..0e904b5ef5 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 => WavReader.WaveLength(sourceStream); + public float LengthInSeconds { get; } public Stream GetPCMInputStream() { return wavStreamFactory(); } public void Dispose() { sourceStream.Dispose(); } @@ -69,6 +69,8 @@ namespace OpenRA.Mods.Common.AudioLoaders if (!WavReader.LoadSound(stream, out wavStreamFactory, out channels, out sampleBits, out sampleRate)) throw new InvalidDataException(); + + LengthInSeconds = WavReader.WaveLength(sourceStream); } } } diff --git a/OpenRA.Mods.Common/FileFormats/WavReader.cs b/OpenRA.Mods.Common/FileFormats/WavReader.cs index 05e0a812c4..69cdb806c2 100644 --- a/OpenRA.Mods.Common/FileFormats/WavReader.cs +++ b/OpenRA.Mods.Common/FileFormats/WavReader.cs @@ -123,7 +123,7 @@ namespace OpenRA.Mods.Common.FileFormats var bitsPerSample = s.ReadInt16(); var length = s.Length * 8; - return length / (channels * sampleRate * bitsPerSample); + return (float)length / (channels * sampleRate * bitsPerSample); } sealed class WavStreamImaAdpcm : ReadOnlyAdapterStream diff --git a/mods/cnc/chrome/assetbrowser.yaml b/mods/cnc/chrome/assetbrowser.yaml index 75b9e4647d..bf22757de8 100644 --- a/mods/cnc/chrome/assetbrowser.yaml +++ b/mods/cnc/chrome/assetbrowser.yaml @@ -190,7 +190,7 @@ Container@ASSETBROWSER_PANEL: MinimumValue: 0 Label@FRAME_COUNT: X: PARENT_RIGHT - WIDTH + 5 - Y: 1 + Y: 0 Width: 80 Height: 25 Font: TinyBold diff --git a/mods/common/chrome/assetbrowser.yaml b/mods/common/chrome/assetbrowser.yaml index 5b35b85024..1852ec51a4 100644 --- a/mods/common/chrome/assetbrowser.yaml +++ b/mods/common/chrome/assetbrowser.yaml @@ -180,7 +180,7 @@ Background@ASSETBROWSER_PANEL: MinimumValue: 0 Label@FRAME_COUNT: X: PARENT_RIGHT - WIDTH + 5 - Y: 1 + Y: 0 Width: 85 Height: 25 Font: TinyBold