Decompiled source of Library of Ruina OST v2.0.2

NAudio.dll

Decompiled 7 months 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 7 months 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 EntityStates.Missions.BrotherEncounter;
using NAudio.Wave;
using NAudio.Wave.SampleProviders;
using On.EntityStates.Missions.BrotherEncounter;
using On.RoR2;
using On.RoR2.UI;
using RoR2;
using RoR2.ConVar;
using RoR2.UI;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("OriginalSoundTrack")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("OriginalSoundTrack")]
[assembly: AssemblyTitle("OriginalSoundTrack")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace OriginalSoundTrack;

[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.kylepaulsen.originalsoundtrack", "OriginalSoundTrack", "1.2.0")]
public class OriginalSoundTrack : BaseUnityPlugin
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static Func<string, string> <>9__14_7;

		public static hook_OnEnter <>9__14_5;

		public static Func<FileInfo, bool> <>9__15_0;

		internal string <Awake>b__14_7(string str)
		{
			return str.Trim();
		}

		internal void <Awake>b__14_5(orig_OnEnter orig, EncounterFinished self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== FINAL BOSS FIGHT DONE ======================");
		}

		internal bool <SearchForAudioFiles>b__15_0(FileInfo f)
		{
			if (!(Path.GetExtension(f.Name) == ".mp3"))
			{
				return Path.GetExtension(f.Name) == ".wav";
			}
			return true;
		}
	}

	private FadeInOutSampleProvider fader;

	private WaveOutEvent outputDevice;

	private FileInfo[] soundFiles;

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

	private AudioFileReader currentSong;

	private string currentSongFullName = "";

	private bool startedTeleporterEvent;

	private bool songPaused;

	private float globalMusicVolume = 0.5f;

	private bool shouldLoop = true;

	private string oldMusicVolume = "";

	private string currentScene = "";

	private Random rnd = new Random();

	private XmlElement settings;

	public void Awake()
	{
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b0: Expected O, but got Unknown
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c1: Expected O, but got Unknown
		//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d2: Expected O, but got Unknown
		//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e3: Expected O, but got Unknown
		//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f4: Expected O, but got Unknown
		//IL_0295: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Expected O, but got Unknown
		//IL_0308: Unknown result type (might be due to invalid IL or missing references)
		//IL_030d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0313: Expected O, but got Unknown
		string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		string text = directoryName;
		try
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(directoryName + "/settings.xml");
			settings = xmlDocument["settings"];
			globalMusicVolume = float.Parse(settings["volume"].InnerText, CultureInfo.InvariantCulture);
			shouldLoop = settings["loop"].InnerText.ToLower() == "true";
			if (settings["music-path"] != null)
			{
				text = settings["music-path"].InnerText;
			}
			soundFiles = SearchForAudioFiles(text);
			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(new char[1] { ',' })
					select str.Trim()).ToArray();
				music.boss = GetAttribute(childNode, "boss").ToLower() == "true";
				music.volume = 1f;
				string attribute = GetAttribute(childNode, "volume");
				if (attribute != "")
				{
					music.volume = float.Parse(attribute, CultureInfo.InvariantCulture);
				}
				FileInfo[] array = soundFiles;
				foreach (FileInfo fileInfo in array)
				{
					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 (!startedTeleporterEvent)
			{
				startedTeleporterEvent = true;
				PickOutMusic(isForTeleporter: true);
			}
		};
		TeleporterInteraction.RpcClientOnActivated += (hook_RpcClientOnActivated)delegate(orig_RpcClientOnActivated orig, TeleporterInteraction self, GameObject activator)
		{
			orig.Invoke(self, activator);
			if (!startedTeleporterEvent)
			{
				startedTeleporterEvent = true;
				PickOutMusic(isForTeleporter: true);
			}
		};
		PauseScreenController.OnEnable += (hook_OnEnable)delegate(orig_OnEnable orig, PauseScreenController self)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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;
			}
		};
		Phase1.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, Phase1 self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== FINAL BOSS FIGHT START ======================");
			PickOutMusic(isForTeleporter: true);
		};
		object obj = <>c.<>9__14_5;
		if (obj == null)
		{
			hook_OnEnter val = delegate(orig_OnEnter orig, EncounterFinished self)
			{
				orig.Invoke(self);
				Debug.Log((object)"====================== FINAL BOSS FIGHT DONE ======================");
			};
			<>c.<>9__14_5 = val;
			obj = (object)val;
		}
		EncounterFinished.OnEnter += (hook_OnEnter)obj;
		SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode)
		{
			if (currentScene != ((Scene)(ref scene)).name)
			{
				currentScene = ((Scene)(ref scene)).name;
				startedTeleporterEvent = false;
				PickOutMusic();
			}
		};
	}

	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;
	}

	private void PickOutMusic(bool isForTeleporter = false)
	{
		Music[] array = musics.Where(delegate(Music music)
		{
			bool flag = isForTeleporter == music.boss;
			return music.fullName != null && flag && sceneMostlyMatches(music.scenes);
		}).ToArray();
		string fullName = currentSongFullName;
		Music music2 = null;
		int num = 0;
		if (array.Length != 0)
		{
			while (fullName == currentSongFullName && num < 10)
			{
				music2 = array[rnd.Next(array.Length)];
				fullName = music2.fullName;
				num++;
			}
			((MonoBehaviour)this).StartCoroutine((IEnumerator)PlayMusic(fullName, music2.volume));
		}
		else
		{
			num = 0;
			while (fullName == currentSongFullName && num < 10)
			{
				fullName = soundFiles[rnd.Next(soundFiles.Length)].FullName;
				num++;
			}
			((MonoBehaviour)this).StartCoroutine((IEnumerator)PlayMusic(fullName));
		}
	}

	private IEnumerator<WaitForSeconds> PlayMusic(string file, float volume = 1f)
	{
		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);
			currentSong.Volume = volume * globalMusicVolume;
			LoopStream loopStream = new LoopStream((WaveStream)(object)currentSong, shouldLoop);
			fader = new FadeInOutSampleProvider((ISampleProvider)new WaveToSampleProvider((IWaveProvider)(object)loopStream), false);
			WaveExtensionMethods.Init((IWavePlayer)(object)outputDevice, (ISampleProvider)(object)fader, false);
			outputDevice.Play();
			songPaused = false;
		}
	}

	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(startedTeleporterEvent);
		}
	}

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

	public string fullName;

	public string[] scenes;

	public bool boss;

	public float volume = 1f;
}
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;
	}
}