Files
OpenRA/OpenRA.Mods.Common/AudioLoaders/WavLoader.cs
penev92 abea3a0f74 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<Stream> 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 .
2022-01-09 18:40:32 +01:00

77 lines
1.8 KiB
C#

#region Copyright & License Information
/*
* Copyright 2007-2021 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 sealed class WavFormat : ISoundFormat
{
public int Channels => channels;
public int SampleBits => sampleBits;
public int SampleRate => sampleRate;
public float LengthInSeconds { get; }
public Stream GetPCMInputStream() { return wavStreamFactory(); }
public void Dispose() { sourceStream.Dispose(); }
readonly Stream sourceStream;
readonly Func<Stream> wavStreamFactory;
readonly short channels;
readonly int sampleBits;
readonly int sampleRate;
public WavFormat(Stream stream)
{
sourceStream = stream;
if (!WavReader.LoadSound(stream, out wavStreamFactory, out channels, out sampleBits, out sampleRate))
throw new InvalidDataException();
LengthInSeconds = WavReader.WaveLength(sourceStream);
}
}
}