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.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 2024")]
[assembly: AssemblyDescription("A library to read and write WAV files")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0.0+228a79b7b5004de94827eb696b66b8be9f373255")]
[assembly: AssemblyProduct("WavLib")]
[assembly: AssemblyTitle("WavLib")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/SFGrenade/WavLib")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[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 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<string> loggingCallback = null)
{
BinaryReader br = new BinaryReader(stream);
if (!MainChunk.Parse(br))
{
return false;
}
bool gotFormat = false;
bool gotFact = false;
bool gotData = false;
Action<Chunk> 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.ReadBytes((int)(8 + nextChunk.Size));
}
};
while (br.BaseStream.Position != br.BaseStream.Length)
{
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<Format, IConverter> dictionary = new Dictionary<Format, IConverter>
{
{
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<string> 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.ReadBytes((int)(8 + chunk.Size));
}
}
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<float> list = new List<float>();
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<byte> _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<byte>(wavData.FormatChunk.ExtraParams, 6, 16);
}
}
public override float[] ConvertSamples(BinaryReader stream, int bytesPerSample)
{
List<float> list = new List<float>();
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<float> list = new List<float>();
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<float> list = new List<float>();
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<float> list = new List<float>();
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);
}
}
}