Decompiled source of ShinMegamiTenseiOSTMix v1.8.1

NAudio.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;
using NAudio.CoreAudioApi;
using NAudio.CoreAudioApi.Interfaces;
using NAudio.Dmo;
using NAudio.Dsp;
using NAudio.FileFormats.Wav;
using NAudio.MediaFoundation;
using NAudio.Mixer;
using NAudio.Utils;
using NAudio.Wave;
using NAudio.Wave.Asio;
using NAudio.Wave.Compression;
using NAudio.Wave.SampleProviders;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("NAudio")]
[assembly: AssemblyDescription("NAudio .NET Audio Library")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Mark Heath")]
[assembly: AssemblyProduct("NAudio")]
[assembly: AssemblyCopyright("© 2001-2017 Mark Heath")]
[assembly: AssemblyTrademark("")]
[assembly: InternalsVisibleTo("NAudioTests")]
[assembly: ComVisible(false)]
[assembly: Guid("e82fa7f0-f952-4d93-b7b0-392bbf53b2a4")]
[assembly: AssemblyFileVersion("1.8.4.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.8.4.0")]
[module: UnverifiableCode]
namespace NAudio
{
	public enum Manufacturers
	{
		Microsoft = 1,
		Creative = 2,
		Mediavision = 3,
		Fujitsu = 4,
		Artisoft = 20,
		TurtleBeach = 21,
		Ibm = 22,
		Vocaltec = 23,
		Roland = 24,
		DspSolutions = 25,
		Nec = 26,
		Ati = 27,
		Wanglabs = 28,
		Tandy = 29,
		Voyetra = 30,
		Antex = 31,
		IclPS = 32,
		Intel = 33,
		Gravis = 34,
		Val = 35,
		Interactive = 36,
		Yamaha = 37,
		Everex = 38,
		Echo = 39,
		Sierra = 40,
		Cat = 41,
		Apps = 42,
		DspGroup = 43,
		Melabs = 44,
		ComputerFriends = 45,
		Ess = 46,
		Audiofile = 47,
		Motorola = 48,
		Canopus = 49,
		Epson = 50,
		Truevision = 51,
		Aztech = 52,
		Videologic = 53,
		Scalacs = 54,
		Korg = 55,
		Apt = 56,
		Ics = 57,
		Iteratedsys = 58,
		Metheus = 59,
		Logitech = 60,
		Winnov = 61,
		Ncr = 62,
		Exan = 63,
		Ast = 64,
		Willowpond = 65,
		Sonicfoundry = 66,
		Vitec = 67,
		Moscom = 68,
		Siliconsoft = 69,
		Supermac = 73,
		Audiopt = 74,
		Speechcomp = 76,
		Ahead = 77,
		Dolby = 78,
		Oki = 79,
		Auravision = 80,
		Olivetti = 81,
		Iomagic = 82,
		Matsushita = 83,
		Controlres = 84,
		Xebec = 85,
		Newmedia = 86,
		Nms = 87,
		Lyrrus = 88,
		Compusic = 89,
		Opti = 90,
		Adlacc = 91,
		Compaq = 92,
		Dialogic = 93,
		Insoft = 94,
		Mptus = 95,
		Weitek = 96,
		LernoutAndHauspie = 97,
		Qciar = 98,
		Apple = 99,
		Digital = 100,
		Motu = 101,
		Workbit = 102,
		Ositech = 103,
		Miro = 104,
		Cirruslogic = 105,
		Isolution = 106,
		Horizons = 107,
		Concepts = 108,
		Vtg = 109,
		Radius = 110,
		Rockwell = 111,
		Xyz = 112,
		Opcode = 113,
		Voxware = 114,
		NorthernTelecom = 115,
		Apicom = 116,
		Grande = 117,
		Addx = 118,
		Wildcat = 119,
		Rhetorex = 120,
		Brooktree = 121,
		Ensoniq = 125,
		Fast = 126,
		Nvidia = 127,
		Oksori = 128,
		Diacoustics = 129,
		Gulbransen = 130,
		KayElemetrics = 131,
		Crystal = 132,
		SplashStudios = 133,
		Quarterdeck = 134,
		Tdk = 135,
		DigitalAudioLabs = 136,
		Seersys = 137,
		Picturetel = 138,
		AttMicroelectronics = 139,
		Osprey = 140,
		Mediatrix = 141,
		Soundesigns = 142,
		Aldigital = 143,
		SpectrumSignalProcessing = 144,
		Ecs = 145,
		Amd = 146,
		Coredynamics = 147,
		Canam = 148,
		Softsound = 149,
		Norris = 150,
		Ddd = 151,
		Euphonics = 152,
		Precept = 153,
		CrystalNet = 154,
		Chromatic = 155,
		Voiceinfo = 156,
		Viennasys = 157,
		Connectix = 158,
		Gadgetlabs = 159,
		Frontier = 160,
		Viona = 161,
		Casio = 162,
		Diamondmm = 163,
		S3 = 164,
		FraunhoferIis = 172
	}
	public class MmException : Exception
	{
		private MmResult result;

		private string function;

		public MmResult Result => result;

		public MmException(MmResult result, string function)
			: base(ErrorMessage(result, function))
		{
			this.result = result;
			this.function = function;
		}

		private static string ErrorMessage(MmResult result, string function)
		{
			return $"{result} calling {function}";
		}

		public static void Try(MmResult result, string function)
		{
			if (result != 0)
			{
				throw new MmException(result, function);
			}
		}
	}
	public enum MmResult
	{
		NoError = 0,
		UnspecifiedError = 1,
		BadDeviceId = 2,
		NotEnabled = 3,
		AlreadyAllocated = 4,
		InvalidHandle = 5,
		NoDriver = 6,
		MemoryAllocationError = 7,
		NotSupported = 8,
		BadErrorNumber = 9,
		InvalidFlag = 10,
		InvalidParameter = 11,
		HandleBusy = 12,
		InvalidAlias = 13,
		BadRegistryDatabase = 14,
		RegistryKeyNotFound = 15,
		RegistryReadError = 16,
		RegistryWriteError = 17,
		RegistryDeleteError = 18,
		RegistryValueNotFound = 19,
		NoDriverCallback = 20,
		MoreData = 21,
		WaveBadFormat = 32,
		WaveStillPlaying = 33,
		WaveHeaderUnprepared = 34,
		WaveSync = 35,
		AcmNotPossible = 512,
		AcmBusy = 513,
		AcmHeaderUnprepared = 514,
		AcmCancelled = 515,
		MixerInvalidLine = 1024,
		MixerInvalidControl = 1025,
		MixerInvalidValue = 1026
	}
}
namespace NAudio.Mixer
{
	public class BooleanMixerControl : MixerControl
	{
		private MixerInterop.MIXERCONTROLDETAILS_BOOLEAN boolDetails;

		public bool Value
		{
			get
			{
				GetControlDetails();
				return boolDetails.fValue == 1;
			}
			set
			{
				boolDetails.fValue = (value ? 1 : 0);
				mixerControlDetails.paDetails = Marshal.AllocHGlobal(Marshal.SizeOf((object)boolDetails));
				Marshal.StructureToPtr((object)boolDetails, mixerControlDetails.paDetails, fDeleteOld: false);
				MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails");
				Marshal.FreeHGlobal(mixerControlDetails.paDetails);
			}
		}

		internal BooleanMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels)
		{
			base.mixerControl = mixerControl;
			base.mixerHandle = mixerHandle;
			base.mixerHandleType = mixerHandleType;
			base.nChannels = nChannels;
			mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS);
			GetControlDetails();
		}

		protected override void GetDetails(IntPtr pDetails)
		{
			boolDetails = (MixerInterop.MIXERCONTROLDETAILS_BOOLEAN)Marshal.PtrToStructure(pDetails, typeof(MixerInterop.MIXERCONTROLDETAILS_BOOLEAN));
		}
	}
	public class CustomMixerControl : MixerControl
	{
		internal CustomMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels)
		{
			base.mixerControl = mixerControl;
			base.mixerHandle = mixerHandle;
			base.mixerHandleType = mixerHandleType;
			base.nChannels = nChannels;
			mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS);
			GetControlDetails();
		}

		protected override void GetDetails(IntPtr pDetails)
		{
		}
	}
	public class ListTextMixerControl : MixerControl
	{
		internal ListTextMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels)
		{
			base.mixerControl = mixerControl;
			base.mixerHandle = mixerHandle;
			base.mixerHandleType = mixerHandleType;
			base.nChannels = nChannels;
			mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS);
			GetControlDetails();
		}

		protected override void GetDetails(IntPtr pDetails)
		{
		}
	}
	public class Mixer
	{
		private MixerInterop.MIXERCAPS caps;

		private IntPtr mixerHandle;

		private MixerFlags mixerHandleType;

		public static int NumberOfDevices => MixerInterop.mixerGetNumDevs();

		public int DestinationCount => (int)caps.cDestinations;

		public string Name => caps.szPname;

		public Manufacturers Manufacturer => (Manufacturers)caps.wMid;

		public int ProductID => caps.wPid;

		public IEnumerable<MixerLine> Destinations
		{
			get
			{
				for (int destination = 0; destination < DestinationCount; destination++)
				{
					yield return GetDestination(destination);
				}
			}
		}

		public static IEnumerable<Mixer> Mixers
		{
			get
			{
				for (int device = 0; device < NumberOfDevices; device++)
				{
					yield return new Mixer(device);
				}
			}
		}

		public Mixer(int mixerIndex)
		{
			if (mixerIndex < 0 || mixerIndex >= NumberOfDevices)
			{
				throw new ArgumentOutOfRangeException("mixerID");
			}
			caps = default(MixerInterop.MIXERCAPS);
			MmException.Try(MixerInterop.mixerGetDevCaps((IntPtr)mixerIndex, ref caps, Marshal.SizeOf((object)caps)), "mixerGetDevCaps");
			mixerHandle = (IntPtr)mixerIndex;
			mixerHandleType = MixerFlags.Mixer;
		}

		public MixerLine GetDestination(int destinationIndex)
		{
			if (destinationIndex < 0 || destinationIndex >= DestinationCount)
			{
				throw new ArgumentOutOfRangeException("destinationIndex");
			}
			return new MixerLine(mixerHandle, destinationIndex, mixerHandleType);
		}
	}
	public abstract class MixerControl
	{
		internal MixerInterop.MIXERCONTROL mixerControl;

		internal MixerInterop.MIXERCONTROLDETAILS mixerControlDetails;

		protected IntPtr mixerHandle;

		protected int nChannels;

		protected MixerFlags mixerHandleType;

		public string Name => mixerControl.szName;

		public MixerControlType ControlType => mixerControl.dwControlType;

		public bool IsBoolean => IsControlBoolean(mixerControl.dwControlType);

		public bool IsListText => IsControlListText(mixerControl.dwControlType);

		public bool IsSigned => IsControlSigned(mixerControl.dwControlType);

		public bool IsUnsigned => IsControlUnsigned(mixerControl.dwControlType);

		public bool IsCustom => IsControlCustom(mixerControl.dwControlType);

		public static IList<MixerControl> GetMixerControls(IntPtr mixerHandle, MixerLine mixerLine, MixerFlags mixerHandleType)
		{
			List<MixerControl> list = new List<MixerControl>();
			if (mixerLine.ControlsCount > 0)
			{
				int num = Marshal.SizeOf(typeof(MixerInterop.MIXERCONTROL));
				MixerInterop.MIXERLINECONTROLS mixerLineControls = default(MixerInterop.MIXERLINECONTROLS);
				IntPtr intPtr = Marshal.AllocHGlobal(num * mixerLine.ControlsCount);
				mixerLineControls.cbStruct = Marshal.SizeOf((object)mixerLineControls);
				mixerLineControls.dwLineID = mixerLine.LineId;
				mixerLineControls.cControls = mixerLine.ControlsCount;
				mixerLineControls.pamxctrl = intPtr;
				mixerLineControls.cbmxctrl = Marshal.SizeOf(typeof(MixerInterop.MIXERCONTROL));
				try
				{
					MmResult mmResult = MixerInterop.mixerGetLineControls(mixerHandle, ref mixerLineControls, MixerFlags.Mixer | mixerHandleType);
					if (mmResult != 0)
					{
						throw new MmException(mmResult, "mixerGetLineControls");
					}
					for (int i = 0; i < mixerLineControls.cControls; i++)
					{
						MixerInterop.MIXERCONTROL mIXERCONTROL = (MixerInterop.MIXERCONTROL)Marshal.PtrToStructure((IntPtr)(intPtr.ToInt64() + num * i), typeof(MixerInterop.MIXERCONTROL));
						MixerControl item = GetMixerControl(mixerHandle, mixerLine.LineId, mIXERCONTROL.dwControlID, mixerLine.Channels, mixerHandleType);
						list.Add(item);
					}
				}
				finally
				{
					Marshal.FreeHGlobal(intPtr);
				}
			}
			return list;
		}

		public static MixerControl GetMixerControl(IntPtr mixerHandle, int nLineID, int controlId, int nChannels, MixerFlags mixerFlags)
		{
			MixerInterop.MIXERLINECONTROLS mixerLineControls = default(MixerInterop.MIXERLINECONTROLS);
			MixerInterop.MIXERCONTROL mIXERCONTROL = default(MixerInterop.MIXERCONTROL);
			IntPtr intPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf((object)mIXERCONTROL));
			mixerLineControls.cbStruct = Marshal.SizeOf((object)mixerLineControls);
			mixerLineControls.cControls = 1;
			mixerLineControls.dwControlID = controlId;
			mixerLineControls.cbmxctrl = Marshal.SizeOf((object)mIXERCONTROL);
			mixerLineControls.pamxctrl = intPtr;
			mixerLineControls.dwLineID = nLineID;
			MmResult mmResult = MixerInterop.mixerGetLineControls(mixerHandle, ref mixerLineControls, MixerFlags.ListText | mixerFlags);
			if (mmResult != 0)
			{
				Marshal.FreeCoTaskMem(intPtr);
				throw new MmException(mmResult, "mixerGetLineControls");
			}
			mIXERCONTROL = (MixerInterop.MIXERCONTROL)Marshal.PtrToStructure(mixerLineControls.pamxctrl, typeof(MixerInterop.MIXERCONTROL));
			Marshal.FreeCoTaskMem(intPtr);
			if (IsControlBoolean(mIXERCONTROL.dwControlType))
			{
				return new BooleanMixerControl(mIXERCONTROL, mixerHandle, mixerFlags, nChannels);
			}
			if (IsControlSigned(mIXERCONTROL.dwControlType))
			{
				return new SignedMixerControl(mIXERCONTROL, mixerHandle, mixerFlags, nChannels);
			}
			if (IsControlUnsigned(mIXERCONTROL.dwControlType))
			{
				return new UnsignedMixerControl(mIXERCONTROL, mixerHandle, mixerFlags, nChannels);
			}
			if (IsControlListText(mIXERCONTROL.dwControlType))
			{
				return new ListTextMixerControl(mIXERCONTROL, mixerHandle, mixerFlags, nChannels);
			}
			if (IsControlCustom(mIXERCONTROL.dwControlType))
			{
				return new CustomMixerControl(mIXERCONTROL, mixerHandle, mixerFlags, nChannels);
			}
			throw new InvalidOperationException($"Unknown mixer control type {mIXERCONTROL.dwControlType}");
		}

		protected void GetControlDetails()
		{
			mixerControlDetails.cbStruct = Marshal.SizeOf((object)mixerControlDetails);
			mixerControlDetails.dwControlID = mixerControl.dwControlID;
			if (IsCustom)
			{
				mixerControlDetails.cChannels = 0;
			}
			else if ((mixerControl.fdwControl & (true ? 1u : 0u)) != 0)
			{
				mixerControlDetails.cChannels = 1;
			}
			else
			{
				mixerControlDetails.cChannels = nChannels;
			}
			if ((mixerControl.fdwControl & 2u) != 0)
			{
				mixerControlDetails.hwndOwner = (IntPtr)mixerControl.cMultipleItems;
			}
			else if (IsCustom)
			{
				mixerControlDetails.hwndOwner = IntPtr.Zero;
			}
			else
			{
				mixerControlDetails.hwndOwner = IntPtr.Zero;
			}
			if (IsBoolean)
			{
				mixerControlDetails.cbDetails = Marshal.SizeOf((object)default(MixerInterop.MIXERCONTROLDETAILS_BOOLEAN));
			}
			else if (IsListText)
			{
				mixerControlDetails.cbDetails = Marshal.SizeOf((object)default(MixerInterop.MIXERCONTROLDETAILS_LISTTEXT));
			}
			else if (IsSigned)
			{
				mixerControlDetails.cbDetails = Marshal.SizeOf((object)default(MixerInterop.MIXERCONTROLDETAILS_SIGNED));
			}
			else if (IsUnsigned)
			{
				mixerControlDetails.cbDetails = Marshal.SizeOf((object)default(MixerInterop.MIXERCONTROLDETAILS_UNSIGNED));
			}
			else
			{
				mixerControlDetails.cbDetails = mixerControl.Metrics.customData;
			}
			int num = mixerControlDetails.cbDetails * mixerControlDetails.cChannels;
			if ((mixerControl.fdwControl & 2u) != 0)
			{
				num *= (int)mixerControl.cMultipleItems;
			}
			IntPtr intPtr = Marshal.AllocCoTaskMem(num);
			mixerControlDetails.paDetails = intPtr;
			MmResult mmResult = MixerInterop.mixerGetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType);
			if (mmResult == MmResult.NoError)
			{
				GetDetails(mixerControlDetails.paDetails);
			}
			Marshal.FreeCoTaskMem(intPtr);
			if (mmResult != 0)
			{
				throw new MmException(mmResult, "mixerGetControlDetails");
			}
		}

		protected abstract void GetDetails(IntPtr pDetails);

		private static bool IsControlBoolean(MixerControlType controlType)
		{
			switch (controlType)
			{
			case MixerControlType.BooleanMeter:
			case MixerControlType.Boolean:
			case MixerControlType.OnOff:
			case MixerControlType.Mute:
			case MixerControlType.Mono:
			case MixerControlType.Loudness:
			case MixerControlType.StereoEnhance:
			case MixerControlType.Button:
			case MixerControlType.SingleSelect:
			case MixerControlType.Mux:
			case MixerControlType.MultipleSelect:
			case MixerControlType.Mixer:
				return true;
			default:
				return false;
			}
		}

		private static bool IsControlListText(MixerControlType controlType)
		{
			if (controlType == MixerControlType.Equalizer || (uint)(controlType - 1879113728) <= 1u || (uint)(controlType - 1895890944) <= 1u)
			{
				return true;
			}
			return false;
		}

		private static bool IsControlSigned(MixerControlType controlType)
		{
			switch (controlType)
			{
			case MixerControlType.SignedMeter:
			case MixerControlType.PeakMeter:
			case MixerControlType.Signed:
			case MixerControlType.Decibels:
			case MixerControlType.Slider:
			case MixerControlType.Pan:
			case MixerControlType.QSoundPan:
				return true;
			default:
				return false;
			}
		}

		private static bool IsControlUnsigned(MixerControlType controlType)
		{
			switch (controlType)
			{
			case MixerControlType.UnsignedMeter:
			case MixerControlType.Unsigned:
			case MixerControlType.Percent:
			case MixerControlType.Fader:
			case MixerControlType.Volume:
			case MixerControlType.Bass:
			case MixerControlType.Treble:
			case MixerControlType.Equalizer:
			case MixerControlType.MicroTime:
			case MixerControlType.MilliTime:
				return true;
			default:
				return false;
			}
		}

		private static bool IsControlCustom(MixerControlType controlType)
		{
			return controlType == MixerControlType.Custom;
		}

		public override string ToString()
		{
			return $"{Name} {ControlType}";
		}
	}
	[Flags]
	internal enum MixerControlClass
	{
		Custom = 0,
		Meter = 0x10000000,
		Switch = 0x20000000,
		Number = 0x30000000,
		Slider = 0x40000000,
		Fader = 0x50000000,
		Time = 0x60000000,
		List = 0x70000000,
		Mask = 0x70000000
	}
	[Flags]
	internal enum MixerControlSubclass
	{
		SwitchBoolean = 0,
		SwitchButton = 0x1000000,
		MeterPolled = 0,
		TimeMicrosecs = 0,
		TimeMillisecs = 0x1000000,
		ListSingle = 0,
		ListMultiple = 0x1000000,
		Mask = 0xF000000
	}
	[Flags]
	internal enum MixerControlUnits
	{
		Custom = 0,
		Boolean = 0x10000,
		Signed = 0x20000,
		Unsigned = 0x30000,
		Decibels = 0x40000,
		Percent = 0x50000,
		Mask = 0xFF0000
	}
	public enum MixerControlType
	{
		Custom = 0,
		BooleanMeter = 268500992,
		SignedMeter = 268566528,
		PeakMeter = 268566529,
		UnsignedMeter = 268632064,
		Boolean = 536936448,
		OnOff = 536936449,
		Mute = 536936450,
		Mono = 536936451,
		Loudness = 536936452,
		StereoEnhance = 536936453,
		Button = 553713664,
		Decibels = 805568512,
		Signed = 805437440,
		Unsigned = 805502976,
		Percent = 805634048,
		Slider = 1073872896,
		Pan = 1073872897,
		QSoundPan = 1073872898,
		Fader = 1342373888,
		Volume = 1342373889,
		Bass = 1342373890,
		Treble = 1342373891,
		Equalizer = 1342373892,
		SingleSelect = 1879113728,
		Mux = 1879113729,
		MultipleSelect = 1895890944,
		Mixer = 1895890945,
		MicroTime = 1610809344,
		MilliTime = 1627586560
	}
	public class MixerLine
	{
		private MixerInterop.MIXERLINE mixerLine;

		private IntPtr mixerHandle;

		private MixerFlags mixerHandleType;

		public string Name => mixerLine.szName;

		public string ShortName => mixerLine.szShortName;

		public int LineId => mixerLine.dwLineID;

		public MixerLineComponentType ComponentType => mixerLine.dwComponentType;

		public string TypeDescription => mixerLine.dwComponentType switch
		{
			MixerLineComponentType.DestinationUndefined => "Undefined Destination", 
			MixerLineComponentType.DestinationDigital => "Digital Destination", 
			MixerLineComponentType.DestinationLine => "Line Level Destination", 
			MixerLineComponentType.DestinationMonitor => "Monitor Destination", 
			MixerLineComponentType.DestinationSpeakers => "Speakers Destination", 
			MixerLineComponentType.DestinationHeadphones => "Headphones Destination", 
			MixerLineComponentType.DestinationTelephone => "Telephone Destination", 
			MixerLineComponentType.DestinationWaveIn => "Wave Input Destination", 
			MixerLineComponentType.DestinationVoiceIn => "Voice Recognition Destination", 
			MixerLineComponentType.SourceUndefined => "Undefined Source", 
			MixerLineComponentType.SourceDigital => "Digital Source", 
			MixerLineComponentType.SourceLine => "Line Level Source", 
			MixerLineComponentType.SourceMicrophone => "Microphone Source", 
			MixerLineComponentType.SourceSynthesizer => "Synthesizer Source", 
			MixerLineComponentType.SourceCompactDisc => "Compact Disk Source", 
			MixerLineComponentType.SourceTelephone => "Telephone Source", 
			MixerLineComponentType.SourcePcSpeaker => "PC Speaker Source", 
			MixerLineComponentType.SourceWaveOut => "Wave Out Source", 
			MixerLineComponentType.SourceAuxiliary => "Auxiliary Source", 
			MixerLineComponentType.SourceAnalog => "Analog Source", 
			_ => "Invalid Component Type", 
		};

		public int Channels => mixerLine.cChannels;

		public int SourceCount => mixerLine.cConnections;

		public int ControlsCount => mixerLine.cControls;

		public bool IsActive => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_ACTIVE) != 0;

		public bool IsDisconnected => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_DISCONNECTED) != 0;

		public bool IsSource => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_SOURCE) != 0;

		public IEnumerable<MixerControl> Controls => MixerControl.GetMixerControls(mixerHandle, this, mixerHandleType);

		public IEnumerable<MixerLine> Sources
		{
			get
			{
				for (int source = 0; source < SourceCount; source++)
				{
					yield return GetSource(source);
				}
			}
		}

		public string TargetName => mixerLine.szPname;

		public MixerLine(IntPtr mixerHandle, int destinationIndex, MixerFlags mixerHandleType)
		{
			this.mixerHandle = mixerHandle;
			this.mixerHandleType = mixerHandleType;
			mixerLine = default(MixerInterop.MIXERLINE);
			mixerLine.cbStruct = Marshal.SizeOf((object)mixerLine);
			mixerLine.dwDestination = destinationIndex;
			MmException.Try(MixerInterop.mixerGetLineInfo(mixerHandle, ref mixerLine, mixerHandleType | MixerFlags.Mixer), "mixerGetLineInfo");
		}

		public MixerLine(IntPtr mixerHandle, int destinationIndex, int sourceIndex, MixerFlags mixerHandleType)
		{
			this.mixerHandle = mixerHandle;
			this.mixerHandleType = mixerHandleType;
			mixerLine = default(MixerInterop.MIXERLINE);
			mixerLine.cbStruct = Marshal.SizeOf((object)mixerLine);
			mixerLine.dwDestination = destinationIndex;
			mixerLine.dwSource = sourceIndex;
			MmException.Try(MixerInterop.mixerGetLineInfo(mixerHandle, ref mixerLine, mixerHandleType | MixerFlags.ListText), "mixerGetLineInfo");
		}

		public static int GetMixerIdForWaveIn(int waveInDevice)
		{
			int mixerID = -1;
			MmException.Try(MixerInterop.mixerGetID((IntPtr)waveInDevice, out mixerID, MixerFlags.WaveIn), "mixerGetID");
			return mixerID;
		}

		public MixerLine GetSource(int sourceIndex)
		{
			if (sourceIndex < 0 || sourceIndex >= SourceCount)
			{
				throw new ArgumentOutOfRangeException("sourceIndex");
			}
			return new MixerLine(mixerHandle, mixerLine.dwDestination, sourceIndex, mixerHandleType);
		}

		public override string ToString()
		{
			return $"{Name} {TypeDescription} ({ControlsCount} controls, ID={mixerLine.dwLineID})";
		}
	}
	[Flags]
	public enum MixerFlags
	{
		Handle = int.MinValue,
		Mixer = 0,
		MixerHandle = int.MinValue,
		WaveOut = 0x10000000,
		WaveOutHandle = -1879048192,
		WaveIn = 0x20000000,
		WaveInHandle = -1610612736,
		MidiOut = 0x30000000,
		MidiOutHandle = -1342177280,
		MidiIn = 0x40000000,
		MidiInHandle = -1073741824,
		Aux = 0x50000000,
		Value = 0,
		ListText = 1,
		QueryMask = 0xF,
		All = 0,
		OneById = 1,
		OneByType = 2,
		GetLineInfoOfDestination = 0,
		GetLineInfoOfSource = 1,
		GetLineInfoOfLineId = 2,
		GetLineInfoOfComponentType = 3,
		GetLineInfoOfTargetType = 4,
		GetLineInfoOfQueryMask = 0xF
	}
	internal class MixerInterop
	{
		[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
		public struct MIXERCONTROLDETAILS
		{
			public int cbStruct;

			public int dwControlID;

			public int cChannels;

			public IntPtr hwndOwner;

			public int cbDetails;

			public IntPtr paDetails;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct MIXERCAPS
		{
			public ushort wMid;

			public ushort wPid;

			public uint vDriverVersion;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
			public string szPname;

			public uint fdwSupport;

			public uint cDestinations;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct MIXERLINECONTROLS
		{
			public int cbStruct;

			public int dwLineID;

			public int dwControlID;

			public int cControls;

			public int cbmxctrl;

			public IntPtr pamxctrl;
		}

		[Flags]
		public enum MIXERLINE_LINEF
		{
			MIXERLINE_LINEF_ACTIVE = 1,
			MIXERLINE_LINEF_DISCONNECTED = 0x8000,
			MIXERLINE_LINEF_SOURCE = int.MinValue
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct MIXERLINE
		{
			public int cbStruct;

			public int dwDestination;

			public int dwSource;

			public int dwLineID;

			public MIXERLINE_LINEF fdwLine;

			public IntPtr dwUser;

			public MixerLineComponentType dwComponentType;

			public int cChannels;

			public int cConnections;

			public int cControls;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
			public string szShortName;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
			public string szName;

			public uint dwType;

			public uint dwDeviceID;

			public ushort wMid;

			public ushort wPid;

			public uint vDriverVersion;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
			public string szPname;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct Bounds
		{
			public int minimum;

			public int maximum;

			public int reserved2;

			public int reserved3;

			public int reserved4;

			public int reserved5;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct Metrics
		{
			public int step;

			public int customData;

			public int reserved2;

			public int reserved3;

			public int reserved4;

			public int reserved5;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct MIXERCONTROL
		{
			public uint cbStruct;

			public int dwControlID;

			public MixerControlType dwControlType;

			public uint fdwControl;

			public uint cMultipleItems;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
			public string szShortName;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
			public string szName;

			public Bounds Bounds;

			public Metrics Metrics;
		}

		public struct MIXERCONTROLDETAILS_BOOLEAN
		{
			public int fValue;
		}

		public struct MIXERCONTROLDETAILS_SIGNED
		{
			public int lValue;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct MIXERCONTROLDETAILS_LISTTEXT
		{
			public uint dwParam1;

			public uint dwParam2;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
			public string szName;
		}

		public struct MIXERCONTROLDETAILS_UNSIGNED
		{
			public uint dwValue;
		}

		public const uint MIXERCONTROL_CONTROLF_UNIFORM = 1u;

		public const uint MIXERCONTROL_CONTROLF_MULTIPLE = 2u;

		public const uint MIXERCONTROL_CONTROLF_DISABLED = 2147483648u;

		public const int MAXPNAMELEN = 32;

		public const int MIXER_SHORT_NAME_CHARS = 16;

		public const int MIXER_LONG_NAME_CHARS = 64;

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern int mixerGetNumDevs();

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerOpen(out IntPtr hMixer, int uMxId, IntPtr dwCallback, IntPtr dwInstance, MixerFlags dwOpenFlags);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerClose(IntPtr hMixer);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerGetControlDetails(IntPtr hMixer, ref MIXERCONTROLDETAILS mixerControlDetails, MixerFlags dwDetailsFlags);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerGetDevCaps(IntPtr nMixerID, ref MIXERCAPS mixerCaps, int mixerCapsSize);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerGetID(IntPtr hMixer, out int mixerID, MixerFlags dwMixerIDFlags);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerGetLineControls(IntPtr hMixer, ref MIXERLINECONTROLS mixerLineControls, MixerFlags dwControlFlags);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerGetLineInfo(IntPtr hMixer, ref MIXERLINE mixerLine, MixerFlags dwInfoFlags);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerMessage(IntPtr hMixer, uint nMessage, IntPtr dwParam1, IntPtr dwParam2);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerSetControlDetails(IntPtr hMixer, ref MIXERCONTROLDETAILS mixerControlDetails, MixerFlags dwDetailsFlags);
	}
	public enum MixerLineComponentType
	{
		DestinationUndefined = 0,
		DestinationDigital = 1,
		DestinationLine = 2,
		DestinationMonitor = 3,
		DestinationSpeakers = 4,
		DestinationHeadphones = 5,
		DestinationTelephone = 6,
		DestinationWaveIn = 7,
		DestinationVoiceIn = 8,
		SourceUndefined = 4096,
		SourceDigital = 4097,
		SourceLine = 4098,
		SourceMicrophone = 4099,
		SourceSynthesizer = 4100,
		SourceCompactDisc = 4101,
		SourceTelephone = 4102,
		SourcePcSpeaker = 4103,
		SourceWaveOut = 4104,
		SourceAuxiliary = 4105,
		SourceAnalog = 4106
	}
	public class SignedMixerControl : MixerControl
	{
		private MixerInterop.MIXERCONTROLDETAILS_SIGNED signedDetails;

		public int Value
		{
			get
			{
				GetControlDetails();
				return signedDetails.lValue;
			}
			set
			{
				signedDetails.lValue = value;
				mixerControlDetails.paDetails = Marshal.AllocHGlobal(Marshal.SizeOf((object)signedDetails));
				Marshal.StructureToPtr((object)signedDetails, mixerControlDetails.paDetails, fDeleteOld: false);
				MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails");
				Marshal.FreeHGlobal(mixerControlDetails.paDetails);
			}
		}

		public int MinValue => mixerControl.Bounds.minimum;

		public int MaxValue => mixerControl.Bounds.maximum;

		public double Percent
		{
			get
			{
				return 100.0 * (double)(Value - MinValue) / (double)(MaxValue - MinValue);
			}
			set
			{
				Value = (int)((double)MinValue + value / 100.0 * (double)(MaxValue - MinValue));
			}
		}

		internal SignedMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels)
		{
			base.mixerControl = mixerControl;
			base.mixerHandle = mixerHandle;
			base.mixerHandleType = mixerHandleType;
			base.nChannels = nChannels;
			mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS);
			GetControlDetails();
		}

		protected override void GetDetails(IntPtr pDetails)
		{
			signedDetails = (MixerInterop.MIXERCONTROLDETAILS_SIGNED)Marshal.PtrToStructure(mixerControlDetails.paDetails, typeof(MixerInterop.MIXERCONTROLDETAILS_SIGNED));
		}

		public override string ToString()
		{
			return $"{base.ToString()} {Percent}%";
		}
	}
	public class UnsignedMixerControl : MixerControl
	{
		private MixerInterop.MIXERCONTROLDETAILS_UNSIGNED[] unsignedDetails;

		public uint Value
		{
			get
			{
				GetControlDetails();
				return unsignedDetails[0].dwValue;
			}
			set
			{
				int num = Marshal.SizeOf((object)unsignedDetails[0]);
				mixerControlDetails.paDetails = Marshal.AllocHGlobal(num * nChannels);
				for (int i = 0; i < nChannels; i++)
				{
					unsignedDetails[i].dwValue = value;
					long num2 = mixerControlDetails.paDetails.ToInt64() + num * i;
					Marshal.StructureToPtr((object)unsignedDetails[i], (IntPtr)num2, fDeleteOld: false);
				}
				MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails");
				Marshal.FreeHGlobal(mixerControlDetails.paDetails);
			}
		}

		public uint MinValue => (uint)mixerControl.Bounds.minimum;

		public uint MaxValue => (uint)mixerControl.Bounds.maximum;

		public double Percent
		{
			get
			{
				return 100.0 * (double)(Value - MinValue) / (double)(MaxValue - MinValue);
			}
			set
			{
				Value = (uint)((double)MinValue + value / 100.0 * (double)(MaxValue - MinValue));
			}
		}

		internal UnsignedMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels)
		{
			base.mixerControl = mixerControl;
			base.mixerHandle = mixerHandle;
			base.mixerHandleType = mixerHandleType;
			base.nChannels = nChannels;
			mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS);
			GetControlDetails();
		}

		protected override void GetDetails(IntPtr pDetails)
		{
			unsignedDetails = new MixerInterop.MIXERCONTROLDETAILS_UNSIGNED[nChannels];
			for (int i = 0; i < nChannels; i++)
			{
				unsignedDetails[i] = (MixerInterop.MIXERCONTROLDETAILS_UNSIGNED)Marshal.PtrToStructure(mixerControlDetails.paDetails, typeof(MixerInterop.MIXERCONTROLDETAILS_UNSIGNED));
			}
		}

		public override string ToString()
		{
			return $"{base.ToString()} {Percent}%";
		}
	}
}
namespace NAudio.Gui
{
	public class Fader : Control
	{
		private int minimum;

		private int maximum;

		private float percent;

		private Orientation orientation;

		private Container components;

		private readonly int SliderHeight = 30;

		private readonly int SliderWidth = 15;

		private Rectangle sliderRectangle;

		private bool dragging;

		private int dragY;

		public int Minimum
		{
			get
			{
				return minimum;
			}
			set
			{
				minimum = value;
			}
		}

		public int Maximum
		{
			get
			{
				return maximum;
			}
			set
			{
				maximum = value;
			}
		}

		public int Value
		{
			get
			{
				return (int)(percent * (float)(maximum - minimum)) + minimum;
			}
			set
			{
				percent = (float)(value - minimum) / (float)(maximum - minimum);
			}
		}

		public Orientation Orientation
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return orientation;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				orientation = value;
			}
		}

		public Fader()
		{
			InitializeComponent();
			((Control)this).SetStyle((ControlStyles)73730, true);
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((Control)this).Dispose(disposing);
		}

		private void DrawSlider(Graphics g)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			Brush val = (Brush)new SolidBrush(Color.White);
			Pen val2 = new Pen(Color.Black);
			sliderRectangle.X = (((Control)this).Width - SliderWidth) / 2;
			sliderRectangle.Width = SliderWidth;
			sliderRectangle.Y = (int)((float)(((Control)this).Height - SliderHeight) * percent);
			sliderRectangle.Height = SliderHeight;
			g.FillRectangle(val, sliderRectangle);
			g.DrawLine(val2, sliderRectangle.Left, sliderRectangle.Top + sliderRectangle.Height / 2, sliderRectangle.Right, sliderRectangle.Top + sliderRectangle.Height / 2);
			val.Dispose();
			val2.Dispose();
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Graphics graphics = e.Graphics;
			if ((int)Orientation == 1)
			{
				Brush val = (Brush)new SolidBrush(Color.Black);
				graphics.FillRectangle(val, ((Control)this).Width / 2, SliderHeight / 2, 2, ((Control)this).Height - SliderHeight);
				val.Dispose();
				DrawSlider(graphics);
			}
			((Control)this).OnPaint(e);
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			if (sliderRectangle.Contains(e.X, e.Y))
			{
				dragging = true;
				dragY = e.Y - sliderRectangle.Y;
			}
			((Control)this).OnMouseDown(e);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			if (dragging)
			{
				int num = e.Y - dragY;
				if (num < 0)
				{
					percent = 0f;
				}
				else if (num > ((Control)this).Height - SliderHeight)
				{
					percent = 1f;
				}
				else
				{
					percent = (float)num / (float)(((Control)this).Height - SliderHeight);
				}
				((Control)this).Invalidate();
			}
			((Control)this).OnMouseMove(e);
		}

		protected override void OnMouseUp(MouseEventArgs e)
		{
			dragging = false;
			((Control)this).OnMouseUp(e);
		}

		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
		}
	}
	public class PanSlider : UserControl
	{
		private Container components;

		private float pan;

		public float Pan
		{
			get
			{
				return pan;
			}
			set
			{
				if (value < -1f)
				{
					value = -1f;
				}
				if (value > 1f)
				{
					value = 1f;
				}
				if (value != pan)
				{
					pan = value;
					if (this.PanChanged != null)
					{
						this.PanChanged(this, EventArgs.Empty);
					}
					((Control)this).Invalidate();
				}
			}
		}

		public event EventHandler PanChanged;

		public PanSlider()
		{
			InitializeComponent();
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((ContainerControl)this).Dispose(disposing);
		}

		private void InitializeComponent()
		{
			((Control)this).Name = "PanSlider";
			((Control)this).Size = new Size(104, 16);
		}

		protected override void OnPaint(PaintEventArgs pe)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			StringFormat val = new StringFormat();
			val.LineAlignment = (StringAlignment)1;
			val.Alignment = (StringAlignment)1;
			string text;
			if ((double)pan == 0.0)
			{
				pe.Graphics.FillRectangle(Brushes.Orange, ((Control)this).Width / 2 - 1, 1, 3, ((Control)this).Height - 2);
				text = "C";
			}
			else if (pan > 0f)
			{
				pe.Graphics.FillRectangle(Brushes.Orange, ((Control)this).Width / 2, 1, (int)((float)(((Control)this).Width / 2) * pan), ((Control)this).Height - 2);
				text = $"{pan * 100f:F0}%R";
			}
			else
			{
				pe.Graphics.FillRectangle(Brushes.Orange, (int)((float)(((Control)this).Width / 2) * (pan + 1f)), 1, (int)((float)(((Control)this).Width / 2) * (0f - pan)), ((Control)this).Height - 2);
				text = $"{pan * -100f:F0}%L";
			}
			pe.Graphics.DrawRectangle(Pens.Black, 0, 0, ((Control)this).Width - 1, ((Control)this).Height - 1);
			pe.Graphics.DrawString(text, ((Control)this).Font, Brushes.Black, (RectangleF)((Control)this).ClientRectangle, val);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			if ((int)e.Button == 1048576)
			{
				SetPanFromMouse(e.X);
			}
			((Control)this).OnMouseMove(e);
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			SetPanFromMouse(e.X);
			((UserControl)this).OnMouseDown(e);
		}

		private void SetPanFromMouse(int x)
		{
			Pan = (float)x / (float)((Control)this).Width * 2f - 1f;
		}
	}
	public class Pot : UserControl
	{
		private double minimum;

		private double maximum = 1.0;

		private double value = 0.5;

		private int beginDragY;

		private double beginDragValue;

		private bool dragging;

		private IContainer components;

		public double Minimum
		{
			get
			{
				return minimum;
			}
			set
			{
				if (value >= maximum)
				{
					throw new ArgumentOutOfRangeException("Minimum must be less than maximum");
				}
				minimum = value;
				if (Value < minimum)
				{
					Value = minimum;
				}
			}
		}

		public double Maximum
		{
			get
			{
				return maximum;
			}
			set
			{
				if (value <= minimum)
				{
					throw new ArgumentOutOfRangeException("Maximum must be greater than minimum");
				}
				maximum = value;
				if (Value > maximum)
				{
					Value = maximum;
				}
			}
		}

		public double Value
		{
			get
			{
				return value;
			}
			set
			{
				SetValue(value, raiseEvents: false);
			}
		}

		public event EventHandler ValueChanged;

		public Pot()
		{
			((Control)this).SetStyle((ControlStyles)73730, true);
			InitializeComponent();
		}

		private void SetValue(double newValue, bool raiseEvents)
		{
			if (value != newValue)
			{
				value = newValue;
				if (raiseEvents && this.ValueChanged != null)
				{
					this.ValueChanged(this, EventArgs.Empty);
				}
				((Control)this).Invalidate();
			}
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			int num = Math.Min(((Control)this).Width - 4, ((Control)this).Height - 4);
			Pen val = new Pen(((Control)this).ForeColor, 3f);
			val.LineJoin = (LineJoin)2;
			GraphicsState val2 = e.Graphics.Save();
			e.Graphics.TranslateTransform((float)(((Control)this).Width / 2), (float)(((Control)this).Height / 2));
			e.Graphics.SmoothingMode = (SmoothingMode)4;
			e.Graphics.DrawArc(val, new Rectangle(num / -2, num / -2, num, num), 135f, 270f);
			double num2 = (value - minimum) / (maximum - minimum);
			double num3 = 135.0 + num2 * 270.0;
			double num4 = (double)num / 2.0 * Math.Cos(Math.PI * num3 / 180.0);
			double num5 = (double)num / 2.0 * Math.Sin(Math.PI * num3 / 180.0);
			e.Graphics.DrawLine(val, 0f, 0f, (float)num4, (float)num5);
			e.Graphics.Restore(val2);
			((Control)this).OnPaint(e);
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			dragging = true;
			beginDragY = e.Y;
			beginDragValue = value;
			((UserControl)this).OnMouseDown(e);
		}

		protected override void OnMouseUp(MouseEventArgs e)
		{
			dragging = false;
			((Control)this).OnMouseUp(e);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			if (dragging)
			{
				int num = beginDragY - e.Y;
				double num2 = (maximum - minimum) * ((double)num / 150.0);
				double num3 = beginDragValue + num2;
				if (num3 < minimum)
				{
					num3 = minimum;
				}
				if (num3 > maximum)
				{
					num3 = maximum;
				}
				SetValue(num3, raiseEvents: true);
			}
			((Control)this).OnMouseMove(e);
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((ContainerControl)this).Dispose(disposing);
		}

		private void InitializeComponent()
		{
			((Control)this).SuspendLayout();
			((ContainerControl)this).AutoScaleDimensions = new SizeF(6f, 13f);
			((ContainerControl)this).AutoScaleMode = (AutoScaleMode)1;
			((Control)this).Name = "Pot";
			((Control)this).Size = new Size(32, 32);
			((Control)this).ResumeLayout(false);
		}
	}
	public class VolumeMeter : Control
	{
		private Brush foregroundBrush;

		private float amplitude;

		private IContainer components;

		[DefaultValue(-3.0)]
		public float Amplitude
		{
			get
			{
				return amplitude;
			}
			set
			{
				amplitude = value;
				((Control)this).Invalidate();
			}
		}

		[DefaultValue(-60.0)]
		public float MinDb { get; set; }

		[DefaultValue(18.0)]
		public float MaxDb { get; set; }

		[DefaultValue(/*Could not decode attribute arguments.*/)]
		public Orientation Orientation { get; set; }

		public VolumeMeter()
		{
			((Control)this).SetStyle((ControlStyles)139266, true);
			MinDb = -60f;
			MaxDb = 18f;
			Amplitude = 0f;
			Orientation = (Orientation)1;
			InitializeComponent();
			((Control)this).OnForeColorChanged(EventArgs.Empty);
		}

		protected override void OnForeColorChanged(EventArgs e)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			foregroundBrush = (Brush)new SolidBrush(((Control)this).ForeColor);
			((Control)this).OnForeColorChanged(e);
		}

		protected override void OnPaint(PaintEventArgs pe)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			pe.Graphics.DrawRectangle(Pens.Black, 0, 0, ((Control)this).Width - 1, ((Control)this).Height - 1);
			double num = 20.0 * Math.Log10(Amplitude);
			if (num < (double)MinDb)
			{
				num = MinDb;
			}
			if (num > (double)MaxDb)
			{
				num = MaxDb;
			}
			double num2 = (num - (double)MinDb) / (double)(MaxDb - MinDb);
			int num3 = ((Control)this).Width - 2;
			int num4 = ((Control)this).Height - 2;
			if ((int)Orientation == 0)
			{
				num3 = (int)((double)num3 * num2);
				pe.Graphics.FillRectangle(foregroundBrush, 1, 1, num3, num4);
			}
			else
			{
				num4 = (int)((double)num4 * num2);
				pe.Graphics.FillRectangle(foregroundBrush, 1, ((Control)this).Height - 1 - num4, num3, num4);
			}
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((Control)this).Dispose(disposing);
		}

		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
		}
	}
	public class VolumeSlider : UserControl
	{
		private Container components;

		private float volume = 1f;

		private float MinDb = -48f;

		[DefaultValue(1f)]
		public float Volume
		{
			get
			{
				return volume;
			}
			set
			{
				if (value < 0f)
				{
					value = 0f;
				}
				if (value > 1f)
				{
					value = 1f;
				}
				if (volume != value)
				{
					volume = value;
					if (this.VolumeChanged != null)
					{
						this.VolumeChanged(this, EventArgs.Empty);
					}
					((Control)this).Invalidate();
				}
			}
		}

		public event EventHandler VolumeChanged;

		public VolumeSlider()
		{
			InitializeComponent();
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((ContainerControl)this).Dispose(disposing);
		}

		private void InitializeComponent()
		{
			((Control)this).Name = "VolumeSlider";
			((Control)this).Size = new Size(96, 16);
		}

		protected override void OnPaint(PaintEventArgs pe)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			StringFormat val = new StringFormat();
			val.LineAlignment = (StringAlignment)1;
			val.Alignment = (StringAlignment)1;
			pe.Graphics.DrawRectangle(Pens.Black, 0, 0, ((Control)this).Width - 1, ((Control)this).Height - 1);
			float num = 20f * (float)Math.Log10(Volume);
			float num2 = 1f - num / MinDb;
			pe.Graphics.FillRectangle(Brushes.LightGreen, 1, 1, (int)((float)(((Control)this).Width - 2) * num2), ((Control)this).Height - 2);
			string text = $"{num:F2} dB";
			pe.Graphics.DrawString(text, ((Control)this).Font, Brushes.Black, (RectangleF)((Control)this).ClientRectangle, val);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			if ((int)e.Button == 1048576)
			{
				SetVolumeFromMouse(e.X);
			}
			((Control)this).OnMouseMove(e);
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			SetVolumeFromMouse(e.X);
			((UserControl)this).OnMouseDown(e);
		}

		private void SetVolumeFromMouse(int x)
		{
			float num = (1f - (float)x / (float)((Control)this).Width) * MinDb;
			if (x <= 0)
			{
				Volume = 0f;
			}
			else
			{
				Volume = (float)Math.Pow(10.0, num / 20f);
			}
		}
	}
	public class WaveformPainter : Control
	{
		private Pen foregroundPen;

		private List<float> samples = new List<float>(1000);

		private int maxSamples;

		private int insertPos;

		private IContainer components;

		public WaveformPainter()
		{
			((Control)this).SetStyle((ControlStyles)139266, true);
			InitializeComponent();
			((Control)this).OnForeColorChanged(EventArgs.Empty);
			((Control)this).OnResize(EventArgs.Empty);
		}

		protected override void OnResize(EventArgs e)
		{
			maxSamples = ((Control)this).Width;
			((Control)this).OnResize(e);
		}

		protected override void OnForeColorChanged(EventArgs e)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			foregroundPen = new Pen(((Control)this).ForeColor);
			((Control)this).OnForeColorChanged(e);
		}

		public void AddMax(float maxSample)
		{
			if (maxSamples != 0)
			{
				if (samples.Count <= maxSamples)
				{
					samples.Add(maxSample);
				}
				else if (insertPos < maxSamples)
				{
					samples[insertPos] = maxSample;
				}
				insertPos++;
				insertPos %= maxSamples;
				((Control)this).Invalidate();
			}
		}

		protected override void OnPaint(PaintEventArgs pe)
		{
			((Control)this).OnPaint(pe);
			for (int i = 0; i < ((Control)this).Width; i++)
			{
				float num = (float)((Control)this).Height * GetSample(i - ((Control)this).Width + insertPos);
				float num2 = ((float)((Control)this).Height - num) / 2f;
				pe.Graphics.DrawLine(foregroundPen, (float)i, num2, (float)i, num2 + num);
			}
		}

		private float GetSample(int index)
		{
			if (index < 0)
			{
				index += maxSamples;
			}
			if ((index >= 0) & (index < samples.Count))
			{
				return samples[index];
			}
			return 0f;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((Control)this).Dispose(disposing);
		}

		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
		}
	}
	public class WaveViewer : UserControl
	{
		private Container components;

		private WaveStream waveStream;

		private int samplesPerPixel = 128;

		private long startPosition;

		private int bytesPerSample;

		public WaveStream WaveStream
		{
			get
			{
				return waveStream;
			}
			set
			{
				waveStream = value;
				if (waveStream != null)
				{
					bytesPerSample = waveStream.WaveFormat.BitsPerSample / 8 * waveStream.WaveFormat.Channels;
				}
				((Control)this).Invalidate();
			}
		}

		public int SamplesPerPixel
		{
			get
			{
				return samplesPerPixel;
			}
			set
			{
				samplesPerPixel = value;
				((Control)this).Invalidate();
			}
		}

		public long StartPosition
		{
			get
			{
				return startPosition;
			}
			set
			{
				startPosition = value;
			}
		}

		public WaveViewer()
		{
			InitializeComponent();
			((Control)this).DoubleBuffered = true;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((ContainerControl)this).Dispose(disposing);
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			if (waveStream != null)
			{
				waveStream.Position = 0L;
				byte[] array = new byte[samplesPerPixel * bytesPerSample];
				waveStream.Position = startPosition + e.ClipRectangle.Left * bytesPerSample * samplesPerPixel;
				for (float num = e.ClipRectangle.X; num < (float)e.ClipRectangle.Right; num += 1f)
				{
					short num2 = 0;
					short num3 = 0;
					int num4 = waveStream.Read(array, 0, samplesPerPixel * bytesPerSample);
					if (num4 == 0)
					{
						break;
					}
					for (int i = 0; i < num4; i += 2)
					{
						short num5 = BitConverter.ToInt16(array, i);
						if (num5 < num2)
						{
							num2 = num5;
						}
						if (num5 > num3)
						{
							num3 = num5;
						}
					}
					float num6 = ((float)num2 - -32768f) / 65535f;
					float num7 = ((float)num3 - -32768f) / 65535f;
					e.Graphics.DrawLine(Pens.Black, num, (float)((Control)this).Height * num6, num, (float)((Control)this).Height * num7);
				}
			}
			((Control)this).OnPaint(e);
		}

		private void InitializeComponent()
		{
			components = new Container();
		}
	}
}
namespace NAudio.SoundFont
{
	public class Generator
	{
		private GeneratorEnum generatorType;

		private ushort rawAmount;

		private Instrument instrument;

		private SampleHeader sampleHeader;

		public GeneratorEnum GeneratorType
		{
			get
			{
				return generatorType;
			}
			set
			{
				generatorType = value;
			}
		}

		public ushort UInt16Amount
		{
			get
			{
				return rawAmount;
			}
			set
			{
				rawAmount = value;
			}
		}

		public short Int16Amount
		{
			get
			{
				return (short)rawAmount;
			}
			set
			{
				rawAmount = (ushort)value;
			}
		}

		public byte LowByteAmount
		{
			get
			{
				return (byte)(rawAmount & 0xFFu);
			}
			set
			{
				rawAmount &= 65280;
				rawAmount += value;
			}
		}

		public byte HighByteAmount
		{
			get
			{
				return (byte)((rawAmount & 0xFF00) >> 8);
			}
			set
			{
				rawAmount &= 255;
				rawAmount += (ushort)(value << 8);
			}
		}

		public Instrument Instrument
		{
			get
			{
				return instrument;
			}
			set
			{
				instrument = value;
			}
		}

		public SampleHeader SampleHeader
		{
			get
			{
				return sampleHeader;
			}
			set
			{
				sampleHeader = value;
			}
		}

		public override string ToString()
		{
			if (generatorType == GeneratorEnum.Instrument)
			{
				return $"Generator Instrument {instrument.Name}";
			}
			if (generatorType == GeneratorEnum.SampleID)
			{
				return $"Generator SampleID {sampleHeader}";
			}
			return $"Generator {generatorType} {rawAmount}";
		}
	}
	internal class GeneratorBuilder : StructureBuilder<Generator>
	{
		public override int Length => 4;

		public Generator[] Generators => data.ToArray();

		public override Generator Read(BinaryReader br)
		{
			Generator generator = new Generator();
			generator.GeneratorType = (GeneratorEnum)br.ReadUInt16();
			generator.UInt16Amount = br.ReadUInt16();
			data.Add(generator);
			return generator;
		}

		public override void Write(BinaryWriter bw, Generator o)
		{
		}

		public void Load(Instrument[] instruments)
		{
			Generator[] generators = Generators;
			foreach (Generator generator in generators)
			{
				if (generator.GeneratorType == GeneratorEnum.Instrument)
				{
					generator.Instrument = instruments[generator.UInt16Amount];
				}
			}
		}

		public void Load(SampleHeader[] sampleHeaders)
		{
			Generator[] generators = Generators;
			foreach (Generator generator in generators)
			{
				if (generator.GeneratorType == GeneratorEnum.SampleID)
				{
					generator.SampleHeader = sampleHeaders[generator.UInt16Amount];
				}
			}
		}
	}
	public enum GeneratorEnum
	{
		StartAddressOffset,
		EndAddressOffset,
		StartLoopAddressOffset,
		EndLoopAddressOffset,
		StartAddressCoarseOffset,
		ModulationLFOToPitch,
		VibratoLFOToPitch,
		ModulationEnvelopeToPitch,
		InitialFilterCutoffFrequency,
		InitialFilterQ,
		ModulationLFOToFilterCutoffFrequency,
		ModulationEnvelopeToFilterCutoffFrequency,
		EndAddressCoarseOffset,
		ModulationLFOToVolume,
		Unused1,
		ChorusEffectsSend,
		ReverbEffectsSend,
		Pan,
		Unused2,
		Unused3,
		Unused4,
		DelayModulationLFO,
		FrequencyModulationLFO,
		DelayVibratoLFO,
		FrequencyVibratoLFO,
		DelayModulationEnvelope,
		AttackModulationEnvelope,
		HoldModulationEnvelope,
		DecayModulationEnvelope,
		SustainModulationEnvelope,
		ReleaseModulationEnvelope,
		KeyNumberToModulationEnvelopeHold,
		KeyNumberToModulationEnvelopeDecay,
		DelayVolumeEnvelope,
		AttackVolumeEnvelope,
		HoldVolumeEnvelope,
		DecayVolumeEnvelope,
		SustainVolumeEnvelope,
		ReleaseVolumeEnvelope,
		KeyNumberToVolumeEnvelopeHold,
		KeyNumberToVolumeEnvelopeDecay,
		Instrument,
		Reserved1,
		KeyRange,
		VelocityRange,
		StartLoopAddressCoarseOffset,
		KeyNumber,
		Velocity,
		InitialAttenuation,
		Reserved2,
		EndLoopAddressCoarseOffset,
		CoarseTune,
		FineTune,
		SampleID,
		SampleModes,
		Reserved3,
		ScaleTuning,
		ExclusiveClass,
		OverridingRootKey,
		Unused5,
		UnusedEnd
	}
	public class InfoChunk
	{
		public SFVersion SoundFontVersion { get; }

		public string WaveTableSoundEngine { get; set; }

		public string BankName { get; set; }

		public string DataROM { get; set; }

		public string CreationDate { get; set; }

		public string Author { get; set; }

		public string TargetProduct { get; set; }

		public string Copyright { get; set; }

		public string Comments { get; set; }

		public string Tools { get; set; }

		public SFVersion ROMVersion { get; set; }

		internal InfoChunk(RiffChunk chunk)
		{
			bool flag = false;
			bool flag2 = false;
			if (chunk.ReadChunkID() != "INFO")
			{
				throw new InvalidDataException("Not an INFO chunk");
			}
			RiffChunk nextSubChunk;
			while ((nextSubChunk = chunk.GetNextSubChunk()) != null)
			{
				switch (nextSubChunk.ChunkID)
				{
				case "ifil":
					flag = true;
					SoundFontVersion = nextSubChunk.GetDataAsStructure(new SFVersionBuilder());
					break;
				case "isng":
					WaveTableSoundEngine = nextSubChunk.GetDataAsString();
					break;
				case "INAM":
					flag2 = true;
					BankName = nextSubChunk.GetDataAsString();
					break;
				case "irom":
					DataROM = nextSubChunk.GetDataAsString();
					break;
				case "iver":
					ROMVersion = nextSubChunk.GetDataAsStructure(new SFVersionBuilder());
					break;
				case "ICRD":
					CreationDate = nextSubChunk.GetDataAsString();
					break;
				case "IENG":
					Author = nextSubChunk.GetDataAsString();
					break;
				case "IPRD":
					TargetProduct = nextSubChunk.GetDataAsString();
					break;
				case "ICOP":
					Copyright = nextSubChunk.GetDataAsString();
					break;
				case "ICMT":
					Comments = nextSubChunk.GetDataAsString();
					break;
				case "ISFT":
					Tools = nextSubChunk.GetDataAsString();
					break;
				default:
					throw new InvalidDataException($"Unknown chunk type {nextSubChunk.ChunkID}");
				}
			}
			if (!flag)
			{
				throw new InvalidDataException("Missing SoundFont version information");
			}
			if (!flag2)
			{
				throw new InvalidDataException("Missing SoundFont name information");
			}
		}

		public override string ToString()
		{
			return string.Format("Bank Name: {0}\r\nAuthor: {1}\r\nCopyright: {2}\r\nCreation Date: {3}\r\nTools: {4}\r\nComments: {5}\r\nSound Engine: {6}\r\nSoundFont Version: {7}\r\nTarget Product: {8}\r\nData ROM: {9}\r\nROM Version: {10}", BankName, Author, Copyright, CreationDate, Tools, "TODO-fix comments", WaveTableSoundEngine, SoundFontVersion, TargetProduct, DataROM, ROMVersion);
		}
	}
	public class Instrument
	{
		private string name;

		internal ushort startInstrumentZoneIndex;

		internal ushort endInstrumentZoneIndex;

		private Zone[] zones;

		public string Name
		{
			get
			{
				return name;
			}
			set
			{
				name = value;
			}
		}

		public Zone[] Zones
		{
			get
			{
				return zones;
			}
			set
			{
				zones = value;
			}
		}

		public override string ToString()
		{
			return name;
		}
	}
	internal class InstrumentBuilder : StructureBuilder<Instrument>
	{
		private Instrument lastInstrument;

		public override int Length => 22;

		public Instrument[] Instruments => data.ToArray();

		public override Instrument Read(BinaryReader br)
		{
			Instrument instrument = new Instrument();
			string text = Encoding.UTF8.GetString(br.ReadBytes(20), 0, 20);
			if (text.IndexOf('\0') >= 0)
			{
				text = text.Substring(0, text.IndexOf('\0'));
			}
			instrument.Name = text;
			instrument.startInstrumentZoneIndex = br.ReadUInt16();
			if (lastInstrument != null)
			{
				lastInstrument.endInstrumentZoneIndex = (ushort)(instrument.startInstrumentZoneIndex - 1);
			}
			data.Add(instrument);
			lastInstrument = instrument;
			return instrument;
		}

		public override void Write(BinaryWriter bw, Instrument instrument)
		{
		}

		public void LoadZones(Zone[] zones)
		{
			for (int i = 0; i < data.Count - 1; i++)
			{
				Instrument instrument = data[i];
				instrument.Zones = new Zone[instrument.endInstrumentZoneIndex - instrument.startInstrumentZoneIndex + 1];
				Array.Copy(zones, instrument.startInstrumentZoneIndex, instrument.Zones, 0, instrument.Zones.Length);
			}
			data.RemoveAt(data.Count - 1);
		}
	}
	public enum TransformEnum
	{
		Linear
	}
	public class Modulator
	{
		private ModulatorType sourceModulationData;

		private GeneratorEnum destinationGenerator;

		private short amount;

		private ModulatorType sourceModulationAmount;

		private TransformEnum sourceTransform;

		public ModulatorType SourceModulationData
		{
			get
			{
				return sourceModulationData;
			}
			set
			{
				sourceModulationData = value;
			}
		}

		public GeneratorEnum DestinationGenerator
		{
			get
			{
				return destinationGenerator;
			}
			set
			{
				destinationGenerator = value;
			}
		}

		public short Amount
		{
			get
			{
				return amount;
			}
			set
			{
				amount = value;
			}
		}

		public ModulatorType SourceModulationAmount
		{
			get
			{
				return sourceModulationAmount;
			}
			set
			{
				sourceModulationAmount = value;
			}
		}

		public TransformEnum SourceTransform
		{
			get
			{
				return sourceTransform;
			}
			set
			{
				sourceTransform = value;
			}
		}

		public override string ToString()
		{
			return $"Modulator {sourceModulationData} {destinationGenerator} {amount} {sourceModulationAmount} {sourceTransform}";
		}
	}
	internal class ModulatorBuilder : StructureBuilder<Modulator>
	{
		public override int Length => 10;

		public Modulator[] Modulators => data.ToArray();

		public override Modulator Read(BinaryReader br)
		{
			Modulator modulator = new Modulator();
			modulator.SourceModulationData = new ModulatorType(br.ReadUInt16());
			modulator.DestinationGenerator = (GeneratorEnum)br.ReadUInt16();
			modulator.Amount = br.ReadInt16();
			modulator.SourceModulationAmount = new ModulatorType(br.ReadUInt16());
			modulator.SourceTransform = (TransformEnum)br.ReadUInt16();
			data.Add(modulator);
			return modulator;
		}

		public override void Write(BinaryWriter bw, Modulator o)
		{
		}
	}
	public enum ControllerSourceEnum
	{
		NoController = 0,
		NoteOnVelocity = 2,
		NoteOnKeyNumber = 3,
		PolyPressure = 10,
		ChannelPressure = 13,
		PitchWheel = 14,
		PitchWheelSensitivity = 16
	}
	public enum SourceTypeEnum
	{
		Linear,
		Concave,
		Convex,
		Switch
	}
	public class ModulatorType
	{
		private bool polarity;

		private bool direction;

		private bool midiContinuousController;

		private ControllerSourceEnum controllerSource;

		private SourceTypeEnum sourceType;

		private ushort midiContinuousControllerNumber;

		internal ModulatorType(ushort raw)
		{
			polarity = (raw & 0x200) == 512;
			direction = (raw & 0x100) == 256;
			midiContinuousController = (raw & 0x80) == 128;
			sourceType = (SourceTypeEnum)((raw & 0xFC00) >> 10);
			controllerSource = (ControllerSourceEnum)(raw & 0x7F);
			midiContinuousControllerNumber = (ushort)(raw & 0x7Fu);
		}

		public override string ToString()
		{
			if (midiContinuousController)
			{
				return $"{sourceType} CC{midiContinuousControllerNumber}";
			}
			return $"{sourceType} {controllerSource}";
		}
	}
	public class Preset
	{
		private string name;

		private ushort patchNumber;

		private ushort bank;

		internal ushort startPresetZoneIndex;

		internal ushort endPresetZoneIndex;

		internal uint library;

		internal uint genre;

		internal uint morphology;

		private Zone[] zones;

		public string Name
		{
			get
			{
				return name;
			}
			set
			{
				name = value;
			}
		}

		public ushort PatchNumber
		{
			get
			{
				return patchNumber;
			}
			set
			{
				patchNumber = value;
			}
		}

		public ushort Bank
		{
			get
			{
				return bank;
			}
			set
			{
				bank = value;
			}
		}

		public Zone[] Zones
		{
			get
			{
				return zones;
			}
			set
			{
				zones = value;
			}
		}

		public override string ToString()
		{
			return $"{bank}-{patchNumber} {name}";
		}
	}
	internal class PresetBuilder : StructureBuilder<Preset>
	{
		private Preset lastPreset;

		public override int Length => 38;

		public Preset[] Presets => data.ToArray();

		public override Preset Read(BinaryReader br)
		{
			Preset preset = new Preset();
			string text = Encoding.UTF8.GetString(br.ReadBytes(20), 0, 20);
			if (text.IndexOf('\0') >= 0)
			{
				text = text.Substring(0, text.IndexOf('\0'));
			}
			preset.Name = text;
			preset.PatchNumber = br.ReadUInt16();
			preset.Bank = br.ReadUInt16();
			preset.startPresetZoneIndex = br.ReadUInt16();
			preset.library = br.ReadUInt32();
			preset.genre = br.ReadUInt32();
			preset.morphology = br.ReadUInt32();
			if (lastPreset != null)
			{
				lastPreset.endPresetZoneIndex = (ushort)(preset.startPresetZoneIndex - 1);
			}
			data.Add(preset);
			lastPreset = preset;
			return preset;
		}

		public override void Write(BinaryWriter bw, Preset preset)
		{
		}

		public void LoadZones(Zone[] presetZones)
		{
			for (int i = 0; i < data.Count - 1; i++)
			{
				Preset preset = data[i];
				preset.Zones = new Zone[preset.endPresetZoneIndex - preset.startPresetZoneIndex + 1];
				Array.Copy(presetZones, preset.startPresetZoneIndex, preset.Zones, 0, preset.Zones.Length);
			}
			data.RemoveAt(data.Count - 1);
		}
	}
	public class PresetsChunk
	{
		private PresetBuilder presetHeaders = new PresetBuilder();

		private ZoneBuilder presetZones = new ZoneBuilder();

		private ModulatorBuilder presetZoneModulators = new ModulatorBuilder();

		private GeneratorBuilder presetZoneGenerators = new GeneratorBuilder();

		private InstrumentBuilder instruments = new InstrumentBuilder();

		private ZoneBuilder instrumentZones = new ZoneBuilder();

		private ModulatorBuilder instrumentZoneModulators = new ModulatorBuilder();

		private GeneratorBuilder instrumentZoneGenerators = new GeneratorBuilder();

		private SampleHeaderBuilder sampleHeaders = new SampleHeaderBuilder();

		public Preset[] Presets => presetHeaders.Presets;

		public Instrument[] Instruments => instruments.Instruments;

		public SampleHeader[] SampleHeaders => sampleHeaders.SampleHeaders;

		internal PresetsChunk(RiffChunk chunk)
		{
			string text = chunk.ReadChunkID();
			if (text != "pdta")
			{
				throw new InvalidDataException($"Not a presets data chunk ({text})");
			}
			RiffChunk nextSubChunk;
			while ((nextSubChunk = chunk.GetNextSubChunk()) != null)
			{
				switch (nextSubChunk.ChunkID)
				{
				case "PHDR":
				case "phdr":
					nextSubChunk.GetDataAsStructureArray(presetHeaders);
					break;
				case "PBAG":
				case "pbag":
					nextSubChunk.GetDataAsStructureArray(presetZones);
					break;
				case "PMOD":
				case "pmod":
					nextSubChunk.GetDataAsStructureArray(presetZoneModulators);
					break;
				case "PGEN":
				case "pgen":
					nextSubChunk.GetDataAsStructureArray(presetZoneGenerators);
					break;
				case "INST":
				case "inst":
					nextSubChunk.GetDataAsStructureArray(instruments);
					break;
				case "IBAG":
				case "ibag":
					nextSubChunk.GetDataAsStructureArray(instrumentZones);
					break;
				case "IMOD":
				case "imod":
					nextSubChunk.GetDataAsStructureArray(instrumentZoneModulators);
					break;
				case "IGEN":
				case "igen":
					nextSubChunk.GetDataAsStructureArray(instrumentZoneGenerators);
					break;
				case "SHDR":
				case "shdr":
					nextSubChunk.GetDataAsStructureArray(sampleHeaders);
					break;
				default:
					throw new InvalidDataException($"Unknown chunk type {nextSubChunk.ChunkID}");
				}
			}
			instrumentZoneGenerators.Load(sampleHeaders.SampleHeaders);
			instrumentZones.Load(instrumentZoneModulators.Modulators, instrumentZoneGenerators.Generators);
			instruments.LoadZones(instrumentZones.Zones);
			presetZoneGenerators.Load(instruments.Instruments);
			presetZones.Load(presetZoneModulators.Modulators, presetZoneGenerators.Generators);
			presetHeaders.LoadZones(presetZones.Zones);
			sampleHeaders.RemoveEOS();
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("Preset Headers:\r\n");
			Preset[] presets = presetHeaders.Presets;
			foreach (Preset arg in presets)
			{
				stringBuilder.AppendFormat("{0}\r\n", arg);
			}
			stringBuilder.Append("Instruments:\r\n");
			Instrument[] array = instruments.Instruments;
			foreach (Instrument arg2 in array)
			{
				stringBuilder.AppendFormat("{0}\r\n", arg2);
			}
			return stringBuilder.ToString();
		}
	}
	internal class RiffChunk
	{
		private string chunkID;

		private uint chunkSize;

		private long dataOffset;

		private BinaryReader riffFile;

		public string ChunkID
		{
			get
			{
				return chunkID;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("ChunkID may not be null");
				}
				if (value.Length != 4)
				{
					throw new ArgumentException("ChunkID must be four characters");
				}
				chunkID = value;
			}
		}

		public uint ChunkSize => chunkSize;

		public long DataOffset => dataOffset;

		public static RiffChunk GetTopLevelChunk(BinaryReader file)
		{
			RiffChunk riffChunk = new RiffChunk(file);
			riffChunk.ReadChunk();
			return riffChunk;
		}

		private RiffChunk(BinaryReader file)
		{
			riffFile = file;
			chunkID = "????";
			chunkSize = 0u;
			dataOffset = 0L;
		}

		public string ReadChunkID()
		{
			byte[] array = riffFile.ReadBytes(4);
			if (array.Length != 4)
			{
				throw new InvalidDataException("Couldn't read Chunk ID");
			}
			return ByteEncoding.Instance.GetString(array, 0, array.Length);
		}

		private void ReadChunk()
		{
			chunkID = ReadChunkID();
			chunkSize = riffFile.ReadUInt32();
			dataOffset = riffFile.BaseStream.Position;
		}

		public RiffChunk GetNextSubChunk()
		{
			if (riffFile.BaseStream.Position + 8 < dataOffset + chunkSize)
			{
				RiffChunk riffChunk = new RiffChunk(riffFile);
				riffChunk.ReadChunk();
				return riffChunk;
			}
			return null;
		}

		public byte[] GetData()
		{
			riffFile.BaseStream.Position = dataOffset;
			byte[] array = riffFile.ReadBytes((int)chunkSize);
			if (array.Length != chunkSize)
			{
				throw new InvalidDataException($"Couldn't read chunk's data Chunk: {this}, read {array.Length} bytes");
			}
			return array;
		}

		public string GetDataAsString()
		{
			byte[] data = GetData();
			if (data == null)
			{
				return null;
			}
			return ByteEncoding.Instance.GetString(data, 0, data.Length);
		}

		public T GetDataAsStructure<T>(StructureBuilder<T> s)
		{
			riffFile.BaseStream.Position = dataOffset;
			if (s.Length != chunkSize)
			{
				throw new InvalidDataException($"Chunk size is: {chunkSize} so can't read structure of: {s.Length}");
			}
			return s.Read(riffFile);
		}

		public T[] GetDataAsStructureArray<T>(StructureBuilder<T> s)
		{
			riffFile.BaseStream.Position = dataOffset;
			if (chunkSize % s.Length != 0L)
			{
				throw new InvalidDataException($"Chunk size is: {chunkSize} not a multiple of structure size: {s.Length}");
			}
			int num = (int)(chunkSize / s.Length);
			T[] array = new T[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = s.Read(riffFile);
			}
			return array;
		}

		public override string ToString()
		{
			return $"RiffChunk ID: {ChunkID} Size: {ChunkSize} Data Offset: {DataOffset}";
		}
	}
	internal class SampleDataChunk
	{
		private byte[] sampleData;

		public byte[] SampleData => sampleData;

		public SampleDataChunk(RiffChunk chunk)
		{
			string text = chunk.ReadChunkID();
			if (text != "sdta")
			{
				throw new InvalidDataException($"Not a sample data chunk ({text})");
			}
			sampleData = chunk.GetData();
		}
	}
	public class SampleHeader
	{
		public string SampleName;

		public uint Start;

		public uint End;

		public uint StartLoop;

		public uint EndLoop;

		public uint SampleRate;

		public byte OriginalPitch;

		public sbyte PitchCorrection;

		public ushort SampleLink;

		public SFSampleLink SFSampleLink;

		public override string ToString()
		{
			return SampleName;
		}
	}
	internal class SampleHeaderBuilder : StructureBuilder<SampleHeader>
	{
		public override int Length => 46;

		public SampleHeader[] SampleHeaders => data.ToArray();

		public override SampleHeader Read(BinaryReader br)
		{
			SampleHeader sampleHeader = new SampleHeader();
			byte[] array = br.ReadBytes(20);
			sampleHeader.SampleName = ByteEncoding.Instance.GetString(array, 0, array.Length);
			sampleHeader.Start = br.ReadUInt32();
			sampleHeader.End = br.ReadUInt32();
			sampleHeader.StartLoop = br.ReadUInt32();
			sampleHeader.EndLoop = br.ReadUInt32();
			sampleHeader.SampleRate = br.ReadUInt32();
			sampleHeader.OriginalPitch = br.ReadByte();
			sampleHeader.PitchCorrection = br.ReadSByte();
			sampleHeader.SampleLink = br.ReadUInt16();
			sampleHeader.SFSampleLink = (SFSampleLink)br.ReadUInt16();
			data.Add(sampleHeader);
			return sampleHeader;
		}

		public override void Write(BinaryWriter bw, SampleHeader sampleHeader)
		{
		}

		internal void RemoveEOS()
		{
			data.RemoveAt(data.Count - 1);
		}
	}
	public enum SampleMode
	{
		NoLoop,
		LoopContinuously,
		ReservedNoLoop,
		LoopAndContinue
	}
	public enum SFSampleLink : ushort
	{
		MonoSample = 1,
		RightSample = 2,
		LeftSample = 4,
		LinkedSample = 8,
		RomMonoSample = 32769,
		RomRightSample = 32770,
		RomLeftSample = 32772,
		RomLinkedSample = 32776
	}
	public class SFVersion
	{
		private short major;

		private short minor;

		public short Major
		{
			get
			{
				return major;
			}
			set
			{
				major = value;
			}
		}

		public short Minor
		{
			get
			{
				return minor;
			}
			set
			{
				minor = value;
			}
		}
	}
	internal class SFVersionBuilder : StructureBuilder<SFVersion>
	{
		public override int Length => 4;

		public override SFVersion Read(BinaryReader br)
		{
			SFVersion sFVersion = new SFVersion();
			sFVersion.Major = br.ReadInt16();
			sFVersion.Minor = br.ReadInt16();
			data.Add(sFVersion);
			return sFVersion;
		}

		public override void Write(BinaryWriter bw, SFVersion v)
		{
			bw.Write(v.Major);
			bw.Write(v.Minor);
		}
	}
	public class SoundFont
	{
		private InfoChunk info;

		private PresetsChunk presetsChunk;

		private SampleDataChunk sampleData;

		public InfoChunk FileInfo => info;

		public Preset[] Presets => presetsChunk.Presets;

		public Instrument[] Instruments => presetsChunk.Instruments;

		public SampleHeader[] SampleHeaders => presetsChunk.SampleHeaders;

		public byte[] SampleData => sampleData.SampleData;

		public SoundFont(string fileName)
			: this(new FileStream(fileName, FileMode.Open, FileAccess.Read))
		{
		}

		public SoundFont(Stream sfFile)
		{
			using (sfFile)
			{
				RiffChunk topLevelChunk = RiffChunk.GetTopLevelChunk(new BinaryReader(sfFile));
				if (topLevelChunk.ChunkID == "RIFF")
				{
					string text = topLevelChunk.ReadChunkID();
					if (text != "sfbk")
					{
						throw new InvalidDataException($"Not a SoundFont ({text})");
					}
					RiffChunk nextSubChunk = topLevelChunk.GetNextSubChunk();
					if (nextSubChunk.ChunkID == "LIST")
					{
						info = new InfoChunk(nextSubChunk);
						RiffChunk nextSubChunk2 = topLevelChunk.GetNextSubChunk();
						sampleData = new SampleDataChunk(nextSubChunk2);
						nextSubChunk2 = topLevelChunk.GetNextSubChunk();
						presetsChunk = new PresetsChunk(nextSubChunk2);
						return;
					}
					throw new InvalidDataException($"Not info list found ({nextSubChunk.ChunkID})");
				}
				throw new InvalidDataException("Not a RIFF file");
			}
		}

		public override string ToString()
		{
			return $"Info Chunk:\r\n{info}\r\nPresets Chunk:\r\n{presetsChunk}";
		}
	}
	internal abstract class StructureBuilder<T>
	{
		protected List<T> data;

		public abstract int Length { get; }

		public T[] Data => data.ToArray();

		public StructureBuilder()
		{
			Reset();
		}

		public abstract T Read(BinaryReader br);

		public abstract void Write(BinaryWriter bw, T o);

		public void Reset()
		{
			data = new List<T>();
		}
	}
	public class Zone
	{
		internal ushort generatorIndex;

		internal ushort modulatorIndex;

		internal ushort generatorCount;

		internal ushort modulatorCount;

		private Modulator[] modulators;

		private Generator[] generators;

		public Modulator[] Modulators
		{
			get
			{
				return modulators;
			}
			set
			{
				modulators = value;
			}
		}

		public Generator[] Generators
		{
			get
			{
				return generators;
			}
			set
			{
				generators = value;
			}
		}

		public override string ToString()
		{
			return $"Zone {generatorCount} Gens:{generatorIndex} {modulatorCount} Mods:{modulatorIndex}";
		}
	}
	internal class ZoneBuilder : StructureBuilder<Zone>
	{
		private Zone lastZone;

		public Zone[] Zones => data.ToArray();

		public override int Length => 4;

		public override Zone Read(BinaryReader br)
		{
			Zone zone = new Zone();
			zone.generatorIndex = br.ReadUInt16();
			zone.modulatorIndex = br.ReadUInt16();
			if (lastZone != null)
			{
				lastZone.generatorCount = (ushort)(zone.generatorIndex - lastZone.generatorIndex);
				lastZone.modulatorCount = (ushort)(zone.modulatorIndex - lastZone.modulatorIndex);
			}
			data.Add(zone);
			lastZone = zone;
			return zone;
		}

		public override void Write(BinaryWriter bw, Zone zone)
		{
		}

		public void Load(Modulator[] modulators, Generator[] generators)
		{
			for (int i = 0; i < data.Count - 1; i++)
			{
				Zone zone = data[i];
				zone.Generators = new Generator[zone.generatorCount];
				Array.Copy(generators, zone.generatorIndex, zone.Generators, 0, zone.generatorCount);
				zone.Modulators = new Modulator[zone.modulatorCount];
				Array.Copy(modulators, zone.modulatorIndex, zone.Modulators, 0, zone.modulatorCount);
			}
			data.RemoveAt(data.Count - 1);
		}
	}
}
namespace NAudio.Dmo
{
	internal class AudioMediaSubtypes
	{
		public static readonly Guid MEDIASUBTYPE_PCM = new Guid("00000001-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIASUBTYPE_PCMAudioObsolete = new Guid("e436eb8a-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_MPEG1Packet = new Guid("e436eb80-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_MPEG1Payload = new Guid("e436eb81-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_MPEG2_AUDIO = new Guid("e06d802b-db46-11cf-b4d1-00805f6cbbea");

		public static readonly Guid MEDIASUBTYPE_DVD_LPCM_AUDIO = new Guid("e06d8032-db46-11cf-b4d1-00805f6cbbea");

		public static readonly Guid MEDIASUBTYPE_DRM_Audio = new Guid("00000009-0000-0010-8000-00aa00389b71");

		public static readonly Guid MEDIASUBTYPE_IEEE_FLOAT = new Guid("00000003-0000-0010-8000-00aa00389b71");

		public static readonly Guid MEDIASUBTYPE_DOLBY_AC3 = new Guid("e06d802c-db46-11cf-b4d1-00805f6cbbea");

		public static readonly Guid MEDIASUBTYPE_DOLBY_AC3_SPDIF = new Guid("00000092-0000-0010-8000-00aa00389b71");

		public static readonly Guid MEDIASUBTYPE_RAW_SPORT = new Guid("00000240-0000-0010-8000-00aa00389b71");

		public static readonly Guid MEDIASUBTYPE_SPDIF_TAG_241h = new Guid("00000241-0000-0010-8000-00aa00389b71");

		public static readonly Guid WMMEDIASUBTYPE_MP3 = new Guid("00000055-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIASUBTYPE_WAVE = new Guid("e436eb8b-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_AU = new Guid("e436eb8c-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_AIFF = new Guid("e436eb8d-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid[] AudioSubTypes = new Guid[13]
		{
			MEDIASUBTYPE_PCM, MEDIASUBTYPE_PCMAudioObsolete, MEDIASUBTYPE_MPEG1Packet, MEDIASUBTYPE_MPEG1Payload, MEDIASUBTYPE_MPEG2_AUDIO, MEDIASUBTYPE_DVD_LPCM_AUDIO, MEDIASUBTYPE_DRM_Audio, MEDIASUBTYPE_IEEE_FLOAT, MEDIASUBTYPE_DOLBY_AC3, MEDIASUBTYPE_DOLBY_AC3_SPDIF,
			MEDIASUBTYPE_RAW_SPORT, MEDIASUBTYPE_SPDIF_TAG_241h, WMMEDIASUBTYPE_MP3
		};

		public static readonly string[] AudioSubTypeNames = new string[13]
		{
			"PCM", "PCM Obsolete", "MPEG1Packet", "MPEG1Payload", "MPEG2_AUDIO", "DVD_LPCM_AUDIO", "DRM_Audio", "IEEE_FLOAT", "DOLBY_AC3", "DOLBY_AC3_SPDIF",
			"RAW_SPORT", "SPDIF_TAG_241h", "MP3"
		};

		public static string GetAudioSubtypeName(Guid subType)
		{
			for (int i = 0; i < AudioSubTypes.Length; i++)
			{
				if (subType == AudioSubTypes[i])
				{
					return AudioSubTypeNames[i];
				}
			}
			return subType.ToString();
		}
	}
	public class DmoDescriptor
	{
		public string Name { get; private set; }

		public Guid Clsid { get; private set; }

		public DmoDescriptor(string name, Guid clsid)
		{
			Name = name;
			Clsid = clsid;
		}
	}
	public class DmoEnumerator
	{
		public static IEnumerable<DmoDescriptor> GetAudioEffectNames()
		{
			return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_EFFECT);
		}

		public static IEnumerable<DmoDescriptor> GetAudioEncoderNames()
		{
			return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_ENCODER);
		}

		public static IEnumerable<DmoDescriptor> GetAudioDecoderNames()
		{
			return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_DECODER);
		}

		private static IEnumerable<DmoDescriptor> GetDmos(Guid category)
		{
			Marshal.ThrowExceptionForHR(DmoInterop.DMOEnum(ref category, DmoEnumFlags.None, 0, null, 0, null, out var enumDmo));
			int itemsFetched;
			do
			{
				enumDmo.Next(1, out var clsid, out var name, out itemsFetched);
				if (itemsFetched == 1)
				{
					string name2 = Marshal.PtrToStringUni(name);
					Marshal.FreeCoTaskMem(name);
					yield return new DmoDescriptor(name2, clsid);
				}
			}
			while (itemsFetched > 0);
		}
	}
	[Flags]
	internal enum DmoEnumFlags
	{
		None = 0,
		DMO_ENUMF_INCLUDE_KEYED = 1
	}
	internal static class DmoGuids
	{
		public static readonly Guid DMOCATEGORY_AUDIO_DECODER = new Guid("57f2db8b-e6bb-4513-9d43-dcd2a6593125");

		public static readonly Guid DMOCATEGORY_AUDIO_ENCODER = new Guid("33D9A761-90C8-11d0-BD43-00A0C911CE86");

		public static readonly Guid DMOCATEGORY_VIDEO_DECODER = new Guid("4a69b442-28be-4991-969c-b500adf5d8a8");

		public static readonly Guid DMOCATEGORY_VIDEO_ENCODER = new Guid("33D9A760-90C8-11d0-BD43-00A0C911CE86");

		public static readonly Guid DMOCATEGORY_AUDIO_EFFECT = new Guid("f3602b3f-0592-48df-a4cd-674721e7ebeb");

		public static readonly Guid DMOCATEGORY_VIDEO_EFFECT = new Guid("d990ee14-776c-4723-be46-3da2f56f10b9");

		public static readonly Guid DMOCATEGORY_AUDIO_CAPTURE_EFFECT = new Guid("f665aaba-3e09-4920-aa5f-219811148f09");
	}
	internal static class DmoMediaTypeGuids
	{
		public static readonly Guid FORMAT_None = new Guid("0F6417D6-C318-11D0-A43F-00A0C9223196");

		public static readonly Guid FORMAT_VideoInfo = new Guid("05589f80-c356-11ce-bf01-00aa0055595a");

		public static readonly Guid FORMAT_VideoInfo2 = new Guid("F72A76A0-EB0A-11d0-ACE4-0000C0CC16BA");

		public static readonly Guid FORMAT_WaveFormatEx = new Guid("05589f81-c356-11ce-bf01-00aa0055595a");

		public static readonly Guid FORMAT_MPEGVideo = new Guid("05589f82-c356-11ce-bf01-00aa0055595a");

		public static readonly Guid FORMAT_MPEGStreams = new Guid("05589f83-c356-11ce-bf01-00aa0055595a");

		public static readonly Guid FORMAT_DvInfo = new Guid("05589f84-c356-11ce-bf01-00aa0055595a");

		public static readonly Guid FORMAT_525WSS = new Guid("C7ECF04D-4582-4869-9ABB-BFB523B62EDF");
	}
	internal enum DmoHResults
	{
		DMO_E_INVALIDSTREAMINDEX = -2147220991,
		DMO_E_INVALIDTYPE,
		DMO_E_TYPE_NOT_SET,
		DMO_E_NOTACCEPTING,
		DMO_E_TYPE_NOT_ACCEPTED,
		DMO_E_NO_MORE_ITEMS
	}
	internal static class DmoInterop
	{
		[DllImport("msdmo.dll")]
		public static extern int DMOEnum([In] ref Guid guidCategory, DmoEnumFlags flags, int inTypes, [In] DmoPartialMediaType[] inTypesArray, int outTypes, [In] DmoPartialMediaType[] outTypesArray, out IEnumDmo enumDmo);

		[DllImport("msdmo.dll")]
		public static extern int MoFreeMediaType([In] ref DmoMediaType mediaType);

		[DllImport("msdmo.dll")]
		public static extern int MoInitMediaType([In][Out] ref DmoMediaType mediaType, int formatBlockBytes);

		[DllImport("msdmo.dll")]
		public static extern int DMOGetName([In] ref Guid clsidDMO, [Out] StringBuilder name);
	}
	internal struct DmoPartialMediaType
	{
		private Guid type;

		private Guid subtype;

		public Guid Type
		{
			get
			{
				return type;
			}
			internal set
			{
				type = value;
			}
		}

		public Guid Subtype
		{
			get
			{
				return subtype;
			}
			internal set
			{
				subtype = value;
			}
		}
	}
	[ComImport]
	[SuppressUnmanagedCodeSecurity]
	[Guid("6d6cbb60-a223-44aa-842f-a2f06750be6d")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface IMediaParamInfo
	{
		[PreserveSig]
		int GetParamCount(out int paramCount);

		[PreserveSig]
		int GetParamInfo(int paramIndex, ref MediaParamInfo paramInfo);

		[PreserveSig]
		int GetParamText(int paramIndex, out IntPtr paramText);

		[PreserveSig]
		int GetNumTimeFormats(out int numTimeFormats);

		[PreserveSig]
		int GetSupportedTimeFormat(int formatIndex, out Guid guidTimeFormat);

		[PreserveSig]
		int GetCurrentTimeFormat(out Guid guidTimeFormat, out int mediaTimeData);
	}
	[Guid("E7E9984F-F09F-4da4-903F-6E2E0EFE56B5")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface IWMResamplerProps
	{
		int SetHalfFilterLength(int outputQuality);

		int SetUserChannelMtx([In] float[] channelConversionMatrix);
	}
	public class MediaBuffer : IMediaBuffer, IDisposable
	{
		private IntPtr buffer;

		private int length;

		private readonly int maxLength;

		public int Length
		{
			get
			{
				return length;
			}
			set
			{
				if (length > maxLength)
				{
					throw new ArgumentException("Cannot be greater than maximum buffer size");
				}
				length = value;
			}
		}

		public MediaBuffer(int maxLength)
		{
			buffer = Marshal.AllocCoTaskMem(maxLength);
			this.maxLength = maxLength;
		}

		public void Dispose()
		{
			if (buffer != IntPtr.Zero)
			{
				Marshal.FreeCoTaskMem(buffer);
				buffer = IntPtr.Zero;
				GC.SuppressFinalize(this);
			}
		}

		~MediaBuffer()
		{
			Dispose();
		}

		int IMediaBuffer.SetLength(int length)
		{
			if (length > maxLength)
			{
				return -2147483645;
			}
			this.length = length;
			return 0;
		}

		int IMediaBuffer.GetMaxLength(out int maxLength)
		{
			maxLength = this.maxLength;
			return 0;
		}

		int IMediaBuffer.GetBufferAndLength(IntPtr bufferPointerPointer, IntPtr validDataLengthPointer)
		{
			if (bufferPointerPointer != IntPtr.Zero)
			{
				Marshal.WriteIntPtr(bufferPointerPointer, buffer);
			}
			if (validDataLengthPointer != IntPtr.Zero)
			{
				Marshal.WriteInt32(validDataLengthPointer, length);
			}
			return 0;
		}

		public void LoadData(byte[] data, int bytes)
		{
			Length = bytes;
			Marshal.Copy(data, 0, buffer, bytes);
		}

		public void RetrieveData(byte[] data, int offset)
		{
			Marshal.Copy(buffer, data, offset, Length);
		}
	}
	public class MediaObject : IDisposable
	{
		private IMediaObject mediaObject;

		private readonly int inputStreams;

		private readonly int outputStreams;

		public int InputStreamCount => inputStreams;

		public int OutputStreamCount => outputStreams;

		internal MediaObject(IMediaObject mediaObject)
		{
			this.mediaObject = mediaObject;
			mediaObject.GetStreamCount(out inputStreams, out outputStreams);
		}

		public DmoMediaType? GetInputType(int inputStream, int inputTypeIndex)
		{
			try
			{
				if (mediaObject.GetInputType(inputStream, inputTypeIndex, out var mediaType) == 0)
				{
					DmoInterop.MoFreeMediaType(ref mediaType);
					return mediaType;
				}
			}
			catch (COMException exception)
			{
				if (exception.GetHResult() != -2147220986)
				{
					throw;
				}
			}
			return null;
		}

		public DmoMediaType? GetOutputType(int outputStream, int outputTypeIndex)
		{
			try
			{
				if (mediaObject.GetOutputType(outputStream, outputTypeIndex, out var mediaType) == 0)
				{
					DmoInterop.MoFreeMediaType(ref mediaType);
					return mediaType;
				}
			}
			catch (COMException exception)
			{
				if (exception.GetHResult() != -2147220986)
				{
					throw;
				}
			}
			return null;
		}

		public DmoMediaType GetOutputCurrentType(int outputStreamIndex)
		{
			DmoMediaType mediaType;
			int outputCurrentType = mediaObject.GetOutputCurrentType(outputStreamIndex, out mediaType);
			switch (outputCurrentType)
			{
			case 0:
				DmoInterop.MoFreeMediaType(ref mediaType);
				return mediaType;
			case -2147220989:
				throw new InvalidOperationException("Media type was not set.");
			default:
				throw Marshal.GetExceptionForHR(outputCurrentType);
			}
		}

		public IEnumerable<DmoMediaType> GetInputTypes(int inputStreamIndex)
		{
			int typeIndex = 0;
			while (true)
			{
				DmoMediaType? inputType;
				DmoMediaType? mediaType = (inputType = GetInputType(inputStreamIndex, typeIndex));
				inputType = inputType;
				if (inputType.HasValue)
				{
					yield return mediaType.Value;
					typeIndex++;
					continue;
				}
				break;
			}
		}

		public IEnumerable<DmoMediaType> GetOutputTypes(int outputStreamIndex)
		{
			int typeIndex = 0;
			while (true)
			{
				DmoMediaType? outputType;
				DmoMediaType? mediaType = (outputType = GetOutputType(outputStreamIndex, typeIndex));
				outputType = outputType;
				if (outputType.HasValue)
				{
					yield return mediaType.Value;
					typeIndex++;
					continue;
				}
				break;
			}
		}

		public bool SupportsInputType(int inputStreamIndex, DmoMediaType mediaType)
		{
			return SetInputType(inputStreamIndex, mediaType, DmoSetTypeFlags.DMO_SET_TYPEF_TEST_ONLY);
		}

		private bool SetInputType(int inputStreamIndex, DmoMediaType mediaType, DmoSetTypeFlags flags)
		{
			switch (mediaObject.SetInputType(inputStreamIndex, ref mediaType, flags))
			{
			case -2147220991:
				throw new ArgumentException("Invalid stream index");
			default:
				_ = -2147220987;
				return false;
			case 0:
				return true;
			}
		}

		public void SetInputType(int inputStreamIndex, DmoMediaType mediaType)
		{
			if (!SetInputType(inputStreamIndex, mediaType, DmoSetTypeFlags.None))
			{
				throw new ArgumentException("Media Type not supported");
			}
		}

		public void SetInputWaveFormat(int inputStreamIndex, WaveFormat waveFormat)
		{
			DmoMediaType mediaType = CreateDmoMediaTypeForWaveFormat(waveFormat);
			bool num = SetInputType(inputStreamIndex, mediaType, DmoSetTypeFlags.None);
			DmoInterop.MoFreeMediaType(ref mediaType);
			if (!num)
			{
				throw new ArgumentException("Media Type not supported");
			}
		}

		public bool SupportsInputWaveFormat(int inputStreamIndex, WaveFormat waveFormat)
		{
			DmoMediaType mediaType = CreateDmoMediaTypeForWaveFormat(waveFormat);
			bool result = SetInputType(inputStreamIndex, mediaType, DmoSetTypeFlags.DMO_SET_TYPEF_TEST_ONLY);
			DmoInterop.MoFreeMediaType(ref mediaType);
			return result;
		}

		private DmoMediaType CreateDmoMediaTypeForWaveFormat(WaveFormat waveFormat)
		{
			DmoMediaType mediaType = default(DmoMediaType);
			int formatBlockBytes = Marshal.SizeOf((object)waveFormat);
			DmoInterop.MoInitMediaType(ref mediaType, formatBlockBytes);
			mediaType.SetWaveFormat(waveFormat);
			return mediaType;
		}

		public bool SupportsOutputType(int outputStreamIndex, DmoMediaType mediaType)
		{
			return SetOutputType(outputStreamIndex, mediaType, DmoSetTypeFlags.DMO_SET_TYPEF_TEST_ONLY);
		}

		public bool SupportsOutputWaveFormat(int outputStreamIndex, WaveFormat waveFormat)
		{
			DmoMediaType mediaType = CreateDmoMediaTypeForWaveFormat(waveFormat);
			bool result = SetOutputType(outputStreamIndex, mediaType, DmoSetTypeFlags.DMO_SET_TYPEF_TEST_ONLY);
			DmoInterop.MoFreeMediaType(ref mediaType);
			return result;
		}

		private bool SetOutputType(int outputStreamIndex, DmoMediaType mediaType, DmoSetTypeFlags flags)
		{
			int num = mediaObject.SetOutputType(outputStreamIndex, ref mediaType, flags);
			return num switch
			{
				-2147220987 => false, 
				0 => true, 
				_ => throw Marshal.GetExceptionForHR(num), 
			};
		}

		public void SetOutputType(int outputStreamIndex, DmoMediaType mediaType)
		{
			if (!SetOutputType(outputStreamIndex, mediaType, DmoSetTypeFlags.None))
			{
				throw new ArgumentException("Media Type not supported");
			}
		}

		public void SetOutputWaveFormat(int outputStreamIndex, WaveFormat waveFormat)
		{
			DmoMediaType mediaType = CreateDmoMediaTypeForWaveFormat(waveFormat);
			bool num = SetOutputType(outputStreamIndex, mediaType, DmoSetTypeFlags.None);
			DmoInterop.MoFreeMediaType(ref mediaType);
			if (!num)
			{
				throw new ArgumentException("Media Type not supported");
			}
		}

		public MediaObjectSizeInfo GetInputSizeInfo(int inputStreamIndex)
		{
			Marshal.ThrowExceptionForHR(mediaObject.GetInputSizeInfo(inputStreamIndex, out var size, out var maxLookahead, out var alignment));
			return new MediaObjectSizeInfo(size, maxLookahead, alignment);
		}

		public MediaObjectSizeInfo GetOutputSizeInfo(int outputStreamIndex)
		{
			Marshal.ThrowExceptionForHR(mediaObject.GetOutputSizeInfo(outputStreamIndex, out var size, out var alignment));
			return new MediaObjectSizeInfo(size, 0, alignment);
		}

		public void ProcessInput(int inputStreamIndex, IMediaBuffer mediaBuffer, DmoInputDataBufferFlags flags, long timestamp, long duration)
		{
			Marshal.ThrowExceptionForHR(mediaObject.ProcessInput(inputStreamIndex, mediaBuffer, flags, timestamp, duration));
		}

		public void ProcessOutput(DmoProcessOutputFlags flags, int outputBufferCount, DmoOutputDataBuffer[] outputBuffers)
		{
			Marshal.ThrowExceptionForHR(mediaObject.ProcessOutput(flags, outputBufferCount, outputBuffers, out var _));
		}

		public void AllocateStreamingResources()
		{
			Marshal.ThrowExceptionForHR(mediaObject.AllocateStreamingResources());
		}

		public void FreeStreamingResources()
		{
			Marshal.ThrowExceptionForHR(mediaObject.FreeStreamingResources());
		}

		public long GetInputMaxLatency(int inputStreamIndex)
		{
			Marshal.ThrowExceptionForHR(mediaObject.GetInputMaxLatency(inputStreamIndex, out var referenceTimeMaxLatency));
			return referenceTimeMaxLatency;
		}

		public void Flush()
		{
			Marshal.ThrowExceptionForHR(mediaObject.Flush());
		}

		public void Discontinuity(int inputStreamIndex)
		{
			Marshal.ThrowExceptionForHR(mediaObject.Discontinuity(inputStreamIndex));
		}

		public bool IsAcceptingData(int inputStreamIndex)
		{
			Marshal.ThrowExceptionForHR(mediaObject.GetInputStatus(inputStreamIndex, out var flags));
			return (flags & DmoInputStatusFlags.DMO_INPUT_STATUSF_ACCEPT_DATA) == DmoInputStatusFlags.DMO_INPUT_STATUSF_ACCEPT_DATA;
		}

		public void Dispose()
		{
			if (mediaObject != null)
			{
				Marshal.ReleaseComObject(mediaObject);
				mediaObject = null;
			}
		}
	}
	public class MediaObjectSizeInfo
	{
		public int Size { get; private set; }

		public int MaxLookahead { get; }

		public int Alignment { get; }

		public MediaObjectSizeInfo(int size, int maxLookahead, int alignment)
		{
			Size = size;
			MaxLookahead = maxLookahead;
			Alignment = alignment;
		}

		public override string ToString()
		{
			return $"Size: {Size}, Alignment {Alignment}, MaxLookahead {MaxLookahead}";
		}
	}
	internal struct MediaParamInfo
	{
		public MediaParamType mpType;

		public MediaParamCurveType mopCaps;

		public float mpdMinValue;

		public float mpdMaxValue;

		public float mpdNeutralValue;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
		public string szUnitText;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
		public string szLabel;
	}
	internal enum MediaParamType
	{
		Int,
		Float,
		Bool,
		Enum,
		Max
	}
	[Flags]
	internal enum MediaParamCurveType
	{
		MP_CURVE_JUMP = 1,
		MP_CURVE_LINEAR = 2,
		MP_CURVE_SQUARE = 4,
		MP_CURVE_INVSQUARE = 8,
		MP_CURVE_SINE = 0x10
	}
	internal static class MediaTypes
	{
		public static readonly Guid MEDIATYPE_AnalogAudio = new Guid("0482DEE1-7817-11cf-8a03-00aa006ecb65");

		public static readonly Guid MEDIATYPE_AnalogVideo = new Guid("0482DDE1-7817-11cf-8A03-00AA006ECB65");

		public static readonly Guid MEDIATYPE_Audio = new Guid("73647561-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIATYPE_AUXLine21Data = new Guid("670AEA80-3A82-11d0-B79B-00AA003767A7");

		public static readonly Guid MEDIATYPE_File = new Guid("656c6966-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIATYPE_Interleaved = new Guid("73766169-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIATYPE_Midi = new Guid("7364696D-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIATYPE_ScriptCommand = new Guid("73636d64-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIATYPE_Stream = new Guid("e436eb83-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIATYPE_Text = new Guid("73747874-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIATYPE_Timecode = new Guid("0482DEE3-7817-11cf-8a03-00aa006ecb65");

		public static readonly Guid MEDIATYPE_Video = new Guid("73646976-0000-0010-8000-00AA00389B71");

		public static readonly Guid[] MajorTypes = new Guid[12]
		{
			MEDIATYPE_AnalogAudio, MEDIATYPE_AnalogVideo, MEDIATYPE_Audio, MEDIATYPE_AUXLine21Data, MEDIATYPE_File, MEDIATYPE_Interleaved, MEDIATYPE_Midi, MEDIATYPE_ScriptCommand, MEDIATYPE_Stream, MEDIATYPE_Text,
			MEDIATYPE_Timecode, MEDIATYPE_Video
		};

		public static readonly string[] MajorTypeNames = new string[12]
		{
			"Analog Audio", "Analog Video", "Audio", "AUXLine21Data", "File", "Interleaved", "Midi", "ScriptCommand", "Stream", "Text",
			"Timecode", "Video"
		};

		public static string GetMediaTypeName(Guid majorType)
		{
			for (int i = 0; i < MajorTypes.Length; i++)
			{
				if (majorType == MajorTypes[i])
				{
					return MajorTypeNames[i];
				}
			}
			throw new ArgumentException("Major Type not found");
		}
	}
	[ComImport]
	[Guid("bbeea841-0a63-4f52-a7ab-a9b3a84ed38a")]
	internal class WindowsMediaMp3DecoderComObject
	{
	}
	public class WindowsMediaMp3Decoder : IDisposable
	{
		private MediaObject mediaObject;

		private IPropertyStore propertyStoreInterface;

		private WindowsMediaMp3DecoderComObject mediaComObject;

		public MediaObject MediaObject => mediaObject;

		public WindowsMediaMp3Decoder()
		{
			mediaComObject = new WindowsMediaMp3DecoderComObject();
			mediaObject = new MediaObject((IMediaObject)mediaComObject);
			propertyStoreInterface = (IPropertyStore)mediaComObject;
		}

		public void Dispose()
		{
			if (propertyStoreInterface != null)
			{
				Marshal.ReleaseComObject(propertyStoreInterface);
				propertyStoreInterface = null;
			}
			if (mediaObject != null)
			{
				mediaObject.Dispose();
				mediaObject = null;
			}
			if (mediaComObject != null)
			{
				Marshal.ReleaseComObject(mediaComObject);
				mediaComObject = null;
			}
		}
	}
	[Flags]
	public enum DmoInputDataBufferFlags
	{
		None = 0,
		SyncPoint = 1,
		Time = 2,
		TimeLength = 4
	}
	[Flags]
	internal enum DmoInputStatusFlags
	{
		None = 0,
		DMO_INPUT_STATUSF_ACCEPT_DATA = 1
	}
	public struct DmoMediaType
	{
		private Guid majortype;

		private Guid subtype;

		private bool bFixedSizeSamples;

		private bool bTemporalCompression;

		private int lSampleSize;

		private Guid formattype;

		private IntPtr pUnk;

		private int cbFormat;

		private IntPtr pbFormat;

		public Guid MajorType => majortype;

		public string MajorTypeName => MediaTypes.GetMediaTypeName(majortype);

		public Guid SubType => subtype;

		public string SubTypeName
		{
			get
			{
				if (majortype == MediaTypes.MEDIATYPE_Audio)
				{
					return AudioMediaSubtypes.GetAudioSubtypeName(subtype);
				}
				return subtype.ToString();
			}
		}

		public bool FixedSizeSamples => bFixedSizeSamples;

		public int SampleSize => lSampleSize;

		public Guid FormatType => formattype;

		public string FormatTypeName
		{
			get
			{
				if (formattype == DmoMediaTypeGuids.FORMAT_None)
				{
					return "None";
				}
				if (formattype == Guid.Empty)
				{
					return "Null";
				}
				if (formattype == DmoMediaTypeGuids.FORMAT_WaveFormatEx)
				{
					return "WaveFormatEx";
				}
				return FormatType.ToString();
			}
		}

		public WaveFormat GetWaveFormat()
		{
			if (formattype == DmoMediaTypeGuids.FORMAT_WaveFormatEx)
			{
				return WaveFormat.MarshalFromPtr(pbFormat);
			}
			throw new InvalidOperationException("Not a WaveFormat type");
		}

		public void SetWaveFormat(WaveFormat waveFormat)
		{
			majortype = MediaTypes.MEDIATYPE_Audio;
			if (waveFormat is WaveFormatExtensible waveFormatExtensible)
			{
				subtype = waveFormatExtensible.SubFormat;
			}
			else
			{
				switch (waveFormat.Encoding)
				{
				case WaveFormatEncoding.Pcm:
					subtype = AudioMediaSubtypes.MEDIASUBTYPE_PCM;
					break;
				case WaveFormatEncoding.IeeeFloat:
					subtype = AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT;
					break;
				case WaveFormatEncoding.MpegLayer3:
					subtype = AudioMediaSubtypes.WMMEDIASUBTYPE_MP3;
					break;
				default:
					throw new ArgumentException($"Not a supported encoding {waveFormat.Encoding}");
				}
			}
			bFixedSizeSamples = SubType == AudioMediaSubtypes.MEDIASUBTYPE_PCM || SubType == AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT;
			formattype = DmoMediaTypeGuids.FORMAT_WaveFormatEx;
			if (cbFormat < Marshal.SizeOf((object)waveFormat))
			{
				throw new InvalidOperationException("Not enough memory assigned for a WaveFormat structure");
			}
			Marshal.StructureToPtr((object)waveFormat, pbFormat, fDeleteOld: false);
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 8)]
	public struct DmoOutputDataBuffer : IDisposable
	{
		[MarshalAs(UnmanagedType.Interface)]
		private IMediaBuffer pBuffer;

		private DmoOutputDataBufferFlags dwStatus;

		private long rtTimestamp;

		private long referenceTimeDuration;

		public IMediaBuffer MediaBuffer
		{
			get
			{
				return pBuffer;
			}
			internal set
			{
				pBuffer = value;
			}
		}

		public int Length => ((MediaBuffer)pBuffer).Length;

		public DmoOutputDataBufferFlags StatusFlags
		{
			get
			{
				return dwStatus;
			}
			internal set
			{
				dwStatus = value;
			}
		}

		public long Timestamp
		{
			get
			{
				return rtTimestamp;
			}
			internal set
			{
				rtTimestamp = value;
			}
		}

		public long Duration
		{
			get
			{
				return referenceTimeDuration;
			}
			internal set
			{
				referenceTimeDuration = value;
			}
		}

		public bool MoreDataAvailable => (StatusFlags & DmoOutputDataBufferFlags.Incomplete) == DmoOutputDataBufferFlags.Incomplete;

OriginalSoundTrack.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Xml;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using EnemiesReturns.ModdedEntityStates.Judgement.Arraign.Phase1;
using EnemiesReturns.ModdedEntityStates.Judgement.WaveInteractable;
using EntityStates.ArtifactShell;
using EntityStates.FalseSonBoss;
using EntityStates.Missions.BrotherEncounter;
using EntityStates.Missions.ChampRush;
using EntityStates.Missions.ProvidenceBossEncounter;
using EntityStates.SolusHeart;
using EntityStates.SolusHeart.Death;
using EntityStates.SolusWing;
using EntityStates.TeleporterCatastrophe.DLC4.Teleporter;
using EntityStates.VoidRaidCrab;
using FathomlessVoidling.EntityStates;
using HarmonyLib;
using NAudio.Wave;
using NAudio.Wave.SampleProviders;
using On.EntityStates.ArtifactShell;
using On.EntityStates.FalseSonBoss;
using On.EntityStates.Missions.BrotherEncounter;
using On.EntityStates.Missions.ChampRush;
using On.EntityStates.Missions.ProvidenceBossEncounter;
using On.EntityStates.SolusHeart;
using On.EntityStates.SolusHeart.Death;
using On.EntityStates.SolusWing;
using On.EntityStates.TeleporterCatastrophe.DLC4.Teleporter;
using On.EntityStates.VoidRaidCrab;
using On.RoR2;
using On.RoR2.Quests.TrialQuests;
using On.RoR2.UI;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.ConVar;
using RoR2.Quests.TrialQuests;
using RoR2.UI;
using TagLib;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("OriginalSoundTrack")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+47d450bfc45073eb8a69c71cdec477c83a625cd8")]
[assembly: AssemblyProduct("OriginalSoundTrack")]
[assembly: AssemblyTitle("OriginalSoundTrack")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace OriginalSoundTrack;

internal static class enemiesreturnswrapper
{
	private static OriginalSoundTrack ostplugin;

	private static bool? _Present;

	public static bool Present
	{
		get
		{
			if (!_Present.HasValue)
			{
				_Present = Chainloader.PluginInfos.ContainsKey("com.Viliger.EnemiesReturns");
			}
			return _Present.Value;
		}
	}

	[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
	public static void Init(OriginalSoundTrack instance)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		Debug.Log((object)"hey i loaded correctly");
		ostplugin = instance;
		Harmony val = new Harmony("com.jasoncreatesblep.moreostsmodplus");
		val.PatchAll(typeof(enemiesreturnswrapper));
	}

	[HarmonyPatch(typeof(Spawn), "OnEnter")]
	[HarmonyPostfix]
	private static void PatchOnEnter()
	{
		Debug.Log((object)"====================== JUDGEMENT BOSS FIGHT START ======================");
		ostplugin.extratracksfrfr = false;
		ostplugin.bossActive = false;
		ostplugin.afterBossPhase = true;
		ostplugin.hasshuffled = false;
		ostplugin.listtracker = 0;
		ostplugin.JudgementWaveCounter = 0;
		ostplugin.PickOutMusic();
	}

	[HarmonyPatch(typeof(StartingUp), "OnEnter")]
	[HarmonyPostfix]
	private static void PatchOnEnter2()
	{
		ostplugin.JudgementWaveCounter++;
		if (!ostplugin.bossActive)
		{
			Debug.Log((object)"====================== JUDGEMENT TRIAl START ======================");
			ostplugin.bossActive = true;
			ostplugin.hasshuffled = false;
			ostplugin.listtracker = 0;
			ostplugin.PickOutMusic(isForTeleporter: true);
		}
		if (ostplugin.JudgementWaveCounter == 5 && ostplugin.judgementfinalwavesenabled)
		{
			Debug.Log((object)"====================== LAST 2 WAVES REMAINING ======================");
			ostplugin.extratracksfrfr = true;
			ostplugin.bossActive = true;
			ostplugin.hasshuffled = false;
			ostplugin.listtracker = 0;
			ostplugin.PickOutMusic(isForTeleporter: true);
		}
	}
}
internal static class fathomlesswrapper
{
	private static OriginalSoundTrack ostpluginfathomless;

	private static bool? _Present2;

	public static bool Present2
	{
		get
		{
			if (!_Present2.HasValue)
			{
				_Present2 = Chainloader.PluginInfos.ContainsKey("Nuxlar.FathomlessVoidling");
			}
			return _Present2.Value;
		}
	}

	[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
	public static void Init2(OriginalSoundTrack instance2)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		Debug.Log((object)"hey i loaded correctly as well uwu");
		ostpluginfathomless = instance2;
		Harmony val = new Harmony("com.jasoncreatesblep.moreostsmodplus");
		val.PatchAll(typeof(fathomlesswrapper));
	}

	[HarmonyPatch(typeof(BetterSpawnState), "OnEnter")]
	[HarmonyPostfix]
	private static void PatchOnEnter()
	{
		Debug.Log((object)"====================== FATHOMLESS VOIDLING BOSS START ======================");
		ostpluginfathomless.extratracksfrfr = false;
		ostpluginfathomless.bossActive = true;
		ostpluginfathomless.afterBossPhase = false;
		ostpluginfathomless.hasshuffled = false;
		ostpluginfathomless.listtracker = 0;
		ostpluginfathomless.PickOutMusic(isForTeleporter: true);
	}
}
internal class NetworkCompatibilityAttribute : Attribute
{
	private CompatibilityLevel noNeedForSync;

	private VersionStrictness differentModVersionsAreOk;

	public NetworkCompatibilityAttribute(CompatibilityLevel noNeedForSync, VersionStrictness differentModVersionsAreOk)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		this.noNeedForSync = noNeedForSync;
		this.differentModVersionsAreOk = differentModVersionsAreOk;
	}
}
[BepInPlugin("com.jasoncreatesblep.moreostsmodplus", "MoreOSTsModPlus", "2.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class OriginalSoundTrack : BaseUnityPlugin
{
	private enum postbossmusicmode
	{
		silence,
		alttrack,
		normaltrack
	}

	private enum randomizationmodelist
	{
		off,
		shuffle,
		shuffleonce
	}

	public class Music
	{
		public string name;

		public string fullName;

		public string[] scenes;

		public bool boss = false;

		public float volume = 1f;

		public bool loop = false;

		public bool afterboss = false;

		public bool simulacrum = false;

		public bool postloopvariant = false;

		public bool isextratrack = false;

		public bool soulboundboss = false;
	}

	public class LoopStream : WaveStream
	{
		private WaveStream sourceStream;

		private bool EnableLooping = true;

		public override WaveFormat WaveFormat => sourceStream.WaveFormat;

		public override long Position
		{
			get
			{
				return ((Stream)(object)sourceStream).Position;
			}
			set
			{
				((Stream)(object)sourceStream).Position = value;
			}
		}

		public override long Length => ((Stream)(object)sourceStream).Length;

		public LoopStream(WaveStream sourceStream, bool shouldLoop)
		{
			this.sourceStream = sourceStream;
			EnableLooping = shouldLoop;
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			int i;
			int num2;
			for (i = 0; i < count; i += num2)
			{
				int num = count - i;
				num2 = ((Stream)(object)sourceStream).Read(buffer, offset + i, num);
				if (num2 < num || ((Stream)(object)sourceStream).Position >= ((Stream)(object)sourceStream).Length)
				{
					if (!EnableLooping)
					{
						break;
					}
					((Stream)(object)sourceStream).Position = 0L;
				}
			}
			return i;
		}
	}

	private FadeInOutSampleProvider fader;

	private WaveOutEvent outputDevice;

	private FileInfo[] soundFiles;

	private List<Music> musics = new List<Music>();

	private AudioFileReader currentSong;

	private string currentSongFullName = "";

	private bool songPaused = false;

	private float currentMusicVolume;

	private ConfigEntry<float> globalMusicVolume;

	private ConfigEntry<bool> EnableMetaData;

	private bool shouldLoop = true;

	public bool hasshuffled = false;

	private string oldMusicVolume = "";

	private string currentScene = "";

	private Random rnd = new Random();

	private postbossmusicmode postbossmusic = postbossmusicmode.silence;

	private randomizationmodelist randomizationmode = randomizationmodelist.off;

	private XmlElement settings;

	private Texture2D modIconTexture;

	private SceneIndex lastStageIndex = (SceneIndex)(-1);

	public bool bossActive = false;

	public bool afterBossPhase = false;

	public bool simulacrumactive = false;

	public bool playanimamusic = false;

	public bool playerhaslooped = false;

	private string[] storedloopstages = null;

	private int postloopamount = 0;

	public bool extratracksfrfr = false;

	public int JudgementWaveCounter = 0;

	public bool artifactmusicenabled = false;

	public bool judgementfinalwavesenabled = false;

	public bool soultrialstrackenabled = false;

	public bool karmicmithrixtrackenabled = false;

	public bool winnowingreckoningenabled = false;

	public bool mithrixaltoutro = false;

	public int listtracker = 0;

	private string lasttitle = "";

	public void Awake()
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Expected O, but got Unknown
		//IL_0063: Expected O, but got Unknown
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Expected O, but got Unknown
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Expected O, but got Unknown
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Expected O, but got Unknown
		//IL_00f4: Expected O, but got Unknown
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Expected O, but got Unknown
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Expected O, but got Unknown
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0777: Unknown result type (might be due to invalid IL or missing references)
		//IL_0781: Expected O, but got Unknown
		//IL_0789: Unknown result type (might be due to invalid IL or missing references)
		//IL_0793: Expected O, but got Unknown
		//IL_079b: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a5: Expected O, but got Unknown
		//IL_07ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_07b7: Expected O, but got Unknown
		//IL_07bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_07c9: Expected O, but got Unknown
		//IL_07d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_07db: Expected O, but got Unknown
		//IL_07e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_07ed: Expected O, but got Unknown
		//IL_07f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_07ff: Expected O, but got Unknown
		//IL_0807: Unknown result type (might be due to invalid IL or missing references)
		//IL_0811: Expected O, but got Unknown
		//IL_0819: Unknown result type (might be due to invalid IL or missing references)
		//IL_0823: Expected O, but got Unknown
		//IL_082b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0835: Expected O, but got Unknown
		//IL_083d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0847: Expected O, but got Unknown
		//IL_084f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0859: Expected O, but got Unknown
		//IL_0861: Unknown result type (might be due to invalid IL or missing references)
		//IL_086b: Expected O, but got Unknown
		//IL_0873: Unknown result type (might be due to invalid IL or missing references)
		//IL_087d: Expected O, but got Unknown
		//IL_0885: Unknown result type (might be due to invalid IL or missing references)
		//IL_088f: Expected O, but got Unknown
		//IL_0897: Unknown result type (might be due to invalid IL or missing references)
		//IL_08a1: Expected O, but got Unknown
		//IL_08a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_08b3: Expected O, but got Unknown
		//IL_08bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_08c5: Expected O, but got Unknown
		//IL_08cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d7: Expected O, but got Unknown
		//IL_08df: Unknown result type (might be due to invalid IL or missing references)
		//IL_08e9: Expected O, but got Unknown
		//IL_08f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_08fb: Expected O, but got Unknown
		//IL_0903: Unknown result type (might be due to invalid IL or missing references)
		//IL_090d: Expected O, but got Unknown
		//IL_0915: Unknown result type (might be due to invalid IL or missing references)
		//IL_091f: Expected O, but got Unknown
		//IL_0927: Unknown result type (might be due to invalid IL or missing references)
		//IL_0931: Expected O, but got Unknown
		//IL_0939: Unknown result type (might be due to invalid IL or missing references)
		//IL_0943: Expected O, but got Unknown
		//IL_0765: Unknown result type (might be due to invalid IL or missing references)
		//IL_076f: Expected O, but got Unknown
		TeleporterInteraction.onTeleporterChargedGlobal += OnTeleporterFinished;
		string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		string text = directoryName;
		globalMusicVolume = ((BaseUnityPlugin)this).Config.Bind<float>(new ConfigDefinition("General", "Volume"), 40f, new ConfigDescription("The volume of the More OSTs Mod music. KEEP THE GAME'S MUSIC VOLUME AT 0!!!", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
		ModSettingsManager.AddOption((BaseOption)new StepSliderOption(globalMusicVolume, new StepSliderConfig
		{
			min = 0f,
			max = 100f,
			increment = 1f,
			formatString = "{0:0}%"
		}));
		globalMusicVolume.SettingChanged += delegate
		{
			UpdateVolume();
		};
		EnableMetaData = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("General", "Display Metadata"), true, new ConfigDescription("toggles whether the current song's title and artist will display in chat", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(EnableMetaData));
		modIconTexture = new Texture2D(0, 0);
		using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("OriginalSoundTrack.ror2_more_osts_mod_clean.png"))
		{
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			byte[] array = memoryStream.ToArray();
			ImageConversion.LoadImage(modIconTexture, array);
		}
		Sprite modIcon = Sprite.Create(modIconTexture, new Rect(0f, 0f, (float)((Texture)modIconTexture).width, (float)((Texture)modIconTexture).height), new Vector2(0f, 0f));
		ModSettingsManager.SetModIcon(modIcon);
		try
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(directoryName + "/settings.xml");
			settings = xmlDocument["settings"];
			shouldLoop = settings["loop"].InnerText.ToLower() == "true";
			if (Enum.TryParse<postbossmusicmode>(settings["aftertptracks"].InnerText, ignoreCase: true, out var result))
			{
				postbossmusic = result;
			}
			if (Enum.TryParse<randomizationmodelist>(settings["randomization"].InnerText, ignoreCase: true, out var result2))
			{
				randomizationmode = result2;
			}
			if (settings["music-path"] != null)
			{
				text = settings["music-path"].InnerText;
			}
			soundFiles = SearchForAudioFiles(text);
			foreach (XmlNode setting in settings)
			{
				if (setting.Name == "postloopstagetracksettings")
				{
					storedloopstages = (from str in settings["postloopstagetracksettings"].GetAttribute("loopscenes").Split(',')
						select str.Trim()).ToArray();
					if (int.TryParse(settings["postloopstagetracksettings"].GetAttribute("enableatloop"), out var result3))
					{
						postloopamount = result3;
					}
				}
				if (setting.Name == "extratracksettings")
				{
					if (bool.TryParse(settings["extratracksettings"].GetAttribute("artifacttrialmusic"), out var result4))
					{
						artifactmusicenabled = result4;
					}
					if (bool.TryParse(settings["extratracksettings"].GetAttribute("judgementwave5track"), out var result5))
					{
						judgementfinalwavesenabled = result5;
					}
					if (bool.TryParse(settings["extratracksettings"].GetAttribute("soultrialtptrack"), out var result6))
					{
						soultrialstrackenabled = result6;
					}
					if (bool.TryParse(settings["extratracksettings"].GetAttribute("karma8mithrixtrack"), out var result7))
					{
						karmicmithrixtrackenabled = result7;
					}
					if (bool.TryParse(settings["extratracksettings"].GetAttribute("winnowingreckoning"), out var result8))
					{
						winnowingreckoningenabled = result8;
					}
				}
			}
			foreach (XmlNode childNode in settings["music"].ChildNodes)
			{
				if (childNode.NodeType == XmlNodeType.Comment)
				{
					continue;
				}
				Music music = new Music();
				music.name = GetAttribute(childNode, "name");
				music.scenes = (from str in GetAttribute(childNode, "scenes").Split(',')
					select str.Trim()).ToArray();
				music.boss = GetAttribute(childNode, "boss").ToLower() == "true";
				music.afterboss = GetAttribute(childNode, "afterboss").ToLower() == "true";
				music.simulacrum = GetAttribute(childNode, "simulacrum").ToLower() == "true";
				music.postloopvariant = GetAttribute(childNode, "postloopvariant").ToLower() == "true";
				music.isextratrack = GetAttribute(childNode, "isextratrack").ToLower() == "true";
				music.soulboundboss = GetAttribute(childNode, "soulboundboss").ToLower().Equals("true");
				if (float.TryParse(GetAttribute(childNode, "volume"), NumberStyles.Any, CultureInfo.InvariantCulture, out var result9))
				{
					music.volume = result9;
				}
				music.loop = GetAttribute(childNode, "loop").ToLower() == "true";
				FileInfo[] array2 = soundFiles;
				foreach (FileInfo fileInfo in array2)
				{
					if (fileInfo.Name == music.name)
					{
						music.fullName = fileInfo.FullName;
						break;
					}
				}
				musics.Add(music);
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)"!!!!! OriginalSoundTrack Mod: Failed to parse settings.xml !!!!!");
			Debug.Log((object)"OriginalSoundTrack Mod: Music will be randomly selected from what is found in the plugin dir.");
			Debug.Log((object)ex);
		}
		if (soundFiles == null)
		{
			text = directoryName;
			soundFiles = SearchForAudioFiles(text);
		}
		if (soundFiles.Length == 0)
		{
			Debug.LogError((object)"!!!!! OriginalSoundTrack Mod: No audio files found. Exiting. !!!!!");
			Debug.LogError((object)("OriginalSoundTrack Mod: Looked for .mp3 and .wav files in: " + text));
			return;
		}
		if (outputDevice == null)
		{
			outputDevice = new WaveOutEvent();
		}
		TeleporterInteraction.OnInteractionBegin += (hook_OnInteractionBegin)delegate(orig_OnInteractionBegin orig, TeleporterInteraction self, Interactor activator)
		{
			orig.Invoke(self, activator);
			if (!bossActive)
			{
				bossActive = true;
				hasshuffled = false;
				listtracker = 0;
				PickOutMusic(isForTeleporter: true);
			}
		};
		TeleporterInteraction.RpcClientOnActivated += (hook_RpcClientOnActivated)delegate(orig_RpcClientOnActivated orig, TeleporterInteraction self, GameObject activator)
		{
			orig.Invoke(self, activator);
			if (!bossActive)
			{
				bossActive = true;
				hasshuffled = false;
				listtracker = 0;
				PickOutMusic(isForTeleporter: true);
			}
		};
		OverchargingInterludeState.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, OverchargingInterludeState self)
		{
			orig.Invoke(self);
			if (bossActive && soultrialstrackenabled)
			{
				Debug.Log((object)"====================== OVERCHARGING THE TELEPORTER!!! ======================");
				bossActive = true;
				extratracksfrfr = true;
				hasshuffled = false;
				listtracker = 0;
				PickOutMusic(isForTeleporter: true);
			}
		};
		PauseScreenController.OnEnable += (hook_OnEnable)delegate(orig_OnEnable orig, PauseScreenController self)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			orig.Invoke(self);
			if (outputDevice != null && (int)outputDevice.PlaybackState == 1)
			{
				outputDevice.Pause();
				songPaused = true;
			}
		};
		PauseScreenController.OnDisable += (hook_OnDisable)delegate(orig_OnDisable orig, PauseScreenController self)
		{
			orig.Invoke(self);
			if (outputDevice != null && songPaused)
			{
				outputDevice.Play();
				songPaused = false;
			}
		};
		InfiniteTowerRun.Start += (hook_Start)delegate(orig_Start orig, InfiniteTowerRun self)
		{
			orig.Invoke(self);
			simulacrumactive = true;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic();
		};
		InfiniteTowerRun.OnDestroy += (hook_OnDestroy)delegate(orig_OnDestroy orig, InfiniteTowerRun self)
		{
			orig.Invoke(self);
			simulacrumactive = false;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic();
		};
		Phase1.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, Phase1 self)
		{
			orig.Invoke(self);
			if (KarmaManager.instance.GetEffectiveKarma() == 8 && karmicmithrixtrackenabled)
			{
				Debug.Log((object)"====================== KARMIC MITHRIX START ======================");
				bossActive = true;
				extratracksfrfr = true;
				mithrixaltoutro = true;
				hasshuffled = false;
				listtracker = 0;
				PickOutMusic(isForTeleporter: true);
			}
			else
			{
				Debug.Log((object)"====================== MITHRIX BOSS FIGHT START ======================");
				bossActive = true;
				hasshuffled = false;
				listtracker = 0;
				PickOutMusic(isForTeleporter: true);
			}
		};
		EncounterFinished.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, EncounterFinished self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== MITHRIX BOSS FIGHT DONE ======================");
			bossActive = false;
			afterBossPhase = true;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic();
		};
		HeartSpawnState.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, HeartSpawnState self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== FALSE SON BOSS FIGHT START ======================");
			bossActive = true;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic(isForTeleporter: true);
		};
		SkyJumpDeathState.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, SkyJumpDeathState self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== FALSE SON BOSS FIGHT DONE ======================");
			bossActive = false;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic();
		};
		CutsceneTransformation.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, CutsceneTransformation self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== SOLUS HEART BOSS FIGHT START ======================");
			bossActive = true;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic(isForTeleporter: true);
		};
		Offering.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, Offering self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== SOLUS HEART BOSS FIGHT DONE ======================");
			bossActive = false;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic();
		};
		SpawnState.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, SpawnState self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== SOLUS WING BOSS FIGHT START ======================");
			bossActive = true;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic(isForTeleporter: true);
		};
		DeathState.OnExit += (hook_OnExit)delegate(orig_OnExit orig, DeathState self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== SOLUS WING BOSS FIGHT DONE ======================");
			bossActive = false;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic();
		};
		SpawnState.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, SpawnState self)
		{
			if (!bossActive)
			{
				orig.Invoke(self);
				Debug.Log((object)"====================== VOIDLING BOSS FIGHT START ======================");
				bossActive = true;
				hasshuffled = false;
				listtracker = 0;
				PickOutMusic(isForTeleporter: true);
			}
		};
		DeathState.OnExit += (hook_OnExit)delegate(orig_OnExit orig, DeathState self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== VOIDLING BOSS FIGHT DONE ======================");
			bossActive = false;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic();
		};
		StartHurt.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, StartHurt self)
		{
			if (artifactmusicenabled)
			{
				orig.Invoke(self);
				Debug.Log((object)"====================== ARTIFACT TRIAL START ======================");
				extratracksfrfr = true;
				bossActive = false;
				hasshuffled = false;
				listtracker = 0;
				PickOutMusic();
			}
		};
		Death.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, Death self)
		{
			if (artifactmusicenabled)
			{
				orig.Invoke(self);
				Debug.Log((object)"====================== ARTIFACT TRIAL END ======================");
				extratracksfrfr = false;
				bossActive = false;
				hasshuffled = false;
				listtracker = 0;
				PickOutMusic();
			}
		};
		StartChampRush.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, StartChampRush self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== SOULBOUND TRIAL START ======================");
			bossActive = true;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic(isForTeleporter: true);
		};
		ReaperFight.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, ReaperFight self)
		{
			if (!playanimamusic)
			{
				orig.Invoke(self);
				Debug.Log((object)"====================== ANIMA HARVESTER BOSS START ======================");
				bossActive = true;
				playanimamusic = true;
				hasshuffled = false;
				listtracker = 0;
				PickOutMusic(isForTeleporter: true);
			}
		};
		Aftermath.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, Aftermath self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== SOULBOUND TRIAL END ======================");
			bossActive = false;
			hasshuffled = false;
			listtracker = 0;
			playanimamusic = false;
			PickOutMusic();
		};
		Phase1.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, Phase1 self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== PROVIDENCE BOSS FIGHT START ======================");
			bossActive = true;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic(isForTeleporter: true);
		};
		BossDeath.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, BossDeath self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== PROVIDENCE BOSS FIGHT END ======================");
			bossActive = false;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic();
		};
		BaseTrialQuest.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, BaseTrialQuest self)
		{
			orig.Invoke(self);
			if (winnowingreckoningenabled)
			{
				Debug.Log((object)"====================== WINNOWING TRIAL START ======================");
				bossActive = true;
				hasshuffled = false;
				listtracker = 0;
				PickOutMusic(isForTeleporter: true);
			}
		};
		BaseTrialQuest.OnExit += (hook_OnExit)delegate(orig_OnExit orig, BaseTrialQuest self)
		{
			orig.Invoke(self);
			if (winnowingreckoningenabled)
			{
				Debug.Log((object)"====================== WINNOWING TRIAL END ======================");
				bossActive = false;
				hasshuffled = false;
				listtracker = 0;
				PickOutMusic();
			}
		};
		if (enemiesreturnswrapper.Present)
		{
			enemiesreturnswrapper.Init(this);
		}
		if (fathomlesswrapper.Present2)
		{
			fathomlesswrapper.Init2(this);
		}
		SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			Debug.Log((object)"====================== CHANGE SCENE ========================");
			Debug.Log((object)((Scene)(ref scene)).name);
			currentScene = ((Scene)(ref scene)).name;
			SceneIndex sceneDefIndex = SceneCatalog.mostRecentSceneDef.sceneDefIndex;
			if (currentScene == "enemiesreturns_judgementoutro")
			{
				extratracksfrfr = false;
				lastStageIndex = sceneDefIndex;
				afterBossPhase = true;
				bossActive = false;
				hasshuffled = false;
				playanimamusic = false;
				listtracker = 0;
				JudgementWaveCounter = 0;
				mithrixaltoutro = false;
				PickOutMusic();
			}
			else if (currentScene == "outro" && mithrixaltoutro)
			{
				extratracksfrfr = true;
				lastStageIndex = sceneDefIndex;
				afterBossPhase = false;
				bossActive = false;
				hasshuffled = false;
				playanimamusic = false;
				listtracker = 0;
				JudgementWaveCounter = 0;
				mithrixaltoutro = false;
				PickOutMusic();
			}
			else if (sceneDefIndex != lastStageIndex)
			{
				if ((Object)(object)Run.instance != (Object)null)
				{
					playerhaslooped = Run.instance.loopClearCount >= postloopamount;
				}
				lastStageIndex = sceneDefIndex;
				playanimamusic = false;
				afterBossPhase = false;
				extratracksfrfr = false;
				bossActive = false;
				hasshuffled = false;
				listtracker = 0;
				JudgementWaveCounter = 0;
				mithrixaltoutro = false;
				PickOutMusic();
			}
			else if (!bossActive)
			{
				extratracksfrfr = false;
				hasshuffled = false;
				playanimamusic = false;
				listtracker = 0;
				JudgementWaveCounter = 0;
				mithrixaltoutro = false;
				PickOutMusic();
			}
		};
	}

	private void OnTeleporterFinished(TeleporterInteraction tp)
	{
		switch (postbossmusic)
		{
		case postbossmusicmode.silence:
			Debug.Log((object)"==================== Play Nothing Once This Song Finishes? COMING RIGHT UP!! ====================");
			break;
		case postbossmusicmode.alttrack:
			Debug.Log((object)"==================== Alt Stage Track Post-Tp ENABLED!!!!!!!!!!!! ====================");
			bossActive = false;
			extratracksfrfr = false;
			afterBossPhase = true;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic();
			break;
		case postbossmusicmode.normaltrack:
			Debug.Log((object)"==================== Normal Stage Track Post-Tp ENABLED!!!!!!!!!!!! ====================");
			bossActive = false;
			extratracksfrfr = false;
			hasshuffled = false;
			listtracker = 0;
			PickOutMusic();
			break;
		}
	}

	private void UpdateVolume()
	{
		currentSong.Volume = currentMusicVolume * globalMusicVolume.Value / 100f;
	}

	private FileInfo[] SearchForAudioFiles(string path)
	{
		DirectoryInfo directoryInfo = new DirectoryInfo(path);
		if (directoryInfo.Exists)
		{
			return (from f in directoryInfo.GetFiles()
				where Path.GetExtension(f.Name) == ".mp3" || Path.GetExtension(f.Name) == ".wav"
				select f).ToArray();
		}
		return new FileInfo[0];
	}

	private string GetAttribute(XmlNode node, string attribute)
	{
		if (node.Attributes != null)
		{
			XmlNode namedItem = node.Attributes.GetNamedItem(attribute);
			if (namedItem != null)
			{
				return namedItem.Value;
			}
		}
		return "";
	}

	private bool sceneMostlyMatches(string[] scenes)
	{
		foreach (string value in scenes)
		{
			if (currentScene.Contains(value))
			{
				return true;
			}
		}
		return false;
	}

	public void PickOutMusic(bool isForTeleporter = false)
	{
		Music[] array = musics.Where(delegate(Music music3)
		{
			bool flag = sceneMostlyMatches(music3.scenes);
			bool flag2 = playanimamusic;
			bool flag3 = isForTeleporter == music3.boss;
			bool flag4 = playerhaslooped && storedloopstages != null && storedloopstages.Contains(currentScene);
			bool flag5 = extratracksfrfr;
			bool flag6 = extratracksfrfr && !currentScene.Contains("enemiesreturns_judgementoutro");
			if (simulacrumactive)
			{
				return music3.simulacrum == simulacrumactive && flag && music3.fullName != null;
			}
			return afterBossPhase ? (music3.afterboss && flag && music3.postloopvariant == flag4 && music3.isextratrack == flag6 && music3.fullName != null) : (music3.fullName != null && flag3 && flag && music3.postloopvariant == flag4 && music3.isextratrack == flag5 && music3.soulboundboss == flag2 && !music3.afterboss && !music3.simulacrum);
		}).ToArray();
		Debug.Log((object)"====== Selecting Music ======");
		Debug.Log((object)("Current Scene: " + currentScene));
		Debug.Log((object)("Is For Teleporter: " + isForTeleporter));
		Debug.Log((object)"Choices: ");
		Music[] array2 = array;
		foreach (Music music in array2)
		{
			Debug.Log((object)music.name);
		}
		Debug.Log((object)"");
		string fullName = currentSongFullName;
		Music music2 = null;
		int num2 = 0;
		if (array.Length != 0)
		{
			while (fullName == currentSongFullName && num2 < 10)
			{
				switch (randomizationmode)
				{
				case randomizationmodelist.off:
					music2 = array[listtracker % array.Length];
					fullName = music2.fullName;
					num2++;
					listtracker++;
					break;
				case randomizationmodelist.shuffle:
					music2 = array[rnd.Next(array.Length)];
					fullName = music2.fullName;
					num2++;
					hasshuffled = true;
					break;
				case randomizationmodelist.shuffleonce:
					if (!hasshuffled)
					{
						listtracker = rnd.Next(array.Length);
						music2 = array[listtracker % array.Length];
						fullName = music2.fullName;
						num2++;
						hasshuffled = true;
					}
					else
					{
						music2 = array[listtracker % array.Length];
						fullName = music2.fullName;
						num2++;
						listtracker++;
					}
					break;
				}
			}
			((MonoBehaviour)this).StartCoroutine((IEnumerator)PlayMusic(fullName, music2.volume));
		}
		else
		{
			Debug.Log((object)"======= MUSIC PICK FAILED! =======");
			Debug.Log((object)"choosing random song...");
			num2 = 0;
			while (fullName == currentSongFullName && num2 < 10)
			{
				fullName = soundFiles[rnd.Next(soundFiles.Length)].FullName;
				num2++;
			}
			((MonoBehaviour)this).StartCoroutine((IEnumerator)PlayMusic(fullName));
		}
	}

	private IEnumerator<WaitForSeconds> PlayMusic(string file, float volume = 1f)
	{
		currentMusicVolume = volume;
		if (file != currentSongFullName)
		{
			currentSongFullName = file;
			if ((int)outputDevice.PlaybackState == 1)
			{
				fader.BeginFadeOut(1500.0);
				yield return new WaitForSeconds(1.5f);
				outputDevice.Stop();
				currentSong = null;
			}
			currentSong = new AudioFileReader(file);
			UpdateVolume();
			LoopStream looper = new LoopStream(shouldLoop: musics.First((Music m) => m.fullName == file).loop, sourceStream: (WaveStream)(object)currentSong);
			fader = new FadeInOutSampleProvider((ISampleProvider)new WaveToSampleProvider((IWaveProvider)(object)looper), false);
			WaveExtensionMethods.Init((IWavePlayer)(object)outputDevice, (ISampleProvider)(object)fader, false);
			Debug.Log((object)("====== Now Playing: " + file));
			if (EnableMetaData.Value && (Object)(object)Run.instance != (Object)null)
			{
				DisplayMetaData(file);
			}
			outputDevice.Play();
			songPaused = false;
		}
		else
		{
			Debug.Log((object)("PlayMusic: Already playing: " + file));
		}
	}

	private void DisplayMetaData(string file)
	{
		try
		{
			File val = File.Create(file);
			try
			{
				string text = string.Join(", ", val.Tag.Performers);
				string text2 = val.Tag.Title;
				if (!(text2 == lasttitle))
				{
					if (string.IsNullOrEmpty(text))
					{
						text = "???";
					}
					if (string.IsNullOrEmpty(text2))
					{
						text2 = "unknown song";
					}
					Chat.AddMessage("<style=cWorldEvent>♬ Currently Playing: " + text + " - " + text2 + " ♬</style>");
					lasttitle = text2;
				}
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}
		catch (Exception ex)
		{
			Debug.Log((object)"OSTMODPLUS failed to display song metadata oopsie doopsie");
			Debug.Log((object)ex);
		}
	}

	public void Update()
	{
		if (oldMusicVolume == "" && (Object)(object)Console.instance != (Object)null)
		{
			BaseConVar val = Console.instance.FindConVar("volume_music");
			if (val != null)
			{
				oldMusicVolume = val.GetString();
				val.SetString("0");
			}
		}
	}

	private void FixedUpdate()
	{
		if (currentSong != null && ((Stream)(object)currentSong).Position >= ((Stream)(object)currentSong).Length && !shouldLoop)
		{
			outputDevice.Stop();
			((Stream)(object)currentSong).Position = ((Stream)(object)currentSong).Length - 1;
			PickOutMusic(bossActive);
		}
	}

	private void OnDestroy()
	{
		BaseConVar val = Console.instance.FindConVar("volume_music");
		if (val != null)
		{
			val.SetString(oldMusicVolume);
		}
	}
}

TagLibSharp.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Xml;
using Microsoft.CodeAnalysis;
using TagLib.Aac;
using TagLib.Aiff;
using TagLib.Ape;
using TagLib.Asf;
using TagLib.Audible;
using TagLib.Dsf;
using TagLib.Flac;
using TagLib.Gif;
using TagLib.IFD;
using TagLib.IFD.Entries;
using TagLib.IFD.Makernotes;
using TagLib.IFD.Tags;
using TagLib.IIM;
using TagLib.Id3v1;
using TagLib.Id3v2;
using TagLib.Image;
using TagLib.Image.NoMetadata;
using TagLib.Jpeg;
using TagLib.Matroska;
using TagLib.Mpeg;
using TagLib.Mpeg4;
using TagLib.MusePack;
using TagLib.NonContainer;
using TagLib.Ogg;
using TagLib.Ogg.Codecs;
using TagLib.Png;
using TagLib.Riff;
using TagLib.Tiff;
using TagLib.Tiff.Arw;
using TagLib.Tiff.Cr2;
using TagLib.Tiff.Dng;
using TagLib.Tiff.Nef;
using TagLib.Tiff.Pef;
using TagLib.Tiff.Rw2;
using TagLib.WavPack;
using TagLib.Xmp;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Brian Nickel, Gabriel Burt, Stephen Shaw, etc")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2006-2007 Brian Nickel.  Copyright (c) 2009-2020 Other contributors")]
[assembly: AssemblyDescription("A library for for reading and writing metadata in media files, including video, audio, and photo formats.")]
[assembly: AssemblyFileVersion("2.3.0.0")]
[assembly: AssemblyInformationalVersion("2.3.0.0")]
[assembly: AssemblyProduct("TagLib#")]
[assembly: AssemblyTitle("TagLibSharp")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/mono/taglib-sharp")]
[assembly: AssemblyVersion("2.3.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}
namespace TagLib
{
	public enum StringType
	{
		Latin1,
		UTF16,
		UTF16BE,
		UTF8,
		UTF16LE
	}
	public class ByteVector : IList<byte>, ICollection<byte>, IEnumerable<byte>, IEnumerable, IComparable<ByteVector>
	{
		private static readonly uint[] crc_table = new uint[256]
		{
			0u, 79764919u, 159529838u, 222504665u, 319059676u, 398814059u, 445009330u, 507990021u, 638119352u, 583659535u,
			797628118u, 726387553u, 890018660u, 835552979u, 1015980042u, 944750013u, 1276238704u, 1221641927u, 1167319070u, 1095957929u,
			1595256236u, 1540665371u, 1452775106u, 1381403509u, 1780037320u, 1859660671u, 1671105958u, 1733955601u, 2031960084u, 2111593891u,
			1889500026u, 1952343757u, 2552477408u, 2632100695u, 2443283854u, 2506133561u, 2334638140u, 2414271883u, 2191915858u, 2254759653u,
			3190512472u, 3135915759u, 3081330742u, 3009969537u, 2905550212u, 2850959411u, 2762807018u, 2691435357u, 3560074640u, 3505614887u,
			3719321342u, 3648080713u, 3342211916u, 3287746299u, 3467911202u, 3396681109u, 4063920168u, 4143685023u, 4223187782u, 4286162673u,
			3779000052u, 3858754371u, 3904687514u, 3967668269u, 881225847u, 809987520u, 1023691545u, 969234094u, 662832811u, 591600412u,
			771767749u, 717299826u, 311336399u, 374308984u, 453813921u, 533576470u, 25881363u, 88864420u, 134795389u, 214552010u,
			2023205639u, 2086057648u, 1897238633u, 1976864222u, 1804852699u, 1867694188u, 1645340341u, 1724971778u, 1587496639u, 1516133128u,
			1461550545u, 1406951526u, 1302016099u, 1230646740u, 1142491917u, 1087903418u, 2896545431u, 2825181984u, 2770861561u, 2716262478u,
			3215044683u, 3143675388u, 3055782693u, 3001194130u, 2326604591u, 2389456536u, 2200899649u, 2280525302u, 2578013683u, 2640855108u,
			2418763421u, 2498394922u, 3769900519u, 3832873040u, 3912640137u, 3992402750u, 4088425275u, 4151408268u, 4197601365u, 4277358050u,
			3334271071u, 3263032808u, 3476998961u, 3422541446u, 3585640067u, 3514407732u, 3694837229u, 3640369242u, 1762451694u, 1842216281u,
			1619975040u, 1682949687u, 2047383090u, 2127137669u, 1938468188u, 2001449195u, 1325665622u, 1271206113u, 1183200824u, 1111960463u,
			1543535498u, 1489069629u, 1434599652u, 1363369299u, 622672798u, 568075817u, 748617968u, 677256519u, 907627842u, 853037301u,
			1067152940u, 995781531u, 51762726u, 131386257u, 177728840u, 240578815u, 269590778u, 349224269u, 429104020u, 491947555u,
			4046411278u, 4126034873u, 4172115296u, 4234965207u, 3794477266u, 3874110821u, 3953728444u, 4016571915u, 3609705398u, 3555108353u,
			3735388376u, 3664026991u, 3290680682u, 3236090077u, 3449943556u, 3378572211u, 3174993278u, 3120533705u, 3032266256u, 2961025959u,
			2923101090u, 2868635157u, 2813903052u, 2742672763u, 2604032198u, 2683796849u, 2461293480u, 2524268063u, 2284983834u, 2364738477u,
			2175806836u, 2238787779u, 1569362073u, 1498123566u, 1409854455u, 1355396672u, 1317987909u, 1246755826u, 1192025387u, 1137557660u,
			2072149281u, 2135122070u, 1912620623u, 1992383480u, 1753615357u, 1816598090u, 1627664531u, 1707420964u, 295390185u, 358241886u,
			404320391u, 483945776u, 43990325u, 106832002u, 186451547u, 266083308u, 932423249u, 861060070u, 1041341759u, 986742920u,
			613929101u, 542559546u, 756411363u, 701822548u, 3316196985u, 3244833742u, 3425377559u, 3370778784u, 3601682597u, 3530312978u,
			3744426955u, 3689838204u, 3819031489u, 3881883254u, 3928223919u, 4007849240u, 4037393693u, 4100235434u, 4180117107u, 4259748804u,
			2310601993u, 2373574846u, 2151335527u, 2231098320u, 2596047829u, 2659030626u, 2470359227u, 2550115596u, 2947551409u, 2876312838u,
			2788305887u, 2733848168u, 3165939309u, 3094707162u, 3040238851u, 2985771188u
		};

		private static bool use_broken_latin1;

		private static readonly ReadOnlyByteVector td1 = new ReadOnlyByteVector(1);

		private static readonly ReadOnlyByteVector td2 = new ReadOnlyByteVector(2);

		private static Encoding last_utf16_encoding = Encoding.Unicode;

		private readonly List<byte> data = new List<byte>();

		public byte[] Data => data.ToArray();

		public bool IsEmpty => data.Count == 0;

		public uint Checksum
		{
			get
			{
				uint num = 0u;
				foreach (byte datum in data)
				{
					num = (num << 8) ^ crc_table[((num >> 24) & 0xFF) ^ datum];
				}
				return num;
			}
		}

		public static bool UseBrokenLatin1Behavior
		{
			get
			{
				return use_broken_latin1;
			}
			set
			{
				use_broken_latin1 = value;
			}
		}

		public int Count => data.Count;

		public bool IsSynchronized => false;

		public object SyncRoot => this;

		public virtual bool IsReadOnly => false;

		public virtual bool IsFixedSize => false;

		public byte this[int index]
		{
			get
			{
				return data[index];
			}
			set
			{
				if (IsReadOnly)
				{
					throw new NotSupportedException("Cannot edit readonly objects.");
				}
				data[index] = value;
			}
		}

		public ByteVector()
		{
		}

		public ByteVector(ByteVector vector)
		{
			if (vector != null)
			{
				data.AddRange(vector);
			}
		}

		public ByteVector(params byte[] data)
		{
			if (data != null)
			{
				this.data.AddRange(data);
			}
		}

		public ByteVector(byte[] data, int length)
		{
			if (length > data.Length)
			{
				throw new ArgumentOutOfRangeException("length", "Length exceeds size of data.");
			}
			if (length < 0)
			{
				throw new ArgumentOutOfRangeException("length", "Length is less than zero.");
			}
			if (length == data.Length)
			{
				this.data.AddRange(data);
				return;
			}
			byte[] array = new byte[length];
			Array.Copy(data, 0, array, 0, length);
			this.data.AddRange(array);
		}

		public ByteVector(int size)
			: this(size, 0)
		{
		}

		public ByteVector(int size, byte value)
		{
			if (size < 0)
			{
				throw new ArgumentOutOfRangeException("size", "Size is less than zero.");
			}
			if (size != 0)
			{
				byte[] array = new byte[size];
				for (int i = 0; i < size; i++)
				{
					array[i] = value;
				}
				data.AddRange(array);
			}
		}

		public ByteVector Mid(int startIndex, int length)
		{
			if (startIndex < 0 || startIndex > Count)
			{
				throw new ArgumentOutOfRangeException("startIndex");
			}
			if (length < 0 || startIndex + length > Count)
			{
				throw new ArgumentOutOfRangeException("length");
			}
			if (length == 0)
			{
				return new ByteVector();
			}
			if (startIndex + length > data.Count)
			{
				length = data.Count - startIndex;
			}
			byte[] array = new byte[length];
			data.CopyTo(startIndex, array, 0, length);
			return array;
		}

		public ByteVector Mid(int index)
		{
			return Mid(index, Count - index);
		}

		public int Find(ByteVector pattern, int offset, int byteAlign)
		{
			if (pattern == null)
			{
				throw new ArgumentNullException("pattern");
			}
			if (offset < 0)
			{
				throw new ArgumentOutOfRangeException("offset", "offset must be at least 0.");
			}
			if (byteAlign < 1)
			{
				throw new ArgumentOutOfRangeException("byteAlign", "byteAlign must be at least 1.");
			}
			if (pattern.Count > Count - offset)
			{
				return -1;
			}
			if (pattern.Count == 1)
			{
				byte b = pattern[0];
				for (int i = offset; i < data.Count; i += byteAlign)
				{
					if (data[i] == b)
					{
						return i;
					}
				}
				return -1;
			}
			int[] array = new int[256];
			for (int j = 0; j < 256; j++)
			{
				array[j] = pattern.Count;
			}
			for (int k = 0; k < pattern.Count - 1; k++)
			{
				array[pattern[k]] = pattern.Count - k - 1;
			}
			for (int l = pattern.Count - 1 + offset; l < data.Count; l += array[data[l]])
			{
				int num = l;
				int num2 = pattern.Count - 1;
				while (num2 >= 0 && data[num] == pattern[num2])
				{
					num--;
					num2--;
				}
				if (-1 == num2 && (num + 1 - offset) % byteAlign == 0)
				{
					return num + 1;
				}
			}
			return -1;
		}

		public int Find(ByteVector pattern, int offset)
		{
			return Find(pattern, offset, 1);
		}

		public int Find(ByteVector pattern)
		{
			return Find(pattern, 0, 1);
		}

		public int RFind(ByteVector pattern, int offset, int byteAlign)
		{
			if (pattern == null)
			{
				throw new ArgumentNullException("pattern");
			}
			if (offset < 0)
			{
				throw new ArgumentOutOfRangeException("offset");
			}
			if (pattern.Count == 0 || pattern.Count > Count - offset)
			{
				return -1;
			}
			if (pattern.Count == 1)
			{
				byte b = pattern[0];
				for (int num = Count - offset - 1; num >= 0; num -= byteAlign)
				{
					if (data[num] == b)
					{
						return num;
					}
				}
				return -1;
			}
			int[] array = new int[256];
			for (int i = 0; i < 256; i++)
			{
				array[i] = pattern.Count;
			}
			for (int num2 = pattern.Count - 1; num2 > 0; num2--)
			{
				array[pattern[num2]] = num2;
			}
			for (int num3 = Count - offset - pattern.Count; num3 >= 0; num3 -= array[data[num3]])
			{
				if ((offset - num3) % byteAlign == 0 && ContainsAt(pattern, num3))
				{
					return num3;
				}
			}
			return -1;
		}

		public int RFind(ByteVector pattern, int offset)
		{
			return RFind(pattern, offset, 1);
		}

		public int RFind(ByteVector pattern)
		{
			return RFind(pattern, 0, 1);
		}

		public bool ContainsAt(ByteVector pattern, int offset, int patternOffset, int patternLength)
		{
			if (pattern == null)
			{
				throw new ArgumentNullException("pattern");
			}
			if (pattern.Count < patternLength)
			{
				patternLength = pattern.Count;
			}
			if (patternLength > data.Count || offset >= data.Count || patternOffset >= pattern.Count || patternLength <= 0 || offset < 0)
			{
				return false;
			}
			for (int i = 0; i < patternLength - patternOffset; i++)
			{
				if (data[i + offset] != pattern[i + patternOffset])
				{
					return false;
				}
			}
			return true;
		}

		public bool ContainsAt(ByteVector pattern, int offset, int patternOffset)
		{
			return ContainsAt(pattern, offset, patternOffset, int.MaxValue);
		}

		public bool ContainsAt(ByteVector pattern, int offset)
		{
			return ContainsAt(pattern, offset, 0);
		}

		public bool StartsWith(ByteVector pattern)
		{
			return ContainsAt(pattern, 0);
		}

		public bool EndsWith(ByteVector pattern)
		{
			if (pattern == null)
			{
				throw new ArgumentNullException("pattern");
			}
			return ContainsAt(pattern, data.Count - pattern.Count);
		}

		public int EndsWithPartialMatch(ByteVector pattern)
		{
			if (pattern == null)
			{
				throw new ArgumentNullException("pattern");
			}
			if (pattern.Count > data.Count)
			{
				return -1;
			}
			int num = data.Count - pattern.Count;
			for (int i = 1; i < pattern.Count; i++)
			{
				if (ContainsAt(pattern, num + i, 0, pattern.Count - i))
				{
					return num + i;
				}
			}
			return -1;
		}

		public void Add(ByteVector data)
		{
			if (IsReadOnly)
			{
				throw new NotSupportedException("Cannot edit readonly objects.");
			}
			if (data != null)
			{
				this.data.AddRange(data);
			}
		}

		public void Add(byte[] data)
		{
			if (IsReadOnly)
			{
				throw new NotSupportedException("Cannot edit readonly objects.");
			}
			if (data != null)
			{
				this.data.AddRange(data);
			}
		}

		public void Insert(int index, ByteVector data)
		{
			if (IsReadOnly)
			{
				throw new NotSupportedException("Cannot edit readonly objects.");
			}
			if (data != null)
			{
				this.data.InsertRange(index, data);
			}
		}

		public void Insert(int index, byte[] data)
		{
			if (IsReadOnly)
			{
				throw new NotSupportedException("Cannot edit readonly objects.");
			}
			if (data != null)
			{
				this.data.InsertRange(index, data);
			}
		}

		public ByteVector Resize(int size, byte padding)
		{
			if (IsReadOnly)
			{
				throw new NotSupportedException("Cannot edit readonly objects.");
			}
			if (data.Count > size)
			{
				data.RemoveRange(size, data.Count - size);
			}
			while (data.Count < size)
			{
				data.Add(padding);
			}
			return this;
		}

		public ByteVector Resize(int size)
		{
			return Resize(size, 0);
		}

		public void RemoveRange(int index, int count)
		{
			if (IsReadOnly)
			{
				throw new NotSupportedException("Cannot edit readonly objects.");
			}
			data.RemoveRange(index, count);
		}

		public int ToInt(bool mostSignificantByteFirst)
		{
			int num = 0;
			int num2 = ((Count > 4) ? 3 : (Count - 1));
			for (int i = 0; i <= num2; i++)
			{
				int num3 = (mostSignificantByteFirst ? (num2 - i) : i);
				num |= this[i] << num3 * 8;
			}
			return num;
		}

		public int ToInt()
		{
			return ToInt(mostSignificantByteFirst: true);
		}

		public uint ToUInt(bool mostSignificantByteFirst)
		{
			uint num = 0u;
			int num2 = ((Count > 4) ? 3 : (Count - 1));
			for (int i = 0; i <= num2; i++)
			{
				int num3 = (mostSignificantByteFirst ? (num2 - i) : i);
				num |= (uint)(this[i] << num3 * 8);
			}
			return num;
		}

		public uint ToUInt()
		{
			return ToUInt(mostSignificantByteFirst: true);
		}

		public short ToShort(bool mostSignificantByteFirst)
		{
			short num = 0;
			int num2 = ((Count > 2) ? 1 : (Count - 1));
			for (int i = 0; i <= num2; i++)
			{
				int num3 = (mostSignificantByteFirst ? (num2 - i) : i);
				num |= (short)(this[i] << num3 * 8);
			}
			return num;
		}

		public short ToShort()
		{
			return ToShort(mostSignificantByteFirst: true);
		}

		public ushort ToUShort(bool mostSignificantByteFirst)
		{
			ushort num = 0;
			int num2 = ((Count > 2) ? 1 : (Count - 1));
			for (int i = 0; i <= num2; i++)
			{
				int num3 = (mostSignificantByteFirst ? (num2 - i) : i);
				num |= (ushort)(this[i] << num3 * 8);
			}
			return num;
		}

		public ushort ToUShort()
		{
			return ToUShort(mostSignificantByteFirst: true);
		}

		public long ToLong(bool mostSignificantByteFirst)
		{
			long num = 0L;
			int num2 = ((Count > 8) ? 7 : (Count - 1));
			for (int i = 0; i <= num2; i++)
			{
				int num3 = (mostSignificantByteFirst ? (num2 - i) : i);
				num |= (long)((ulong)this[i] << num3 * 8);
			}
			return num;
		}

		public long ToLong()
		{
			return ToLong(mostSignificantByteFirst: true);
		}

		public ulong ToULong(bool mostSignificantByteFirst)
		{
			ulong num = 0uL;
			int num2 = ((Count > 8) ? 7 : (Count - 1));
			for (int i = 0; i <= num2; i++)
			{
				int num3 = (mostSignificantByteFirst ? (num2 - i) : i);
				num |= (ulong)this[i] << num3 * 8;
			}
			return num;
		}

		public ulong ToULong()
		{
			return ToULong(mostSignificantByteFirst: true);
		}

		public float ToFloat(bool mostSignificantByteFirst)
		{
			byte[] array = (byte[])Data.Clone();
			if (mostSignificantByteFirst)
			{
				Array.Reverse((Array)array);
			}
			return BitConverter.ToSingle(array, 0);
		}

		public float ToFloat()
		{
			return ToFloat(mostSignificantByteFirst: true);
		}

		public double ToDouble(bool mostSignificantByteFirst)
		{
			byte[] array = (byte[])Data.Clone();
			if (mostSignificantByteFirst)
			{
				Array.Reverse((Array)array);
			}
			return BitConverter.ToDouble(array, 0);
		}

		public double ToDouble()
		{
			return ToDouble(mostSignificantByteFirst: true);
		}

		public double ToExtendedPrecision()
		{
			int num = ((this[0] & 0x7F) << 8) | this[1];
			ulong num2 = ((ulong)this[2] << 24) | ((ulong)this[3] << 16) | ((ulong)this[4] << 8) | this[5];
			ulong num3 = ((ulong)this[6] << 24) | ((ulong)this[7] << 16) | ((ulong)this[8] << 8) | this[9];
			double num4;
			if (num == 0 && num2 == 0L && num3 == 0L)
			{
				num4 = 0.0;
			}
			else if (num == 32767)
			{
				num4 = double.PositiveInfinity;
			}
			else
			{
				num -= 16383;
				num4 = (double)num2 * Math.Pow(2.0, num -= 31);
				num4 += (double)num3 * Math.Pow(2.0, num -= 32);
			}
			if ((this[0] & 0x80) == 0)
			{
				return num4;
			}
			return 0.0 - num4;
		}

		public string ToString(StringType type, int offset, int count)
		{
			if (offset < 0 || offset > Count)
			{
				throw new ArgumentOutOfRangeException("offset");
			}
			if (count < 0 || count + offset > Count)
			{
				throw new ArgumentOutOfRangeException("count");
			}
			ByteVector bom = ((type == StringType.UTF16 && data.Count - offset > 1) ? Mid(offset, 2) : null);
			string @string = StringTypeToEncoding(type, bom).GetString(Data, offset, count);
			if (@string.Length != 0 && (@string[0] == '\ufffe' || @string[0] == '\ufeff'))
			{
				return @string.Substring(1);
			}
			return @string;
		}

		[Obsolete("Use ToString(StringType,int,int)")]
		public string ToString(StringType type, int offset)
		{
			return ToString(type, offset, Count - offset);
		}

		public string ToString(StringType type)
		{
			return ToString(type, 0, Count);
		}

		public override string ToString()
		{
			return ToString(StringType.UTF8, 0, Count);
		}

		public string[] ToStrings(StringType type, int offset)
		{
			return ToStrings(type, offset, int.MaxValue);
		}

		public string[] ToStrings(StringType type, int offset, int count)
		{
			int num = 0;
			int num2 = offset;
			List<string> list = new List<string>();
			ByteVector byteVector = TextDelimiter(type);
			int count2 = byteVector.Count;
			while (num < count && num2 < Count)
			{
				int num3 = num2;
				if (num + 1 == count)
				{
					num2 = offset + count;
				}
				else
				{
					num2 = Find(byteVector, num3, count2);
					if (num2 < 0)
					{
						num2 = Count;
					}
				}
				int num4 = num2 - num3;
				if (num4 == 0)
				{
					list.Add(string.Empty);
				}
				else
				{
					string text = ToString(type, num3, num4);
					if (text.Length != 0 && (text[0] == '\ufffe' || text[0] == '\ufeff'))
					{
						text = text.Substring(1);
					}
					list.Add(text);
				}
				num2 += count2;
			}
			return list.ToArray();
		}

		public static bool operator ==(ByteVector first, ByteVector second)
		{
			bool flag = (object)first == null;
			bool flag2 = (object)second == null;
			if (flag && flag2)
			{
				return true;
			}
			if (flag || flag2)
			{
				return false;
			}
			return first.Equals(second);
		}

		public static bool operator !=(ByteVector first, ByteVector second)
		{
			return !(first == second);
		}

		public static bool operator <(ByteVector first, ByteVector second)
		{
			if (first == null)
			{
				throw new ArgumentNullException("first");
			}
			if (second == null)
			{
				throw new ArgumentNullException("second");
			}
			return first.CompareTo(second) < 0;
		}

		public static bool operator <=(ByteVector first, ByteVector second)
		{
			if (first == null)
			{
				throw new ArgumentNullException("first");
			}
			if (second == null)
			{
				throw new ArgumentNullException("second");
			}
			return first.CompareTo(second) <= 0;
		}

		public static bool operator >(ByteVector first, ByteVector second)
		{
			if (first == null)
			{
				throw new ArgumentNullException("first");
			}
			if (second == null)
			{
				throw new ArgumentNullException("second");
			}
			return first.CompareTo(second) > 0;
		}

		public static bool operator >=(ByteVector first, ByteVector second)
		{
			if (first == null)
			{
				throw new ArgumentNullException("first");
			}
			if (second == null)
			{
				throw new ArgumentNullException("second");
			}
			return first.CompareTo(second) >= 0;
		}

		public static ByteVector operator +(ByteVector first, ByteVector second)
		{
			return new ByteVector(first) { second };
		}

		public static implicit operator ByteVector(byte value)
		{
			return new ByteVector(value);
		}

		public static implicit operator ByteVector(byte[] value)
		{
			return new ByteVector(value);
		}

		public static implicit operator ByteVector(string value)
		{
			return FromString(value, StringType.UTF8);
		}

		public static ByteVector FromInt(int value, bool mostSignificantByteFirst)
		{
			ByteVector byteVector = new ByteVector();
			for (int i = 0; i < 4; i++)
			{
				int num = (mostSignificantByteFirst ? (3 - i) : i);
				byteVector.Add((byte)((uint)(value >> num * 8) & 0xFFu));
			}
			return byteVector;
		}

		public static ByteVector FromInt(int value)
		{
			return FromInt(value, mostSignificantByteFirst: true);
		}

		public static ByteVector FromUInt(uint value, bool mostSignificantByteFirst)
		{
			ByteVector byteVector = new ByteVector();
			for (int i = 0; i < 4; i++)
			{
				int num = (mostSignificantByteFirst ? (3 - i) : i);
				byteVector.Add((byte)((value >> num * 8) & 0xFFu));
			}
			return byteVector;
		}

		public static ByteVector FromUInt(uint value)
		{
			return FromUInt(value, mostSignificantByteFirst: true);
		}

		public static ByteVector FromShort(short value, bool mostSignificantByteFirst)
		{
			ByteVector byteVector = new ByteVector();
			for (int i = 0; i < 2; i++)
			{
				int num = (mostSignificantByteFirst ? (1 - i) : i);
				byteVector.Add((byte)((uint)(value >> num * 8) & 0xFFu));
			}
			return byteVector;
		}

		public static ByteVector FromShort(short value)
		{
			return FromShort(value, mostSignificantByteFirst: true);
		}

		public static ByteVector FromUShort(ushort value, bool mostSignificantByteFirst)
		{
			ByteVector byteVector = new ByteVector();
			for (int i = 0; i < 2; i++)
			{
				int num = (mostSignificantByteFirst ? (1 - i) : i);
				byteVector.Add((byte)((uint)(value >> num * 8) & 0xFFu));
			}
			return byteVector;
		}

		public static ByteVector FromUShort(ushort value)
		{
			return FromUShort(value, mostSignificantByteFirst: true);
		}

		public static ByteVector FromLong(long value, bool mostSignificantByteFirst)
		{
			ByteVector byteVector = new ByteVector();
			for (int i = 0; i < 8; i++)
			{
				int num = (mostSignificantByteFirst ? (7 - i) : i);
				byteVector.Add((byte)((value >> num * 8) & 0xFF));
			}
			return byteVector;
		}

		public static ByteVector FromLong(long value)
		{
			return FromLong(value, mostSignificantByteFirst: true);
		}

		public static ByteVector FromULong(ulong value, bool mostSignificantByteFirst)
		{
			ByteVector byteVector = new ByteVector();
			for (int i = 0; i < 8; i++)
			{
				int num = (mostSignificantByteFirst ? (7 - i) : i);
				byteVector.Add((byte)((value >> num * 8) & 0xFF));
			}
			return byteVector;
		}

		public static ByteVector FromULong(ulong value)
		{
			return FromULong(value, mostSignificantByteFirst: true);
		}

		public static ByteVector FromString(string text, StringType type, int length)
		{
			ByteVector byteVector = new ByteVector();
			if (type == StringType.UTF16)
			{
				byteVector.Add(new byte[2] { 255, 254 });
			}
			if (text == null || text.Length == 0)
			{
				return byteVector;
			}
			if (text.Length > length)
			{
				text = text.Substring(0, length);
			}
			byteVector.Add(StringTypeToEncoding(type, byteVector).GetBytes(text));
			return byteVector;
		}

		public static ByteVector FromString(string text, StringType type)
		{
			return FromString(text, type, int.MaxValue);
		}

		public static ByteVector FromString(string text, int length)
		{
			return FromString(text, StringType.UTF8, length);
		}

		[Obsolete("Use FromString(string,StringType)")]
		public static ByteVector FromString(string text)
		{
			return FromString(text, StringType.UTF8);
		}

		public static ByteVector FromPath(string path)
		{
			byte[] firstChunk;
			return FromPath(path, out firstChunk, copyFirstChunk: false);
		}

		internal static ByteVector FromPath(string path, out byte[] firstChunk, bool copyFirstChunk)
		{
			if (path == null)
			{
				throw new ArgumentNullException("path");
			}
			return FromFile(new File.LocalFileAbstraction(path), out firstChunk, copyFirstChunk);
		}

		public static ByteVector FromFile(File.IFileAbstraction abstraction)
		{
			byte[] firstChunk;
			return FromFile(abstraction, out firstChunk, copyFirstChunk: false);
		}

		internal static ByteVector FromFile(File.IFileAbstraction abstraction, out byte[] firstChunk, bool copyFirstChunk)
		{
			if (abstraction == null)
			{
				throw new ArgumentNullException("abstraction");
			}
			Stream readStream = abstraction.ReadStream;
			ByteVector result = FromStream(readStream, out firstChunk, copyFirstChunk);
			abstraction.CloseStream(readStream);
			return result;
		}

		public static ByteVector FromStream(Stream stream)
		{
			byte[] firstChunk;
			return FromStream(stream, out firstChunk, copyFirstChunk: false);
		}

		internal static ByteVector FromStream(Stream stream, out byte[] firstChunk, bool copyFirstChunk)
		{
			ByteVector byteVector = new ByteVector();
			byte[] array = new byte[4096];
			int num = array.Length;
			int num2 = 0;
			bool flag = false;
			firstChunk = null;
			int num3;
			do
			{
				Array.Clear(array, 0, array.Length);
				num3 = stream.Read(array, 0, num);
				byteVector.Add(array);
				num2 += num3;
				if (flag)
				{
					continue;
				}
				if (copyFirstChunk)
				{
					if (firstChunk == null || firstChunk.Length != num)
					{
						firstChunk = new byte[num];
					}
					Array.Copy(array, 0, firstChunk, 0, num3);
				}
				flag = true;
			}
			while ((num2 != stream.Length || stream.Length <= 0) && (num3 >= num || stream.Length > 0));
			if (stream.Length > 0 && byteVector.Count != stream.Length)
			{
				byteVector.Resize((int)stream.Length);
			}
			return byteVector;
		}

		public static ByteVector TextDelimiter(StringType type)
		{
			if (type != StringType.UTF16 && type != StringType.UTF16BE && type != StringType.UTF16LE)
			{
				return td1;
			}
			return td2;
		}

		private static Encoding StringTypeToEncoding(StringType type, ByteVector bom)
		{
			switch (type)
			{
			case StringType.UTF16:
				if (bom == null)
				{
					return last_utf16_encoding;
				}
				if (bom[0] == byte.MaxValue && bom[1] == 254)
				{
					return last_utf16_encoding = Encoding.Unicode;
				}
				if (bom[1] == byte.MaxValue && bom[0] == 254)
				{
					return last_utf16_encoding = Encoding.BigEndianUnicode;
				}
				return last_utf16_encoding;
			case StringType.UTF16BE:
				return Encoding.BigEndianUnicode;
			case StringType.UTF8:
				return Encoding.UTF8;
			case StringType.UTF16LE:
				return Encoding.Unicode;
			default:
				if (use_broken_latin1)
				{
					return Encoding.Default;
				}
				try
				{
					return Encoding.GetEncoding("latin1");
				}
				catch (ArgumentException)
				{
					return Encoding.UTF8;
				}
			}
		}

		public override bool Equals(object other)
		{
			if (!(other is ByteVector))
			{
				return false;
			}
			return Equals((ByteVector)other);
		}

		public bool Equals(ByteVector other)
		{
			return CompareTo(other) == 0;
		}

		public override int GetHashCode()
		{
			return (int)Checksum;
		}

		public int CompareTo(ByteVector other)
		{
			if ((object)other == null)
			{
				throw new ArgumentNullException("other");
			}
			int num = Count - other.Count;
			int num2 = 0;
			while (num == 0 && num2 < Count)
			{
				num = this[num2] - other[num2];
				num2++;
			}
			return num;
		}

		public IEnumerator<byte> GetEnumerator()
		{
			return data.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return data.GetEnumerator();
		}

		public void Clear()
		{
			if (IsReadOnly)
			{
				throw new NotSupportedException("Cannot edit readonly objects.");
			}
			data.Clear();
		}

		public void Add(byte item)
		{
			if (IsReadOnly)
			{
				throw new NotSupportedException("Cannot edit readonly objects.");
			}
			data.Add(item);
		}

		public bool Remove(byte item)
		{
			if (IsReadOnly)
			{
				throw new NotSupportedException("Cannot edit readonly objects.");
			}
			return data.Remove(item);
		}

		public void CopyTo(byte[] array, int arrayIndex)
		{
			data.CopyTo(array, arrayIndex);
		}

		public bool Contains(byte item)
		{
			return data.Contains(item);
		}

		public void RemoveAt(int index)
		{
			if (IsReadOnly)
			{
				throw new NotSupportedException("Cannot edit readonly objects.");
			}
			data.RemoveAt(index);
		}

		public void Insert(int index, byte item)
		{
			if (IsReadOnly)
			{
				throw new NotSupportedException("Cannot edit readonly objects.");
			}
			data.Insert(index, item);
		}

		public int IndexOf(byte item)
		{
			return data.IndexOf(item);
		}
	}
	[ComVisible(false)]
	public class ByteVectorCollection : ListBase<ByteVector>
	{
		public ByteVectorCollection()
		{
		}

		public ByteVectorCollection(IEnumerable<ByteVector> list)
		{
			if (list != null)
			{
				Add(list);
			}
		}

		public ByteVectorCollection(params ByteVector[] list)
		{
			if (list != null)
			{
				Add(list);
			}
		}

		public override void SortedInsert(ByteVector item, bool unique)
		{
			if (item == null)
			{
				throw new ArgumentNullException("item");
			}
			int i;
			for (i = 0; i < base.Count; i++)
			{
				if (item == base[i] && unique)
				{
					return;
				}
				if (item >= base[i])
				{
					break;
				}
			}
			Insert(i + 1, item);
		}

		public ByteVector ToByteVector(ByteVector separator)
		{
			if (separator == null)
			{
				throw new ArgumentNullException("separator");
			}
			ByteVector byteVector = new ByteVector();
			for (int i = 0; i < base.Count; i++)
			{
				if (i != 0 && separator.Count > 0)
				{
					byteVector.Add(separator);
				}
				byteVector.Add(base[i]);
			}
			return byteVector;
		}

		public static ByteVectorCollection Split(ByteVector vector, ByteVector pattern, int byteAlign, int max)
		{
			if (vector == null)
			{
				throw new ArgumentNullException("vector");
			}
			if (pattern == null)
			{
				throw new ArgumentNullException("pattern");
			}
			if (byteAlign < 1)
			{
				throw new ArgumentOutOfRangeException("byteAlign", "byteAlign must be at least 1.");
			}
			ByteVectorCollection byteVectorCollection = new ByteVectorCollection();
			int num = 0;
			int num2 = vector.Find(pattern, 0, byteAlign);
			while (num2 != -1 && (max < 1 || max > byteVectorCollection.Count + 1))
			{
				byteVectorCollection.Add(vector.Mid(num, num2 - num));
				num = num2 + pattern.Count;
				num2 = vector.Find(pattern, num2 + pattern.Count, byteAlign);
			}
			if (num < vector.Count)
			{
				byteVectorCollection.Add(vector.Mid(num, vector.Count - num));
			}
			return byteVectorCollection;
		}

		public static ByteVectorCollection Split(ByteVector vector, ByteVector pattern, int byteAlign)
		{
			return Split(vector, pattern, byteAlign, 0);
		}

		public static ByteVectorCollection Split(ByteVector vector, ByteVector pattern)
		{
			return Split(vector, pattern, 1);
		}
	}
	public class CombinedTag : Tag
	{
		private readonly List<Tag> tags;

		public virtual Tag[] Tags => tags.ToArray();

		public override TagTypes TagTypes
		{
			get
			{
				TagTypes tagTypes = TagTypes.None;
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tagTypes |= tag.TagTypes;
					}
				}
				return tagTypes;
			}
		}

		public override string Title
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string title = tag.Title;
						if (title != null)
						{
							return title;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Title = value;
					}
				}
			}
		}

		public override string Subtitle
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string subtitle = tag.Subtitle;
						if (subtitle != null)
						{
							return subtitle;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Subtitle = value;
					}
				}
			}
		}

		public override string Description
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string description = tag.Description;
						if (description != null)
						{
							return description;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Description = value;
					}
				}
			}
		}

		public override string[] Performers
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string[] performers = tag.Performers;
						if (performers != null && performers.Length != 0)
						{
							return performers;
						}
					}
				}
				return new string[0];
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Performers = value;
					}
				}
			}
		}

		public override string[] PerformersSort
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string[] performersSort = tag.PerformersSort;
						if (performersSort != null && performersSort.Length != 0)
						{
							return performersSort;
						}
					}
				}
				return new string[0];
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.PerformersSort = value;
					}
				}
			}
		}

		public override string[] PerformersRole
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string[] performersRole = tag.PerformersRole;
						if (performersRole != null && performersRole.Length != 0)
						{
							return performersRole;
						}
					}
				}
				return new string[0];
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.PerformersRole = value;
					}
				}
			}
		}

		public override string[] AlbumArtistsSort
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string[] albumArtistsSort = tag.AlbumArtistsSort;
						if (albumArtistsSort != null && albumArtistsSort.Length != 0)
						{
							return albumArtistsSort;
						}
					}
				}
				return new string[0];
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.AlbumArtistsSort = value;
					}
				}
			}
		}

		public override string[] AlbumArtists
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string[] albumArtists = tag.AlbumArtists;
						if (albumArtists != null && albumArtists.Length != 0)
						{
							return albumArtists;
						}
					}
				}
				return new string[0];
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.AlbumArtists = value;
					}
				}
			}
		}

		public override string[] Composers
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string[] composers = tag.Composers;
						if (composers != null && composers.Length != 0)
						{
							return composers;
						}
					}
				}
				return new string[0];
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Composers = value;
					}
				}
			}
		}

		public override string[] ComposersSort
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string[] composersSort = tag.ComposersSort;
						if (composersSort != null && composersSort.Length != 0)
						{
							return composersSort;
						}
					}
				}
				return new string[0];
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.ComposersSort = value;
					}
				}
			}
		}

		public override string TitleSort
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string titleSort = tag.TitleSort;
						if (titleSort != null && titleSort.Length > 0)
						{
							return titleSort;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.TitleSort = value;
					}
				}
			}
		}

		public override string AlbumSort
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string albumSort = tag.AlbumSort;
						if (albumSort != null && albumSort.Length > 0)
						{
							return albumSort;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.AlbumSort = value;
					}
				}
			}
		}

		public override string Album
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string album = tag.Album;
						if (album != null)
						{
							return album;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Album = value;
					}
				}
			}
		}

		public override string Comment
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string comment = tag.Comment;
						if (comment != null)
						{
							return comment;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Comment = value;
					}
				}
			}
		}

		public override string[] Genres
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string[] genres = tag.Genres;
						if (genres != null && genres.Length != 0)
						{
							return genres;
						}
					}
				}
				return new string[0];
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Genres = value;
					}
				}
			}
		}

		public override uint Year
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						uint year = tag.Year;
						if (year != 0)
						{
							return year;
						}
					}
				}
				return 0u;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Year = value;
					}
				}
			}
		}

		public override uint Track
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						uint track = tag.Track;
						if (track != 0)
						{
							return track;
						}
					}
				}
				return 0u;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Track = value;
					}
				}
			}
		}

		public override uint TrackCount
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						uint trackCount = tag.TrackCount;
						if (trackCount != 0)
						{
							return trackCount;
						}
					}
				}
				return 0u;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.TrackCount = value;
					}
				}
			}
		}

		public override uint Disc
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						uint disc = tag.Disc;
						if (disc != 0)
						{
							return disc;
						}
					}
				}
				return 0u;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Disc = value;
					}
				}
			}
		}

		public override uint DiscCount
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						uint discCount = tag.DiscCount;
						if (discCount != 0)
						{
							return discCount;
						}
					}
				}
				return 0u;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.DiscCount = value;
					}
				}
			}
		}

		public override string Lyrics
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string lyrics = tag.Lyrics;
						if (lyrics != null)
						{
							return lyrics;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Lyrics = value;
					}
				}
			}
		}

		public override string Grouping
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string grouping = tag.Grouping;
						if (grouping != null)
						{
							return grouping;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Grouping = value;
					}
				}
			}
		}

		public override uint BeatsPerMinute
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						uint beatsPerMinute = tag.BeatsPerMinute;
						if (beatsPerMinute != 0)
						{
							return beatsPerMinute;
						}
					}
				}
				return 0u;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.BeatsPerMinute = value;
					}
				}
			}
		}

		public override string Conductor
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string conductor = tag.Conductor;
						if (conductor != null)
						{
							return conductor;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Conductor = value;
					}
				}
			}
		}

		public override string Copyright
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string copyright = tag.Copyright;
						if (copyright != null)
						{
							return copyright;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Copyright = value;
					}
				}
			}
		}

		public override DateTime? DateTagged
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						DateTime? dateTagged = tag.DateTagged;
						if (dateTagged.HasValue)
						{
							return dateTagged;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.DateTagged = value;
					}
				}
			}
		}

		public override string MusicBrainzArtistId
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string musicBrainzArtistId = tag.MusicBrainzArtistId;
						if (musicBrainzArtistId != null)
						{
							return musicBrainzArtistId;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.MusicBrainzArtistId = value;
					}
				}
			}
		}

		public override string MusicBrainzReleaseGroupId
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string musicBrainzReleaseGroupId = tag.MusicBrainzReleaseGroupId;
						if (musicBrainzReleaseGroupId != null)
						{
							return musicBrainzReleaseGroupId;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.MusicBrainzReleaseGroupId = value;
					}
				}
			}
		}

		public override string MusicBrainzReleaseId
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string musicBrainzReleaseId = tag.MusicBrainzReleaseId;
						if (musicBrainzReleaseId != null)
						{
							return musicBrainzReleaseId;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.MusicBrainzReleaseId = value;
					}
				}
			}
		}

		public override string MusicBrainzReleaseArtistId
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string musicBrainzReleaseArtistId = tag.MusicBrainzReleaseArtistId;
						if (musicBrainzReleaseArtistId != null)
						{
							return musicBrainzReleaseArtistId;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.MusicBrainzReleaseArtistId = value;
					}
				}
			}
		}

		public override string MusicBrainzTrackId
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string musicBrainzTrackId = tag.MusicBrainzTrackId;
						if (musicBrainzTrackId != null)
						{
							return musicBrainzTrackId;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.MusicBrainzTrackId = value;
					}
				}
			}
		}

		public override string MusicBrainzDiscId
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string musicBrainzDiscId = tag.MusicBrainzDiscId;
						if (musicBrainzDiscId != null)
						{
							return musicBrainzDiscId;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.MusicBrainzDiscId = value;
					}
				}
			}
		}

		public override string MusicIpId
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string musicIpId = tag.MusicIpId;
						if (musicIpId != null)
						{
							return musicIpId;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.MusicIpId = value;
					}
				}
			}
		}

		public override string AmazonId
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string amazonId = tag.AmazonId;
						if (amazonId != null)
						{
							return amazonId;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.AmazonId = value;
					}
				}
			}
		}

		public override string MusicBrainzReleaseStatus
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string musicBrainzReleaseStatus = tag.MusicBrainzReleaseStatus;
						if (musicBrainzReleaseStatus != null)
						{
							return musicBrainzReleaseStatus;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.MusicBrainzReleaseStatus = value;
					}
				}
			}
		}

		public override string MusicBrainzReleaseType
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string musicBrainzReleaseType = tag.MusicBrainzReleaseType;
						if (musicBrainzReleaseType != null)
						{
							return musicBrainzReleaseType;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.MusicBrainzReleaseType = value;
					}
				}
			}
		}

		public override string MusicBrainzReleaseCountry
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string musicBrainzReleaseCountry = tag.MusicBrainzReleaseCountry;
						if (musicBrainzReleaseCountry != null)
						{
							return musicBrainzReleaseCountry;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.MusicBrainzReleaseCountry = value;
					}
				}
			}
		}

		public override IPicture[] Pictures
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						IPicture[] pictures = tag.Pictures;
						if (pictures != null && pictures.Length != 0)
						{
							return pictures;
						}
					}
				}
				return base.Pictures;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Pictures = value;
					}
				}
			}
		}

		public override double ReplayGainTrackGain
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						double replayGainTrackGain = tag.ReplayGainTrackGain;
						if (!double.IsNaN(replayGainTrackGain))
						{
							return replayGainTrackGain;
						}
					}
				}
				return double.NaN;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.ReplayGainTrackGain = value;
					}
				}
			}
		}

		public override double ReplayGainTrackPeak
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						double replayGainTrackPeak = tag.ReplayGainTrackPeak;
						if (!double.IsNaN(replayGainTrackPeak))
						{
							return replayGainTrackPeak;
						}
					}
				}
				return double.NaN;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.ReplayGainTrackPeak = value;
					}
				}
			}
		}

		public override double ReplayGainAlbumGain
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						double replayGainAlbumGain = tag.ReplayGainAlbumGain;
						if (!double.IsNaN(replayGainAlbumGain))
						{
							return replayGainAlbumGain;
						}
					}
				}
				return double.NaN;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.ReplayGainAlbumGain = value;
					}
				}
			}
		}

		public override double ReplayGainAlbumPeak
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						double replayGainAlbumPeak = tag.ReplayGainAlbumPeak;
						if (!double.IsNaN(replayGainAlbumPeak))
						{
							return replayGainAlbumPeak;
						}
					}
				}
				return double.NaN;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.ReplayGainAlbumPeak = value;
					}
				}
			}
		}

		public override string InitialKey
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string initialKey = tag.InitialKey;
						if (initialKey != null)
						{
							return initialKey;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.InitialKey = value;
					}
				}
			}
		}

		public override string RemixedBy
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string remixedBy = tag.RemixedBy;
						if (remixedBy != null)
						{
							return remixedBy;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.RemixedBy = value;
					}
				}
			}
		}

		public override string Publisher
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string publisher = tag.Publisher;
						if (publisher != null)
						{
							return publisher;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Publisher = value;
					}
				}
			}
		}

		public override string ISRC
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string iSRC = tag.ISRC;
						if (iSRC != null)
						{
							return iSRC;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.ISRC = value;
					}
				}
			}
		}

		public override string Length
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						string length = tag.Length;
						if (length != null)
						{
							return length;
						}
					}
				}
				return null;
			}
			set
			{
				foreach (Tag tag in tags)
				{
					if (tag != null)
					{
						tag.Length = value;
					}
				}
			}
		}

		public override bool IsEmpty
		{
			get
			{
				foreach (Tag tag in tags)
				{
					if (tag.IsEmpty)
					{
						return true;
					}
				}
				return false;
			}
		}

		public CombinedTag()
		{
			tags = new List<Tag>();
		}

		public CombinedTag(params Tag[] tags)
		{
			this.tags = new List<Tag>(tags);
		}

		public void SetTags(params Tag[] tags)
		{
			this.tags.Clear();
			this.tags.AddRange(tags);
		}

		protected void InsertTag(int index, Tag tag)
		{
			tags.Insert(index, tag);
		}

		protected void AddTag(Tag tag)
		{
			tags.Add(tag);
		}

		protected void RemoveTag(Tag tag)
		{
			tags.Remove(tag);
		}

		protected void ClearTags()
		{
			tags.Clear();
		}

		public override void Clear()
		{
			foreach (Tag tag in tags)
			{
				tag.Clear();
			}
		}
	}
	[Serializable]
	public class CorruptFileException : Exception
	{
		public CorruptFileException(string message)
			: base(message)
		{
		}

		public CorruptFileException()
		{
		}

		public CorruptFileException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		protected CorruptFileException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}
	}
	internal static class Debugger
	{
		public delegate void DebugMessageSentHandler(string message);

		private struct DebugTimeData
		{
			public TimeSpan time;

			public long occurances;

			public DebugTimeData(TimeSpan time, int occurances)
			{
				this.time = time;
				this.occurances = occurances;
			}
		}

		private static readonly string allowed = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~!@#$%^&*()_+-={}[];:'\",.<>?/\\|";

		private static readonly Dictionary<object, Dictionary<object, DebugTimeData>> debug_times = new Dictionary<object, Dictionary<object, DebugTimeData>>();

		public static event DebugMessageSentHandler DebugMessageSent;

		public static void Debug(string message)
		{
			Debugger.DebugMessageSent?.Invoke(message);
		}

		public static void DumpHex(ByteVector data)
		{
			DumpHex(data.Data);
		}

		public static void DumpHex(byte[] data)
		{
			int num = 16;
			int num2 = data.Length / num + ((data.Length % num != 0) ? 1 : 0);
			for (int i = 0; i < num2; i++)
			{
				for (int j = 0; j < num; j++)
				{
					if (i == num2 - 1 && data.Length % num != 0 && j >= data.Length % num)
					{
						Console.Write("   ");
					}
					else
					{
						Console.Write(" {0:x2}", data[i * num + j]);
					}
				}
				Console.Write(" | ");
				for (int k = 0; k < num; k++)
				{
					if (i == num2 - 1 && data.Length % num != 0 && k >= data.Length % num)
					{
						Console.Write(" ");
					}
					else
					{
						WriteByte2(data[i * num + k]);
					}
				}
				Console.WriteLine();
			}
			Console.WriteLine();
		}

		private static void WriteByte2(byte data)
		{
			string text = allowed;
			foreach (char c in text)
			{
				if (c == data)
				{
					Console.Write(c);
					return;
				}
			}
			Console.Write(".");
		}

		public static void AddDebugTime(object o1, object o2, DateTime start)
		{
			DebugTimeData value = new DebugTimeData(DateTime.Now - start, 1);
			if (debug_times.ContainsKey(o1) && debug_times[o1].ContainsKey(o2))
			{
				value.time += debug_times[o1][o2].time;
				value.occurances += debug_times[o1][o2].occurances;
			}
			if (!debug_times.ContainsKey(o1))
			{
				debug_times.Add(o1, new Dictionary<object, DebugTimeData>());
			}
			if (!debug_times[o1].ContainsKey(o2))
			{
				debug_times[o1].Add(o2, value);
			}
			else
			{
				debug_times[o1][o2] = value;
			}
		}

		public static void DumpDebugTime(object o1)
		{
			Console.WriteLine(o1.ToString());
			if (!debug_times.ContainsKey(o1))
			{
				return;
			}
			foreach (KeyValuePair<object, DebugTimeData> item in debug_times[o1])
			{
				Console.WriteLine("  {0}", item.Key);
				Console.WriteLine("    Objects: {0}", item.Value.time);
				Console.WriteLine("    Total:   {0}", item.Value.occurances);
				Console.WriteLine("    Average: {0}", new TimeSpan(item.Value.time.Ticks / item.Value.occurances));
				Console.WriteLine();
			}
			debug_times.Remove(o1);
		}
	}
	[Flags]
	public enum ReadStyle
	{
		None = 0,
		Average = 2,
		PictureLazy = 4
	}
	public abstract class File : IDisposable
	{
		public enum AccessMode
		{
			Read,
			Write,
			Closed
		}

		public delegate File FileTypeResolver(IFileAbstraction abstraction, string mimetype, ReadStyle style);

		public class LocalFileAbstraction : IFileAbstraction
		{
			private readonly string name;

			public string Name => name;

			public Stream ReadStream => System.IO.File.Open(Name, FileMode.Open, FileAccess.Read, FileShare.Read);

			public Stream WriteStream => System.IO.File.Open(Name, FileMode.Open, FileAccess.ReadWrite);

			public LocalFileAbstraction(string path)
			{
				if (path == null)
				{
					throw new ArgumentNullException("path");
				}
				name = path;
			}

			public void CloseStream(Stream stream)
			{
				if (stream == null)
				{
					throw new ArgumentNullException("stream");
				}
				stream.Close();
			}
		}

		public interface IFileAbstraction
		{
			string Name { get; }

			Stream ReadStream { get; }

			Stream WriteStream { get; }

			void CloseStream(Stream stream);
		}

		private Stream file_stream;

		protected IFileAbstraction file_abstraction;

		private static readonly int buffer_size = 1024;

		private static readonly List<FileTypeResolver> file_type_resolvers = new List<FileTypeResolver>();

		private List<string> corruption_reasons;

		public static uint BufferSize => (uint)buffer_size;

		public abstract Tag Tag { get; }

		public abstract Properties Properties { get; }

		public TagTypes TagTypesOnDisk { get; protected set; }

		public TagTypes TagTypes => Tag?.TagTypes ?? TagTypes.None;

		public string Name => file_abstraction.Name;

		public string MimeType { get; internal set; }

		public long Tell
		{
			get
			{
				if (Mode != AccessMode.Closed)
				{
					return file_stream.Position;
				}
				return 0L;
			}
		}

		public long Length
		{
			get
			{
				if (Mode != AccessMode.Closed)
				{
					return file_stream.Length;
				}
				return 0L;
			}
		}

		public long InvariantStartPosition { get; protected set; } = -1L;


		public long InvariantEndPosition { get; protected set; } = -1L;


		public AccessMode Mode
		{
			get
			{
				if (file_stream == null)
				{
					return AccessMode.Closed;
				}
				if (file_stream.CanWrite)
				{
					return AccessMode.Write;
				}
				return AccessMode.Read;
			}
			set
			{
				if (Mode != value && (Mode != AccessMode.Write || value != 0))
				{
					if (file_stream != null)
					{
						file_abstraction.CloseStream(file_stream);
					}
					file_stream = null;
					switch (value)
					{
					case AccessMode.Read:
						file_stream = file_abstraction.ReadStream;
						break;
					case AccessMode.Write:
						file_stream = file_abstraction.WriteStream;
						break;
					}
					Mode = value;
				}
			}
		}

		public IFileAbstraction FileAbstraction => file_abstraction;

		public virtual bool Writeable => !PossiblyCorrupt;

		public bool PossiblyCorrupt => corruption_reasons != null;

		public IEnumerable<string> CorruptionReasons => corruption_reasons;

		protected File(string path)
		{
			if (path == null)
			{
				throw new ArgumentNullException("path");
			}
			file_abstraction = new LocalFileAbstraction(path);
		}

		protected File(IFileAbstraction abstraction)
		{
			if (abstraction == null)
			{
				throw new ArgumentNullException("abstraction");
			}
			file_abstraction = abstraction;
		}

		internal void MarkAsCorrupt(string reason)
		{
			if (corruption_reasons == null)
			{
				corruption_reasons = new List<string>();
			}
			corruption_reasons.Add(reason);
		}

		public void Dispose()
		{
			Mode = AccessMode.Closed;
		}

		public abstract void Save();

		public abstract void RemoveTags(TagTypes types);

		public abstract Tag GetTag(TagTypes type, bool create);

		public Tag GetTag(TagTypes type)
		{
			return GetTag(type, create: false);
		}

		public ByteVector ReadBlock(int length)
		{
			if (length < 0)
			{
				throw new ArgumentException("Length must be non-negative", "length");
			}
			if (length == 0)
			{
				return new ByteVector();
			}
			Mode = AccessMode.Read;
			byte[] array = new byte[length];
			int num = 0;
			int num2 = 0;
			int num3 = length;
			do
			{
				num = file_stream.Read(array, num2, num3);
				num2 += num;
				num3 -= num;
			}
			while (num3 > 0 && num != 0);
			return new ByteVector(array, num2);
		}

		public void WriteBlock(ByteVector data)
		{
			if (data == null)
			{
				throw new ArgumentNullException("data");
			}
			Mode = AccessMode.Write;
			file_stream.Write(data.Data, 0, data.Count);
		}

		public long Find(ByteVector pattern, long startPosition, ByteVector before)
		{
			if (pattern == null)
			{
				throw new ArgumentNullException("pattern");
			}
			Mode = AccessMode.Read;
			if (pattern.Count > buffer_size)
			{
				return -1L;
			}
			long num = startPosition;
			long position = file_stream.Position;
			try
			{
				file_stream.Position = startPosition;
				ByteVector byteVector = ReadBlock(buffer_size);
				while (byteVector.Count > 0)
				{
					int num2 = byteVector.Find(pattern);
					if (before != null && byteVector.Find(before) < num2)
					{
						return -1L;
					}
					if (num2 >= 0)
					{
						return num + num2;
					}
					num += buffer_size - pattern.Count;
					if (before != null && before.Count > pattern.Count)
					{
						num -= before.Count - pattern.Count;
					}
					file_stream.Position = num;
					byteVector = ReadBlock(buffer_size);
				}
				return -1L;
			}
			finally
			{
				file_stream.Position = position;
			}
		}

		public long Find(ByteVector pattern, long startPosition)
		{
			return Find(pattern, startPosition, null);
		}

		public long Find(ByteVector pattern)
		{
			return Find(pattern, 0L);
		}

		private long RFind(ByteVector pattern, long startPosition, ByteVector after)
		{
			if (pattern == null)
			{
				throw new ArgumentNullException("pattern");
			}
			Mode = AccessMode.Read;
			if (pattern.Count > buffer_size)
			{
				return -1L;
			}
			long position = file_stream.Position;
			long num = Length - startPosition;
			int num2 = buffer_size;
			num2 = (int)Math.Min(num, buffer_size);
			num -= num2;
			file_stream.Position = num;
			ByteVector byteVector = ReadBlock(num2);
			while (byteVector.Count > 0)
			{
				long num3 = byteVector.RFind(pattern);
				if (num3 >= 0)
				{
					file_stream.Position = position;
					return num + num3;
				}
				if (after != null && byteVector.RFind(after) >= 0)
				{
					file_stream.Position = position;
					return -1L;
				}
				num2 = (int)Math.Min(num, buffer_size);
				num -= num2;
				if (num2 + pattern.Count > buffer_size)
				{
					num += pattern.Count;
				}
				file_stream.Position = num;
				byteVector = ReadBlock(num2);
			}
			file_stream.Position = position;
			return -1L;
		}

		public long RFind(ByteVector pattern, long startPosition)
		{
			return RFind(pattern, startPosition, null);
		}

		public long RFind(ByteVector pattern)
		{
			return RFind(pattern, 0L);
		}

		public void Insert(ByteVector data, long start, long replace)
		{
			if (data == null)
			{
				throw new ArgumentNullException("data");
			}
			Insert(data, data.Count, start, replace);
		}

		public void Insert(ByteVector data, long start)
		{
			Insert(data, start, 0L);
		}

		public void Insert(long size, long start)
		{
			Insert(null, size, start, 0L);
		}

		public void RemoveBlock(long start, long length)
		{
			if (length > 0)
			{
				Mode = AccessMode.Write;
				int length2 = buffer_size;
				long num = start + length;
				long num2 = start;
				ByteVector byteVector = (byte)1;
				while (byteVector.Count != 0)
				{
					file_stream.Position = num;
					byteVector = ReadBlock(length2);
					num += byteVector.Count;
					file_stream.Position = num2;
					WriteBlock(byteVector);
					num2 += byteVector.Count;
				}
				Truncate(num2);
			}
		}

		public void Seek(long offset, SeekOrigin origin)
		{
			if (Mode != AccessMode.Closed)
			{
				file_stream.Seek(offset, origin);
			}
		}

		public void Seek(long offset)
		{
			Seek(offset, SeekOrigin.Begin);
		}

		public static File Create(string path)
		{
			return Create(path, null, ReadStyle.Average);
		}

		public static File Create(IFileAbstraction abstraction)
		{
			return Create(abstraction, null, ReadStyle.Average);
		}

		public static File Create(string path, ReadStyle propertiesStyle)
		{
			return Create(path, null, propertiesStyle);
		}

		public static File Create(IFileAbstraction abstraction, ReadStyle propertiesStyle)
		{
			return Create(abstraction, null, propertiesStyle);
		}

		public static File Create(string path, string mimetype, ReadStyle propertiesStyle)
		{
			return Create(new LocalFileAbstraction(path), mimetype, propertiesStyle);
		}

		public static File Create(IFileAbstraction abstraction, string mimetype, ReadStyle propertiesStyle)
		{
			if (mimetype == null)
			{
				string text = string.Empty;
				int num = abstraction.Name.LastIndexOf(".") + 1;
				if (num >= 1 && num < abstraction.Name.Length)
				{
					text = abstraction.Name.Substring(num, abstraction.Name.Length - num);
				}
				mimetype = "taglib/" + text.ToLower(CultureInfo.InvariantCulture);
			}
			foreach (FileTypeResolver file_type_resolver in file_type_resolvers)
			{
				File file = file_type_resolver(abstraction, mimetype, propertiesStyle);
				if (file != null)
				{
					return file;
				}
			}
			if (!FileTypes.AvailableTypes.ContainsKey(mimetype))
			{
				throw new UnsupportedFormatException(string.Format(CultureInfo.InvariantCulture, "{0} ({1})", abstraction.Name, mimetype));
			}
			Type type = FileTypes.AvailableTypes[mimetype];
			try
			{
				File obj = (File)Activator.CreateInstance(type, abstraction, propertiesStyle);
				obj.MimeType = mimetype;
				return obj;
			}
			catch (TargetInvocationException ex)
			{
				PrepareExceptionForRethrow(ex.InnerException);
				throw ex.InnerException;
			}
		}

		public static void AddFileTypeResolver(FileTypeResolver resolver)
		{
			if (resolver != null)
			{
				file_type_resolvers.Insert(0, resolver);
			}
		}

		protected void PreSave()
		{
			if (!Writeable)
			{
				throw new InvalidOperationException("File not writeable.");
			}
			if (PossiblyCorrupt)
			{
				throw new CorruptFileException("Corrupted file cannot be saved.");
			}
			if (Tag?.Pictures == null)
			{
				return;
			}
			IPicture[] pictures = Tag.Pictures;
			for (int i = 0; i < pictures.Length; i++)
			{
				if (pictures[i] is ILazy lazy)
				{
					lazy.Load();
				}
			}
		}

		private void Insert(ByteVector data, long size, long start, long replace)
		{
			Mode = AccessMode.Write;
			if (size == replace)
			{
				if (data != null)
				{
					file_stream.Position = start;
					WriteBlock(data);
				}
				return;
			}
			if (size < replace)
			{
				if (data != null)
				{
					file_stream.Position = start;
					WriteBlock(data);
				}
				RemoveBlock(start + size, replace - size);
				return;
			}
			int num = (int)(size - replace);
			int num2 = num % buffer_size;
			if (num2 != 0)
			{
				num += buffer_size - num2;
			}
			long num3 = start + replace;
			long num4 = start;
			file_stream.Position = num3;
			byte[] data2 = ReadBlock(num).Data;
			num3 += num;
			if (data != null)
			{
				file_stream.Position = num4;
				WriteBlock(data);
			}
			else if (start + size > Length)
			{
				file_stream.SetLength(start + size);
			}
			num4 += size;
			byte[] array = new byte[data2.Length];
			Array.Copy(data2, 0, array, 0, data2.Length);
			while (num != 0)
			{
				file_stream.Position = num3;
				int num5 = file_stream.Read(data2, 0, (num < data2.Length) ? num : data2.Length);
				num3 += num;
				file_stream.Position = num4;
				file_stream.Write(array, 0, (num < array.Length) ? num : array.Length);
				num4 += num;
				Array.Copy(data2, 0, array, 0, num5);
				num = num5;
			}
		}

		protected void Truncate(long length)
		{
			AccessMode mode = Mode;
			Mode = AccessMode.Write;
			file_stream.SetLength(length);
			Mode = mode;
		}

		private static void PrepareExceptionForRethrow(Exception ex)
		{
			StreamingContext context = new StreamingContext(StreamingContextStates.CrossAppDomain);
			ObjectManager objectManager = new ObjectManager(null, context);
			SerializationInfo info = new SerializationInfo(ex.GetType(), new FormatterConverter());
			ex.GetObjectData(info, context);
			objectManager.RegisterObject(ex, 1L, info);
			objectManager.DoFixups();
		}
	}
	public static class FileTypes
	{
		private static Dictionary<string, Type> file_types;

		private static readonly Type[] static_file_types;

		public static IDictionary<string, Type> AvailableTypes => file_types;

		static FileTypes()
		{
			static_file_types = new Type[26]
			{
				typeof(TagLib.Aac.File),
				typeof(TagLib.Aiff.File),
				typeof(TagLib.Ape.File),
				typeof(TagLib.Asf.File),
				typeof(TagLib.Audible.File),
				typeof(TagLib.Dsf.File),
				typeof(TagLib.Flac.File),
				typeof(TagLib.Matroska.File),
				typeof(TagLib.Gif.File),
				typeof(TagLib.Image.NoMetadata.File),
				typeof(TagLib.Jpeg.File),
				typeof(TagLib.Mpeg4.File),
				typeof(AudioFile),
				typeof(TagLib.Mpeg.File),
				typeof(TagLib.MusePack.File),
				typeof(TagLib.Ogg.File),
				typeof(TagLib.Png.File),
				typeof(TagLib.Riff.File),
				typeof(TagLib.Tiff.Arw.File),
				typeof(TagLib.Tiff.Cr2.File),
				typeof(TagLib.Tiff.Dng.File),
				typeof(TagLib.Tiff.File),
				typeof(TagLib.Tiff.Nef.File),
				typeof(TagLib.Tiff.Pef.File),
				typeof(TagLib.Tiff.Rw2.File),
				typeof(TagLib.WavPack.File)
			};
			Init();
		}

		internal static void Init()
		{
			if (file_types == null)
			{
				file_types = new Dictionary<string, Type>();
				Type[] array = static_file_types;
				for (int i = 0; i < array.Length; i++)
				{
					Register(array[i]);
				}
			}
		}

		public static void Register(Type type)
		{
			Attribute[] customAttributes = Attribute.GetCustomAttributes(type, typeof(SupportedMimeType), inherit: false);
			if (customAttributes.Length != 0)
			{
				Attribute[] array = customAttributes;
				for (int i = 0; i < array.Length; i++)
				{
					SupportedMimeType supportedMimeType = (SupportedMimeType)array[i];
					file_types.Add(supportedMimeType.MimeType, type);
				}
			}
		}
	}
	public static class Genres
	{
		private static readonly string[] audio = new string[148]
		{
			"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal",
			"New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial",
			"Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk",
			"Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise",
			"Alternative Rock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic",
			"Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta",
			"Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychedelic", "Rave", "Showtunes",
			"Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock",
			"Folk", "Folk/Rock", "National Folk", "Swing", "Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass",
			"Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic",
			"Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove",
			"Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle",
			"Duet", "Punk Rock", "Drum Solo", "A Cappella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore",
			"Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover",
			"Contemporary Christian", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "Jpop", "Synthpop"
		};

		private static readonly string[] video = new string[40]
		{
			"Action", "Action/Adventure", "Adult", "Adventure", "Catastrophe", "Child's", "Claymation", "Comedy", "Concert", "Documentary",
			"Drama", "Eastern", "Entertaining", "Erotic", "Extremal Sport", "Fantasy", "Fashion", "Historical", "Horror", "Horror/Mystic",
			"Humor", "Indian", "Informercial", "Melodrama", "Military & War", "Music Video", "Musical", "Mystery", "Nature", "Political Satire",
			"Popular Science", "Psychological Thriller", "Religion", "Science Fiction", "Scifi Action", "Slapstick", "Splatter", "Sports", "Thriller", "Western"
		};

		public static string[] Audio => (string[])audio.Clone();

		public static string[] Video => (string[])video.Clone();

		public static byte AudioToIndex(string name)
		{
			for (byte b = 0; b < audio.Length; b++)
			{
				if (name == audio[b])
				{
					return b;
				}
			}
			return byte.MaxValue;
		}

		public static byte VideoToIndex(string name)
		{
			for (byte b = 0; b < video.Length; b++)
			{
				if (name == video[b])
				{
					return b;
				}
			}
			return byte.MaxValue;
		}

		public static string IndexToAudio(byte index)
		{
			if (index >= audio.Length)
			{
				return null;
			}
			return audio[index];
		}

		public static string IndexToVideo(byte index)
		{
			if (index >= video.Length)
			{
				return null;
			}
			return video[index];
		}

		public static string IndexToAudio(string text)
		{
			return IndexToAudio(StringToByte(text));
		}

		public static string IndexToVideo(string text)
		{
			return IndexToVideo(StringToByte(text));
		}

		private static byte StringToByte(string text)
		{
			int num;
			if (text != null && text.Length > 2 && text[0] == '(' && (num = text.IndexOf(')')) != -1 && byte.TryParse(text.Substring(1, num - 1), out var result))
			{
				return result;
			}
			if (text != null && byte.TryParse(text, out result))
			{
				return result;
			}
			return byte.MaxValue;
		}
	}
	[Flags]
	public enum MediaTypes
	{
		None = 0,
		Audio = 1,
		Video = 2,
		Photo = 4,
		Text = 8
	}
	public interface ICodec
	{
		TimeSpan Duration { get; }

		MediaTypes MediaTypes { get; }

		string Description { get; }
	}
	public interface IAudioCodec : ICodec
	{
		int AudioBitrate { get; }

		int AudioSampleRate { get; }

		int AudioChannels { get; }
	}
	public interface ILosslessAudioCodec
	{
		int BitsPerSample { get; }
	}
	public interface IVideoCodec : ICodec
	{
		int VideoWidth { get; }

		int VideoHeight { get; }
	}
	public interface IPhotoCodec : ICodec
	{
		int PhotoWidth { get; }

		int PhotoHeight { get; }

		int PhotoQuality { get; }
	}
	public interface ILazy
	{
		bool IsLoaded { get; }

		void Load();
	}
	public class ListBase<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable where T : IComparable<T>
	{
		private readonly List<T> data = new List<T>();

		public bool IsEmpty => Count == 0;

		public bool IsReadOnly => false;

		public bool IsFixedSize => false;

		public T this[int index]
		{
			get
			{
				return data[index];
			}
			set
			{
				data[index] = value;
			}
		}

		public int Count => data.Count;

		public bool IsSynchronized => false;

		public object SyncRoot => this;

		public ListBase()
		{
		}

		public ListBase(ListBase<T> list)
		{
			if (list != null)
			{
				Add(list);
			}
		}

		public ListBase(params T[] list)
		{
			if (list != null)
			{
				Add(list);
			}
		}

		public void Add(ListBase<T> list)
		{
			if (list != null)
			{
				data.AddRange(list);
			}
		}

		public void Add(IEnumerable<T> list)
		{
			if (list != null)
			{
				data.AddRange(list);
			}
		}

		public void Add(T[] list)
		{
			if (list != null)
			{
				data.AddRange(list);
			}
		}

		public virtual void SortedInsert(T item, bool unique)
		{
			if (item == null)
			{
				throw new ArgumentNullException("item");
			}
			int i;
			for (i = 0; i < data.Count; i++)
			{
				if (item.CompareTo(data[i]) == 0 && unique)
				{
					return;
				}
				if (item.CompareTo(data[i]) <= 0)
				{
					break;
				}
			}
			Insert(i, item);
		}

		public void SortedInsert(T item)
		{
			if (item == null)
			{
				throw new ArgumentNullException("item");
			}
			SortedInsert(item, unique: false);
		}

		public T[] ToArray()
		{
			return data.ToArray();
		}

		public void Add(T item)
		{
			data.Add(item);
		}

		public void Clear()
		{
			data.Clear();
		}

		public bool Contains(T item)
		{
			return data.Contains(item);
		}

		public int IndexOf(T item)
		{
			return data.IndexOf(item);
		}

		public void Insert(int index, T item)
		{
			data.Insert(index, item);
		}

		public bool Remove(T item)
		{
			return data.Remove(item);
		}

		public void RemoveAt(int index)
		{
			data.RemoveAt(index);
		}

		public string ToString(string separator)
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < Count; i++)
			{
				if (i != 0)
				{
					stringBuilder.Append(separator);
				}
				stringBuilder.Append(this[i]);
			}
			return stringBuilder.ToString();
		}

		public override string ToString()
		{
			return ToString(", ");
		}

		public void CopyTo(T[] array, int arrayIndex)
		{
			data.CopyTo(array, arrayIndex);
		}

		public IEnumerator<T> GetEnumerator()
		{
			return data.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return data.GetEnumerator();
		}
	}
	public class TextBox : Box
	{
		private ByteVector data;

		public override ByteVector Data
		{
			get
			{
				return data;
			}
			set
			{
				data = value;
			}
		}

		public TextBox(BoxHeader header, File file, IsoHandlerBox handler)
			: base(header, handler)
		{
			if (file == null)
			{
				throw new ArgumentNullException("file");
			}
			data = LoadData(file);
		}
	}
	public class UrlBox : Box
	{
		private ByteVector data;

		public override ByteVector Data
		{
			get
			{
				return data;
			}
			set
			{
				data = value;
			}
		}

		public UrlBox(BoxHeader header, File file, IsoHandlerBox handler)
			: base(header, handler)
		{
			if (file == null)
			{
				throw new ArgumentNullException("file");
			}
			data = LoadData(file);
		}
	}
	public enum PictureType
	{
		Other = 0,
		FileIcon = 1,
		OtherFileIcon = 2,
		FrontCover = 3,
		BackCover = 4,
		LeafletPage = 5,
		Media = 6,
		LeadArtist = 7,
		Artist = 8,
		Conductor = 9,
		Band = 10,
		Composer = 11,
		Lyricist = 12,
		RecordingLocation = 13,
		DuringRecording = 14,
		DuringPerformance = 15,
		MovieScreenCapture = 16,
		ColoredFish = 17,
		Illustration = 18,
		BandLogo = 19,
		PublisherLogo = 20,
		NotAPicture = 255
	}
	public interface IPicture
	{
		string MimeType { get; set; }

		PictureType Type { get; set; }

		string Filename { get; set; }

		string Description { get; set; }

		ByteVector Data { get; set; }
	}
	public class Picture : IPicture
	{
		private static readonly string[] lutExtensionMime = new string[150]
		{
			"aac", "audio/aac", "abw", "application/x-abiword", "arc", "application/octet-stream", "avi", "video/x-msvideo", "azw", "application/vnd.amazon.ebook",
			"bin", "application/octet-stream", "bmp", "image/bmp", "bmp", "image/x-windows-bmp", "bm", "image/bmp", "bz", "application/x-bzip",
			"bz2", "application/x-bzip2", "csh", "application/x-csh", "css", "text/css", "csv", "text/csv", "doc", "application/msword",
			"eot", "application/vnd.ms-fontobject", "epub", "application/epub+zip", "gif", "image/gif", "htm", "text/html", "html", "text/html",
			"ico", "image/x-icon", "ics", "text/calendar", "jar", "application/java-archive", "jpg", "image/jpeg", "jpeg", "image/jpeg",
			"js", "application/javascript", "json", "application/json", "mid", "audio/midi", "midi", "audio/midi", "mp3", "audio/mpeg",
			"mp1", "audio/mpeg", "mp2", "audio/mpeg", "mpg", "video/mpeg", "mpeg", "video/mpeg", "m4a", "audio/mp4",
			"mp4", "video/mp4", "m4v", "video/mp4", "mpkg", "application/vnd.apple.installer+xml", "odp", "application/vnd.oasis.opendocument.presentation", "ods", "application/vnd.oasis.opendocument.spreadsheet",
			"odt", "application/vnd.oasis.opendocument.text", "oga", "audio/ogg", "ogg", "audio/ogg", "ogx", "application/ogg", "ogv", "video/ogg",
			"otf", "font/otf", "png", "image/png", "pdf", "application/pdf", "ppt", "application/vnd.ms-powerpoint", "rar", "application/x-rar-compressed",
			"rtf", "application/rtf", "sh", "application/x-sh", "svg", "image/svg+xml", "swf", "application/x-shockwave-flash", "tar", "application/x-tar",
			"tif", "image/tiff", "tiff", "image/tiff", "ts", "video/vnd.dlna.mpeg-tts", "ttf", "font/ttf", "vsd", "application/vnd.visio",
			"wav", "audio/x-wav", "weba", "audio/webm", "webm", "video/webm", "webp", "image/webp", "woff", "font/woff",
			"woff2", "font/woff2", "xhtml", "application/xhtml+xml", "xls", "application/vnd.ms", "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xml", "application/xml",
			"xul", "application/vnd.mozilla.xul+xml", "zip", "application/zip", "3gp", "video/3gpp", "3g2", "video/3gpp2", "7z", "application/x-7z-compressed"
		};

		public string MimeType { get; set; }

		public PictureType Type { get; set; }

		public string Filename { get; set; }

		public string Description { get; set; }

		public ByteVector Data { get; set; }

		public Picture()
		{
		}

		public Picture(string path)
		{
			if (path == null)
			{
				throw new ArgumentNullException("path");
			}
			Data = ByteVector.FromPath(path);
			Filename = Path.GetFileName(path);
			Description = Filename;
			MimeType = GetMimeFromExtension(Filename);
			Type = (MimeType.StartsWith("image/") ? PictureType.FrontCover : PictureType.NotAPicture);
		}

		public Picture(File.IFileAbstraction abstraction)
		{
			if (abstraction == null)
			{
				throw new ArgumentNullException("abstraction");
			}
			Data = ByteVector.FromFile(abstraction);
			Filename = abstraction.Name;
			Description = abstraction.Name;
			if (!string.IsNullOrEmpty(Filename) && Filename.Contains("."))
			{
				MimeType = GetMimeFromExtension(Filename);
				Type = (MimeType.StartsWith("image/") ? PictureType.FrontCover : PictureType.NotAPicture);
				return;
			}
			string extensionFromData = GetExtensionFromData(Data);
			MimeType = GetMimeFromExtension(extensionFromData);
			if (extensionFromData != null)
			{
				Type = PictureType.FrontCover;
				Filename = (Description = "cover" + extensionFromData);
			}
			else
			{
				Type = PictureType.NotAPicture;
				Filename = "UnknownType";
			}
		}

		public Picture(ByteVector data)
		{
			if (data == null)
			{
				throw new ArgumentNullException("data");
			}
			Data = new ByteVector(data);
			string extensionFromData = GetExtensionFromData(data);
			MimeType = GetMimeFromExtension(extensionFromData);
			if (extensionFromData != null)
			{
				Type = PictureType.FrontCover;
				Filename = (Description = "cover" + extensionFromData);
			}
			else
			{
				Type = PictureType.NotAPicture;
				Filename = "UnknownType";
			}
		}

		public Picture(IPicture picture)
		{
			MimeType = picture.MimeType;
			Type = picture.Type;
			Filename = picture.Filename;
			Description = picture.Description;
			Data = picture.Data;
		}

		[Obsolete("Use Picture(string filename) constructor instead.")]
		public static Picture CreateFromPath(string filename)
		{
			return new Picture(filename);
		}

		[Obsolete("Use Picture(File.IFileAbstraction abstraction) constructor instead.")]
		public static Picture CreateFromFile(File.IFileAbstraction abstraction)
		{
			return new Picture(abstraction);
		}

		public static string GetExtensionFromData(ByteVector data)
		{
			string result = null;
			if (data.Count >= 4)
			{
				if (data[1] == 80 && data[2] == 78 && data[3] == 71)
				{
					result = ".png";
				}
				else if (data[0] == 71 && data[1] == 73 && data[2] == 70)
				{
					result = ".gif";
				}
				else if (data[0] == 66 && data[1] == 77)
				{
					result = ".bmp";
				}
				else if (data[0] == byte.MaxValue && data[1] == 216 && data[data.Count - 2] == byte.MaxValue && data[data.Count - 1] == 217)
				{
					result = ".jpg";
				}
			}
			return result;
		}

		public static string GetExtensionFromMime(string mime)
		{
			string result = null;
			for (int i = 1; i < lutExtensionMime.Length; i += 2)
			{
				if (lutExtensionMime[i] == mime)
				{
					result = lutExtensionMime[i - 1];
					break;
				}
			}
			return result;
		}

		public static string GetMimeFromExtension(string name)
		{
			string result = "application/octet-stream";
			if (string.IsNullOrEmpty(name))
			{
				return result;
			}
			string extension = Path.GetExtension(name);
			extension = ((!string.IsNullOrEmpty(extension)) ? extension.Substring(1) : name);
			extension = extension.ToLower();
			for (int i = 0; i < lutExtensionMime.Length; i += 2)
			{
				if (lutExtensionMime[i] == extension)
				{
					result = lutExtensionMime[i + 1];
					break;
				}
			}
			return result;
		}
	}
	public class PictureLazy : IPicture, ILazy
	{
		private string mime_type;

		private PictureType type;

		private string filename;

		private ByteVector data;

		private File.IFileAbstraction file;

		private readonly long stream_offset;

		private readonly long stream_size = -1L;

		public string MimeType
		{
			get
			{
				if (mime_type == null)
				{
					Load();
				}
				return mime_type;
			}
			set
			{
				mime_type = value;
			}
		}

		public PictureType Type
		{
			get
			{
				if (type == PictureType.Other && mime_type == null)
				{
					Load();
				}
				return type;
			}
			set
			{
				type = value;
			}
		}

		public string Filename
		{
			get
			{
				if (filename == null)
				{
					Load();
				}
				return filename;
			}
			set
			{
				filename = value;
			}
		}

		public string Description { get; set; }

		public ByteVector Data
		{
			get
			{
				if (data == null)
				{
					Load();
				}
				return data;
			}
			set
			{
				data = value;
			}
		}

		public bool IsLoaded => data != null;

		public PictureLazy()
		{
		}

		public PictureLazy(string path)
		{
			if (path == null)
			{
				throw new ArgumentNullException("path");
			}
			file = new File.LocalFileAbstraction(path);
			filename = Path.GetFileName(path);
			Description = filename;
			mime_type = Picture.GetMimeFromExtension(filename);
			type = (mime_type.StartsWith("image/") ? PictureType.FrontCover : PictureType.NotAPicture);
		}

		public PictureLazy(File.IFileAbstraction abstraction, long offset = 0L, long size = -1L)
		{
			if (abstraction == null)
			{
				throw new ArgumentNullException("abstraction");
			}
			file = abstraction;
			stream_offset = offset;
			stream_size = size;
			filename = abstraction.Name;
			Description = abstraction.Name;
			if (!string.IsNullOrEmpty(filename) && filename.Contains("."))
			{
				mime_type = Picture.GetMimeFromExtension(filename);
				type = (mime_type.StartsWith("image/") ? PictureType.FrontCover : PictureType.NotAPicture);
			}
		}

		public PictureLazy(ByteVector data)
		{
			if (data == null)
			{
				throw new ArgumentNullException("data");
			}
			Data = new ByteVector(data);
			string extensionFromData = Picture.GetExtensionFromData(data);
			MimeType = Picture.GetMimeFromExtension(extensionFromData);
			if (extensionFromData != null)
			{
				type = PictureType.FrontCover;
				filename = (Description = "cover" + extensionFromData);
			}
			else
			{
				type = PictureType.NotAPicture;
				filename = "UnknownType";
			}
		}

		public PictureLazy(IPicture picture)
		{
			mime_type = picture.MimeType;
			type = picture.Type;
			filename = picture.Filename;
			Description = picture.Description;
			data = picture.Data;
		}

		public void Load()
		{
			if (data != null)
			{
				return;
			}
			Stream stream = null;
			try
			{
				if (stream_size == 0L)
				{
					data = new ByteVector();
				}
				else if (stream_size > 0)
				{
					stream = file.ReadStream;
					stream.Seek(stream_offset, SeekOrigin.Begin);
					int num = 0;
					int num2 = 0;
					int num3 = (int)stream_size;
					byte[] buffer = new byte[num3];
					do
					{
						num = stream.Read(buffer, num2, num3);
						num2 += num;
						num3 -= num;
					}
					while (num3 > 0 && num != 0);
					data = new ByteVector(buffer, num2);
				}
				else
				{
					stream = file.ReadStream;
					stream.Seek(stream_offset, SeekOrigin.Begin);
					data = ByteVector.FromStream(stream);
				}
			}
			finally
			{
				if (stream != null && file != null)
				{
					file.CloseStream(stream);
				}
				file = null;
			}
			if (mime_type != null)
			{
				return;
			}
			string extensionFromData = Picture.GetExtensionFromData(data);
			MimeType = Picture.GetMimeFromExtension(extensionFromData);
			if (extensionFromData != null)
			{
				type = PictureType.FrontCover;
				if (filename == null)
				{
					string text2 = (Description = "cover" + extensionFromData);
					filename = text2;
				}
			}
			else
			{
				type = PictureType.NotAPicture;
				if (filename == null)
				{
					filename = "UnknownType";
				}
			}
		}
	}
	public class Properties : IAudioCodec, ICodec, IVideoCodec, IPhotoCodec
	{
		private readonly ICodec[] codecs = new ICodec[0];

		private TimeSpan duration = TimeSpan.Zero;

		public IEnumerable<ICodec> Codecs => codecs;

		public TimeSpan Duration
		{
			get
			{
				TimeSpan timeSpan = duration;
				if (timeSpan != TimeSpan.Zero)
				{
					return timeSpan;
				}
				ICodec[] array = codecs;
				foreach (ICodec codec in array)
				{
					if (codec != null && codec.Duration > timeSpan)
					{
						timeSpan = codec.Duration;
					}
				}
				return timeSpan;
			}
		}

		public MediaTypes MediaTypes
		{
			get
			{
				MediaTypes mediaTypes = MediaTypes.None;
				ICodec[] array = codecs;
				foreach (ICodec codec in array)
				{
					if (codec != null)
					{
						mediaTypes |= codec.MediaTypes;
					}
				}
				return mediaTypes;
			}
		}

		public string Description
		{
			get
			{
				StringBuilder stringBuilder = new StringBuilder();
				ICodec[] array = codecs;
				foreach (ICodec codec in array)
				{
					if (codec != null)
					{
						if (stringBuilder.Length != 0)
						{
							stringBuilder.Append("; ");
						}
						stringBuilder.Append(codec.Description);
					}
				}
				return stringBuilder.ToString();
			}
		}

		public int AudioBitrate
		{
			get
			{
				ICodec[] array = codecs;
				foreach (ICodec codec in array)
				{
					if (codec != null && (codec.MediaTypes & MediaTypes.Audio) != 0 && codec is IAudioCodec audioCodec && audioCodec.AudioBitrate != 0)
					{
						return audioCodec.AudioBitrate;
					}
				}
				return 0;
			}
		}

		public int AudioSampleRate
		{
			get
			{
				ICodec[] array = codecs;
				foreach (ICodec codec in array)
				{
					if (codec != null && (codec.MediaTypes & MediaTypes.Audio) != 0 && codec is IAudioCodec audioCodec && audioCodec.AudioSampleRate != 0)
					{
						return audioCodec.AudioSampleRate;
					}
				}
				return 0;
			}
		}

		public int BitsPerSample
		{
			get
			{
				ICodec[] array = codecs;
				foreach (ICodec codec in array)
				{
					if (codec != null && (codec.MediaTypes & MediaTypes.Audio) != 0 && codec is ILosslessAudioCodec losslessAudioCodec && losslessAudioCodec.BitsPerSample != 0)
					{
						return losslessAudioCodec.BitsPerSample;
					}
				}
				return 0;
			}
		}

		public int AudioChannels
		{
			get
			{
				ICodec[] array = codecs;
				foreach (ICodec codec in array)
				{
					if (codec != null && (codec.MediaTypes & MediaTypes.Audio) != 0 && codec is IAudioCodec audioCodec && audioCodec.AudioChannels != 0)
					{
						return audioCodec.AudioChannels;
					}
				}
				return 0;
			}
		}

		public int VideoWidth
		{
			get
			{
				ICodec[] array = codecs;
				foreach (ICodec codec in array)
				{
					if (codec != null && (codec.MediaTypes & MediaTypes.Video) != 0 && codec is IVideoCodec videoCodec && videoCodec.VideoWidth != 0)
					{
						return videoCodec.VideoWidth;
					}
				}
				return 0;
			}
		}

		public int VideoHeight
		{
			get
			{
				ICodec[] array = codecs;
				foreach (ICodec codec in array)
				{
					if (codec != null && (codec.MediaTypes & MediaTypes.Video) != 0 && codec is IVideoCodec videoCodec && videoCodec.VideoHeight != 0)
					{
						return videoCodec.VideoHeight;
					}
				}
				return 0;
			}
		}

		public int PhotoWidth
		{
			get
			{
				ICodec[] array = codecs;
				foreach (ICodec codec in array)
				{
					if (codec != null && (codec.MediaTypes & MediaTypes.Photo) != 0 && codec is IPhotoCodec photoCodec && photoCodec.PhotoWidth != 0)
					{
						return photoCodec.PhotoWidth;
					}
				}
				return 0;
			}
		}

		public int PhotoHeight
		{
			get
			{
				ICodec[] array = codecs;
				foreach (ICodec codec in array)
				{
					if (codec != null && (codec.MediaTypes & MediaTypes.Photo) != 0 && codec is IPhotoCodec photoCodec && photoCodec.PhotoHeight != 0)
					{
						return photoCodec.PhotoHeight;
					}
				}
				return 0;
			}
		}

		public int PhotoQuality
		{
			get
			{
				ICodec[] array = codecs;
				foreach (ICodec codec in array)
				{
					if (codec != null && (codec.MediaTypes & MediaTypes.Photo) != 0 && codec is IPhotoCodec photoCodec && photoCodec.PhotoQuality != 0)
					{
						return photoCodec.PhotoQuality;
					}
				}
				return 0;
			}
		}

		public Properties()
		{
		}

		public Properties(TimeSpan duration, params ICodec[] codecs)
		{
			this.duration = duration;
			if (codecs != null)
			{
				this.codecs = codecs;
			}
		}

		public Properties(TimeSpan duration, IEnumerable<ICodec> codecs)
		{
			this.duration = duration;
			if (codecs != null)
			{
				this.codecs = new List<ICodec>(codecs).ToArray();
			}
		}
	}
	public sealed class ReadOnlyByteVector : ByteVector
	{
		public override bool IsReadOnly => true;

		public override bool IsFixedSize => true;

		public ReadOnlyByteVector()
		{
		}

		public ReadOnlyByteVector(int size, byte value)
			: base(size, value)
		{
		}

		public ReadOnlyByteVector(int size)
			: this(size, 0)
		{
		}

		public ReadOnlyByteVector(ByteVector vector)
			: base(vector)
		{
		}

		public ReadOnlyByteVector(byte[] data, int length)
			: base(data, length)
		{
		}

		public ReadOnlyByteVector(params byte[] data)
			: base(data)
		{
		}

		public static implicit operator ReadOnlyByteVector(byte value)
		{
			return new ReadOnlyByteVector(value);
		}

		public static implicit operator ReadOnlyByteVector(byte[] value)
		{
			return new ReadOnlyByteVector(value);
		}

		public static implicit operator ReadOnlyByteVector(string value)
		{
			return new ReadOnlyByteVector(ByteVector.FromString(value, StringType.UTF8));
		}
	}
	[ComVisible(false)]
	public class StringCollection : ListBase<string>
	{
		public StringCollection()
		{
		}

		public StringCollection(StringCollection values)
		{
			Add(values);
		}

		public StringCollection(params string[] values)
		{
			Add(values);
		}

		public StringCollection(ByteVectorCollection vectorList, StringType type)
		{
			foreach (ByteVector vector in vectorList)
			{
				Add(vector.ToString(type));
			}
		}

		public StringCollection(ByteVectorCollection vectorList)
			: this(vectorList, StringType.UTF8)
		{
		}

		public static StringCollection Split(string value, string pattern)
		{
			if (value == null)
			{
				throw new ArgumentNullException("value");
			}
			if (pattern == null)
			{
				throw new ArgumentNullException("pattern");
			}
			StringCollection stringCollection = new StringCollection();
			int num = 0;
			int num2 = value.IndexOf(pattern, 0);
			int length = pattern.Length;
			while (num2 != -1)
			{
				stringCollection.Add(value.Substring(num, num2 - num));
				num = num2 + length;
				num2 = value.IndexOf(pattern, num);
			}
			stringCollection.Add(value.Substring(num));
			return stringCollection;
		}
	}
	[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
	public sealed class SupportedMimeType : Attribute
	{
		private static readonly List<SupportedMimeType> mimetypes;

		public string MimeType { get; private set; }

		public string Extension { get; private set; }

		public static IEnumerable<string> AllMimeTypes
		{
			get
			{
				foreach (SupportedMimeType mimetype in mimetypes)
				{
					yield return mimetype.MimeType;
				}
			}
		}

		public static IEnumerable<string> AllExtensions
		{
			get
			{
				foreach (SupportedMimeType mimetype in mimetypes)
				{
					if (mimetype.Extension != null)
					{
						yield return mimetype.Extension;
					}
				}
			}
		}

		static SupportedMimeType()
		{
			mimetypes = new List<SupportedMimeType>();
			FileTypes.Init();
		}

		public SupportedMimeType(string mimetype)
		{
			MimeType = mimetype;
			mimetypes.Add(this);
		}

		public SupportedMimeType(string mimetype, string extension)
			: this(mimetype)
		{
			Extension = extension;
		}
	}
	[Flags]
	public enum TagTypes : uint
	{
		None = 0u,
		Xiph = 1u,
		Id3v1 = 2u,
		Id3v2 = 4u,
		Ape = 8u,
		Apple = 0x10u,
		Asf = 0x20u,
		RiffInfo = 0x40u,
		MovieId = 0x80u,
		DivX = 0x100u,
		FlacMetadata = 0x200u,
		TiffIFD = 0x400u,
		XMP = 0x800u,
		JpegComment = 0x1000u,
		GifComment = 0x2000u,
		Png = 0x4000u,
		IPTCIIM = 0x8000u,
		AudibleMetadata = 0x10000u,
		Matroska = 0x20000u,
		AllTags = uint.MaxValue
	}
	public abstract class Tag
	{
		public abstract TagTypes TagTypes { get; }

		public virtual string Title
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string TitleSort
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string Subtitle
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string Description
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string[] Performers
		{
			get
			{
				return new string[0];
			}
			set
			{
			}
		}

		public virtual string[] PerformersSort
		{
			get
			{
				return new string[0];
			}
			set
			{
			}
		}

		public virtual string[] PerformersRole
		{
			get
			{
				return new string[0];
			}
			set
			{
			}
		}

		public virtual string[] AlbumArtists
		{
			get
			{
				return new string[0];
			}
			set
			{
			}
		}

		public virtual string[] AlbumArtistsSort
		{
			get
			{
				return new string[0];
			}
			set
			{
			}
		}

		public virtual string[] Composers
		{
			get
			{
				return new string[0];
			}
			set
			{
			}
		}

		public virtual string[] ComposersSort
		{
			get
			{
				return new string[0];
			}
			set
			{
			}
		}

		public virtual string Album
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string AlbumSort
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string Comment
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string[] Genres
		{
			get
			{
				return new string[0];
			}
			set
			{
			}
		}

		public virtual uint Year
		{
			get
			{
				return 0u;
			}
			set
			{
			}
		}

		public virtual uint Track
		{
			get
			{
				return 0u;
			}
			set
			{
			}
		}

		public virtual uint TrackCount
		{
			get
			{
				return 0u;
			}
			set
			{
			}
		}

		public virtual uint Disc
		{
			get
			{
				return 0u;
			}
			set
			{
			}
		}

		public virtual uint DiscCount
		{
			get
			{
				return 0u;
			}
			set
			{
			}
		}

		public virtual string Lyrics
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string Grouping
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual uint BeatsPerMinute
		{
			get
			{
				return 0u;
			}
			set
			{
			}
		}

		public virtual string Conductor
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string Copyright
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual DateTime? DateTagged
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string MusicBrainzArtistId
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string MusicBrainzReleaseGroupId
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string MusicBrainzReleaseId
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string MusicBrainzReleaseArtistId
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string MusicBrainzTrackId
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string MusicBrainzDiscId
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string MusicIpId
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string AmazonId
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string MusicBrainzReleaseStatus
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string MusicBrainzReleaseType
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string MusicBrainzReleaseCountry
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual double ReplayGainTrackGain
		{
			get
			{
				return double.NaN;
			}
			set
			{
			}
		}

		public virtual double ReplayGainTrackPeak
		{
			get
			{
				return double.NaN;
			}
			set
			{
			}
		}

		public virtual double ReplayGainAlbumGain
		{
			get
			{
				return double.NaN;
			}
			set
			{
			}
		}

		public virtual double ReplayGainAlbumPeak
		{
			get
			{
				return double.NaN;
			}
			set
			{
			}
		}

		public virtual string InitialKey
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string RemixedBy
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string Publisher
		{
			get
			{
				return null;
			}