using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using Microsoft.CodeAnalysis; using WavLib.SampleConverters; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SFGrenade")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © SFGrenade 2026")] [assembly: AssemblyDescription("A library to read and write WAV files")] [assembly: AssemblyFileVersion("1.1.9")] [assembly: AssemblyInformationalVersion("1.1.9+87f86c748e07122251aea780e6a0cadc83edc072")] [assembly: AssemblyProduct("WavLib")] [assembly: AssemblyTitle("WavLib")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/SFGrenade/WavLib")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.9.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Microsoft.CodeAnalysis.Embedded] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Microsoft.CodeAnalysis.Embedded] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Microsoft.CodeAnalysis { [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace WavLib { public class Chunk { public string Id { get; private set; } public uint Size { get; protected set; } public Chunk(string id) { if (id.Length != 4) { throw new ArgumentException("ID has to have 4 characters!"); } Id = id; } public virtual bool Parse(BinaryReader stream) { bool result = BitConverter.ToUInt32(Encoding.ASCII.GetBytes(Id), 0) == stream.ReadUInt32(); Size = stream.ReadUInt32(); return result; } public static Chunk PeekInfo(BinaryReader stream) { Chunk result = new Chunk(" ") { Id = Encoding.ASCII.GetString(stream.ReadBytes(4)), Size = stream.ReadUInt32() }; stream.BaseStream.Seek(-8L, SeekOrigin.Current); return result; } } public class DataChunk : Chunk { private byte[] _samples; public byte[] Samples { get { return _samples; } set { _samples = value; base.Size = (uint)_samples.Length; } } public DataChunk() : base("data") { } public override bool Parse(BinaryReader stream) { if (!base.Parse(stream)) { return false; } _samples = stream.ReadBytes((int)base.Size); return true; } } public class FactChunk : Chunk { private uint _amountTotalSamples; public uint AmountTotalSamples { get { return _amountTotalSamples; } set { _amountTotalSamples = value; base.Size = 4u; } } public FactChunk() : base("fact") { } public override bool Parse(BinaryReader stream) { if (!base.Parse(stream)) { return false; } _amountTotalSamples = stream.ReadUInt32(); return true; } } public class FmtChunk : Chunk { private Format _audioFormat; private ushort _bitsPerSample; private byte[] _extraParams = new byte[0]; private ushort _extraParamSize; private ushort _numChannels; private uint _sampleRate; public Format AudioFormat { get { return _audioFormat; } set { _audioFormat = value; base.Size = 16u; if (_audioFormat != Format.Uncompressed) { base.Size += (uint)(2 + _extraParamSize); } } } public ushort NumChannels { get { return _numChannels; } set { _numChannels = value; ByteRate = (uint)(_numChannels * _sampleRate * (_bitsPerSample / 8)); BlockAlign = (ushort)(_numChannels * (_bitsPerSample / 8)); } } public uint SampleRate { get { return _sampleRate; } set { _sampleRate = value; ByteRate = (uint)(_numChannels * _sampleRate * (_bitsPerSample / 8)); } } public uint ByteRate { get; private set; } public ushort BlockAlign { get; private set; } public ushort BitsPerSample { get { return _bitsPerSample; } set { _bitsPerSample = value; ByteRate = (uint)(_numChannels * _sampleRate * (_bitsPerSample / 8)); BlockAlign = (ushort)(_numChannels * (_bitsPerSample / 8)); } } public ushort ExtraParamSize { get { return _extraParamSize; } set { _extraParamSize = value; byte[] extraParams = _extraParams; _extraParams = new byte[_extraParamSize]; Array.Copy(extraParams, _extraParams, extraParams.Length); for (int i = extraParams.Length; i < _extraParamSize; i++) { _extraParams[i] = 0; } base.Size = (uint)(18 + _extraParamSize); } } public byte[] ExtraParams { get { return _extraParams; } set { _extraParams = value; _extraParamSize = (ushort)_extraParams.Length; base.Size = (uint)(18 + _extraParamSize); } } public FmtChunk() : base("fmt ") { } public override bool Parse(BinaryReader stream) { if (!base.Parse(stream)) { return false; } _audioFormat = (Format)stream.ReadUInt16(); _numChannels = stream.ReadUInt16(); _sampleRate = stream.ReadUInt32(); ByteRate = stream.ReadUInt32(); BlockAlign = stream.ReadUInt16(); _bitsPerSample = stream.ReadUInt16(); if (AudioFormat == Format.Uncompressed && base.Size <= 16) { return true; } _extraParamSize = stream.ReadUInt16(); _extraParams = stream.ReadBytes(_extraParamSize); return true; } } public enum Format { Unknown = 0, Uncompressed = 1, Adpcm = 2, IeeeFloat = 3, Vselp = 4, IbmCvsd = 5, Alaw = 6, Mulaw = 7, Dts = 8, Drm = 9, Wmavoice9 = 10, Wmavoice10 = 11, OkiAdpcm = 16, DviAdpcm = 17, ImaAdpcm = 17, MediaspaceAdpcm = 18, SierraAdpcm = 19, G723Adpcm = 20, Digistd = 21, Digifix = 22, DialogicOkiAdpcm = 23, MediavisionAdpcm = 24, CuCodec = 25, HpDynVoice = 26, YamahaAdpcm = 32, Sonarc = 33, DspgroupTruespeech = 34, Echosc1 = 35, AudiofileAf36 = 36, Aptx = 37, AudiofileAf10 = 38, Prosody1612 = 39, Lrc = 40, DolbyAc2 = 48, Gsm610 = 49, Msnaudio = 50, AntexAdpcme = 51, ControlResVqlpc = 52, Digireal = 53, Digiadpcm = 54, ControlResCr10 = 55, NmsVbxadpcm = 56, CsImaadpcm = 57, Echosc3 = 58, RockwellAdpcm = 59, RockwellDigitalk = 60, Xebec = 61, G721Adpcm = 64, G728Celp = 65, Msg723 = 66, IntelG7231 = 67, IntelG729 = 68, SharpG726 = 69, Mpeg = 80, Rt24 = 82, Pac = 83, Mpeglayer3 = 85, LucentG723 = 89, Cirrus = 96, Espcm = 97, Voxware = 98, CanopusAtrac = 99, G726Adpcm = 100, G722Adpcm = 101, Dsat = 102, DsatDisplay = 103, VoxwareByteAligned = 105, VoxwareAc8 = 112, VoxwareAc10 = 113, VoxwareAc16 = 114, VoxwareAc20 = 115, VoxwareRt24 = 116, VoxwareRt29 = 117, VoxwareRt29Hw = 118, VoxwareVr12 = 119, VoxwareVr18 = 120, VoxwareTq40 = 121, VoxwareSc3 = 122, VoxwareSc31 = 123, Softsound = 128, VoxwareTq60 = 129, Msrt24 = 130, G729A = 131, MviMvi2 = 132, DfG726 = 133, DfGsm610 = 134, Isiaudio = 136, Onlive = 137, MultitudeFtSx20 = 138, InfocomItsG721Adpcm = 139, ConvediaG729 = 140, Congruency = 141, Sbc24 = 145, DolbyAc3Spdif = 146, MediasonicG723 = 147, Prosody8Kbps = 148, ZyxelAdpcm = 151, PhilipsLpcbb = 152, Packed = 153, MaldenPhonytalk = 160, RacalRecorderGsm = 161, RacalRecorderG720A = 162, RacalRecorderG7231 = 163, RacalRecorderTetraAcelp = 164, NecAac = 176, RawAac1 = 255, RhetorexAdpcm = 256, Irat = 257, VivoG723 = 273, VivoSiren = 274, PhilipsCelp = 288, PhilipsGrundig = 289, DigitalG723 = 291, SanyoLdAdpcm = 293, SiprolabAceplnet = 304, SiprolabAcelp4800 = 305, SiprolabAcelp8V3 = 306, SiprolabG729 = 307, SiprolabG729A = 308, SiprolabKelvin = 309, VoiceageAmr = 310, G726AdpcmAlt = 320, DictaphoneCelp68 = 321, DictaphoneCelp54 = 322, QualcommPurevoice = 336, QualcommHalfrate = 337, Tubgsm = 341, Msaudio1 = 352, Wmaudio2 = 353, Wmaudio3 = 354, WmaudioLossless = 355, Wmaspdif = 356, UnisysNapAdpcm = 368, UnisysNapUlaw = 369, UnisysNapAlaw = 370, UnisysNap16K = 371, SycomAcmSyc008 = 372, SycomAcmSyc701G726L = 373, SycomAcmSyc701Celp54 = 374, SycomAcmSyc701Celp68 = 375, KnowledgeAdventureAdpcm = 376, FraunhoferIisMpeg2Aac = 384, DtsDs = 400, CreativeAdpcm = 512, CreativeFastspeech8 = 514, CreativeFastspeech10 = 515, UherAdpcm = 528, UleadDvAudio = 533, UleadDvAudio1 = 534, Quarterdeck = 544, IlinkVc = 560, RawSport = 576, EsstAc3 = 577, GenericPassthru = 585, IpiHsx = 592, IpiRpelp = 593, Cs2 = 608, SonyScx = 624, SonyScy = 625, SonyAtrac3 = 626, SonySpc = 627, TelumAudio = 640, TelumIaAudio = 641, NorcomVoiceSystemsAdpcm = 645, FmTownsSnd = 768, Micronas = 848, MicronasCelp833 = 849, BtvDigital = 1024, IntelMusicCoder = 1025, IndeoAudio = 1026, QdesignMusic = 1104, On2Vp7Audio = 1280, On2Vp6Audio = 1281, VmeVmpcm = 1664, Tpc = 1665, LightwaveLossless = 2222, Oligsm = 4096, Oliadpcm = 4097, Olicelp = 4098, Olisbc = 4099, Oliopr = 4100, LhCodec = 4352, LhCodecCelp = 4353, LhCodecSbc8 = 4354, LhCodecSbc12 = 4355, LhCodecSbc16 = 4356, Norris = 5120, Isiaudio2 = 5121, SoundspaceMusicompress = 5376, MpegAdtsAac = 5632, MpegRawAac = 5633, MpegLoas = 5634, NokiaMpegAdtsAac = 5640, NokiaMpegRawAac = 5641, VodafoneMpegAdtsAac = 5642, VodafoneMpegRawAac = 5643, MpegHeaac = 5648, VoxwareRt24Speech = 6172, SonicfoundryLossless = 6513, InningsTelecomAdpcm = 6521, LucentSx8300P = 7175, LucentSx5363S = 7180, Cuseeme = 7939, NtcsoftAlf2CmAcm = 8132, Dvm = 8192, Dts2 = 8193, Makeavis = 13075, DivioMpeg4Aac = 16707, NokiaAdaptiveMultirate = 16897, DivioG726 = 16963, LeadSpeech = 17228, LeadVorbis = 22092, WavpackAudio = 22358, Alac = 27745, OggVorbisMode1 = 26447, OggVorbisMode2 = 26448, OggVorbisMode3 = 26449, OggVorbisMode1Plus = 26479, OggVorbisMode2Plus = 26480, OggVorbisMode3Plus = 26481, ThreecomNbx = 28672, Opus = 28751, FaadAac = 28781, AmrNb = 29537, AmrWb = 29538, AmrWp = 29539, GsmAmrCbr = 31265, GsmAmrVbrSid = 31266, ComverseInfosysG7231 = 41216, ComverseInfosysAvqsbc = 41217, ComverseInfosysSbc = 41218, SymbolG729A = 41219, VoiceageAmrWb = 41220, IngenientG726 = 41221, Mpeg4Aac = 41222, EncoreG726 = 41223, ZollAsao = 41224, SpeexVoice = 41225, VianixMasc = 41226, Wm9SpectrumAnalyzer = 41227, WmfSpectrumAnayzer = 41228, Gsm610Alt = 41229, Gsm620 = 41230, Gsm660 = 41231, Gsm690 = 41232, GsmAdaptiveMultirateWb = 41233, PolycomG722 = 41234, PolycomG728 = 41235, PolycomG729A = 41236, PolycomSiren = 41237, GlobalIpIlbc = 41238, RadiotimeTimeShiftRadio = 41239, NiceAca = 41240, NiceAdpcm = 41241, VocordG721 = 41242, VocordG726 = 41243, VocordG7221 = 41244, VocordG728 = 41245, VocordG729 = 41246, VocordG729A = 41247, VocordG7231 = 41248, VocordLbc = 41249, NiceG728 = 41250, FraceTelecomG729 = 41251, Codian = 41252, Flac = 61868, Extensible = 65534 } public class RiffChunk : Chunk { public static string Format => "WAVE"; public RiffChunk() : base("RIFF") { } public override bool Parse(BinaryReader stream) { if (!base.Parse(stream)) { return false; } return BitConverter.ToUInt32(Encoding.ASCII.GetBytes(Format), 0) == stream.ReadUInt32(); } } public class WavData { public RiffChunk MainChunk { get; } = new RiffChunk(); public FactChunk FactChunk { get; } = new FactChunk(); public FmtChunk FormatChunk { get; } = new FmtChunk(); public DataChunk SoundDataChunk { get; } = new DataChunk(); public bool Parse(Stream stream, Action loggingCallback = null) { BinaryReader br = new BinaryReader(stream); if (!MainChunk.Parse(br)) { return false; } bool gotFormat = false; bool gotFact = false; bool gotData = false; Action action = delegate(Chunk nextChunk) { if (nextChunk.Id == FormatChunk.Id) { gotFormat = true; loggingCallback?.Invoke("Reading format chunk"); FormatChunk.Parse(br); } else if (nextChunk.Id == FactChunk.Id) { gotFact = true; loggingCallback?.Invoke("Reading fact chunk"); FactChunk.Parse(br); } else if (nextChunk.Id == SoundDataChunk.Id) { gotData = true; loggingCallback?.Invoke("Reading data chunk"); SoundDataChunk.Parse(br); } else { loggingCallback?.Invoke($"Skipping chunk \"{nextChunk.Id}\" of size {nextChunk.Size}"); br.BaseStream.Seek(8 + nextChunk.Size, SeekOrigin.Current); } }; while (br.PeekChar() != -1) { Chunk obj = Chunk.PeekInfo(br); action(obj); } return gotFormat && gotData; } public float[] GetSamples() { int bytesPerSample = (int)Math.Ceiling((float)(int)FormatChunk.BitsPerSample / 8f); byte[] samples = SoundDataChunk.Samples; MemoryStream memoryStream = new MemoryStream(samples, 0, samples.Length, writable: false); BinaryReader binaryReader = new BinaryReader(memoryStream); float[] array = new float[0]; Dictionary dictionary = new Dictionary { { Format.Uncompressed, new UncompressedConverter(this) }, { Format.IeeeFloat, new IeeeFloatConverter(this) }, { Format.Alaw, new AlawConverter(this) }, { Format.Mulaw, new MulawConverter(this) }, { Format.Extensible, new ExtensibleConverter(this) } }; if (dictionary.ContainsKey(FormatChunk.AudioFormat)) { array = dictionary[FormatChunk.AudioFormat].ConvertSamples(binaryReader, bytesPerSample); binaryReader.Close(); memoryStream.Close(); return array; } throw new DataException($"Format \"{FormatChunk.AudioFormat}\" is currently not supported!"); } public static void Inspect(Stream stream, Action loggingCallback) { BinaryReader binaryReader = new BinaryReader(stream); new RiffChunk().Parse(binaryReader); while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length) { Chunk chunk = Chunk.PeekInfo(binaryReader); loggingCallback?.Invoke($"Chunk \"{chunk.Id}\" with size {chunk.Size}"); if (chunk.Size < 4095) { byte[] source = binaryReader.ReadBytes((int)(8 + chunk.Size)); loggingCallback?.Invoke("\tChunk data: " + string.Join(", ", source.Select((byte x) => x.ToString("x2")).ToArray())); } else { binaryReader.BaseStream.Seek(8 + chunk.Size, SeekOrigin.Current); } } binaryReader.BaseStream.Seek(0L, SeekOrigin.Begin); } } } namespace WavLib.SampleConverters { public class AlawConverter : BaseConverter { private static short AlawClip = 32635; private static readonly byte[] AlawSegment = new byte[128] { 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 }; private static readonly short[] Alaw2Lpcm = new short[256] { -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, -344, -328, -376, -360, -280, -264, -312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72, -120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136, -184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656, -752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816, -784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848 }; public AlawConverter(WavData wavData = null) : base(wavData) { } public override float[] ConvertSamples(BinaryReader stream, int bytesPerSample) { List list = new List(); while (stream.BaseStream.Position < stream.BaseStream.Length) { list.Add(ConvertSample(stream, bytesPerSample)); } return list.ToArray(); } private static float ConvertSample(BinaryReader stream, int bytesPerSample) { float num = 0f; float num2 = 1f; if (2 == bytesPerSample) { num = Alaw2Lpcm[stream.ReadByte()]; num2 = 32767f; } return num / num2; } } public abstract class BaseConverter : IConverter { protected WavData _wavData; public BaseConverter(WavData wavData = null) { _wavData = wavData; } public abstract float[] ConvertSamples(BinaryReader stream, int bytesPerSample); } public class ExtensibleConverter : BaseConverter { private uint _channelMask; private ArraySegment _guidInlcDataFormat; private ushort _validBitsPerSample; public ExtensibleConverter(WavData wavData = null) : base(wavData) { if (wavData.FormatChunk.ExtraParams.Length != 0) { _validBitsPerSample = BitConverter.ToUInt16(wavData.FormatChunk.ExtraParams, 0); _channelMask = BitConverter.ToUInt32(wavData.FormatChunk.ExtraParams, 2); _guidInlcDataFormat = new ArraySegment(wavData.FormatChunk.ExtraParams, 6, 16); } } public override float[] ConvertSamples(BinaryReader stream, int bytesPerSample) { List list = new List(); while (stream.BaseStream.Position < stream.BaseStream.Length) { stream.ReadByte(); list.Add(ConvertSample(stream, bytesPerSample)); } return list.ToArray(); } private static float ConvertSample(BinaryReader stream, int bytesPerSample) { double num = 0.0; double num2 = 1.0; if (1 == bytesPerSample) { num = 2.0 * ((double)(int)stream.ReadByte() / 255.0) - 1.0; num2 = 1.0; } else { num2 = Math.Pow(256.0, bytesPerSample) / 2.0; bool flag = false; for (uint num3 = 0u; num3 < bytesPerSample; num3++) { byte b = stream.ReadByte(); if (num3 == bytesPerSample - 1 && (b & 0x80) == 128) { flag = true; } } stream.BaseStream.Seek(-bytesPerSample, SeekOrigin.Current); num = 0.0; for (uint num4 = 0u; num4 < bytesPerSample; num4++) { byte b2 = stream.ReadByte(); if (flag) { b2 = (byte)(~b2); } num += (double)Math.Abs(b2) * Math.Pow(256.0, num4); } if (flag) { num = 0.0 - num - 1.0; } } return (float)(num / num2); } } public interface IConverter { float[] ConvertSamples(BinaryReader stream, int bytesPerSample); } public class IeeeFloatConverter : BaseConverter { public IeeeFloatConverter(WavData wavData = null) : base(wavData) { } public override float[] ConvertSamples(BinaryReader stream, int bytesPerSample) { List list = new List(); while (stream.BaseStream.Position < stream.BaseStream.Length) { list.Add(ConvertSample(stream, bytesPerSample)); } return list.ToArray(); } private static float ConvertSample(BinaryReader stream, int bytesPerSample) { if (4 == bytesPerSample) { return stream.ReadSingle(); } if (8 == bytesPerSample) { return (float)stream.ReadDouble(); } return 0f; } } public class MulawConverter : BaseConverter { private static short UlawBias = 132; private static short UlawClip = 32635; private static byte[] UlawSegment = new byte[256] { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 }; private static readonly short[] Ulaw2Lpcm = new short[256] { -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, -876, -844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524, -492, -460, -428, -396, -372, -356, -340, -324, -308, -292, -276, -260, -244, -228, -212, -196, -180, -164, -148, -132, -120, -112, -104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, 0, 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, 876, 844, 812, 780, 748, 716, 684, 652, 620, 588, 556, 524, 492, 460, 428, 396, 372, 356, 340, 324, 308, 292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0 }; public MulawConverter(WavData wavData = null) : base(wavData) { } public override float[] ConvertSamples(BinaryReader stream, int bytesPerSample) { List list = new List(); while (stream.BaseStream.Position < stream.BaseStream.Length) { list.Add(ConvertSample(stream, bytesPerSample)); } return list.ToArray(); } private static float ConvertSample(BinaryReader stream, int bytesPerSample) { float num = 0f; float num2 = 1f; if (2 == bytesPerSample) { num = Ulaw2Lpcm[stream.ReadByte()]; num2 = 32767f; } return num / num2; } } public class UncompressedConverter : BaseConverter { public UncompressedConverter(WavData wavData = null) : base(wavData) { } public override float[] ConvertSamples(BinaryReader stream, int bytesPerSample) { List list = new List(); while (stream.BaseStream.Position < stream.BaseStream.Length) { list.Add(ConvertSample(stream, bytesPerSample)); } return list.ToArray(); } private static float ConvertSample(BinaryReader stream, int bytesPerSample) { double num = 0.0; double num2 = 1.0; if (1 == bytesPerSample) { num = 2.0 * ((double)(int)stream.ReadByte() / 255.0) - 1.0; num2 = 1.0; } else { num2 = Math.Pow(256.0, bytesPerSample) / 2.0; bool flag = false; for (uint num3 = 0u; num3 < bytesPerSample; num3++) { byte b = stream.ReadByte(); if (num3 == bytesPerSample - 1 && (b & 0x80) == 128) { flag = true; } } stream.BaseStream.Seek(-bytesPerSample, SeekOrigin.Current); num = 0.0; for (uint num4 = 0u; num4 < bytesPerSample; num4++) { byte b2 = stream.ReadByte(); if (flag) { b2 = (byte)(~b2); } num += (double)Math.Abs(b2) * Math.Pow(256.0, num4); } if (flag) { num = 0.0 - num - 1.0; } } return (float)(num / num2); } } }