Decompiled source of ModAudio v2.2.1

plugins/Marioalexsan.ModAudio.dll

Decompiled a month ago
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Marioalexsan.ModAudio.SoftDependencies;
using Microsoft.CodeAnalysis;
using NAudio.Wave;
using NVorbis;
using Newtonsoft.Json;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Serialization;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Events;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AudioModule")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Marioalexsan.ModAudio")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("2.2.1.0")]
[assembly: AssemblyInformationalVersion("2.2.1+6f4dbb5df69bcc99947b875e45f2286892b94c03")]
[assembly: AssemblyProduct("ModAudio")]
[assembly: AssemblyTitle("Marioalexsan.ModAudio")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.2.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace NAudio.Wave
{
	public class Mp3FileReader : Mp3FileReaderBase
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static FrameDecompressorBuilder <0>__CreateAcmFrameDecompressor;
		}

		public Mp3FileReader(string mp3FileName)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			FileStream fileStream = File.OpenRead(mp3FileName);
			object obj = <>O.<0>__CreateAcmFrameDecompressor;
			if (obj == null)
			{
				FrameDecompressorBuilder val = CreateAcmFrameDecompressor;
				<>O.<0>__CreateAcmFrameDecompressor = val;
				obj = (object)val;
			}
			((Mp3FileReaderBase)this)..ctor((Stream)fileStream, (FrameDecompressorBuilder)obj, true);
		}

		public Mp3FileReader(Stream inputStream)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			object obj = <>O.<0>__CreateAcmFrameDecompressor;
			if (obj == null)
			{
				FrameDecompressorBuilder val = CreateAcmFrameDecompressor;
				<>O.<0>__CreateAcmFrameDecompressor = val;
				obj = (object)val;
			}
			((Mp3FileReaderBase)this)..ctor(inputStream, (FrameDecompressorBuilder)obj, false);
		}

		public static IMp3FrameDecompressor CreateAcmFrameDecompressor(WaveFormat mp3Format)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			return (IMp3FrameDecompressor)new AcmMp3FrameDecompressor(mp3Format);
		}
	}
}
namespace Marioalexsan.ModAudio
{
	public static class AudioClipLoader
	{
		public interface IAudioStream : IDisposable
		{
			int TotalFrames { get; }

			int ChannelsPerFrame { get; }

			int Frequency { get; }

			void OnAudioRead(float[] samples);

			void OnAudioSetPosition(int newPosition);
		}

		private class OggStream : IAudioStream, IDisposable
		{
			private readonly VorbisReader _reader = new VorbisReader(stream, true);

			public float VolumeModifier = 1f;

			public int TotalFrames => (int)_reader.TotalSamples;

			public int ChannelsPerFrame => _reader.Channels;

			public int Frequency => _reader.SampleRate;

			public OggStream(Stream stream)
			{
			}//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown


			public void OnAudioRead(float[] samples)
			{
				_reader.ReadSamples((Span<float>)samples);
				OptimizedMethods.MultiplyFloatArray(samples, VolumeModifier);
			}

			public void OnAudioSetPosition(int newPosition)
			{
				_reader.SamplePosition = newPosition;
			}

			public void Dispose()
			{
				_reader.Dispose();
			}
		}

		private class WavStream : IAudioStream, IDisposable
		{
			private readonly WaveFileReader _reader;

			private readonly ISampleProvider _provider;

			public float VolumeModifier = 1f;

			public int TotalFrames => (int)_reader.SampleCount;

			public int ChannelsPerFrame => ((WaveStream)_reader).WaveFormat.Channels;

			public int Frequency => ((WaveStream)_reader).WaveFormat.SampleRate;

			public WavStream(Stream stream)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Expected O, but got Unknown
				_reader = new WaveFileReader(stream);
				_provider = WaveExtensionMethods.ToSampleProvider((IWaveProvider)(object)_reader);
			}

			public void OnAudioRead(float[] samples)
			{
				_provider.Read(samples, 0, samples.Length);
				OptimizedMethods.MultiplyFloatArray(samples, VolumeModifier);
			}

			public void OnAudioSetPosition(int newPosition)
			{
				((Stream)(object)_reader).Position = newPosition * ((WaveStream)_reader).BlockAlign;
			}

			public void Dispose()
			{
				((Stream)(object)_reader).Dispose();
			}
		}

		private class Mp3Stream : IAudioStream, IDisposable
		{
			private readonly Mp3FileReader _reader;

			private readonly ISampleProvider _provider;

			public float VolumeModifier = 1f;

			public int TotalFrames => (int)(((Stream)(object)_reader).Length * 8 / ChannelsPerFrame / ((WaveStream)_reader).WaveFormat.BitsPerSample);

			public int ChannelsPerFrame => ((WaveStream)_reader).WaveFormat.Channels;

			public int Frequency => ((WaveStream)_reader).WaveFormat.SampleRate;

			public Mp3Stream(Stream stream)
			{
				_reader = new Mp3FileReader(stream);
				_provider = WaveExtensionMethods.ToSampleProvider((IWaveProvider)(object)_reader);
			}

			public void OnAudioRead(float[] samples)
			{
				_provider.Read(samples, 0, samples.Length);
				OptimizedMethods.MultiplyFloatArray(samples, VolumeModifier);
			}

			public void OnAudioSetPosition(int newPosition)
			{
				((Stream)(object)_reader).Position = newPosition * ((WaveStream)_reader).BlockAlign;
			}

			public void Dispose()
			{
				((Stream)(object)_reader).Dispose();
			}
		}

		public static readonly string[] SupportedLoadExtensions = new string[7] { ".aiff", ".aif", ".mp3", ".ogg", ".wav", ".aac", ".alac" };

		public static readonly string[] SupportedStreamExtensions = new string[3] { ".wav", ".ogg", ".mp3" };

		public static readonly string[] SupportedExtensions;

		public static AudioClip LoadFromFile(string clipName, string path, float volumeModifier)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(new Uri(path ?? ""), (AudioType)0);
			try
			{
				audioClip.SendWebRequest();
				while (!audioClip.isDone)
				{
					Thread.Yield();
				}
				if ((int)audioClip.result != 1)
				{
					throw new Exception("Request for audio clip " + path + " failed.");
				}
				DownloadHandlerAudioClip val = (DownloadHandlerAudioClip)audioClip.downloadHandler;
				AudioClip audioClip2 = val.audioClip;
				((Object)audioClip2).name = clipName;
				float[] array = new float[audioClip2.samples * audioClip2.channels];
				audioClip2.GetData(array, 0);
				OptimizedMethods.MultiplyFloatArray(array, volumeModifier);
				audioClip2.SetData(array, 0);
				((DownloadHandler)val).Dispose();
				return audioClip2;
			}
			finally
			{
				((IDisposable)audioClip)?.Dispose();
			}
		}

		public static AudioClip StreamFromFile(string clipName, string path, float volumeModifier, out IAudioStream openedStream)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			//IL_00ba: Expected O, but got Unknown
			IAudioStream audioStream = null;
			if (path.EndsWith(".ogg"))
			{
				audioStream = new OggStream(File.OpenRead(path))
				{
					VolumeModifier = volumeModifier
				};
			}
			if (path.EndsWith(".mp3"))
			{
				audioStream = new Mp3Stream(File.OpenRead(path))
				{
					VolumeModifier = volumeModifier
				};
			}
			if (path.EndsWith(".wav"))
			{
				audioStream = new WavStream(File.OpenRead(path))
				{
					VolumeModifier = volumeModifier
				};
			}
			if (audioStream == null)
			{
				throw new NotImplementedException("The given file format isn't supported for streaming.");
			}
			openedStream = audioStream;
			int totalFrames = audioStream.TotalFrames;
			int channelsPerFrame = audioStream.ChannelsPerFrame;
			int frequency = audioStream.Frequency;
			IAudioStream audioStream2 = audioStream;
			PCMReaderCallback val = audioStream2.OnAudioRead;
			IAudioStream audioStream3 = audioStream;
			return AudioClip.Create(clipName, totalFrames, channelsPerFrame, frequency, true, val, new PCMSetPositionCallback(audioStream3.OnAudioSetPosition));
		}

		static AudioClipLoader()
		{
			string[] supportedStreamExtensions = SupportedStreamExtensions;
			string[] supportedLoadExtensions = SupportedLoadExtensions;
			int num = 0;
			string[] array = new string[supportedStreamExtensions.Length + supportedLoadExtensions.Length];
			ReadOnlySpan<string> readOnlySpan = new ReadOnlySpan<string>(supportedStreamExtensions);
			readOnlySpan.CopyTo(new Span<string>(array).Slice(num, readOnlySpan.Length));
			num += readOnlySpan.Length;
			ReadOnlySpan<string> readOnlySpan2 = new ReadOnlySpan<string>(supportedLoadExtensions);
			readOnlySpan2.CopyTo(new Span<string>(array).Slice(num, readOnlySpan2.Length));
			num += readOnlySpan2.Length;
			SupportedExtensions = array;
		}
	}
	internal static class AudioEngine
	{
		private struct SourceState
		{
			public AudioClip Clip;

			public float Volume;

			public float Pitch;

			public AudioClip AppliedClip;

			public float AppliedVolume;

			public float AppliedPitch;

			public bool DisableRouting;

			public bool IsOneShotSource;

			public bool IsOverlay;

			public bool JustRouted;

			public bool JustUsedDefaultClip;

			public bool WasStoppedOrDisabled;

			public AudioSource OneShotOrigin;
		}

		private static readonly Random RNG = new Random();

		private static readonly Stopwatch Watch = new Stopwatch();

		private static readonly Dictionary<AudioSource, SourceState> TrackedSources = new Dictionary<AudioSource, SourceState>();

		private static readonly HashSet<AudioSource> TrackedPlayOnAwakeSources = new HashSet<AudioSource>();

		private static AudioClip _emptyClip;

		public static List<AudioPack> AudioPacks { get; } = new List<AudioPack>();


		public static IEnumerable<AudioPack> EnabledPacks => AudioPacks.Where((AudioPack x) => x.Enabled);

		private static AudioClip EmptyClip
		{
			get
			{
				if ((Object)(object)_emptyClip == (Object)null)
				{
					_emptyClip = AudioClip.Create("___nothing___", 16384, 1, 44100, false);
					_emptyClip.SetData(new float[16384], 0);
				}
				return _emptyClip;
			}
		}

		private static bool IsValidTarget(AudioSource source, AudioPackConfig.Route route)
		{
			AudioClip clip = TrackedSources[source].Clip;
			string text = ((clip != null) ? ((Object)clip).name : null);
			bool flag = false;
			if (text != null)
			{
				for (int i = 0; i < route.OriginalClips.Count; i++)
				{
					if (route.OriginalClips[i] == text)
					{
						flag = true;
						break;
					}
				}
			}
			if (!flag)
			{
				return false;
			}
			if (route.FilterBySources.Count > 0)
			{
				string name = ((Object)source).name;
				bool flag2 = false;
				for (int j = 0; j < route.FilterBySources.Count; j++)
				{
					if (route.FilterBySources[j] == name)
					{
						flag2 = true;
						break;
					}
				}
				if (!flag2)
				{
					return false;
				}
			}
			if (route.FilterByObject.Count > 0)
			{
				Transform val = ((Component)source).transform;
				bool flag3 = false;
				while ((Object)(object)val != (Object)null)
				{
					string name2 = ((Object)((Component)val).gameObject).name;
					for (int k = 0; k < route.FilterByObject.Count; k++)
					{
						if (route.FilterByObject[k] == name2)
						{
							flag3 = true;
							break;
						}
					}
					val = val.parent;
				}
				if (!flag3)
				{
					return false;
				}
			}
			return true;
		}

		public static void HardReload()
		{
			Reload(hardReload: true);
		}

		public static void SoftReload()
		{
			Reload(hardReload: false);
		}

		private static void Reload(bool hardReload)
		{
			Watch.Restart();
			try
			{
				Logging.LogInfo("Reloading engine...");
				CleanupSources();
				if (hardReload)
				{
					OptimizedMethods.CachedForeach(TrackedSources, delegate(in KeyValuePair<AudioSource, SourceState> source)
					{
						KeyValuePair<AudioSource, SourceState> keyValuePair = source;
						if (keyValuePair.Value.IsOneShotSource)
						{
							Dictionary<AudioSource, SourceState> trackedSources = TrackedSources;
							keyValuePair = source;
							trackedSources.Remove(keyValuePair.Key);
							keyValuePair = source;
							Object.Destroy((Object)(object)keyValuePair.Key);
						}
					});
				}
				Dictionary<AudioSource, bool> dictionary = new Dictionary<AudioSource, bool>();
				AudioSource[] array = Object.FindObjectsOfType<AudioSource>(true);
				foreach (AudioSource val in array)
				{
					dictionary[val] = val.isPlaying;
					if (dictionary[val])
					{
						val.Stop();
					}
				}
				foreach (KeyValuePair<AudioSource, SourceState> trackedSource in TrackedSources)
				{
					if ((Object)(object)trackedSource.Key != (Object)null)
					{
						trackedSource.Key.clip = trackedSource.Value.Clip;
						trackedSource.Key.volume = trackedSource.Value.Volume;
						trackedSource.Key.pitch = trackedSource.Value.Pitch;
					}
				}
				TrackedSources.Clear();
				if (hardReload)
				{
					Logging.LogInfo("Reloading audio packs...");
					foreach (AudioPack audioPack in AudioPacks)
					{
						foreach (AudioClipLoader.IAudioStream openStream in audioPack.OpenStreams)
						{
							openStream.Dispose();
						}
					}
					AudioPacks.Clear();
					AudioPacks.AddRange(AudioPackLoader.LoadAudioPacks());
					ModAudio.Plugin.InitializePackConfiguration();
				}
				Logging.LogInfo("Preloading audio data...");
				foreach (AudioPack audioPack2 in AudioPacks)
				{
					if (audioPack2.Enabled && audioPack2.PendingClipsToLoad.Count > 0)
					{
						string[] array2 = audioPack2.PendingClipsToLoad.Keys.ToArray();
						string[] array3 = array2;
						foreach (string name in array3)
						{
							audioPack2.TryGetReadyClip(name, out var _);
						}
						Logging.LogInfo($"{audioPack2.Config.Id} - {array2.Length} clips preloaded.");
					}
				}
				Logging.LogInfo("Audio data preloaded.");
				AudioSource[] array4 = Object.FindObjectsOfType<AudioSource>(true);
				foreach (AudioSource val2 in array4)
				{
					if (dictionary[val2])
					{
						val2.Play();
					}
				}
				Logging.LogInfo("Done with reload!");
			}
			catch (Exception ex)
			{
				Logging.LogError("ModAudio crashed in Reload! Please report this error to the mod developer:");
				Logging.LogError(ex.ToString());
			}
			Watch.Stop();
			Logging.LogInfo($"Reload took {Watch.ElapsedMilliseconds} milliseconds.");
		}

		public static void Update()
		{
			try
			{
				AudioSource[] array = Object.FindObjectsOfType<AudioSource>(true);
				foreach (AudioSource val in array)
				{
					if (val.playOnAwake)
					{
						if (!TrackedPlayOnAwakeSources.Contains(val) && ((Behaviour)val).isActiveAndEnabled && val.isPlaying)
						{
							AudioPlayed(val);
						}
						else if (TrackedPlayOnAwakeSources.Contains(val) && !((Behaviour)val).isActiveAndEnabled && !val.isPlaying)
						{
							AudioStopped(val, stopOneShots: false);
						}
					}
				}
				CleanupSources();
			}
			catch (Exception ex)
			{
				Logging.LogError("ModAudio crashed in Update! Please report this error to the mod developer:");
				Logging.LogError(ex.ToString());
			}
		}

		private static void CleanupSources()
		{
			OptimizedMethods.CachedForeach(TrackedPlayOnAwakeSources, delegate(in AudioSource source)
			{
				if ((Object)(object)source == (Object)null)
				{
					TrackedPlayOnAwakeSources.Remove(source);
				}
			});
			OptimizedMethods.CachedForeach(TrackedSources, delegate(in KeyValuePair<AudioSource, SourceState> source)
			{
				KeyValuePair<AudioSource, SourceState> keyValuePair = source;
				if ((Object)(object)keyValuePair.Key == (Object)null)
				{
					Dictionary<AudioSource, SourceState> trackedSources = TrackedSources;
					keyValuePair = source;
					trackedSources.Remove(keyValuePair.Key);
				}
				else
				{
					keyValuePair = source;
					if (keyValuePair.Value.IsOneShotSource)
					{
						keyValuePair = source;
						if (!keyValuePair.Key.isPlaying)
						{
							Dictionary<AudioSource, SourceState> trackedSources2 = TrackedSources;
							keyValuePair = source;
							trackedSources2.Remove(keyValuePair.Key);
							keyValuePair = source;
							AudioStopped(keyValuePair.Key, stopOneShots: false);
							keyValuePair = source;
							Object.Destroy((Object)(object)keyValuePair.Key);
						}
					}
				}
			});
		}

		private static void TrackSource(AudioSource source)
		{
			if (!TrackedSources.ContainsKey(source))
			{
				TrackedSources.Add(source, new SourceState
				{
					AppliedClip = source.clip,
					Clip = source.clip,
					Pitch = source.pitch,
					Volume = source.volume,
					AppliedPitch = source.pitch,
					AppliedVolume = source.volume
				});
			}
		}

		private static AudioSource CreateOneShotFromSource(AudioSource source)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)source).gameObject;
			int num = 3;
			do
			{
				ParticleSystem component = gameObject.GetComponent<ParticleSystem>();
				if ((Object)(object)component == (Object)null || (Object)(object)gameObject.transform.parent == (Object)null)
				{
					break;
				}
				gameObject = ((Component)gameObject.transform.parent).gameObject;
			}
			while (num-- > 0);
			AudioSource val = gameObject.AddComponent<AudioSource>();
			val.volume = source.volume;
			val.pitch = source.pitch;
			val.clip = source.clip;
			val.outputAudioMixerGroup = source.outputAudioMixerGroup;
			val.loop = false;
			val.ignoreListenerVolume = source.ignoreListenerVolume;
			val.ignoreListenerPause = source.ignoreListenerPause;
			val.velocityUpdateMode = source.velocityUpdateMode;
			val.panStereo = source.panStereo;
			val.spatialBlend = source.spatialBlend;
			val.spatialize = source.spatialize;
			val.spatializePostEffects = source.spatializePostEffects;
			val.reverbZoneMix = source.reverbZoneMix;
			val.bypassEffects = source.bypassEffects;
			val.bypassListenerEffects = source.bypassListenerEffects;
			val.bypassReverbZones = source.bypassReverbZones;
			val.dopplerLevel = source.dopplerLevel;
			val.spread = source.spread;
			val.priority = source.priority;
			val.mute = source.mute;
			val.minDistance = source.minDistance;
			val.maxDistance = source.maxDistance;
			val.rolloffMode = source.rolloffMode;
			val.playOnAwake = false;
			val.SetCustomCurve((AudioSourceCurveType)0, source.GetCustomCurve((AudioSourceCurveType)0));
			val.SetCustomCurve((AudioSourceCurveType)2, source.GetCustomCurve((AudioSourceCurveType)2));
			val.SetCustomCurve((AudioSourceCurveType)1, source.GetCustomCurve((AudioSourceCurveType)1));
			val.SetCustomCurve((AudioSourceCurveType)3, source.GetCustomCurve((AudioSourceCurveType)3));
			TrackSource(val);
			Dictionary<AudioSource, SourceState> trackedSources = TrackedSources;
			SourceState value = TrackedSources[val];
			value.IsOneShotSource = true;
			value.OneShotOrigin = source;
			trackedSources[val] = value;
			return val;
		}

		public static bool OneShotClipPlayed(AudioClip clip, AudioSource source, float volumeScale)
		{
			try
			{
				AudioSource val = CreateOneShotFromSource(source);
				val.volume *= volumeScale;
				val.clip = clip;
				Dictionary<AudioSource, SourceState> trackedSources = TrackedSources;
				SourceState value = TrackedSources[val];
				value.Clip = clip;
				value.AppliedClip = val.clip;
				value.Volume = val.volume;
				value.AppliedVolume = val.volume;
				trackedSources[val] = value;
				val.Play();
				return false;
			}
			catch (Exception ex)
			{
				Logging.LogError("ModAudio crashed in OneShotClipPlayed! Please report this error to the mod developer:");
				Logging.LogError(ex.ToString());
				Logging.LogError("AudioSource that caused the crash:");
				Logging.LogError("  name = " + (((source != null) ? ((Object)source).name : null) ?? "(null)"));
				object obj;
				if (source == null)
				{
					obj = null;
				}
				else
				{
					AudioClip clip2 = source.clip;
					obj = ((clip2 != null) ? ((Object)clip2).name : null);
				}
				if (obj == null)
				{
					obj = "(null)";
				}
				Logging.LogError("  clip = " + (string?)obj);
				Logging.LogError("AudioClip that caused the crash:");
				Logging.LogError("  name = " + (((clip != null) ? ((Object)clip).name : null) ?? "(null)"));
				Logging.LogError(string.Format("Parameter {0} was: {1}", "volumeScale", volumeScale));
				return true;
			}
		}

		private static void LogAudio(AudioSource source)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			float num = float.MinValue;
			if (ModAudio.Plugin.UseMaxDistanceForLogging.Value && Object.op_Implicit((Object)(object)Player._mainPlayer))
			{
				num = Vector3.Distance(((Component)Player._mainPlayer).transform.position, ((Component)source).transform.position);
				if (num > ModAudio.Plugin.MaxDistanceForLogging.Value)
				{
					return;
				}
			}
			AudioMixerGroup outputAudioMixerGroup = source.outputAudioMixerGroup;
			string text = ((outputAudioMixerGroup == null) ? null : ((Object)outputAudioMixerGroup).name?.ToLower()) ?? "(null)";
			if ((ModAudio.Plugin.LogAmbience.Value || !(text == "ambience")) && (ModAudio.Plugin.LogGame.Value || !(text == "game")) && (ModAudio.Plugin.LogGUI.Value || !(text == "gui")) && (ModAudio.Plugin.LogMusic.Value || !(text == "music")) && (ModAudio.Plugin.LogVoice.Value || !(text == "voice")))
			{
				AudioClip clip = TrackedSources[source].Clip;
				string text2 = ((clip != null) ? ((Object)clip).name : null) ?? "(null)";
				AudioClip clip2 = source.clip;
				string text3 = ((clip2 != null) ? ((Object)clip2).name : null) ?? "(null)";
				bool flag = (Object)(object)TrackedSources[source].Clip != (Object)(object)source.clip;
				if (TrackedSources[source].JustUsedDefaultClip)
				{
					flag = true;
					text3 = "___default___";
				}
				float volume = TrackedSources[source].Volume;
				float appliedVolume = TrackedSources[source].AppliedVolume;
				float pitch = TrackedSources[source].Pitch;
				float appliedPitch = TrackedSources[source].AppliedPitch;
				string text4 = (flag ? (text2 + " > " + text3) : text2);
				string text5 = ((volume != appliedVolume) ? $"{volume:F2} > {appliedVolume:F2}" : $"{volume:F2}");
				string text6 = ((pitch != appliedPitch) ? $"{pitch:F2} > {appliedPitch:F2}" : $"{pitch:F2}");
				string text7 = "Clip " + text4 + " Src " + ((Object)source).name + " Vol " + text5 + " Pit " + text6 + " Grp " + text;
				if (num != float.MinValue)
				{
					text7 += $" Dst {num:F2}";
				}
				if (TrackedSources[source].IsOverlay)
				{
					text7 += " overlay";
				}
				if (TrackedSources[source].IsOneShotSource)
				{
					text7 += " oneshot";
				}
				Logging.LogInfo(text7, ModAudio.Plugin.LogAudioPlayed);
			}
		}

		public static bool AudioPlayed(AudioSource source)
		{
			try
			{
				TrackSource(source);
				if (source.playOnAwake)
				{
					TrackedPlayOnAwakeSources.Add(source);
				}
				bool isPlaying = source.isPlaying;
				if (!Route(source))
				{
					LogAudio(source);
					return true;
				}
				Dictionary<AudioSource, SourceState> trackedSources = TrackedSources;
				SourceState value = TrackedSources[source];
				value.JustRouted = false;
				value.WasStoppedOrDisabled = false;
				trackedSources[source] = value;
				bool flag = isPlaying && !source.isPlaying;
				if (flag)
				{
					source.Play();
				}
				else
				{
					LogAudio(source);
				}
				return !flag;
			}
			catch (Exception ex)
			{
				Logging.LogError("ModAudio crashed in AudioPlayed! Please report this error to the mod developer:");
				Logging.LogError(ex.ToString());
				Logging.LogError("AudioSource that caused the crash:");
				Logging.LogError("  name = " + (((source != null) ? ((Object)source).name : null) ?? "(null)"));
				object obj;
				if (source == null)
				{
					obj = null;
				}
				else
				{
					AudioClip clip = source.clip;
					obj = ((clip != null) ? ((Object)clip).name : null);
				}
				if (obj == null)
				{
					obj = "(null)";
				}
				Logging.LogError("  clip = " + (string?)obj);
				return true;
			}
		}

		public static bool AudioStopped(AudioSource source, bool stopOneShots)
		{
			try
			{
				TrackSource(source);
				if (source.playOnAwake)
				{
					TrackedPlayOnAwakeSources.Remove(source);
				}
				if (stopOneShots)
				{
					OptimizedMethods.CachedForeach(TrackedSources, in source, delegate(in KeyValuePair<AudioSource, SourceState> trackedSource, in AudioSource stoppedSource)
					{
						KeyValuePair<AudioSource, SourceState> keyValuePair = trackedSource;
						if (keyValuePair.Value.IsOneShotSource)
						{
							keyValuePair = trackedSource;
							if ((Object)(object)keyValuePair.Value.OneShotOrigin == (Object)(object)stoppedSource)
							{
								keyValuePair = trackedSource;
								if ((Object)(object)keyValuePair.Key != (Object)null)
								{
									keyValuePair = trackedSource;
									if (keyValuePair.Key.isPlaying)
									{
										keyValuePair = trackedSource;
										keyValuePair.Key.Stop();
									}
								}
							}
						}
					});
				}
				Dictionary<AudioSource, SourceState> trackedSources = TrackedSources;
				AudioSource key = source;
				SourceState value = TrackedSources[source];
				value.WasStoppedOrDisabled = true;
				trackedSources[key] = value;
				return true;
			}
			catch (Exception ex)
			{
				Logging.LogError("ModAudio crashed in AudioStopped! Please report this error to the mod developer:");
				Logging.LogError(ex.ToString());
				Logging.LogError("AudioSource that caused the crash:");
				Logging.LogError("  name = " + (((source != null) ? ((Object)source).name : null) ?? "(null)"));
				object obj;
				if (source == null)
				{
					obj = null;
				}
				else
				{
					AudioClip clip = source.clip;
					obj = ((clip != null) ? ((Object)clip).name : null);
				}
				if (obj == null)
				{
					obj = "(null)";
				}
				Logging.LogError("  clip = " + (string?)obj);
				Logging.LogError(string.Format("Parameter {0} was: {1}", "stopOneShots", stopOneShots));
				return true;
			}
		}

		private static bool Route(AudioSource source)
		{
			SourceState sourceState = TrackedSources[source];
			SourceState value;
			if ((Object)(object)source.clip != (Object)(object)sourceState.AppliedClip)
			{
				Dictionary<AudioSource, SourceState> trackedSources = TrackedSources;
				value = TrackedSources[source];
				value.Clip = source.clip;
				value.AppliedClip = source.clip;
				trackedSources[source] = value;
				if ((double)Math.Abs(source.volume - sourceState.AppliedVolume) >= 0.005)
				{
					Dictionary<AudioSource, SourceState> trackedSources2 = TrackedSources;
					value = TrackedSources[source];
					value.Volume = source.volume;
					value.AppliedVolume = source.volume;
					trackedSources2[source] = value;
				}
				else
				{
					source.volume = sourceState.Volume;
				}
				if ((double)Math.Abs(source.pitch - sourceState.AppliedPitch) >= 0.005)
				{
					Dictionary<AudioSource, SourceState> trackedSources3 = TrackedSources;
					value = TrackedSources[source];
					value.Pitch = source.pitch;
					value.AppliedPitch = source.pitch;
					trackedSources3[source] = value;
				}
				else
				{
					source.pitch = sourceState.Pitch;
				}
			}
			if (sourceState.JustRouted || sourceState.DisableRouting)
			{
				return false;
			}
			Dictionary<AudioSource, SourceState> trackedSources4 = TrackedSources;
			value = TrackedSources[source];
			value.JustRouted = true;
			value.JustUsedDefaultClip = false;
			trackedSources4[source] = value;
			List<(AudioPack, AudioPackConfig.Route)> list = new List<(AudioPack, AudioPackConfig.Route)>();
			foreach (AudioPack enabledPack in EnabledPacks)
			{
				foreach (AudioPackConfig.Route route in enabledPack.Config.Routes)
				{
					if (IsValidTarget(source, route))
					{
						list.Add((enabledPack, route));
					}
				}
			}
			(AudioPack, AudioPackConfig.Route) tuple = (null, null);
			if (list.Count > 0)
			{
				tuple = SelectRandomWeighted(list);
				if (tuple.Item2.RelativeReplacementEffects)
				{
					source.volume = sourceState.Volume * tuple.Item2.Volume;
					source.pitch = sourceState.Pitch * tuple.Item2.Pitch;
				}
				else
				{
					source.volume = tuple.Item2.Volume;
					source.pitch = tuple.Item2.Pitch;
				}
				Dictionary<AudioSource, SourceState> trackedSources5 = TrackedSources;
				value = TrackedSources[source];
				value.AppliedPitch = source.pitch;
				value.AppliedVolume = source.volume;
				trackedSources5[source] = value;
				if (tuple.Item2.ReplacementClips.Count > 0)
				{
					AudioPackConfig.Route.ClipSelection clipSelection = SelectRandomWeighted(tuple.Item2.ReplacementClips);
					AudioClip clip;
					if (clipSelection.Name == "___default___")
					{
						clip = TrackedSources[source].Clip;
						Dictionary<AudioSource, SourceState> trackedSources6 = TrackedSources;
						value = TrackedSources[source];
						value.JustUsedDefaultClip = true;
						trackedSources6[source] = value;
					}
					else if (clipSelection.Name == "___nothing___")
					{
						clip = EmptyClip;
					}
					else
					{
						tuple.Item1.TryGetReadyClip(clipSelection.Name, out clip);
					}
					if ((Object)(object)clip != (Object)null)
					{
						source.volume *= clipSelection.Volume;
						source.pitch *= clipSelection.Pitch;
						Dictionary<AudioSource, SourceState> trackedSources7 = TrackedSources;
						value = TrackedSources[source];
						value.AppliedClip = clip;
						value.JustRouted = true;
						value.AppliedPitch = source.pitch;
						value.AppliedVolume = source.volume;
						trackedSources7[source] = value;
						if ((Object)(object)source.clip != (Object)(object)clip && source.isPlaying)
						{
							source.Stop();
						}
						source.clip = clip;
					}
					else
					{
						Logging.LogWarning(Texts.AudioClipNotFound(clipSelection.Name));
					}
				}
			}
			List<(AudioPack, AudioPackConfig.Route)> list2 = new List<(AudioPack, AudioPackConfig.Route)>();
			foreach (AudioPack enabledPack2 in EnabledPacks)
			{
				foreach (AudioPackConfig.Route route2 in enabledPack2.Config.Routes)
				{
					if ((!route2.OverlaysIgnoreRestarts || TrackedSources[source].WasStoppedOrDisabled || !source.isPlaying) && route2.OverlayClips.Count > 0 && IsValidTarget(source, route2) && (!route2.LinkOverlayAndReplacement || tuple.Item2 == route2))
					{
						list2.Add((enabledPack2, route2));
					}
				}
			}
			if (list2.Count > 0 && !TrackedSources[source].IsOverlay)
			{
				foreach (var item3 in list2)
				{
					AudioPack item = item3.Item1;
					AudioPackConfig.Route item2 = item3.Item2;
					AudioPackConfig.Route.ClipSelection clipSelection2 = SelectRandomWeighted(item2.OverlayClips);
					if (clipSelection2.Name == "___nothing___")
					{
						continue;
					}
					if (item.TryGetReadyClip(clipSelection2.Name, out var clip2))
					{
						AudioSource val = CreateOneShotFromSource(source);
						val.clip = clip2;
						if (item2.RelativeOverlayEffects)
						{
							val.volume = sourceState.Volume * clipSelection2.Volume;
							val.pitch = sourceState.Pitch * clipSelection2.Pitch;
						}
						else
						{
							val.volume = clipSelection2.Volume;
							val.pitch = clipSelection2.Pitch;
						}
						Dictionary<AudioSource, SourceState> trackedSources8 = TrackedSources;
						value = TrackedSources[val];
						value.Pitch = val.pitch;
						value.Volume = val.volume;
						value.AppliedPitch = val.pitch;
						value.AppliedVolume = val.volume;
						value.Clip = val.clip;
						value.AppliedClip = val.clip;
						value.IsOverlay = true;
						value.DisableRouting = true;
						trackedSources8[val] = value;
						val.Play();
					}
					else
					{
						Logging.LogWarning(Texts.AudioClipNotFound(clipSelection2.Name));
					}
				}
			}
			return true;
		}

		private static (AudioPack Pack, AudioPackConfig.Route Route) SelectRandomWeighted(List<(AudioPack Pack, AudioPackConfig.Route Route)> routes)
		{
			double num = 0.0;
			for (int i = 0; i < routes.Count; i++)
			{
				num += (double)routes[i].Route.ReplacementWeight;
			}
			int num2 = -1;
			double num3 = RNG.NextDouble() * num;
			do
			{
				num2++;
				num3 -= (double)routes[num2].Route.ReplacementWeight;
			}
			while (num3 >= 0.0);
			return routes[num2];
		}

		private static AudioPackConfig.Route.ClipSelection SelectRandomWeighted(List<AudioPackConfig.Route.ClipSelection> selections)
		{
			double num = 0.0;
			for (int i = 0; i < selections.Count; i++)
			{
				num += (double)selections[i].Weight;
			}
			int num2 = -1;
			double num3 = RNG.NextDouble() * num;
			do
			{
				num2++;
				num3 -= (double)selections[num2].Weight;
			}
			while (num3 >= 0.0);
			return selections[num2];
		}
	}
	public class AudioPack
	{
		public string PackPath { get; set; } = "???";


		public bool Enabled { get; set; } = false;


		public bool OverrideModeEnabled { get; set; } = false;


		public AudioPackConfig Config { get; set; } = new AudioPackConfig();


		public List<AudioClipLoader.IAudioStream> OpenStreams { get; } = new List<AudioClipLoader.IAudioStream>();


		public Dictionary<string, AudioClip> ReadyClips { get; } = new Dictionary<string, AudioClip>();


		public Dictionary<string, Func<AudioClip>> PendingClipsToLoad { get; } = new Dictionary<string, Func<AudioClip>>();


		public Dictionary<string, Func<AudioClip>> PendingClipsToStream { get; } = new Dictionary<string, Func<AudioClip>>();


		public bool IsUserPack()
		{
			return PackPath.StartsWith(ModAudio.Plugin.ModAudioConfigFolder) || PackPath.StartsWith(ModAudio.Plugin.ModAudioPluginFolder);
		}

		public bool TryGetReadyClip(string name, out AudioClip clip)
		{
			if (ReadyClips.TryGetValue(name, out clip))
			{
				return true;
			}
			if (PendingClipsToStream.TryGetValue(name, out var value))
			{
				PendingClipsToStream.Remove(name);
				AudioClip val2 = (ReadyClips[name] = value());
				clip = val2;
				return true;
			}
			if (PendingClipsToLoad.TryGetValue(name, out var value2))
			{
				PendingClipsToLoad.Remove(name);
				AudioClip val2 = (ReadyClips[name] = value2());
				clip = val2;
				return true;
			}
			clip = null;
			return false;
		}
	}
	public class AudioPackConfig
	{
		public class Settings
		{
			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public bool AutoloadReplacementClips { get; set; } = true;

		}

		public class AudioClipData
		{
			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public string Name { get; set; } = "";


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public string Path { get; set; } = "";


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public float Volume { get; set; } = 1f;


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public bool IgnoreClipExtension { get; set; } = false;

		}

		public class Route
		{
			public class ClipSelection
			{
				[JsonProperty(/*Could not decode attribute arguments.*/)]
				public string Name { get; set; } = "";


				[JsonProperty(/*Could not decode attribute arguments.*/)]
				public float Weight { get; set; } = 1f;


				[JsonProperty(/*Could not decode attribute arguments.*/)]
				public float Volume { get; set; } = 1f;


				[JsonProperty(/*Could not decode attribute arguments.*/)]
				public float Pitch { get; set; } = 1f;

			}

			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public bool LinkOverlayAndReplacement { get; set; } = true;


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public bool RelativeReplacementEffects { get; set; } = true;


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public bool RelativeOverlayEffects { get; set; } = false;


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public bool OverlaysIgnoreRestarts { get; set; } = false;


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public List<string> OriginalClips { get; set; } = new List<string>();


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public List<ClipSelection> ReplacementClips { get; set; } = new List<ClipSelection>();


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public List<ClipSelection> OverlayClips { get; set; } = new List<ClipSelection>();


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public List<string> FilterBySources { get; set; } = new List<string>();


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public List<string> FilterByObject { get; set; } = new List<string>();


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public float ReplacementWeight { get; set; } = 1f;


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public float Volume { get; set; } = 1f;


			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public float Pitch { get; set; } = 1f;

		}

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string Id { get; set; } = "";


		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string DisplayName { get; set; } = "";


		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public Settings AudioPackSettings { get; set; } = new Settings();


		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public List<AudioClipData> CustomClips { get; set; } = new List<AudioClipData>();


		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public List<Route> Routes { get; set; } = new List<Route>();


		public static AudioPackConfig ReadJSON(Stream stream)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			List<string> warnings = new List<string>();
			StreamReader streamReader = new StreamReader(stream);
			AudioPackConfig result = JsonConvert.DeserializeObject<AudioPackConfig>(streamReader.ReadToEnd(), new JsonSerializerSettings
			{
				MissingMemberHandling = (MissingMemberHandling)1,
				Error = delegate(object obj, ErrorEventArgs e)
				{
					Exception error = e.ErrorContext.Error;
					JsonException val = (JsonException)(object)((error is JsonException) ? error : null);
					if (val != null && ((Exception)(object)val).Message.Contains("Could not find member"))
					{
						warnings.Add(((Exception)(object)val).Message);
						e.ErrorContext.Handled = true;
					}
				}
			});
			foreach (string item in warnings)
			{
				Logging.LogWarning(item);
			}
			return result;
		}

		public static AudioPackConfig ConvertFromRoutes(RouteConfig routeConfig)
		{
			AudioPackConfig audioPackConfig = new AudioPackConfig
			{
				CustomClips = (from x in (from x in routeConfig.Routes.SelectMany((Route x) => x.ReplacementClips.Concat(x.OverlayClips))
						select x.Name into x
						where x != "___default___" && x != "___nothing___"
						select x).Distinct()
					select new AudioClipData
					{
						Name = x,
						Path = x,
						IgnoreClipExtension = true,
						Volume = (routeConfig.ClipVolumes.ContainsKey(x) ? routeConfig.ClipVolumes[x] : 1f)
					}).ToList(),
				Routes = routeConfig.Routes,
				Id = routeConfig.Id,
				DisplayName = routeConfig.DisplayName
			};
			foreach (KeyValuePair<string, float> clipVolume in routeConfig.ClipVolumes)
			{
				if (!audioPackConfig.CustomClips.Any((AudioClipData x) => x.Name == clipVolume.Key))
				{
					Logging.LogWarning("Couldn't find clip " + clipVolume.Key + " to set volume for.");
				}
			}
			return audioPackConfig;
		}

		public static string GenerateSchema()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return ((object)new JsonSchemaGenerator().Generate(typeof(AudioPackConfig))).ToString();
		}
	}
	public static class AudioPackLoader
	{
		public const float OneMB = 1048576f;

		public const string AudioPackConfigName = "modaudio.config.json";

		public const string RoutesConfigName = "__routes.txt";

		public const int FileSizeLimitForLoading = 1048576;

		public static string ReplaceRootPath(string path)
		{
			return Path.GetFullPath(path).Replace(Paths.PluginPath + "/", "plugin://").Replace(Paths.PluginPath + "\\", "plugin://")
				.Replace(Paths.ConfigPath + "/", "config://")
				.Replace(Paths.ConfigPath + "\\", "config://");
		}

		private static bool IsNormalizedId(string id)
		{
			return !id.Contains("\\");
		}

		private static string NormalizeId(string id)
		{
			return id.Replace("\\", "/");
		}

		private static string ConvertPathToId(string path)
		{
			return NormalizeId(ReplaceRootPath(path));
		}

		private static string ConvertPathToDisplayName(string path)
		{
			string text = Path.GetFullPath(path).Replace(Paths.PluginPath + "/", "").Replace(Paths.PluginPath + "\\", "")
				.Replace(Paths.ConfigPath + "/", "")
				.Replace(Paths.ConfigPath + "\\", "")
				.Replace("\\", "/");
			int num = text.IndexOf('/');
			return (num == -1) ? text : text.Substring(0, num);
		}

		public static List<AudioPack> LoadAudioPacks()
		{
			List<AudioPack> list = new List<AudioPack>();
			string[] directories = Directory.GetDirectories(Paths.ConfigPath);
			string[] directories2 = Directory.GetDirectories(Paths.PluginPath);
			List<string> list2 = new List<string>(directories.Length + directories2.Length);
			list2.AddRange(directories);
			list2.AddRange(directories2);
			List<string> list3 = list2;
			foreach (string item in list3)
			{
				LoadAudioPacksFromRoot(list, item);
			}
			foreach (AudioPack item2 in list)
			{
				FinalizePack(item2);
				Logging.LogInfo(Texts.PackLoaded(item2), ModAudio.Plugin.LogPackLoading);
			}
			return list;
		}

		private static void FinalizePack(AudioPack pack)
		{
			foreach (AudioPackConfig.Route route in pack.Config.Routes)
			{
				float num = Mathf.Clamp(route.ReplacementWeight, 0.001f, 1000f);
				if (num != route.ReplacementWeight)
				{
					Logging.LogWarning(Texts.WeightClamped(num, pack));
				}
				route.ReplacementWeight = num;
				foreach (AudioPackConfig.Route.ClipSelection replacementClip in route.ReplacementClips)
				{
					num = Mathf.Clamp(replacementClip.Weight, 0.001f, 1000f);
					if (num != replacementClip.Weight)
					{
						Logging.LogWarning(Texts.WeightClamped(num, pack));
					}
					replacementClip.Weight = num;
				}
				foreach (AudioPackConfig.Route.ClipSelection overlayClip in route.OverlayClips)
				{
					num = Mathf.Clamp(overlayClip.Weight, 0.001f, 1000f);
					if (num != overlayClip.Weight)
					{
						Logging.LogWarning(Texts.WeightClamped(num, pack));
					}
					overlayClip.Weight = num;
				}
			}
		}

		private static void LoadAudioPacksFromRoot(List<AudioPack> packs, string rootPath)
		{
			Queue<string> queue = new Queue<string>();
			queue.Enqueue(rootPath);
			while (queue.Count > 0)
			{
				string text = queue.Dequeue();
				string[] directories = Directory.GetDirectories(text);
				foreach (string item in directories)
				{
					queue.Enqueue(item);
				}
				string path = Path.Combine(text, "modaudio.config.json");
				if (File.Exists(path))
				{
					AudioPack audioPack = LoadAudioPack(packs, path);
					if (audioPack != null)
					{
						packs.Add(audioPack);
					}
					continue;
				}
				string path2 = Path.Combine(text, "__routes.txt");
				if (File.Exists(path2))
				{
					AudioPack audioPack2 = LoadLegacyAudioPack(packs, path2);
					if (audioPack2 != null)
					{
						packs.Add(audioPack2);
					}
				}
				else if ((text == rootPath || text == Path.Combine(rootPath, "audio")) && Directory.GetFiles(text).Any((string x) => VanillaClipNames.IsKnownClip(Path.GetFileNameWithoutExtension(x))))
				{
					AudioPack audioPack3 = LoadLegacyAudioPack(packs, path2);
					if (audioPack3 != null)
					{
						packs.Add(audioPack3);
					}
				}
			}
		}

		private static AudioPack LoadAudioPack(List<AudioPack> existingPacks, string path)
		{
			Logging.LogInfo(Texts.LoadingPack(path), ModAudio.Plugin.LogPackLoading);
			using FileStream stream = File.OpenRead(path);
			AudioPackConfig config;
			try
			{
				config = AudioPackConfig.ReadJSON(stream);
			}
			catch (Exception ex)
			{
				Logging.LogWarning("Failed to read audio pack config for " + ReplaceRootPath(path) + ".");
				Logging.LogWarning(ex.ToString());
				return null;
			}
			AudioPack pack = new AudioPack
			{
				Config = config,
				PackPath = path
			};
			if (string.IsNullOrEmpty(pack.Config.Id))
			{
				pack.Config.Id = ConvertPathToId(pack.PackPath);
			}
			else if (!IsNormalizedId(pack.Config.Id))
			{
				Logging.LogWarning(Texts.InvalidPackId(pack.PackPath, pack.Config.Id));
				return null;
			}
			if (string.IsNullOrEmpty(pack.Config.DisplayName))
			{
				pack.Config.DisplayName = ConvertPathToDisplayName(pack.PackPath);
			}
			if (existingPacks.Any((AudioPack x) => x.Config.Id == pack.Config.Id))
			{
				Logging.LogWarning(Texts.DuplicatePackId(pack.PackPath, pack.Config.Id));
				return null;
			}
			string fullPath = Path.GetFullPath(Path.GetDirectoryName(path));
			LoadCustomClips(fullPath, pack, extensionless: false);
			if (pack.Config.AudioPackSettings.AutoloadReplacementClips)
			{
				Logging.LogInfo(Texts.AutoloadingClips(path), ModAudio.Plugin.LogPackLoading);
				AutoLoadReplacementClipsFromPath(path, pack);
			}
			return pack;
		}

		private static AudioPack LoadLegacyAudioPack(List<AudioPack> existingPacks, string path)
		{
			Logging.LogInfo(Texts.LoadingPack(path), ModAudio.Plugin.LogPackLoading);
			string id = NormalizeId(ReplaceRootPath(path));
			if (existingPacks.Any((AudioPack x) => x.Config.Id == id))
			{
				Logging.LogWarning(Texts.DuplicatePackId(path, id));
				return null;
			}
			AudioPack audioPack = new AudioPack
			{
				PackPath = path,
				Config = 
				{
					AudioPackSettings = 
					{
						AutoloadReplacementClips = true
					}
				}
			};
			if (File.Exists(path))
			{
				RouteConfig routeConfig = RouteConfig.ReadTextFormat(path);
				audioPack.Config = AudioPackConfig.ConvertFromRoutes(routeConfig);
			}
			if (string.IsNullOrWhiteSpace(audioPack.Config.DisplayName))
			{
				audioPack.Config.DisplayName = ConvertPathToDisplayName(path);
			}
			if (string.IsNullOrWhiteSpace(audioPack.Config.Id))
			{
				audioPack.Config.Id = ConvertPathToId(path);
			}
			string fullPath = Path.GetFullPath(Path.GetDirectoryName(path));
			LoadCustomClips(fullPath, audioPack, extensionless: true);
			AutoLoadReplacementClipsFromPath(path, audioPack);
			return audioPack;
		}

		private static void LoadCustomClips(string rootPath, AudioPack pack, bool extensionless)
		{
			foreach (AudioPackConfig.AudioClipData clipData in pack.Config.CustomClips)
			{
				if (pack.ReadyClips.Any((KeyValuePair<string, AudioClip> x) => ((Object)x.Value).name == clipData.Name))
				{
					Logging.LogWarning(Texts.DuplicateClipId(clipData.Path, clipData.Name));
					continue;
				}
				string clipPath = Path.GetFullPath(Path.Combine(rootPath, clipData.Path));
				if (!clipPath.StartsWith(rootPath))
				{
					Logging.LogWarning(Texts.InvalidPackPath(clipData.Path, clipData.Name));
					continue;
				}
				if (clipData.IgnoreClipExtension)
				{
					string[] supportedStreamExtensions = AudioClipLoader.SupportedStreamExtensions;
					foreach (string text in supportedStreamExtensions)
					{
						if (File.Exists(clipPath + text))
						{
							clipPath += text;
							break;
						}
					}
				}
				if (!AudioClipLoader.SupportedExtensions.Any(clipPath.EndsWith))
				{
					Logging.LogWarning(Texts.UnsupportedAudioFile(clipData.Path, clipData.Name));
					continue;
				}
				long length = new FileInfo(clipPath).Length;
				bool flag = length >= 1048576;
				if (flag && !AudioClipLoader.SupportedStreamExtensions.Any(clipPath.EndsWith))
				{
					Logging.LogWarning(Texts.AudioCannotBeStreamed(clipPath, length));
					flag = false;
				}
				try
				{
					Logging.LogInfo(Texts.LoadingClip(clipPath, clipData.Name, flag), ModAudio.Plugin.LogPackLoading);
					if (flag)
					{
						pack.PendingClipsToStream[clipData.Name] = delegate
						{
							AudioClipLoader.IAudioStream openedStream;
							AudioClip result = AudioClipLoader.StreamFromFile(clipData.Name, clipPath, clipData.Volume, out openedStream);
							pack.OpenStreams.Add(openedStream);
							return result;
						};
					}
					else
					{
						pack.PendingClipsToLoad[clipData.Name] = () => AudioClipLoader.LoadFromFile(clipData.Name, clipPath, clipData.Volume);
					}
				}
				catch (Exception arg)
				{
					Logging.LogWarning("Failed to load " + clipData.Name + " from " + ReplaceRootPath(clipPath) + "!");
					Logging.LogWarning($"Exception: {arg}");
				}
			}
		}

		private static void AutoLoadReplacementClipsFromPath(string path, AudioPack pack)
		{
			List<string> list = new List<string>();
			string[] files = Directory.GetFiles(Path.GetDirectoryName(path));
			foreach (string file in files)
			{
				if (!AudioClipLoader.SupportedExtensions.Any(file.EndsWith) || !VanillaClipNames.IsKnownClip(Path.GetFileNameWithoutExtension(path)))
				{
					continue;
				}
				long length = new FileInfo(file).Length;
				bool flag = length >= 1048576;
				if (flag && !AudioClipLoader.SupportedStreamExtensions.Any(file.EndsWith))
				{
					Logging.LogWarning(Texts.AudioCannotBeStreamed(file, length));
					flag = false;
				}
				string name = Path.GetFileNameWithoutExtension(file);
				if (pack.ReadyClips.ContainsKey(name))
				{
					Logging.LogWarning(Texts.DuplicateClipSkipped(file, name));
					continue;
				}
				list.Add(name);
				try
				{
					Logging.LogInfo(Texts.LoadingClip(name, file, flag), ModAudio.Plugin.LogPackLoading);
					if (flag)
					{
						pack.PendingClipsToStream[name] = delegate
						{
							AudioClipLoader.IAudioStream openedStream;
							AudioClip result = AudioClipLoader.StreamFromFile(name, file, 1f, out openedStream);
							pack.OpenStreams.Add(openedStream);
							return result;
						};
					}
					else
					{
						pack.PendingClipsToLoad[name] = () => AudioClipLoader.LoadFromFile(name, file, 1f);
					}
				}
				catch (Exception arg)
				{
					Logging.LogWarning("Failed to load " + name + " from " + ReplaceRootPath(file) + "!");
					Logging.LogWarning($"Exception: {arg}");
				}
			}
			foreach (string item in list)
			{
				pack.Config.Routes.Add(new AudioPackConfig.Route
				{
					OriginalClips = new List<string>(1) { item },
					ReplacementClips = new List<AudioPackConfig.Route.ClipSelection>(1)
					{
						new AudioPackConfig.Route.ClipSelection
						{
							Name = item
						}
					}
				});
			}
		}
	}
	internal static class Logging
	{
		private static ManualLogSource InternalLogger => ModAudio.Plugin.Logger;

		public static void LogFatal(object data, ConfigEntry<bool> toggle = null)
		{
			Log(data, (LogLevel)1, toggle);
		}

		public static void LogError(object data, ConfigEntry<bool> toggle = null)
		{
			Log(data, (LogLevel)2, toggle);
		}

		public static void LogWarning(object data, ConfigEntry<bool> toggle = null)
		{
			Log(data, (LogLevel)4, toggle);
		}

		public static void LogMessage(object data, ConfigEntry<bool> toggle = null)
		{
			Log(data, (LogLevel)8, toggle);
		}

		public static void LogInfo(object data, ConfigEntry<bool> toggle = null)
		{
			Log(data, (LogLevel)16, toggle);
		}

		public static void LogDebug(object data, ConfigEntry<bool> toggle = null)
		{
			Log(data, (LogLevel)32, toggle);
		}

		private static void Log(object data, LogLevel level = 16, ConfigEntry<bool> toggle = null)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (toggle == null || toggle.Value)
			{
				ManualLogSource internalLogger = InternalLogger;
				if (internalLogger != null)
				{
					internalLogger.Log(level, data);
				}
			}
		}
	}
	[BepInPlugin("Marioalexsan.ModAudio", "ModAudio", "2.2.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ModAudio : BaseUnityPlugin
	{
		public const float MinWeight = 0.001f;

		public const float MaxWeight = 1000f;

		public const float DefaultWeight = 1f;

		public const string DefaultClipIdentifier = "___default___";

		private Harmony _harmony;

		private bool _reloadRequired = true;

		public static ModAudio Plugin { get; private set; }

		internal ManualLogSource Logger { get; private set; }

		public string ModAudioConfigFolder => Path.Combine(Paths.ConfigPath, "Marioalexsan.ModAudio_UserAudioPack");

		public string ModAudioPluginFolder => Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);

		public ConfigEntry<bool> LogPackLoading { get; private set; }

		public ConfigEntry<bool> LogAudioPlayed { get; private set; }

		public ConfigEntry<bool> UseMaxDistanceForLogging { get; private set; }

		public ConfigEntry<float> MaxDistanceForLogging { get; private set; }

		public ConfigEntry<bool> LogAmbience { get; private set; }

		public ConfigEntry<bool> LogGame { get; private set; }

		public ConfigEntry<bool> LogGUI { get; private set; }

		public ConfigEntry<bool> LogMusic { get; private set; }

		public ConfigEntry<bool> LogVoice { get; private set; }

		public Dictionary<string, ConfigEntry<bool>> AudioPackEnabled { get; } = new Dictionary<string, ConfigEntry<bool>>();


		public Dictionary<string, GameObject> AudioPackEnabledObjects { get; } = new Dictionary<string, GameObject>();


		public GameObject AudioPackEnabledRoot { get; set; }

		private void SetupBaseAudioPack()
		{
			if (!Directory.Exists(ModAudioConfigFolder))
			{
				Directory.CreateDirectory(ModAudioConfigFolder);
			}
			VanillaClipNames.GenerateReferenceFile(Path.Combine(ModAudioConfigFolder, "clip_names.txt"));
			File.WriteAllText(Path.Combine(ModAudioConfigFolder, "schema_modaudio.config.json"), AudioPackConfig.GenerateSchema());
		}

		private void Awake()
		{
			Plugin = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			_harmony = Harmony.CreateAndPatchAll(typeof(ModAudio).Assembly, "Marioalexsan.ModAudio");
			SetupBaseAudioPack();
			InitializeConfiguration();
		}

		private void InitializeConfiguration()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Expected O, but got Unknown
			LogPackLoading = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogPackLoading", true, "True to enable logging when loading audio packs,  false to disable it.");
			LogAudioPlayed = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogAudioPlayed", false, "True to enable console logging for audio played, false to disable it.");
			UseMaxDistanceForLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "UseMaxDistanceForLogging", false, "True to log audio played only if it's within a certain range of the player, false to log all sounds.");
			MaxDistanceForLogging = ((BaseUnityPlugin)this).Config.Bind<float>("Logging", "MaxDistanceForLogging", 32f, new ConfigDescription("The max distance in units from the player where audio will be logged (for reference, 12 units ~ Angela Flux's height).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(32f, 2048f), Array.Empty<object>()));
			LogAmbience = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogAmbience", true, "True to log audio that's part of the ambience group, false to skip it.");
			LogGame = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogGame", true, "True to log audio that's part of the game group, false to skip it.");
			LogGUI = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogGUI", true, "True to log audio that's part of the GUI group, false to skip it.");
			LogMusic = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogMusic", true, "True to log audio that's part of the music group, false to skip it.");
			LogVoice = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogVoice", true, "True to log audio that's part of the voice group, false to skip it.");
			if (!EasySettings.IsAvailable)
			{
				return;
			}
			EasySettings.OnApplySettings.AddListener((UnityAction)delegate
			{
				try
				{
					((BaseUnityPlugin)this).Config.Save();
					bool flag = false;
					foreach (AudioPack audioPack in AudioEngine.AudioPacks)
					{
						ConfigEntry<bool> value;
						bool flag2 = !AudioPackEnabled.TryGetValue(audioPack.Config.Id, out value) || value.Value;
						if (flag2 != audioPack.Enabled)
						{
							Logger.LogInfo((object)("Pack " + audioPack.Config.Id + " is now " + (flag2 ? "enabled" : "disabled")));
							flag = true;
						}
						audioPack.Enabled = flag2;
					}
					if (flag)
					{
						AudioEngine.SoftReload();
					}
				}
				catch (Exception ex)
				{
					Logging.LogError("ModAudio crashed in OnApplySettings! Please report this error to the mod developer:");
					Logging.LogError(ex.ToString());
				}
			});
			EasySettings.OnInitialized.AddListener((UnityAction)delegate
			{
				EasySettings.AddHeader("ModAudio");
				EasySettings.AddToggle("Log audio pack loading", LogPackLoading);
				EasySettings.AddToggle("Log audio played", LogAudioPlayed);
				EasySettings.AddToggle("Limit audio logged by distance", UseMaxDistanceForLogging);
				EasySettings.AddAdvancedSlider("Max log distance", MaxDistanceForLogging, wholeNumbers: true);
				EasySettings.AddToggle("Log ambience audio", LogAmbience);
				EasySettings.AddToggle("Log game audio", LogGame);
				EasySettings.AddToggle("Log GUI audio", LogGUI);
				EasySettings.AddToggle("Log music audio", LogMusic);
				EasySettings.AddToggle("Log voice audio", LogVoice);
			});
		}

		internal void InitializePackConfiguration()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)AudioPackEnabledRoot) && EasySettings.IsAvailable)
			{
				EasySettings.AddHeader("ModAudio audio packs");
				EasySettings.AddButton("Open custom audio pack folder", (UnityAction)delegate
				{
					SetupBaseAudioPack();
					Application.OpenURL(new Uri(ModAudioConfigFolder ?? "").AbsoluteUri);
				});
				AudioPackEnabledRoot = EasySettings.AddButton("Reload audio packs", (UnityAction)delegate
				{
					_reloadRequired = true;
				});
			}
			foreach (AudioPack audioPack in AudioEngine.AudioPacks)
			{
				if (!AudioPackEnabled.TryGetValue(audioPack.Config.Id, out var value))
				{
					ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("EnabledAudioPacks", audioPack.Config.Id, true, Texts.EnablePackDescription(audioPack.Config.DisplayName));
					AudioPackEnabled[audioPack.Config.Id] = val;
					if (EasySettings.IsAvailable && !AudioPackEnabledObjects.ContainsKey(audioPack.Config.Id))
					{
						AudioPackEnabledObjects[audioPack.Config.Id] = EasySettings.AddToggle(audioPack.Config.DisplayName, val);
					}
					audioPack.Enabled = val.Value;
				}
				else
				{
					audioPack.Enabled = value.Value;
				}
			}
			if (!EasySettings.IsAvailable)
			{
				return;
			}
			int num = AudioPackEnabledRoot.transform.GetSiblingIndex() + 1;
			foreach (KeyValuePair<string, GameObject> item in AudioPackEnabledObjects.OrderBy((KeyValuePair<string, GameObject> x) => x.Key))
			{
				item.Value.transform.SetSiblingIndex(num++);
			}
			foreach (KeyValuePair<string, GameObject> config in AudioPackEnabledObjects)
			{
				config.Value.SetActive(AudioEngine.AudioPacks.Any((AudioPack x) => x.Config.Id == config.Key));
			}
		}

		private void CheckForObsoleteStuff()
		{
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			string path = Path.Combine(directoryName, "audio");
			bool flag = false;
			if (Directory.GetFiles(directoryName).Any(IsAudioPackFile))
			{
				flag = true;
			}
			if (Directory.Exists(path) && Directory.GetFiles(path).Any(IsAudioPackFile))
			{
				flag = true;
			}
			if (flag)
			{
				Logger.LogWarning((object)"There is an audio pack under ModAudio's plugin folder!");
				Logger.LogWarning((object)"Please use the folder from BepInEx/config for your custom packs instead of the plugin folder.");
				Logger.LogWarning((object)"When using r2modman, the plugin folder might be deleted mercilessly when you update or uninstall your mod, which will delete your custom audio.");
			}
			static bool IsAudioPackFile(string name)
			{
				return Path.GetFileName(name) == "modaudio.config.json" || Path.GetFileName(name) == "__routes.txt" || AudioClipLoader.SupportedLoadExtensions.Contains<string>(Path.GetExtension(name));
			}
		}

		private void Update()
		{
			try
			{
				if (_reloadRequired)
				{
					_reloadRequired = false;
					CheckForObsoleteStuff();
					AudioEngine.HardReload();
				}
				AudioEngine.Update();
			}
			catch (Exception ex)
			{
				Logging.LogError("ModAudio crashed in Update! Please report this error to the mod developer:");
				Logging.LogError(ex.ToString());
			}
		}
	}
	internal static class OptimizedMethods
	{
		public delegate void CachedForeachAction<T>(in T value);

		public delegate void CachedForeachAction<T, V>(in T value, in V context);

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void MultiplyFloatArray(float[] data, float factor)
		{
			fixed (float* ptr = data)
			{
				float* ptr2 = ptr;
				for (float* ptr3 = ptr + data.Length; ptr2 != ptr3; ptr2++)
				{
					*ptr2 *= factor;
				}
			}
		}

		public static void CachedForeach<T>(ICollection<T> enumerable, CachedForeachAction<T> action)
		{
			T[] array = ArrayPool<T>.Shared.Rent(enumerable.Count);
			int num = 0;
			foreach (T item in enumerable)
			{
				array[num++] = item;
			}
			for (int i = 0; i < num; i++)
			{
				action(in array[i]);
			}
			ArrayPool<T>.Shared.Return(array);
		}

		public static void CachedForeach<T, V>(ICollection<T> enumerable, in V context, CachedForeachAction<T, V> action)
		{
			T[] array = ArrayPool<T>.Shared.Rent(enumerable.Count);
			int num = 0;
			foreach (T item in enumerable)
			{
				array[num++] = item;
			}
			for (int i = 0; i < num; i++)
			{
				action(in array[i], in context);
			}
			ArrayPool<T>.Shared.Return(array);
		}
	}
	public class RouteConfig
	{
		private static readonly char[] ReplacementSeparator = new char[1] { '=' };

		private static readonly char[] OverlaySeparator = new char[1] { '@' };

		private static readonly char[] EffectSeparator = new char[1] { '~' };

		private static readonly char[] RouteSeparators;

		private static readonly char[] FieldSeparator;

		private static readonly char[] ListSeparator;

		public Dictionary<string, float> ClipVolumes { get; set; } = new Dictionary<string, float>();


		public List<AudioPackConfig.Route> Routes { get; set; } = new List<AudioPackConfig.Route>();


		public string Id { get; set; } = "";


		public string DisplayName { get; set; } = "";


		public static RouteConfig ReadTextFormat(string path)
		{
			using StreamReader streamReader = new StreamReader(File.OpenRead(path));
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			List<AudioPackConfig.Route> list = new List<AudioPackConfig.Route>();
			string id = "";
			string displayName = "";
			int num = -1;
			string text;
			while ((text = streamReader.ReadLine()) != null)
			{
				num++;
				if (text.Trim() == "" || text.Trim().StartsWith("#"))
				{
					continue;
				}
				if (text.Trim().StartsWith("%"))
				{
					if (text.Trim().StartsWith("%id "))
					{
						id = text.Trim().Substring("%id ".Length);
					}
					else if (text.Trim().StartsWith("%displayname "))
					{
						displayName = text.Trim().Substring("%displayname ".Length);
					}
					else if (text.Trim().StartsWith("%customclipvolume "))
					{
						string[] array = text.Trim().Substring("%customclipvolume ".Length).Split(new char[1] { '=' });
						if (array.Length != 2)
						{
							Logging.LogWarning($"Line {num}: Expected %customclipvolume clipName = volume.");
						}
						if (array[0].Trim() == "")
						{
							Logging.LogWarning($"Line {num}: Expected a clip name.");
						}
						if (!float.TryParse(array[1], out var result))
						{
							Logging.LogWarning($"Line {num}: Volume is not a number.");
						}
						dictionary[array[0].Trim()] = result;
					}
					else
					{
						Logging.LogWarning($"Line {num}: Unrecognized attribute {text.Trim().Substring(1)}.");
					}
					continue;
				}
				if (text.Contains("/") || (text.IndexOfAny(EffectSeparator) == -1 && text.IndexOfAny(OverlaySeparator) == -1 && text.IndexOfAny(FieldSeparator) == -1 && text.IndexOfAny(ListSeparator) == -1))
				{
					string[] array2 = text.Split(ReplacementSeparator, 3);
					if (array2.Length != 2)
					{
						Logging.LogWarning($"Line {num}: Encountered a malformed route (expected key = value), skipping it.");
						continue;
					}
					string[] array3 = array2[1].Split(new char[1] { '/' }, 3);
					if (array3.Length > 2)
					{
						Logging.LogWarning($"Line {num}: Too many values defined for a route (expected at most 2), skipping it.");
						continue;
					}
					string text2 = array2[0].Trim();
					string text3 = array3[0].Trim();
					float result2 = 1f;
					if (text2.Trim() == "" || text3.Trim() == "")
					{
						Logging.LogWarning($"Line {num}: Either clip name or replacement was empty for a route, skipping it.");
						continue;
					}
					if (array3.Length > 1 && !float.TryParse(array3[1], out result2))
					{
						Logging.LogWarning($"Line {num}: Couldn't parse random weight {array3[1]} for {text2} => {text3}, defaulting to {1f}.");
					}
					list.Add(new AudioPackConfig.Route
					{
						OriginalClips = new List<string>(1) { text2 },
						ReplacementClips = new List<AudioPackConfig.Route.ClipSelection>(1)
						{
							new AudioPackConfig.Route.ClipSelection
							{
								Name = text3,
								Weight = result2
							}
						}
					});
					continue;
				}
				string[] array4 = text.Split(RouteSeparators, 5, StringSplitOptions.None);
				int num2 = -1;
				int num3 = -1;
				int num4 = -1;
				int num5 = -1;
				int num6 = -1;
				int num7 = -1;
				if (array4.Length > 5 || array4.Length == 1)
				{
					Logging.LogWarning($"Line {num}: Encountered a malformed route (expected source = replacement @ overlay ~ modifier), skipping it.");
					continue;
				}
				int num8 = text.IndexOfAny(RouteSeparators, 0);
				int num9 = 1;
				if (num8 == -1)
				{
					Logging.LogWarning($"Line {num}: Encountered a malformed route (expected source = replacement @ overlay ~ effect), skipping it.");
					continue;
				}
				bool flag = false;
				while (num8 != -1)
				{
					if (text[num8] == ReplacementSeparator[0])
					{
						if (num2 != -1 || num3 != -1 || num4 != -1)
						{
							flag = true;
							break;
						}
						num2 = num8;
						num5 = num9++;
					}
					else if (text[num8] == OverlaySeparator[0])
					{
						if (num3 != -1)
						{
							flag = true;
							break;
						}
						num3 = num8;
						num6 = num9++;
					}
					else if (text[num8] == EffectSeparator[0])
					{
						if (num4 != -1)
						{
							flag = true;
							break;
						}
						num4 = num8;
						num7 = num9++;
					}
					num8 = text.IndexOfAny(RouteSeparators, num8 + 1);
				}
				if (flag)
				{
					Logging.LogWarning($"Line {num}: Encountered a malformed route (expected source = replacement @ overlay ~ effect), skipping it.");
					continue;
				}
				AudioPackConfig.Route route = new AudioPackConfig.Route();
				bool flag2 = num3 < num4;
				List<string> list2 = (from x in array4[0].Trim().Split(ListSeparator, StringSplitOptions.RemoveEmptyEntries)
					select x.Trim()).ToList();
				List<string> list3 = ((num5 == -1) ? new List<string>() : (from x in array4[num5].Trim().Split(ListSeparator, StringSplitOptions.RemoveEmptyEntries)
					select x.Trim()).ToList());
				List<string> list4 = ((num6 == -1) ? new List<string>() : (from x in array4[num6].Split(ListSeparator, StringSplitOptions.RemoveEmptyEntries)
					select x.Trim()).ToList());
				List<string> list5 = ((num7 == -1) ? new List<string>() : (from x in array4[num7].Split(ListSeparator, StringSplitOptions.RemoveEmptyEntries)
					select x.Trim()).ToList());
				for (int i = 0; i < list2.Count; i++)
				{
					if (list2[i] == "")
					{
						Logging.LogWarning($"Line {num}: empty clip, ignoring it.");
						list2.RemoveAt(i--);
					}
				}
				if (list2.Count == 0)
				{
					Logging.LogWarning($"Line {num}: Expected at least one source clip, skipping route.");
					continue;
				}
				route.OriginalClips = list2;
				for (int j = 0; j < list3.Count; j++)
				{
					string[] array5 = (from x in list3[j].Split(FieldSeparator)
						select x.Trim()).ToArray();
					if (array5.Length > 4)
					{
						Logging.LogWarning($"Line {num}: Too many values defined for a target clip (expected at most 4), skipping it.");
						continue;
					}
					string text4 = array5[0];
					if (text4 == "")
					{
						Logging.LogWarning($"Line {num}: empty clip, ignoring it.");
						list3.RemoveAt(j--);
					}
					float result3 = 1f;
					float result4 = 1f;
					float result5 = 1f;
					if (array5.Length > 1 && !float.TryParse(array5[1], out result3))
					{
						Logging.LogWarning($"Line {num}: Couldn't parse random weight {array5[1]} for {text4}, defaulting to {1f}.");
					}
					if (array5.Length > 2 && !float.TryParse(array5[2], out result4))
					{
						Logging.LogWarning($"Line {num}: Couldn't parse volume {array5[2]} for {text4}, defaulting to 1.");
					}
					if (array5.Length > 3 && !float.TryParse(array5[3], out result5))
					{
						Logging.LogWarning($"Line {num}: Couldn't parse pitch {array5[3]} for {text4}, defaulting to 1.");
					}
					route.ReplacementClips.Add(new AudioPackConfig.Route.ClipSelection
					{
						Name = text4,
						Weight = result3,
						Volume = result4,
						Pitch = result5
					});
				}
				list.Add(route);
				for (int k = 0; k < list4.Count; k++)
				{
					string[] array6 = (from x in list4[k].Split(FieldSeparator)
						select x.Trim()).ToArray();
					if (array6.Length > 4)
					{
						Logging.LogWarning($"Line {num}: Too many values defined for a target clip (expected at most 4), skipping it.");
						continue;
					}
					string text5 = array6[0];
					if (text5 == "")
					{
						ModAudio plugin = ModAudio.Plugin;
						if (plugin != null)
						{
							ManualLogSource logger = plugin.Logger;
							if (logger != null)
							{
								logger.LogWarning((object)$"Line {num}: empty clip, ignoring it.");
							}
						}
						list4.RemoveAt(k--);
					}
					float result6 = 1f;
					float result7 = 1f;
					float result8 = 1f;
					if (array6.Length > 1 && !float.TryParse(array6[1], out result6))
					{
						Logging.LogWarning($"Line {num}: Couldn't parse random weight {array6[1]} for {text5}, defaulting to {1f}.");
					}
					if (array6.Length > 2 && !float.TryParse(array6[2], out result7))
					{
						Logging.LogWarning($"Line {num}: Couldn't parse volume {array6[2]} for {text5}, defaulting to 1.");
					}
					if (array6.Length > 3 && !float.TryParse(array6[3], out result8))
					{
						Logging.LogWarning($"Line {num}: Couldn't parse pitch {array6[3]} for {text5}, defaulting to 1.");
					}
					route.OverlayClips.Add(new AudioPackConfig.Route.ClipSelection
					{
						Name = text5,
						Weight = result6,
						Volume = result7,
						Pitch = result8
					});
				}
				for (int l = 0; l < list5.Count; l++)
				{
					string[] array7 = (from x in list5[l].Split(FieldSeparator)
						select x.Trim()).ToArray();
					switch (array7[0])
					{
					case "weight":
					{
						float result10;
						if (array7.Length != 2)
						{
							Logging.LogWarning($"Line {num}: Expected a value for replacement weight.");
						}
						else if (!float.TryParse(array7[1], out result10))
						{
							Logging.LogWarning($"Line {num}: Couldn't parse replacement weight {array7[1]}.");
						}
						else
						{
							route.ReplacementWeight = result10;
						}
						break;
					}
					case "volume":
					{
						float result12;
						if (array7.Length != 2)
						{
							Logging.LogWarning($"Line {num}: Expected a value for volume.");
						}
						else if (!float.TryParse(array7[1], out result12))
						{
							Logging.LogWarning($"Line {num}: Couldn't parse volume {array7[1]}.");
						}
						else
						{
							route.Volume = result12;
						}
						break;
					}
					case "pitch":
					{
						float result11;
						if (array7.Length != 2)
						{
							Logging.LogWarning($"Line {num}: Expected a value for pitch.");
						}
						else if (!float.TryParse(array7[1], out result11))
						{
							Logging.LogWarning($"Line {num}: Couldn't parse pitch {array7[1]}.");
						}
						else
						{
							route.Pitch = result11;
						}
						break;
					}
					case "overlays_ignore_restarts":
					{
						bool result9;
						if (array7.Length != 2)
						{
							Logging.LogWarning($"Line {num}: Expected a value for overlays_ignore_restarts.");
						}
						else if (!bool.TryParse(array7[1], out result9))
						{
							Logging.LogWarning($"Line {num}: Couldn't parse {array7[1]} boolean for overlays_ignore_restarts.");
						}
						else
						{
							route.OverlaysIgnoreRestarts = result9;
						}
						break;
					}
					default:
						Logging.LogWarning($"Line {num}: Unrecognized route effect / setting {array7[0]}.");
						break;
					}
				}
			}
			return new RouteConfig
			{
				ClipVolumes = dictionary,
				Id = id,
				DisplayName = displayName,
				Routes = list
			};
		}

		static RouteConfig()
		{
			char[] replacementSeparator = ReplacementSeparator;
			char[] overlaySeparator = OverlaySeparator;
			char[] effectSeparator = EffectSeparator;
			int num = 0;
			char[] array = new char[replacementSeparator.Length + overlaySeparator.Length + effectSeparator.Length];
			ReadOnlySpan<char> readOnlySpan = new ReadOnlySpan<char>(replacementSeparator);
			readOnlySpan.CopyTo(new Span<char>(array).Slice(num, readOnlySpan.Length));
			num += readOnlySpan.Length;
			ReadOnlySpan<char> readOnlySpan2 = new ReadOnlySpan<char>(overlaySeparator);
			readOnlySpan2.CopyTo(new Span<char>(array).Slice(num, readOnlySpan2.Length));
			num += readOnlySpan2.Length;
			ReadOnlySpan<char> readOnlySpan3 = new ReadOnlySpan<char>(effectSeparator);
			readOnlySpan3.CopyTo(new Span<char>(array).Slice(num, readOnlySpan3.Length));
			num += readOnlySpan3.Length;
			RouteSeparators = array;
			FieldSeparator = new char[1] { ':' };
			ListSeparator = new char[1] { '|' };
		}
	}
	public static class Texts
	{
		public const string LogAudioLoadingTitle = "Log audio pack loading";

		public const string LogAudioLoadingDescription = "True to enable logging when loading audio packs,  false to disable it.";

		public const string LogAudioPlayedTitle = "Log audio played";

		public const string LogAudioPlayedDescription = "True to enable console logging for audio played, false to disable it.";

		public const string UseMaxDistanceForLoggingTitle = "Limit audio logged by distance";

		public const string UseMaxDistanceForLoggingDescription = "True to log audio played only if it's within a certain range of the player, false to log all sounds.";

		public const string MaxDistanceForLoggingTitle = "Max log distance";

		public const string MaxDistanceForLoggingDescription = "The max distance in units from the player where audio will be logged (for reference, 12 units ~ Angela Flux's height).";

		public const string LogAmbienceTitle = "Log ambience audio";

		public const string LogAmbienceDescription = "True to log audio that's part of the ambience group, false to skip it.";

		public const string LogGameTitle = "Log game audio";

		public const string LogGameDescription = "True to log audio that's part of the game group, false to skip it.";

		public const string LogGUITitle = "Log GUI audio";

		public const string LogGUIDescription = "True to log audio that's part of the GUI group, false to skip it.";

		public const string LogMusicTitle = "Log music audio";

		public const string LogMusicDescription = "True to log audio that's part of the music group, false to skip it.";

		public const string LogVoiceTitle = "Log voice audio";

		public const string LogVoiceDescription = "True to log audio that's part of the voice group, false to skip it.";

		public const string ReloadTitle = "Reload audio packs";

		public const string OpenCustomAudioPackTitle = "Open custom audio pack folder";

		public static string WeightClamped(float weight, AudioPack pack)
		{
			return $"Pack {pack.Config.Id} has a weight {weight} that is outside the [{0.001f}, {1000f}] range and will be clamped.";
		}

		public static string EnablePackDescription(string displayName)
		{
			return "Set to true to enable " + displayName + ", false to disable it.";
		}

		public static string InvalidPackId(string path, string id)
		{
			return "Refusing to load pack " + id + " from " + path + ", its ID contains invalid characters.";
		}

		public static string DuplicatePackId(string path, string id)
		{
			return "Refusing to load pack " + id + " from " + path + ", an audio pack with that ID already exists.";
		}

		public static string DuplicateClipId(string path, string id)
		{
			return "Refusing to load clip " + id + " from " + path + ", a clip with that name was already loaded.";
		}

		public static string InvalidPackPath(string path, string id)
		{
			return "Refusing to load clip " + id + " from " + path + ", its path was outside of audio pack.";
		}

		public static string UnsupportedAudioFile(string file, string id)
		{
			return "File " + file + " from clip " + id + " is not a supported audio format.";
		}

		public static string DuplicateClipSkipped(string file, string id)
		{
			return "Audio file " + file + " was not loaded, clip " + id + " was already loaded previously.";
		}

		public static string AutoloadingClips(string path)
		{
			return "Autoloading replacement clips from " + AudioPackLoader.ReplaceRootPath(path);
		}

		public static string LoadingPack(string path)
		{
			return "Loading pack from " + AudioPackLoader.ReplaceRootPath(path);
		}

		public static string PackLoaded(AudioPack pack)
		{
			return $"Loaded pack {pack.Config.Id} with {pack.Config.Routes.Count} routes, {pack.PendingClipsToStream.Count} clips to streams and {pack.PendingClipsToLoad.Count} clips to load";
		}

		public static string LoadingClip(string path, string name, bool useStreaming)
		{
			return (useStreaming ? "Streaming" : "Loading") + " clip " + name + " from " + AudioPackLoader.ReplaceRootPath(path);
		}

		public static string AudioCannotBeStreamed(string path, long fileSize)
		{
			return "Audio file " + path + " is above the size threshold for streaming" + $" ({(float)fileSize / 1048576f}MB >= {1f}MB)," + " but it cannot be streamed using the current audio format. Please try using one of the following supported formats: " + string.Join(", ", AudioClipLoader.SupportedStreamExtensions) + ".";
		}

		public static string AudioClipNotFound(string name)
		{
			return "Couldn't get clip " + name + " to play for audio event!";
		}
	}
	public static class VanillaClipNames
	{
		private struct Metadata
		{
			public AudioGroup AudioGroup;

			public string Description;

			public Metadata(AudioGroup audioGroup, string description)
			{
				AudioGroup = audioGroup;
				Description = description;
			}
		}

		private enum AudioGroup
		{
			Unknown,
			Ambience,
			Game,
			GUI,
			Master,
			Music,
			Voice
		}

		private static readonly string[] AllClipNames;

		private static readonly HashSet<string> ClipNamesHashed;

		public const int TotalClips = 482;

		public const string Absorb = "_absorb";

		public const string Acre_Bolt = "acre_bolt";

		public const string AmbBla = "_ambBla";

		public const string AmbCave01 = "_ambCave01";

		public const string AmbCave02 = "_ambCave02";

		public const string AmbCoast = "_ambCoast";

		public const string AmbCricket01 = "_ambCricket01";

		public const string AmbCuckoo = "_ambCuckoo";

		public const string AmbFire01 = "_ambFire01";

		public const string AmbFrst01 = "_ambFrst01";

		public const string AmbFrst02 = "_ambFrst02";

		public const string AmbFrst03 = "_ambFrst03";

		public const string AmbGlyph01 = "_ambGlyph01";

		public const string AmbGlyph02 = "_ambGlyph02";

		public const string AmbGlyph03 = "_ambGlyph03";

		public const string AmbGuest01 = "_ambGuest01";

		public const string AmbOutside01 = "_ambOutside01";

		public const string AmbOutside02 = "_ambOutside02";

		public const string AmbRiver01 = "_ambRiver01";

		public const string AmbUnderwater = "_ambUnderwater";

		public const string AmbWat_Cave = "_ambWat_cave";

		public const string AmbWater01 = "_ambWater01";

		public const string AmbWater02 = "_ambWater02";

		public const string AmbWaterfall01 = "_ambWaterfall01";

		public const string AmbWatfall = "_ambWatfall";

		public const string AmbWind01 = "_ambWind01";

		public const string AmbWind02 = "_ambWind02";

		public const string AmbWind02_0 = "_ambWind02_0";

		public const string AmbWind03 = "_ambWind03";

		public const string AmbWind04 = "_ambWind04";

		public const string AmbWind05 = "_ambWind05";

		public const string AmbWind06 = "_ambWind06";

		public const string AmbWind07 = "_ambWind07";

		public const string AmbWindChime01 = "_ambWindChime01";

		public const string Amb_Jungle00 = "_amb_jungle00";

		public const string Amb_Jungle01 = "_amb_jungle01";

		public const string Amb_Jungle02 = "_amb_jungle02";

		public const string Amb_Rain01 = "_amb_rain01";

		public const string Angela_Aura = "angela_aura";

		public const string AtlyssSet_Catacomb_Action5 = "_atlyssSet_catacomb_action5";

		public const string AtlyssSet_Catacomb_Amb3 = "_atlyssSet_catacomb_amb3";

		public const string AtlyssSet_Track01 = "_atlyssSet_track01";

		public const string AttackClick = "attackClick";

		public const string AttackMiss = "_attackMiss";

		public const string AttributeGlyph = "_attributeGlyph";

		public const string BeamStatue_BeamLoop = "_beamStatue_beamLoop";

		public const string BeamStatue_ProneLoop = "_beamStatue_proneLoop";

		public const string BellSwing01 = "_bellSwing01";

		public const string BellSwing02 = "_bellSwing02";

		public const string BellSwing03 = "_bellSwing03";

		public const string BellSwing04 = "_bellSwing04";

		public const string BladeTrap_Init = "_bladeTrap_init";

		public const string BladeTrap_SpinLoop = "_bladeTrap_spinLoop";

		public const string BladeTrap_SpinLoop2 = "_bladeTrap_spinLoop2";

		public const string BlockBreak = "_blockBreak";

		public const string BlockHit = "_blockHit";

		public const string BobbyVox01 = "bobbyVox01";

		public const string BobbyVox02 = "bobbyVox02";

		public const string BobbyVox03 = "bobbyVox03";

		public const string BobbyVox04 = "bobbyVox04";

		public const string BobbyVox05 = "bobbyVox05";

		public const string BobbyVox06 = "bobbyVox06";

		public const string BobbyVox07 = "bobbyVox07";

		public const string BombBiggenEX = "bombBiggenEX";

		public const string BombHitChar = "bombHitChar";

		public const string BombKick = "bombKick";

		public const string Book_Handled_1 = "book handled 1";

		public const string Bow_Fire01 = "bow_fire01";

		public const string Bow_TakeOut = "bow_takeOut";

		public const string Break01 = "_break01";

		public const string BreakBox01 = "_breakBox01";

		public const string Buff_Resolute = "buff_resolute";

		public const string BuyItem = "_buyItem";

		public const string ByrdleTalk01 = "_byrdleTalk01";

		public const string ByrdleTalk02 = "_byrdleTalk02";

		public const string ByrdleTalk03 = "_byrdleTalk03";

		public const string ByrdleTalk04 = "_byrdleTalk04";

		public const string Cannonbug_BeginMove = "cannonbug_beginMove";

		public const string Cannonbug_CannonShot = "cannonbug_cannonShot";

		public const string Cannonbug_ChargeShot = "cannonbug_chargeShot";

		public const string Cannonbug_FrontalAttack = "cannonbug_frontalAttack";

		public const string Cannonbug_Spin = "cannonbug_spin";

		public const string Carbuncle_Death = "_carbuncle_death";

		public const string Carbuncle_Hurt00 = "_carbuncle_hurt00";

		public const string CastChannelShadow = "castChannelShadow";

		public const string CastChannelShadow2 = "castChannelShadow2";

		public const string CastEarth = "_castEarth";

		public const string CastLoop_00 = "_castLoop_00";

		public const string CastLoop_01 = "_castLoop_01";

		public const string CastMysticSpell = "_castMysticSpell";

		public const string CastWater = "_castWater";

		public const string Cast_00 = "_cast_00";

		public const string Cast_01 = "_cast_01";

		public const string Cast_02 = "_cast_02";

		public const string Cast_03 = "_cast_03";

		public const string Cast_04 = "_cast_04";

		public const string Cast_05 = "_cast_05";

		public const string Cast_06 = "_cast_06";

		public const string Cast_07 = "_cast_07";

		public const string Cast_FlameBurst = "cast_flameBurst";

		public const string Cast_Holy = "_cast_holy";

		public const string Cast_Octane = "cast_octane";

		public const string ChangTalk01 = "_changTalk01";

		public const string ChangTalk02 = "_changTalk02";

		public const string ChangTalk03 = "_changTalk03";

		public const string ChangTalk04 = "_changTalk04";

		public const string ChannelEarthSpell = "_channelEarthSpell";

		public const string ChannelMysticSpell = "_channelMysticSpell";

		public const string ChestOpen = "chestOpen";

		public const string Chime02 = "_chime02";

		public const string Chime03 = "_chime03";

		public const string Chime04 = "_chime04";

		public const string Clap01 = "_clap01";

		public const string ClearSkill = "_clearSkill";

		public const string CloseShop = "_closeShop";

		public const string Coin01 = "_coin01";

		public const string CoinSell = "_coinSell";

		public const string Collide01 = "_collide01";

		public const string ConsumableHeal = "consumableHeal";

		public const string Cop_Turretcharge = "cop_turretcharge";

		public const string CreepAggroNotif = "_creepAggroNotif";

		public const string CreepSfx_SlimeAtk1 = "_creepSfx_slimeAtk1";

		public const string CreepSfx_SlimeAtk2 = "_creepSfx_slimeAtk2";

		public const string CreepSfx_SlimeAtk3 = "_creepSfx_slimeAtk3";

		public const string CreepSfx_SlimeDeath = "_creepSfx_slimeDeath";

		public const string CreepSfx_SlimeHit = "_creepSfx_slimeHit";

		public const string CreepSfx_SlimeHurt = "_creepSfx_slimeHurt";

		public const string CreepSpawn = "_creepSpawn";

		public const string Crit = "_crit";

		public const string CrossExplodeSfx01 = "_crossExplodeSfx01";

		public const string CrossLoopSfx01 = "_crossLoopSfx01";

		public const string CurrencyTally = "_currencyTally";

		public const string Debuff_Bleed = "debuff_bleed";

		public const string Debuff_Freeze = "debuff_freeze";

		public const string Debuff_Freeze_Old1 = "debuff_freeze-old1";

		public const string Debuff_Poison = "debuff_poison";

		public const string DungeonFloorSwitch_Pressed = "_dungeonFloorSwitch_pressed";

		public const string DungeonFloorSwitch_Unpressed = "_dungeonFloorSwitch_unpressed";

		public const string DungeonLock_Open = "_dungeonLock_open";

		public const string Effect_Demon01 = "_effect_demon01";

		public const string Electric01 = "_electric01";

		public const string EnemyPreAttack = "enemyPreAttack";

		public const string Enemyalert = "enemyalert";

		public const string Enok_Vox01 = "_enok_vox01";

		public const string Enok_Vox02 = "_enok_vox02";

		public const string Enok_Vox03 = "_enok_vox03";

		public const string Enok_Vox04 = "_enok_vox04";

		public const string Enok_Vox05 = "_enok_vox05";

		public const string Enok_Vox06 = "_enok_vox06";

		public const string Enok_Vox07 = "_enok_vox07";

		public const string Enok_Vox08 = "_enok_vox08";

		public const string Equip01 = "_equip01";

		public const string Equip02 = "_equip02";

		public const string ExpPickup_F = "expPickup_f";

		public const string Expression_Surprise = "_expression_surprise";

		public const string Fanfale3 = "fanfale3";

		public const string Fanfale4 = "fanfale4";

		public const string Fistcuffs_Swing01 = "_fistcuffs_swing01";

		public const string Fistcuffs_Swing02 = "_fistcuffs_swing02";

		public const string Fistcuffs_Swing03 = "_fistcuffs_swing03";

		public const string Fistcuffs_Swing04 = "_fistcuffs_swing04";

		public const string Fistcuffs_Swing05 = "_fistcuffs_swing05";

		public const string FloatSkull_Attack01 = "_floatSkull_attack01";

		public const string FloatSkull_Attack02 = "_floatSkull_attack02";

		public const string FloatSkull_Death = "_floatSkull_death";

		public const string FloatSkull_Hurt = "_floatSkull_hurt";

		public const string FluxSpear01 = "_fluxSpear01";

		public const string Focus = "focus";

		public const string Focusoff = "focusoff";

		public const string FootStep_Basic = "footStep_basic";

		public const string FootStep_Grass = "footStep_grass";

		public const string FootStep_Grass02 = "footStep_grass02";

		public const string FootStep_Stone = "footStep_stone";

		public const string FootStep_Water = "footStep_water";

		public const string FootStep_Wood = "footStep_wood";

		public const string FootstepGrass02 = "_footstepGrass02";

		public const string GeistLaugh = "_geistLaugh";

		public const string GeistLaugh02 = "_geistLaugh02";

		public const string Geist_Attack01 = "_geist_attack01";

		public const string Geist_Attack02 = "_geist_attack02";

		public const string Geist_Death = "_geist_death";

		public const string Geist_Hurt = "_geist_hurt";

		public const string GetClassSfx = "_getClassSfx";

		public const string Gib = "_gib";

		public const string GlassBreak = "glassBreak";

		public const string GlassBreak2 = "glassBreak2";

		public const string Golem_Death01 = "_golem_death01";

		public const string Golem_Hurt01 = "_golem_hurt01";

		public const string Golem_Hurt02 = "_golem_hurt02";

		public const string Guard_Block = "guard_block";

		public const string Hampter_Defend = "hampter_defend";

		public const string Hampter_Login = "hampter_login";

		public const string HealConsumable = "_healConsumable";

		public const string HeavyInit01 = "_heavyInit01";

		public const string HeavyInit02 = "_heavyInit02";

		public const string HeavyInit03 = "_heavyInit03";

		public const string HeavySheath = "_heavySheath";

		public const string Homerun_Hit = "_homerun_hit";

		public const string ImbueSkillSfx = "_imbueSkillSfx";

		public const string ImpTalk01 = "_impTalk01";

		public const string ImpTalk02 = "_impTalk02";

		public const string ImpTalk03 = "_impTalk03";

		public const string ImpTalk04 = "_impTalk04";

		public const string ImpTalk05 = "_impTalk05";

		public const string ImpTalk06 = "_impTalk06";

		public const string IntroNoise_00 = "_introNoise_00";

		public const string IntroNoise_01 = "_introNoise_01";

		public const string IntroNoise_02 = "_introNoise_02";

		public const string ItemDrop_Rare = "_itemDrop_rare";

		public const string ItemEntryPlace01 = "_itemEntryPlace01";

		public const string ItemEntryPlace02 = "_itemEntryPlace02";

		public const string ItemObject_Pickup = "itemObject_pickup";

		public const string ItemObject_Spawn = "itemObject_spawn";

		public const string KinggolemDeath_00 = "_kinggolemDeath_00";

		public const string KuboldTalk01 = "_kuboldTalk01";

		public const string KuboldTalk02 = "_kuboldTalk02";

		public const string KuboldTalk03 = "_kuboldTalk03";

		public const string KuboldTalk04 = "_kuboldTalk04";

		public const string KuboldTalk05 = "_kuboldTalk05";

		public const string Land_Grass01 = "land_grass01";

		public const string Land_Stone01 = "land_stone01";

		public const string Land_Water = "land_water";

		public const string Land_Wood = "land_wood";

		public const string LargeFootstep01 = "_largeFootstep01";

		public const string LedgeGrab = "_ledgeGrab";

		public const string Levelup = "levelup";

		public const string LeverSfx01 = "_leverSfx01";

		public const string LexiconBell = "_lexiconBell";

		public const string LexiconClose = "_lexiconClose";

		public const string LexiconOpen = "_lexiconOpen";

		public const string LightSheath = "_lightSheath";

		public const string Lockon = "lockon";

		public const string Lockout = "lockout";

		public const string LowHealthPulse01 = "_lowHealthPulse01";

		public const string LowHealthWarning = "_lowHealthWarning";

		public const string LungePower = "_lungePower";

		public const string MediumSheath = "_mediumSheath";

		public const string MeeleSkillCharge = "_meeleSkillCharge";

		public const string Mekboar_ChargeAtk01 = "_mekboar_chargeAtk01";

		public const string Mekboar_ChargeAtk02 = "_mekboar_chargeAtk02";

		public const string Mekboar_ChargeAtk03 = "_mekboar_chargeAtk03";

		public const string Mekboar_Death = "_mekboar_death";

		public const string Mekboar_Hurt = "_mekboar_hurt";

		public const string MeleeSkillLoop = "_meleeSkillLoop";

		public const string Melee_Swipe = "melee_swipe";

		public const string MouthEnemy_Death01 = "mouthEnemy_death01";

		public const string MouthEnemy_Hurt01 = "mouthEnemy_hurt01";

		public const string MouthEnemy_Hurt02 = "mouthEnemy_hurt02";

		public const string MouthEnemy_Vomit01 = "mouthEnemy_vomit01";

		public const string MouthEnemy_Vomit02 = "mouthEnemy_vomit02";

		public const string Mover_MetalGateClose = "_mover_metalGateClose";

		public const string Mover_MetalGateLoop = "_mover_metalGateLoop";

		public const string Mover_MetalGateOpen = "_mover_metalGateOpen";

		public const string Mu_AmbCrispr = "_mu_ambCrispr";

		public const string Mu_Botany = "_mu_botany";

		public const string Mu_Cahoots = "_mu_cahoots";

		public const string Mu_Calp = "_mu_calp";

		public const string Mu_Cane = "_mu_cane";

		public const string Mu_Discover01 = "_mu_discover01";

		public const string Mu_Discover02 = "_mu_discover02";

		public const string Mu_Discover03 = "_mu_discover03";

		public const string Mu_Discover04 = "_mu_discover04";

		public const string Mu_Discover05 = "_mu_discover05";

		public const string Mu_Ecka = "_mu_ecka";

		public const string Mu_Flyby = "_mu_flyby";

		public const string Mu_Haven = "_mu_haven";

		public const string Mu_Hell01 = "_mu_hell01";

		public const string Mu_Hell02 = "_mu_hell02";

		public const string Mu_Laid = "_mu_laid";

		public const string Mu_Lethargy = "_mu_lethargy";

		public const string Mu_NouCove = "mu_nouCove";

		public const string Mu_Photo = "_mu_photo";

		public const string Mu_Sailex = "_mu_sailex";

		public const string Mu_Select1 = "mu_select1";

		public const string Mu_Selee = "_mu_selee";

		public const string Mu_SnatchNight = "_mu_snatchNight";

		public const string Mu_Snatchsprings = "mu_snatchsprings";

		public const string Mu_Tex01 = "_mu_tex01";

		public const string Mu_Wasp = "_mu_wasp";

		public const string Mu_Wonton = "_mu_wonton";

		public const string Mu_Wonton5 = "_mu_wonton5";

		public const string Music_Whisper = "music_whisper";

		public const string NovaSkill_Init01 = "_novaSkill_init01";

		public const string NovaSkill_Init02 = "_novaSkill_init02";

		public const string OpenShop = "_openShop";

		public const string Option = "option";

		public const string PartyInviteSfx = "_partyInviteSfx";

		public const string Party_Init01 = "_party_init01";

		public const string Party_Join = "_party_join";

		public const string Pickup01 = "_pickup01";

		public const string Pickup02 = "_pickup02";

		public const string PlayerPort = "_playerPort";

		public const string Player_Dash = "player_dash";

		public const string Player_InitDeath = "_player_initDeath";

		public const string Player_InitDeath2 = "_player_initDeath2";

		public const string Player_Jiggle2 = "player_jiggle2";

		public const string Player_Jump = "player_jump";

		public const string PolearmSwing01 = "_polearmSwing01";

		public const string PolearmSwing02 = "_polearmSwing02";

		public const string PolearmSwing03 = "_polearmSwing03";

		public const string PolearmTakeOut01 = "_polearmTakeOut01";

		public const string PoonBounce = "_poonBounce";

		public const string PoonBounce02 = "_poonBounce02";

		public const string PoonTalk01 = "_poonTalk01";

		public const string PoonTalk02 = "_poonTalk02";

		public const string PoonTalk03 = "_poonTalk03";

		public const string PoonTalk04 = "_poonTalk04";

		public const string PoonTalk05 = "_poonTalk05";

		public const string PoonTalk06 = "_poonTalk06";

		public const string Port = "port";

		public const string PortalGlyph = "_portalGlyph";

		public const string PortalInteract = "_portalInteract";

		public const string PrismSkill_Init01 = "_prismSkill_init01";

		public const string PrismSkill_Loop01 = "_prismSkill_loop01";

		public const string Pushblock_Loop = "_pushblock_loop";

		public const string Pushblock_Stop = "_pushblock_stop";

		public const string PvpFlagInit = "_pvpFlagInit";

		public const string QuestAbandon = "_questAbandon";

		public const string QuestAccept = "_questAccept";

		public const string QuestProgressTick = "_questProgressTick";

		public const string QuestTurnIn = "_questTurnIn";

		public const string RageSfx01 = "_rageSfx01";

		public const string Railgun_Lv3 = "railgun_lv3";

		public const string ResShrineLoop = "_resShrineLoop";

		public const string Rock_Impact = "rock_impact";

		public const string RoosterDaySfx01 = "_roosterDaySfx01";

		public const string RopeClimb = "_ropeClimb";

		public const string SallyVox01 = "_sallyVox01";

		public const string SallyVox02 = "_sallyVox02";

		public const string SallyVox03 = "_sallyVox03";

		public const string SallyVox04 = "_sallyVox04";

		public const string SallyVox05 = "_sallyVox05";

		public const string SallyVox06 = "_sallyVox06";

		public const string SallyVox07 = "_sallyVox07";

		public const string Sally_Sweep = "_sally_sweep";

		public const string Satch_Explodelv2 = "satch_explodelv2";

		public const string ScepterCharge = "_scepterCharge";

		public const string ScepterChargeWeak = "_scepterChargeWeak";

		public const string ScepterProjectileBurst = "scepterProjectileBurst";

		public const string SeedPickup = "seedPickup";

		public const string Seekr_Equip = "seekr_equip";

		public const string SkillSet = "_skillSet";

		public const string SkritVox_00 = "_skritVox_00";

		public const string SkritVox_01 = "_skritVox_01";

		public const string SkritVox_02 = "_skritVox_02";

		public const string SkritVox_03 = "_skritVox_03";

		public const string Slap = "_slap";

		public const string SlimeDiva_AttackAoeSwing = "_slimeDiva_attackAoeSwing";

		public const string SlimeDiva_ChargeTitGun = "_slimeDiva_chargeTitGun";

		public const string SlimeDiva_Death = "_slimeDiva_death";

		public const string SlimeDiva_FloatMoveLoop = "_slimeDiva_floatMoveLoop";

		public const string SlimeDiva_Hurt01 = "_slimeDiva_hurt01";

		public const string SlimeDiva_Laugh01 = "_slimeDiva_laugh01";

		public const string SlimeDiva_Laugh02 = "_slimeDiva_laugh02";

		public const string SlimeDiva_Moan01 = "_slimeDiva_moan01";

		public const string SlimeDiva_SlimeOrb_Bounce = "_slimeDiva_slimeOrb_bounce";

		public const string SlimeDiva_SlimeOrb_Explode = "_slimeDiva_slimeOrb_explode";

		public const string SlimeDiva_TitBullet = "_slimeDiva_titBullet";

		public const string SmallClap = "_smallClap";

		public const string Snd_GrubdogBite = "snd_grubdogBite";

		public const string Snd_GrubdogConsume = "snd_grubdogConsume";

		public const string Snd_SummonAngel = "snd_summonAngel";

		public 

plugins/NAudio.Core.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using NAudio.Dmo;
using NAudio.Dsp;
using NAudio.FileFormats.Wav;
using NAudio.Utils;
using NAudio.Wave;
using NAudio.Wave.SampleProviders;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Mark Heath")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Mark Heath 2023")]
[assembly: AssemblyFileVersion("2.2.1.0")]
[assembly: AssemblyInformationalVersion("2.2.1")]
[assembly: AssemblyProduct("NAudio.Core")]
[assembly: AssemblyTitle("NAudio.Core")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.2.1.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
	{
		public MmResult Result { get; }

		public string Function { get; }

		public MmException(MmResult result, string function)
			: base(ErrorMessage(result, function))
		{
			Result = result;
			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.CoreAudioApi
{
	public enum CaptureState
	{
		Stopped,
		Starting,
		Capturing,
		Stopping
	}
}
namespace NAudio.Dmo
{
	public 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 MEDIASUBTYPE_I420 = new Guid("30323449-0000-0010-8000-00AA00389B71");

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

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

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

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

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

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

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

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

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

		public static readonly Guid MEDIASUBTYPE_VIDEOIMAGE = new Guid("1d4a45f2-e5f6-4b44-8388-f0ae5c0e0c37");

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

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

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

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

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

		public static readonly Guid WMFORMAT_Script = new Guid("5C8510F2-DEBE-4ca7-BBA5-F07A104F8DFF");

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

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

		public static readonly Guid WMFORMAT_WebStream = new Guid("da1e6b13-8359-4050-b398-388e965bf00c");

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

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

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

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

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

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

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

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

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

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

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

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

		public static readonly Guid WMMEDIASUBTYPE_WebStream = new Guid("776257d4-c627-41cb-8f81-7ac7ff1c40cc");

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

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

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

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

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

		public static readonly Guid WMMEDIASUBTYPE_WMSP1 = new Guid("0000000A-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMV1 = new Guid("31564D57-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMV2 = new Guid("32564D57-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMV3 = new Guid("33564D57-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMVA = new Guid("41564D57-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMVP = new Guid("50564D57-0000-0010-8000-00AA00389B71");

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

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

		public static readonly Guid WMMEDIATYPE_FileTransfer = new Guid("D9E47579-930E-4427-ADFC-AD80F290E470");

		public static readonly Guid WMMEDIATYPE_Image = new Guid("34A50FD8-8AA5-4386-81FE-A0EFE0488E31");

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

		public static readonly Guid WMMEDIATYPE_Text = new Guid("9BBA1EA7-5AB2-4829-BA57-0940209BCF3E");

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

		public static readonly Guid WMSCRIPTTYPE_TwoStrings = new Guid("82f38a70-c29f-11d1-97ad-00a0c95ea850");

		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();
		}
	}
}
namespace NAudio.Utils
{
	public static class BufferHelpers
	{
		public static byte[] Ensure(byte[] buffer, int bytesRequired)
		{
			if (buffer == null || buffer.Length < bytesRequired)
			{
				buffer = new byte[bytesRequired];
			}
			return buffer;
		}

		public static float[] Ensure(float[] buffer, int samplesRequired)
		{
			if (buffer == null || buffer.Length < samplesRequired)
			{
				buffer = new float[samplesRequired];
			}
			return buffer;
		}
	}
	public static class ByteArrayExtensions
	{
		public static bool IsEntirelyNull(byte[] buffer)
		{
			for (int i = 0; i < buffer.Length; i++)
			{
				if (buffer[i] != 0)
				{
					return false;
				}
			}
			return true;
		}

		public static string DescribeAsHex(byte[] buffer, string separator, int bytesPerLine)
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num = 0;
			foreach (byte b in buffer)
			{
				stringBuilder.AppendFormat("{0:X2}{1}", b, separator);
				if (++num % bytesPerLine == 0)
				{
					stringBuilder.Append("\r\n");
				}
			}
			stringBuilder.Append("\r\n");
			return stringBuilder.ToString();
		}

		public static string DecodeAsString(byte[] buffer, int offset, int length, Encoding encoding)
		{
			for (int i = 0; i < length; i++)
			{
				if (buffer[offset + i] == 0)
				{
					length = i;
				}
			}
			return encoding.GetString(buffer, offset, length);
		}

		public static byte[] Concat(params byte[][] byteArrays)
		{
			int num = 0;
			byte[][] array = byteArrays;
			foreach (byte[] array2 in array)
			{
				num += array2.Length;
			}
			if (num <= 0)
			{
				return new byte[0];
			}
			byte[] array3 = new byte[num];
			int num2 = 0;
			array = byteArrays;
			foreach (byte[] array4 in array)
			{
				Array.Copy(array4, 0, array3, num2, array4.Length);
				num2 += array4.Length;
			}
			return array3;
		}
	}
	public class ByteEncoding : Encoding
	{
		public static readonly ByteEncoding Instance = new ByteEncoding();

		private ByteEncoding()
		{
		}

		public override int GetByteCount(char[] chars, int index, int count)
		{
			return count;
		}

		public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
		{
			for (int i = 0; i < charCount; i++)
			{
				bytes[byteIndex + i] = (byte)chars[charIndex + i];
			}
			return charCount;
		}

		public override int GetCharCount(byte[] bytes, int index, int count)
		{
			for (int i = 0; i < count; i++)
			{
				if (bytes[index + i] == 0)
				{
					return i;
				}
			}
			return count;
		}

		public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
		{
			for (int i = 0; i < byteCount; i++)
			{
				byte b = bytes[byteIndex + i];
				if (b == 0)
				{
					return i;
				}
				chars[charIndex + i] = (char)b;
			}
			return byteCount;
		}

		public override int GetMaxCharCount(int byteCount)
		{
			return byteCount;
		}

		public override int GetMaxByteCount(int charCount)
		{
			return charCount;
		}
	}
	public class ChunkIdentifier
	{
		public static int ChunkIdentifierToInt32(string s)
		{
			if (s.Length != 4)
			{
				throw new ArgumentException("Must be a four character string");
			}
			byte[] bytes = Encoding.UTF8.GetBytes(s);
			if (bytes.Length != 4)
			{
				throw new ArgumentException("Must encode to exactly four bytes");
			}
			return BitConverter.ToInt32(bytes, 0);
		}
	}
	public class CircularBuffer
	{
		private readonly byte[] buffer;

		private readonly object lockObject;

		private int writePosition;

		private int readPosition;

		private int byteCount;

		public int MaxLength => buffer.Length;

		public int Count
		{
			get
			{
				lock (lockObject)
				{
					return byteCount;
				}
			}
		}

		public CircularBuffer(int size)
		{
			buffer = new byte[size];
			lockObject = new object();
		}

		public int Write(byte[] data, int offset, int count)
		{
			lock (lockObject)
			{
				int num = 0;
				if (count > buffer.Length - byteCount)
				{
					count = buffer.Length - byteCount;
				}
				int num2 = Math.Min(buffer.Length - writePosition, count);
				Array.Copy(data, offset, buffer, writePosition, num2);
				writePosition += num2;
				writePosition %= buffer.Length;
				num += num2;
				if (num < count)
				{
					Array.Copy(data, offset + num, buffer, writePosition, count - num);
					writePosition += count - num;
					num = count;
				}
				byteCount += num;
				return num;
			}
		}

		public int Read(byte[] data, int offset, int count)
		{
			lock (lockObject)
			{
				if (count > byteCount)
				{
					count = byteCount;
				}
				int num = 0;
				int num2 = Math.Min(buffer.Length - readPosition, count);
				Array.Copy(buffer, readPosition, data, offset, num2);
				num += num2;
				readPosition += num2;
				readPosition %= buffer.Length;
				if (num < count)
				{
					Array.Copy(buffer, readPosition, data, offset + num, count - num);
					readPosition += count - num;
					num = count;
				}
				byteCount -= num;
				return num;
			}
		}

		public void Reset()
		{
			lock (lockObject)
			{
				ResetInner();
			}
		}

		private void ResetInner()
		{
			byteCount = 0;
			readPosition = 0;
			writePosition = 0;
		}

		public void Advance(int count)
		{
			lock (lockObject)
			{
				if (count >= byteCount)
				{
					ResetInner();
					return;
				}
				byteCount -= count;
				readPosition += count;
				readPosition %= MaxLength;
			}
		}
	}
	public class Decibels
	{
		private const double LOG_2_DB = 8.685889638065037;

		private const double DB_2_LOG = 0.11512925464970228;

		public static double LinearToDecibels(double lin)
		{
			return Math.Log(lin) * 8.685889638065037;
		}

		public static double DecibelsToLinear(double dB)
		{
			return Math.Exp(dB * 0.11512925464970228);
		}
	}
	[AttributeUsage(AttributeTargets.Field)]
	public class FieldDescriptionAttribute : Attribute
	{
		public string Description { get; }

		public FieldDescriptionAttribute(string description)
		{
			Description = description;
		}

		public override string ToString()
		{
			return Description;
		}
	}
	public static class FieldDescriptionHelper
	{
		public static string Describe(Type t, Guid guid)
		{
			FieldInfo[] fields = t.GetFields(BindingFlags.Static | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!fieldInfo.IsPublic || !fieldInfo.IsStatic || !(fieldInfo.FieldType == typeof(Guid)) || !((Guid)fieldInfo.GetValue(null) == guid))
				{
					continue;
				}
				object[] customAttributes = fieldInfo.GetCustomAttributes(inherit: false);
				for (int j = 0; j < customAttributes.Length; j++)
				{
					if (customAttributes[j] is FieldDescriptionAttribute fieldDescriptionAttribute)
					{
						return fieldDescriptionAttribute.Description;
					}
				}
				return fieldInfo.Name;
			}
			return guid.ToString();
		}
	}
	public static class HResult
	{
		public const int S_OK = 0;

		public const int S_FALSE = 1;

		public const int E_INVALIDARG = -2147483645;

		private const int FACILITY_AAF = 18;

		private const int FACILITY_ACS = 20;

		private const int FACILITY_BACKGROUNDCOPY = 32;

		private const int FACILITY_CERT = 11;

		private const int FACILITY_COMPLUS = 17;

		private const int FACILITY_CONFIGURATION = 33;

		private const int FACILITY_CONTROL = 10;

		private const int FACILITY_DISPATCH = 2;

		private const int FACILITY_DPLAY = 21;

		private const int FACILITY_HTTP = 25;

		private const int FACILITY_INTERNET = 12;

		private const int FACILITY_ITF = 4;

		private const int FACILITY_MEDIASERVER = 13;

		private const int FACILITY_MSMQ = 14;

		private const int FACILITY_NULL = 0;

		private const int FACILITY_RPC = 1;

		private const int FACILITY_SCARD = 16;

		private const int FACILITY_SECURITY = 9;

		private const int FACILITY_SETUPAPI = 15;

		private const int FACILITY_SSPI = 9;

		private const int FACILITY_STORAGE = 3;

		private const int FACILITY_SXS = 23;

		private const int FACILITY_UMI = 22;

		private const int FACILITY_URT = 19;

		private const int FACILITY_WIN32 = 7;

		private const int FACILITY_WINDOWS = 8;

		private const int FACILITY_WINDOWS_CE = 24;

		public static int MAKE_HRESULT(int sev, int fac, int code)
		{
			return (sev << 31) | (fac << 16) | code;
		}

		public static int GetHResult(this COMException exception)
		{
			return exception.ErrorCode;
		}
	}
	public static class IEEE
	{
		private static double UnsignedToFloat(ulong u)
		{
			return (double)(long)(u - int.MaxValue - 1) + 2147483648.0;
		}

		private static double ldexp(double x, int exp)
		{
			return x * Math.Pow(2.0, exp);
		}

		private static double frexp(double x, out int exp)
		{
			exp = (int)Math.Floor(Math.Log(x) / Math.Log(2.0)) + 1;
			return 1.0 - (Math.Pow(2.0, exp) - x) / Math.Pow(2.0, exp);
		}

		private static ulong FloatToUnsigned(double f)
		{
			return (ulong)((long)(f - 2147483648.0) + int.MaxValue + 1);
		}

		public static byte[] ConvertToIeeeExtended(double num)
		{
			int num2;
			if (num < 0.0)
			{
				num2 = 32768;
				num *= -1.0;
			}
			else
			{
				num2 = 0;
			}
			ulong num4;
			ulong num5;
			int num3;
			if (num == 0.0)
			{
				num3 = 0;
				num4 = 0uL;
				num5 = 0uL;
			}
			else
			{
				double num6 = frexp(num, out num3);
				if (num3 > 16384 || !(num6 < 1.0))
				{
					num3 = num2 | 0x7FFF;
					num4 = 0uL;
					num5 = 0uL;
				}
				else
				{
					num3 += 16382;
					if (num3 < 0)
					{
						num6 = ldexp(num6, num3);
						num3 = 0;
					}
					num3 |= num2;
					num6 = ldexp(num6, 32);
					double num7 = Math.Floor(num6);
					num4 = FloatToUnsigned(num7);
					num6 = ldexp(num6 - num7, 32);
					num7 = Math.Floor(num6);
					num5 = FloatToUnsigned(num7);
				}
			}
			return new byte[10]
			{
				(byte)(num3 >> 8),
				(byte)num3,
				(byte)(num4 >> 24),
				(byte)(num4 >> 16),
				(byte)(num4 >> 8),
				(byte)num4,
				(byte)(num5 >> 24),
				(byte)(num5 >> 16),
				(byte)(num5 >> 8),
				(byte)num5
			};
		}

		public static double ConvertFromIeeeExtended(byte[] bytes)
		{
			if (bytes.Length != 10)
			{
				throw new Exception("Incorrect length for IEEE extended.");
			}
			int num = ((bytes[0] & 0x7F) << 8) | bytes[1];
			uint num2 = (uint)((bytes[2] << 24) | (bytes[3] << 16) | (bytes[4] << 8) | bytes[5]);
			uint num3 = (uint)((bytes[6] << 24) | (bytes[7] << 16) | (bytes[8] << 8) | bytes[9]);
			double num4;
			if (num == 0 && num2 == 0 && num3 == 0)
			{
				num4 = 0.0;
			}
			else if (num == 32767)
			{
				num4 = double.NaN;
			}
			else
			{
				num -= 16383;
				num4 = ldexp(UnsignedToFloat(num2), num -= 31);
				num4 += ldexp(UnsignedToFloat(num3), num -= 32);
			}
			if ((bytes[0] & 0x80) == 128)
			{
				return 0.0 - num4;
			}
			return num4;
		}
	}
	public class IgnoreDisposeStream : Stream
	{
		public Stream SourceStream { get; private set; }

		public bool IgnoreDispose { get; set; }

		public override bool CanRead => SourceStream.CanRead;

		public override bool CanSeek => SourceStream.CanSeek;

		public override bool CanWrite => SourceStream.CanWrite;

		public override long Length => SourceStream.Length;

		public override long Position
		{
			get
			{
				return SourceStream.Position;
			}
			set
			{
				SourceStream.Position = value;
			}
		}

		public IgnoreDisposeStream(Stream sourceStream)
		{
			SourceStream = sourceStream;
			IgnoreDispose = true;
		}

		public override void Flush()
		{
			SourceStream.Flush();
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			return SourceStream.Read(buffer, offset, count);
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			return SourceStream.Seek(offset, origin);
		}

		public override void SetLength(long value)
		{
			SourceStream.SetLength(value);
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			SourceStream.Write(buffer, offset, count);
		}

		protected override void Dispose(bool disposing)
		{
			if (!IgnoreDispose)
			{
				SourceStream.Dispose();
				SourceStream = null;
			}
		}
	}
	public static class NativeMethods
	{
		[DllImport("kernel32.dll")]
		public static extern IntPtr LoadLibrary(string dllToLoad);

		[DllImport("kernel32.dll")]
		public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

		[DllImport("kernel32.dll")]
		public static extern bool FreeLibrary(IntPtr hModule);
	}
	public static class WavePositionExtensions
	{
		public static TimeSpan GetPositionTimeSpan(this IWavePosition @this)
		{
			return TimeSpan.FromMilliseconds((double)(@this.GetPosition() / (@this.OutputWaveFormat.Channels * @this.OutputWaveFormat.BitsPerSample / 8)) * 1000.0 / (double)@this.OutputWaveFormat.SampleRate);
		}
	}
}
namespace NAudio.FileFormats.Wav
{
	public class WaveFileChunkReader
	{
		private WaveFormat waveFormat;

		private long dataChunkPosition;

		private long dataChunkLength;

		private List<RiffChunk> riffChunks;

		private readonly bool strictMode;

		private bool isRf64;

		private readonly bool storeAllChunks;

		private long riffSize;

		public WaveFormat WaveFormat => waveFormat;

		public long DataChunkPosition => dataChunkPosition;

		public long DataChunkLength => dataChunkLength;

		public List<RiffChunk> RiffChunks => riffChunks;

		public WaveFileChunkReader()
		{
			storeAllChunks = true;
			strictMode = false;
		}

		public void ReadWaveHeader(Stream stream)
		{
			dataChunkPosition = -1L;
			waveFormat = null;
			riffChunks = new List<RiffChunk>();
			dataChunkLength = 0L;
			BinaryReader binaryReader = new BinaryReader(stream);
			ReadRiffHeader(binaryReader);
			riffSize = binaryReader.ReadUInt32();
			if (binaryReader.ReadInt32() != ChunkIdentifier.ChunkIdentifierToInt32("WAVE"))
			{
				throw new FormatException("Not a WAVE file - no WAVE header");
			}
			if (isRf64)
			{
				ReadDs64Chunk(binaryReader);
			}
			int num = ChunkIdentifier.ChunkIdentifierToInt32("data");
			int num2 = ChunkIdentifier.ChunkIdentifierToInt32("fmt ");
			long num3 = Math.Min(riffSize + 8, stream.Length);
			while (stream.Position <= num3 - 8)
			{
				int num4 = binaryReader.ReadInt32();
				uint num5 = binaryReader.ReadUInt32();
				if (num4 == num)
				{
					dataChunkPosition = stream.Position;
					if (!isRf64)
					{
						dataChunkLength = num5;
					}
					stream.Position += num5;
				}
				else if (num4 == num2)
				{
					if (num5 > int.MaxValue)
					{
						throw new InvalidDataException($"Format chunk length must be between 0 and {int.MaxValue}.");
					}
					waveFormat = WaveFormat.FromFormatChunk(binaryReader, (int)num5);
				}
				else
				{
					if (num5 > stream.Length - stream.Position)
					{
						if (!strictMode)
						{
						}
						break;
					}
					if (storeAllChunks)
					{
						if (num5 > int.MaxValue)
						{
							throw new InvalidDataException($"RiffChunk chunk length must be between 0 and {int.MaxValue}.");
						}
						riffChunks.Add(GetRiffChunk(stream, num4, (int)num5));
					}
					stream.Position += num5;
				}
				if (num5 % 2 != 0 && binaryReader.PeekChar() == 0)
				{
					stream.Position++;
				}
			}
			if (waveFormat == null)
			{
				throw new FormatException("Invalid WAV file - No fmt chunk found");
			}
			if (dataChunkPosition == -1)
			{
				throw new FormatException("Invalid WAV file - No data chunk found");
			}
		}

		private void ReadDs64Chunk(BinaryReader reader)
		{
			int num = ChunkIdentifier.ChunkIdentifierToInt32("ds64");
			if (reader.ReadInt32() != num)
			{
				throw new FormatException("Invalid RF64 WAV file - No ds64 chunk found");
			}
			int num2 = reader.ReadInt32();
			riffSize = reader.ReadInt64();
			dataChunkLength = reader.ReadInt64();
			reader.ReadInt64();
			reader.ReadBytes(num2 - 24);
		}

		private static RiffChunk GetRiffChunk(Stream stream, int chunkIdentifier, int chunkLength)
		{
			return new RiffChunk(chunkIdentifier, chunkLength, stream.Position);
		}

		private void ReadRiffHeader(BinaryReader br)
		{
			int num = br.ReadInt32();
			if (num == ChunkIdentifier.ChunkIdentifierToInt32("RF64"))
			{
				isRf64 = true;
			}
			else if (num != ChunkIdentifier.ChunkIdentifierToInt32("RIFF"))
			{
				throw new FormatException("Not a WAVE file - no RIFF header");
			}
		}
	}
}
namespace NAudio.SoundFont
{
	public class Generator
	{
		public GeneratorEnum GeneratorType { get; set; }

		public ushort UInt16Amount { get; set; }

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

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

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

		public Instrument Instrument { get; set; }

		public SampleHeader SampleHeader { get; set; }

		public override string ToString()
		{
			if (GeneratorType == GeneratorEnum.Instrument)
			{
				return "Generator Instrument " + Instrument.Name;
			}
			if (GeneratorType == GeneratorEnum.SampleID)
			{
				return $"Generator SampleID {SampleHeader}";
			}
			return $"Generator {GeneratorType} {UInt16Amount}";
		}
	}
	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
	{
		internal ushort startInstrumentZoneIndex;

		internal ushort endInstrumentZoneIndex;

		public string Name { get; set; }

		public Zone[] Zones { get; set; }

		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
	{
		public ModulatorType SourceModulationData { get; set; }

		public GeneratorEnum DestinationGenerator { get; set; }

		public short Amount { get; set; }

		public ModulatorType SourceModulationAmount { get; set; }

		public TransformEnum SourceTransform { get; set; }

		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
	{
		internal ushort startPresetZoneIndex;

		internal ushort endPresetZoneIndex;

		internal uint library;

		internal uint genre;

		internal uint morphology;

		public string Name { get; set; }

		public ushort PatchNumber { get; set; }

		public ushort Bank { get; set; }

		public Zone[] Zones { get; set; }

		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 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 { get; private set; }

		public long DataOffset { get; private set; }

		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
	{
		public byte[] SampleData { get; private set; }

		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
	{
		public short Major { get; set; }

		public short Minor { get; set; }
	}
	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;

		public Modulator[] Modulators { get; set; }

		public Generator[] Generators { get; set; }

		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.Wave
{
	public enum ChannelMode
	{
		Stereo,
		JointStereo,
		DualChannel,
		Mono
	}
	public class Id3v2Tag
	{
		private long tagStartPosition;

		private long tagEndPosition;

		private byte[] rawData;

		public byte[] RawData => rawData;

		public static Id3v2Tag ReadTag(Stream input)
		{
			try
			{
				return new Id3v2Tag(input);
			}
			catch (FormatException)
			{
				return null;
			}
		}

		public static Id3v2Tag Create(IEnumerable<KeyValuePair<string, string>> tags)
		{
			return ReadTag(CreateId3v2TagStream(tags));
		}

		private static byte[] FrameSizeToBytes(int n)
		{
			byte[] bytes = BitConverter.GetBytes(n);
			Array.Reverse((Array)bytes);
			return bytes;
		}

		private static byte[] CreateId3v2Frame(string key, string value)
		{
			if (string.IsNullOrEmpty(key))
			{
				throw new ArgumentNullException("key");
			}
			if (string.IsNullOrEmpty(value))
			{
				throw new ArgumentNullException("value");
			}
			if (key.Length != 4)
			{
				throw new ArgumentOutOfRangeException("key", "key " + key + " must be 4 characters long");
			}
			byte[] array = new byte[2] { 255, 254 };
			byte[] array2 = new byte[3];
			byte[] array3 = new byte[2];
			byte[] array4 = ((!(key == "COMM")) ? ByteArrayExtensions.Concat(new byte[1] { 1 }, array, Encoding.Unicode.GetBytes(value)) : ByteArrayExtensions.Concat(new byte[1] { 1 }, array2, array3, array, Encoding.Unicode.GetBytes(value)));
			return ByteArrayExtensions.Concat(Encoding.UTF8.GetBytes(key), FrameSizeToBytes(array4.Length), new byte[2], array4);
		}

		private static byte[] GetId3TagHeaderSize(int size)
		{
			byte[] array = new byte[4];
			for (int num = array.Length - 1; num >= 0; num--)
			{
				array[num] = (byte)(size % 128);
				size /= 128;
			}
			return array;
		}

		private static byte[] CreateId3v2TagHeader(IEnumerable<byte[]> frames)
		{
			int num = 0;
			foreach (byte[] frame in frames)
			{
				num += frame.Length;
			}
			return ByteArrayExtensions.Concat(Encoding.UTF8.GetBytes("ID3"), new byte[2] { 3, 0 }, new byte[1], GetId3TagHeaderSize(num));
		}

		private static Stream CreateId3v2TagStream(IEnumerable<KeyValuePair<string, string>> tags)
		{
			List<byte[]> list = new List<byte[]>();
			foreach (KeyValuePair<string, string> tag in tags)
			{
				list.Add(CreateId3v2Frame(tag.Key, tag.Value));
			}
			byte[] array = CreateId3v2TagHeader(list);
			MemoryStream memoryStream = new MemoryStream();
			memoryStream.Write(array, 0, array.Length);
			foreach (byte[] item in list)
			{
				memoryStream.Write(item, 0, item.Length);
			}
			memoryStream.Position = 0L;
			return memoryStream;
		}

		private Id3v2Tag(Stream input)
		{
			tagStartPosition = input.Position;
			BinaryReader binaryReader = new BinaryReader(input);
			byte[] array = binaryReader.ReadBytes(10);
			if (array.Length >= 3 && array[0] == 73 && array[1] == 68 && array[2] == 51)
			{
				if ((array[5] & 0x40) == 64)
				{
					byte[] array2 = binaryReader.ReadBytes(4);
					_ = array2[0] * 2097152 + array2[1] * 16384 + array2[2] * 128;
					_ = array2[3];
				}
				int num = array[6] * 2097152;
				num += array[7] * 16384;
				num += array[8] * 128;
				num += array[9];
				binaryReader.ReadBytes(num);
				if ((array[5] & 0x10) == 16)
				{
					binaryReader.ReadBytes(10);
				}
				tagEndPosition = input.Position;
				input.Position = tagStartPosition;
				rawData = binaryReader.ReadBytes((int)(tagEndPosition - tagStartPosition));
				return;
			}
			input.Position = tagStartPosition;
			throw new FormatException("Not an ID3v2 tag");
		}
	}
	public interface IMp3FrameDecompressor : IDisposable
	{
		WaveFormat OutputFormat { get; }

		int DecompressFrame(Mp3Frame frame, byte[] dest, int destOffset);

		void Reset();
	}
	public class Mp3Frame
	{
		private static readonly int[,,] bitRates = new int[2, 3, 15]
		{
			{
				{
					0, 32, 64, 96, 128, 160, 192, 224, 256, 288,
					320, 352, 384, 416, 448
				},
				{
					0, 32, 48, 56, 64, 80, 96, 112, 128, 160,
					192, 224, 256, 320, 384
				},
				{
					0, 32, 40, 48, 56, 64, 80, 96, 112, 128,
					160, 192, 224, 256, 320
				}
			},
			{
				{
					0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
					160, 176, 192, 224, 256
				},
				{
					0, 8, 16, 24, 32, 40, 48, 56, 64, 80,
					96, 112, 128, 144, 160
				},
				{
					0, 8, 16, 24, 32, 40, 48, 56, 64, 80,
					96, 112, 128, 144, 160
				}
			}
		};

		private static readonly int[,] samplesPerFrame = new int[2, 3]
		{
			{ 384, 1152, 1152 },
			{ 384, 1152, 576 }
		};

		private static readonly int[] sampleRatesVersion1 = new int[3] { 44100, 48000, 32000 };

		private static readonly int[] sampleRatesVersion2 = new int[3] { 22050, 24000, 16000 };

		private static readonly int[] sampleRatesVersion25 = new int[3] { 11025, 12000, 8000 };

		private const int MaxFrameLength = 16384;

		public int SampleRate { get; private set; }

		public int FrameLength { get; private set; }

		public int BitRate { get; private set; }

		public byte[] RawData { get; private set; }

		public MpegVersion MpegVersion { get; private set; }

		public MpegLayer MpegLayer { get; private set; }

		public ChannelMode ChannelMode { get; private set; }

		public int SampleCount { get; private set; }

		public int ChannelExtension { get; private set; }

		public int BitRateIndex { get; private set; }

		public bool Copyright { get; private set; }

		public bool CrcPresent { get; private set; }

		public long FileOffset { get; private set; }

		public static Mp3Frame LoadFromStream(Stream input)
		{
			return LoadFromStream(input, readData: true);
		}

		public static Mp3Frame LoadFromStream(Stream input, bool readData)
		{
			Mp3Frame mp3Frame = new Mp3Frame();
			mp3Frame.FileOffset = input.Position;
			byte[] array = new byte[4];
			if (input.Read(array, 0, array.Length) < array.Length)
			{
				return null;
			}
			while (!IsValidHeader(array, mp3Frame))
			{
				array[0] = array[1];
				array[1] = array[2];
				array[2] = array[3];
				if (input.Read(array, 3, 1) < 1)
				{
					return null;
				}
				mp3Frame.FileOffset++;
			}
			int num = mp3Frame.FrameLength - 4;
			if (readData)
			{
				mp3Frame.RawData = new byte[mp3Frame.FrameLength];
				Array.Copy(array, mp3Frame.RawData, 4);
				if (input.Read(mp3Frame.RawData, 4, num) < num)
				{
					throw new EndOfStreamException("Unexpected end of stream before frame complete");
				}
			}
			else
			{
				input.Position += num;
			}
			return mp3Frame;
		}

		private Mp3Frame()
		{
		}

		private static bool IsValidHeader(byte[] headerBytes, Mp3Frame frame)
		{
			if (headerBytes[0] == byte.MaxValue && (headerBytes[1] & 0xE0) == 224)
			{
				frame.MpegVersion = (MpegVersion)((headerBytes[1] & 0x18) >> 3);
				if (frame.MpegVersion == MpegVersion.Reserved)
				{
					return false;
				}
				frame.MpegLayer = (MpegLayer)((headerBytes[1] & 6) >> 1);
				if (frame.MpegLayer == MpegLayer.Reserved)
				{
					return false;
				}
				int num = ((frame.MpegLayer != MpegLayer.Layer1) ? ((frame.MpegLayer == MpegLayer.Layer2) ? 1 : 2) : 0);
				frame.CrcPresent = (headerBytes[1] & 1) == 0;
				frame.BitRateIndex = (headerBytes[2] & 0xF0) >> 4;
				if (frame.BitRateIndex == 15)
				{
					return false;
				}
				int num2 = ((frame.MpegVersion != MpegVersion.Version1) ? 1 : 0);
				frame.BitRate = bitRates[num2, num, frame.BitRateIndex] * 1000;
				if (frame.BitRate == 0)
				{
					return false;
				}
				int num3 = (headerBytes[2] & 0xC) >> 2;
				if (num3 == 3)
				{
					return false;
				}
				if (frame.MpegVersion == MpegVersion.Version1)
				{
					frame.SampleRate = sampleRatesVersion1[num3];
				}
				else if (frame.MpegVersion == MpegVersion.Version2)
				{
					frame.SampleRate = sampleRatesVersion2[num3];
				}
				else
				{
					frame.SampleRate = sampleRatesVersion25[num3];
				}
				bool flag = (headerBytes[2] & 2) == 2;
				_ = headerBytes[2];
				frame.ChannelMode = (ChannelMode)((headerBytes[3] & 0xC0) >> 6);
				frame.ChannelExtension = (headerBytes[3] & 0x30) >> 4;
				if (frame.ChannelExtension != 0 && frame.ChannelMode != ChannelMode.JointStereo)
				{
					return false;
				}
				frame.Copyright = (headerBytes[3] & 8) == 8;
				_ = headerBytes[3];
				_ = headerBytes[3];
				int num4 = (flag ? 1 : 0);
				frame.SampleCount = samplesPerFrame[num2, num];
				int num5 = frame.SampleCount / 8;
				if (frame.MpegLayer == MpegLayer.Layer1)
				{
					frame.FrameLength = (num5 * frame.BitRate / frame.SampleRate + num4) * 4;
				}
				else
				{
					frame.FrameLength = num5 * frame.BitRate / frame.SampleRate + num4;
				}
				if (frame.FrameLength > 16384)
				{
					return false;
				}
				return true;
			}
			return false;
		}
	}
	public enum MpegLayer
	{
		Reserved,
		Layer3,
		Layer2,
		Layer1
	}
	public enum MpegVersion
	{
		Version25,
		Reserved,
		Version2,
		Version1
	}
	public class XingHeader
	{
		[Flags]
		private enum XingHeaderOptions
		{
			Frames = 1,
			Bytes = 2,
			Toc = 4,
			VbrScale = 8
		}

		private static int[] sr_table = new int[4] { 44100, 48000, 32000, 99999 };

		private int vbrScale = -1;

		private int startOffset;

		private int endOffset;

		private int tocOffset = -1;

		private int framesOffset = -1;

		private int bytesOffset = -1;

		private Mp3Frame frame;

		public int Frames
		{
			get
			{
				if (framesOffset == -1)
				{
					return -1;
				}
				return ReadBigEndian(frame.RawData, framesOffset);
			}
			set
			{
				if (framesOffset == -1)
				{
					throw new InvalidOperationException("Frames flag is not set");
				}
				WriteBigEndian(frame.RawData, framesOffset, value);
			}
		}

		public int Bytes
		{
			get
			{
				if (bytesOffset == -1)
				{
					return -1;
				}
				return ReadBigEndian(frame.RawData, bytesOffset);
			}
			set
			{
				if (framesOffset == -1)
				{
					throw new InvalidOperationException("Bytes flag is not set");
				}
				WriteBigEndian(frame.RawData, bytesOffset, value);
			}
		}

		public int VbrScale => vbrScale;

		public Mp3Frame Mp3Frame => frame;

		private static int ReadBigEndian(byte[] buffer, int offset)
		{
			return (((((buffer[offset] << 8) | buffer[offset + 1]) << 8) | buffer[offset + 2]) << 8) | buffer[offset + 3];
		}

		private void WriteBigEndian(byte[] buffer, int offset, int value)
		{
			byte[] bytes = BitConverter.GetBytes(value);
			for (int i = 0; i < 4; i++)
			{
				buffer[offset + 3 - i] = bytes[i];
			}
		}

		public static XingHeader LoadXingHeader(Mp3Frame frame)
		{
			XingHeader xingHeader = new XingHeader();
			xingHeader.frame = frame;
			int num = 0;
			if (frame.MpegVersion == MpegVersion.Version1)
			{
				num = ((frame.ChannelMode == ChannelMode.Mono) ? 21 : 36);
			}
			else
			{
				if (frame.MpegVersion != MpegVersion.Version2)
				{
					return null;
				}
				num = ((frame.ChannelMode == ChannelMode.Mono) ? 13 : 21);
			}
			if (frame.RawData[num] == 88 && frame.RawData[num + 1] == 105 && frame.RawData[num + 2] == 110 && frame.RawData[num + 3] == 103)
			{
				xingHeader.startOffset = num;
				num += 4;
			}
			else
			{
				if (frame.RawData[num] != 73 || frame.RawData[num + 1] != 110 || frame.RawData[num + 2] != 102 || frame.RawData[num + 3] != 111)
				{
					return null;
				}
				xingHeader.startOffset = num;
				num += 4;
			}
			int num2 = ReadBigEndian(frame.RawData, num);
			num += 4;
			if (((uint)num2 & (true ? 1u : 0u)) != 0)
			{
				xingHeader.framesOffset = num;
				num += 4;
			}
			if (((uint)num2 & 2u) != 0)
			{
				xingHeader.bytesOffset = num;
				num += 4;
			}
			if (((uint)num2 & 4u) != 0)
			{
				xingHeader.tocOffset = num;
				num += 100;
			}
			if (((uint)num2 & 8u) != 0)
			{
				xingHeader.vbrScale = ReadBigEndian(frame.RawData, num);
				num += 4;
			}
			xingHeader.endOffset = num;
			return xingHeader;
		}

		private XingHeader()
		{
		}
	}
	public static class WaveExtensionMethods
	{
		public static ISampleProvider ToSampleProvider(this IWaveProvider waveProvider)
		{
			return SampleProviderConverters.ConvertWaveProviderIntoSampleProvider(waveProvider);
		}

		public static void Init(this IWavePlayer wavePlayer, ISampleProvider sampleProvider, bool convertTo16Bit = false)
		{
			IWaveProvider waveProvider2;
			if (!convertTo16Bit)
			{
				IWaveProvider waveProvider = new SampleToWaveProvider(sampleProvider);
				waveProvider2 = waveProvider;
			}
			else
			{
				IWaveProvider waveProvider = new SampleToWaveProvider16(sampleProvider);
				waveProvider2 = waveProvider;
			}
			IWaveProvider waveProvider3 = waveProvider2;
			wavePlayer.Init(waveProvider3);
		}

		public static WaveFormat AsStandardWaveFormat(this WaveFormat waveFormat)
		{
			if (!(waveFormat is WaveFormatExtensible waveFormatExtensible))
			{
				return waveFormat;
			}
			return waveFormatExtensible.ToStandardWaveFormat();
		}

		public static IWaveProvider ToWaveProvider(this ISampleProvider sampleProvider)
		{
			return new SampleToWaveProvider(sampleProvider);
		}

		public static IWaveProvider ToWaveProvider16(this ISampleProvider sampleProvider)
		{
			return new SampleToWaveProvider16(sampleProvider);
		}

		public static ISampleProvider FollowedBy(this ISampleProvider sampleProvider, ISampleProvider next)
		{
			return new ConcatenatingSampleProvider(new ISampleProvider[2] { sampleProvider, next });
		}

		public static ISampleProvider FollowedBy(this ISampleProvider sampleProvider, TimeSpan silenceDuration, ISampleProvider next)
		{
			OffsetSampleProvider offsetSampleProvider = new OffsetSampleProvider(sampleProvider)
			{
				LeadOut = silenceDuration
			};
			return new ConcatenatingSampleProvider(new ISampleProvider[2] { offsetSampleProvider, next });
		}

		public static ISampleProvider Skip(this ISampleProvider sampleProvider, TimeSpan skipDuration)
		{
			return new OffsetSampleProvider(sampleProvider)
			{
				SkipOver = skipDuration
			};
		}

		public static ISampleProvider Take(this ISampleProvider sampleProvider, TimeSpan takeDuration)
		{
			return new OffsetSampleProvider(sampleProvider)
			{
				Take = takeDuration
			};
		}

		public static ISampleProvider ToMono(this ISampleProvider sourceProvider, float leftVol = 0.5f, float rightVol = 0.5f)
		{
			if (sourceProvider.WaveFormat.Channels == 1)
			{
				return sourceProvider;
			}
			return new StereoToMonoSampleProvider(sourceProvider)
			{
				LeftVolume = leftVol,
				RightVolume = rightVol
			};
		}

		public static ISampleProvider ToStereo(this ISampleProvider sourceProvider, float leftVol = 1f, float rightVol = 1f)
		{
			if (sourceProvider.WaveFormat.Channels == 2)
			{
				return sourceProvider;
			}
			return new MonoToStereoSampleProvider(sourceProvider)
			{
				LeftVolume = leftVol,
				RightVolume = rightVol
			};
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class AdpcmWaveFormat : WaveFormat
	{
		private short samplesPerBlock;

		private short numCoeff;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
		private short[] coefficients;

		public int SamplesPerBlock => samplesPerBlock;

		public int NumCoefficients => numCoeff;

		public short[] Coefficients => coefficients;

		private AdpcmWaveFormat()
			: this(8000, 1)
		{
		}

		public AdpcmWaveFormat(int sampleRate, int channels)
			: base(sampleRate, 0, channels)
		{
			waveFormatTag = WaveFormatEncoding.Adpcm;
			extraSize = 32;
			switch (base.sampleRate)
			{
			case 8000:
			case 11025:
				blockAlign = 256;
				break;
			case 22050:
				blockAlign = 512;
				break;
			default:
				blockAlign = 1024;
				break;
			}
			bitsPerSample = 4;
			samplesPerBlock = (short)((blockAlign - 7 * channels) * 8 / (bitsPerSample * channels) + 2);
			averageBytesPerSecond = base.SampleRate * blockAlign / samplesPerBlock;
			numCoeff = 7;
			coefficients = new short[14]
			{
				256, 0, 512, -256, 0, 0, 192, 64, 240, 0,
				460, -208, 392, -232
			};
		}

		public override void Serialize(BinaryWriter writer)
		{
			base.Serialize(writer);
			writer.Write(samplesPerBlock);
			writer.Write(numCoeff);
			short[] array = coefficients;
			foreach (short value in array)
			{
				writer.Write(value);
			}
		}

		public override string ToString()
		{
			return $"Microsoft ADPCM {base.SampleRate} Hz {channels} channels {bitsPerSample} bits per sample {samplesPerBlock} samples per block";
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class Gsm610WaveFormat : WaveFormat
	{
		private readonly short samplesPerBlock;

		public short SamplesPerBlock => samplesPerBlock;

		public Gsm610WaveFormat()
		{
			waveFormatTag = WaveFormatEncoding.Gsm610;
			channels = 1;
			averageBytesPerSecond = 1625;
			bitsPerSample = 0;
			blockAlign = 65;
			sampleRate = 8000;
			extraSize = 2;
			samplesPerBlock = 320;
		}

		public override void Serialize(BinaryWriter writer)
		{
			base.Serialize(writer);
			writer.Write(samplesPerBlock);
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class ImaAdpcmWaveFormat : WaveFormat
	{
		private short samplesPerBlock;

		private ImaAdpcmWaveFormat()
		{
		}

		public ImaAdpcmWaveFormat(int sampleRate, int channels, int bitsPerSample)
		{
			waveFormatTag = WaveFormatEncoding.DviAdpcm;
			base.sampleRate = sampleRate;
			base.channels = (short)channels;
			base.bitsPerSample = (short)bitsPerSample;
			extraSize = 2;
			blockAlign = 0;
			averageBytesPerSecond = 0;
			samplesPerBlock = 0;
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class Mp3WaveFormat : WaveFormat
	{
		public Mp3WaveFormatId id;

		public Mp3WaveFormatFlags flags;

		public ushort blockSize;

		public ushort framesPerBlock;

		public ushort codecDelay;

		private const short Mp3WaveFormatExtraBytes = 12;

		public Mp3WaveFormat(int sampleRate, int channels, int blockSize, int bitRate)
		{
			waveFormatTag = WaveFormatEncoding.MpegLayer3;
			base.channels = (short)channels;
			averageBytesPerSecond = bitRate / 8;
			bitsPerSample = 0;
			blockAlign = 1;
			base.sampleRate = sampleRate;
			extraSize = 12;
			id = Mp3WaveFormatId.Mpeg;
			flags = Mp3WaveFormatFlags.PaddingIso;
			this.blockSize = (ushort)blockSize;
			framesPerBlock = 1;
			codecDelay = 0;
		}
	}
	[Flags]
	public enum Mp3WaveFormatFlags
	{
		PaddingIso = 0,
		PaddingOn = 1,
		PaddingOff = 2
	}
	public enum Mp3WaveFormatId : ushort
	{
		Unknown,
		Mpeg,
		ConstantFrameSize
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	internal class OggWaveFormat : WaveFormat
	{
		public uint dwVorbisACMVersion;

		public uint dwLibVorbisVersion;
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class TrueSpeechWaveFormat : WaveFormat
	{
		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
		private short[] unknown;

		public TrueSpeechWaveFormat()
		{
			waveFormatTag = WaveFormatEncoding.DspGroupTrueSpeech;
			channels = 1;
			averageBytesPerSecond = 1067;
			bitsPerSample = 1;
			blockAlign = 32;
			sampleRate = 8000;
			extraSize = 32;
			unknown = new short[16];
			unknown[0] = 1;
			unknown[1] = 240;
		}

		public override void Serialize(BinaryWriter writer)
		{
			base.Serialize(writer);
			short[] array = unknown;
			foreach (short value in array)
			{
				writer.Write(value);
			}
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class WaveFormat
	{
		protected WaveFormatEncoding waveFormatTag;

		protected short channels;

		protected int sampleRate;

		protected int averageBytesPerSecond;

		protected short blockAlign;

		protected short bitsPerSample;

		protected short extraSize;

		public WaveFormatEncoding Encoding => waveFormatTag;

		public int Channels => channels;

		public int SampleRate => sampleRate;

		public int AverageBytesPerSecond => averageBytesPerSecond;

		public virtual int BlockAlign => blockAlign;

		public int BitsPerSample => bitsPerSample;

		public int ExtraSize => extraSize;

		public WaveFormat()
			: this(44100, 16, 2)
		{
		}

		public WaveFormat(int sampleRate, int channels)
			: this(sampleRate, 16, channels)
		{
		}

		public int ConvertLatencyToByteSize(int milliseconds)
		{
			int num = (int)((double)AverageBytesPerSecond / 1000.0 * (double)milliseconds);
			if (num % BlockAlign != 0)
			{
				num = num + BlockAlign - num % BlockAlign;
			}
			return num;
		}

		public static WaveFormat CreateCustomFormat(WaveFormatEncoding tag, int sampleRate, int channels, int averageBytesPerSecond, int blockAlign, int bitsPerSample)
		{
			return new WaveFormat
			{
				waveFormatTag = tag,
				channels = (short)channels,
				sampleRate = sampleRate,
				averageBytesPerSecond = averageBytesPerSecond,
				blockAlign = (short)blockAlign,
				bitsPerSample = (short)bitsPerSample,
				extraSize = 0
			};
		}

		public static WaveFormat CreateALawFormat(int sampleRate, int channels)
		{
			return CreateCustomFormat(WaveFormatEncoding.ALaw, sampleRate, channels, sampleRate * channels, channels, 8);
		}

		public static WaveFormat CreateMuLawFormat(int sampleRate, int channels)
		{
			return CreateCustomFormat(WaveFormatEncoding.MuLaw, sampleRate, channels, sampleRate * channels, channels, 8);
		}

		public WaveFormat(int rate, int bits, int channels)
		{
			if (channels < 1)
			{
				throw new ArgumentOutOfRangeException("channels", "Channels must be 1 or greater");
			}
			waveFormatTag = WaveFormatEncoding.Pcm;
			this.channels = (short)channels;
			sampleRate = rate;
			bitsPerSample = (short)bits;
			extraSize = 0;
			blockAlign = (short)(channels * (bits / 8));
			averageBytesPerSecond = sampleRate * blockAlign;
		}

		public static WaveFormat CreateIeeeFloatWaveFormat(int sampleRate, int channels)
		{
			WaveFormat waveFormat = new WaveFormat();
			waveFormat.waveFormatTag = WaveFormatEncoding.IeeeFloat;
			waveFormat.channels = (short)channels;
			waveFormat.bitsPerSample = 32;
			waveFormat.sampleRate = sampleRate;
			waveFormat.blockAlign = (short)(4 * channels);
			waveFormat.averageBytesPerSecond = sampleRate * waveFormat.blockAlign;
			waveFormat.extraSize = 0;
			return waveFormat;
		}

		public static WaveFormat MarshalFromPtr(IntPtr pointer)
		{
			WaveFormat waveFormat = Marshal.PtrToStructure<WaveFormat>(pointer);
			switch (waveFormat.Encoding)
			{
			case WaveFormatEncoding.Pcm:
				waveFormat.extraSize = 0;
				break;
			case WaveFormatEncoding.Extensible:
				waveFormat = Marshal.PtrToStructure<WaveFormatExtensible>(pointer);
				break;
			case WaveFormatEncoding.Adpcm:
				waveFormat = Marshal.PtrToStructure<AdpcmWaveFormat>(pointer);
				break;
			case WaveFormatEncoding.Gsm610:
				waveFormat = Marshal.PtrToStructure<Gsm610WaveFormat>(pointer);
				break;
			default:
				if (waveFormat.ExtraSize > 0)
				{
					waveFormat = Marshal.PtrToStructure<WaveFormatExtraData>(pointer);
				}
				break;
			}
			return waveFormat;
		}

		public static IntPtr MarshalToPtr(WaveFormat format)
		{
			IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(format));
			Marshal.StructureToPtr(format, intPtr, fDeleteOld: false);
			return intPtr;
		}

		public static WaveFormat FromFormatChunk(BinaryReader br, int formatChunkLength)
		{
			WaveFormatExtraData waveFormatExtraData = new WaveFormatExtraData();
			waveFormatExtraData.ReadWaveFormat(br, formatChunkLength);
			waveFormatExtraData.ReadExtraData(br);
			return waveFormatExtraData;
		}

		private void ReadWaveFormat(BinaryReader br, int formatChunkLength)
		{
			if (formatChunkLength < 16)
			{
				throw new InvalidDataException("Invalid WaveFormat Structure");
			}
			waveFormatTag = (WaveFormatEncoding)br.ReadUInt16();
			channels = br.ReadInt16();
			sampleRate = br.ReadInt32();
			averageBytesPerSecond = br.ReadInt32();
			blockAlign = br.ReadInt16();
			bitsPerSample = br.ReadInt16();
			if (formatChunkLength > 16)
			{
				extraSize = br.ReadInt16();
				if (extraSize != formatChunkLength - 18)
				{
					extraSize = (short)(formatChunkLength - 18);
				}
			}
		}

		public WaveFormat(BinaryReader br)
		{
			int formatChunkLength = br.ReadInt32();
			ReadWaveFormat(br, formatChunkLength);
		}

		public override string ToString()
		{
			switch (waveFormatTag)
			{
			case WaveFormatEncoding.Pcm:
			case WaveFormatEncoding.Extensible:
				return $"{bitsPerSample} bit PCM: {sampleRate}Hz {channels} channels";
			case WaveFormatEncoding.IeeeFloat:
				return $"{bitsPerSample} bit IEEFloat: {sampleRate}Hz {channels} channels";
			default:
				return waveFormatTag.ToString();
			}
		}

		public override bool Equals(object obj)
		{
			if (obj is WaveFormat waveFormat)
			{
				if (waveFormatTag == waveFormat.waveFormatTag && channels == waveFormat.channels && sampleRate == waveFormat.sampleRate && averageBytesPerSecond == waveFormat.averageBytesPerSecond && blockAlign == waveFormat.blockAlign)
				{
					return bitsPerSample == waveFormat.bitsPerSample;
				}
				return false;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return (int)waveFormatTag ^ (int)channels ^ sampleRate ^ averageBytesPerSecond ^ blockAlign ^ bitsPerSample;
		}

		public virtual void Serialize(BinaryWriter writer)
		{
			writer.Write(18 + extraSize);
			writer.Write((short)Encoding);
			writer.Write((short)Channels);
			writer.Write(SampleRate);
			writer.Write(AverageBytesPerSecond);
			writer.Write((short)BlockAlign);
			writer.Write((short)BitsPerSample);
			writer.Write(extraSize);
		}
	}
	public sealed class WaveFormatCustomMarshaler : ICustomMarshaler
	{
		private static WaveFormatCustomMarshaler marshaler;

		public static ICustomMarshaler GetInstance(string cookie)
		{
			if (marshaler == null)
			{
				marshaler = new WaveFormatCustomMarshaler();
			}
			return marshaler;
		}

		public void CleanUpManagedData(object ManagedObj)
		{
		}

		public void CleanUpNativeData(IntPtr pNativeData)
		{
			Marshal.FreeHGlobal(pNativeData);
		}

		public int GetNativeDataSize()
		{
			throw new NotImplementedException();
		}

		public IntPtr MarshalManagedToNative(object ManagedObj)
		{
			return WaveFormat.MarshalToPtr((WaveFormat)ManagedObj);
		}

		public object MarshalNativeToManaged(IntPtr pNativeData)
		{
			return WaveFormat.MarshalFromPtr(pNativeData);
		}
	}
	public enum WaveFormatEncoding : ushort
	{
		Unknown = 0,
		Pcm = 1,
		Adpcm = 2,
		IeeeFloat = 3,
		Vselp = 4,
		IbmCvsd = 5,
		ALaw = 6,
		MuLaw = 7,
		Dts = 8,
		Drm = 9,
		WmaVoice9 = 10,
		OkiAdpcm = 16,
		DviAdpcm = 17,
		ImaAdpcm = 17,
		MediaspaceAdpcm = 18,
		SierraAdpcm = 19,
		G723Adpcm = 20,
		DigiStd = 21,
		DigiFix = 22,
		DialogicOkiAdpcm = 23,
		MediaVisionAdpcm = 24,
		CUCodec = 25,
		YamahaAdpcm = 32,
		SonarC = 33,
		DspGroupTrueSpeech = 34,
		EchoSpeechCorporation1 = 35,
		AudioFileAf36 = 36,
		Aptx = 37,
		AudioFileAf10 = 38,
		Prosody1612 = 39,
		Lrc = 40,
		DolbyAc2 = 48,
		Gsm610 = 49,
		MsnAudio = 50,
		AntexAdpcme = 51,
		ControlResVqlpc = 52,
		DigiReal = 53,
		DigiAdpcm = 54,
		ControlResCr10 = 55,
		WAVE_FORMAT_NMS_VBXADPCM = 56,
		WAVE_FORMAT_CS_IMAADPCM = 57,
		WAVE_FORMAT_ECHOSC3 = 58,
		WAVE_FORMAT_ROCKWELL_ADPCM = 59,
		WAVE_FORMAT_ROCKWELL_DIGITALK = 60,
		WAVE_FORMAT_XEBEC = 61,
		WAVE_FORMAT_G721_ADPCM = 64,
		WAVE_FORMAT_G728_CELP = 65,
		WAVE_FORMAT_MSG723 = 66,
		Mpeg = 80,
		WAVE_FORMAT_RT24 = 82,
		WAVE_FORMAT_PAC = 83,
		MpegLayer3 = 85,
		WAVE_FORMAT_LUCENT_G723 = 89,
		WAVE_FORMAT_CIRRUS = 96,
		WAVE_FORMAT_ESPCM = 97,
		WAVE_FORMAT_VOXWARE = 98,
		WAVE_FORMAT_CANOPUS_ATRAC = 99,
		WAVE_FORMAT_G726_ADPCM = 100,
		WAVE_FORMAT_G722_ADPCM = 101,
		WAVE_FORMAT_DSAT_DISPLAY = 103,
		WAVE_FORMAT_VOXWARE_BYTE_ALIGNED = 105,
		WAVE_FORMAT_VOXWARE_AC8 = 112,
		WAVE_FORMAT_VOXWARE_AC10 = 113,
		WAVE_FORMAT_VOXWARE_AC16 = 114,
		WAVE_FORMAT_VOXWARE_AC20 = 115,
		WAVE_FORMAT_VOXWARE_RT24 = 116,
		WAVE_FORMAT_VOXWARE_RT29 = 117,
		WAVE_FORMAT_VOXWARE_RT29HW = 118,
		WAVE_FORMAT_VOXWARE_VR12 = 119,
		WAVE_FORMAT_VOXWARE_VR18 = 120,
		WAVE_FORMAT_VOXWARE_TQ40 = 121,
		WAVE_FORMAT_SOFTSOUND = 128,
		WAVE_FORMAT_VOXWARE_TQ60 = 129,
		WAVE_FORMAT_MSRT24 = 130,
		WAVE_FORMAT_G729A = 131,
		WAVE_FORMAT_MVI_MVI2 = 132,
		WAVE_FORMAT_DF_G726 = 133,
		WAVE_FORMAT_DF_GSM610 = 134,
		WAVE_FORMAT_ISIAUDIO = 136,
		WAVE_FORMAT_ONLIVE = 137,
		WAVE_FORMAT_SBC24 = 145,
		WAVE_FORMAT_DOLBY_AC3_SPDIF = 146,
		WAVE_FORMAT_MEDIASONIC_G723 = 147,
		WAVE_FORMAT_PROSODY_8KBPS = 148,
		WAVE_FORMAT_ZYXEL_ADPCM = 151,
		WAVE_FORMAT_PHILIPS_LPCBB = 152,
		WAVE_FORMAT_PACKED = 153,
		WAVE_FORMAT_MALDEN_PHONYTALK = 160,
		Gsm = 161,
		G729 = 162,
		G723 = 163,
		Acelp = 164,
		RawAac = 255,
		WAVE_FORMAT_RHETOREX_ADPCM = 256,
		WAVE_FORMAT_IRAT = 257,
		WAVE_FORMAT_VIVO_G723 = 273,
		WAVE_FORMAT_VIVO_SIREN = 274,
		WAVE_FORMAT_DIGITAL_G723 = 291,
		WAVE_FORMAT_SANYO_LD_ADPCM = 293,
		WAVE_FORMAT_SIPROLAB_ACEPLNET = 304,
		WAVE_FORMAT_SIPROLAB_ACELP4800 = 305,
		WAVE_FORMAT_SIPROLAB_ACELP8V3 = 306,
		WAVE_FORMAT_SIPROLAB_G729 = 307,
		WAVE_FORMAT_SIPROLAB_G729A = 308,
		WAVE_FORMAT_SIPROLAB_KELVIN = 309,
		WAVE_FORMAT_G726ADPCM = 320,
		WAVE_FORMAT_QUALCOMM_PUREVOICE = 336,
		WAVE_FORMAT_QUALCOMM_HALFRATE = 337,
		WAVE_FORMAT_TUBGSM = 341,
		WAVE_FORMAT_MSAUDIO1 = 352,
		WindowsMediaAudio = 353,
		WindowsMediaAudioProfessional = 354,
		WindowsMediaAudioLosseless = 355,
		WindowsMediaAudioSpdif = 356,
		WAVE_FORMAT_UNISYS_NAP_ADPCM = 368,
		WAVE_FORMAT_UNISYS_NAP_ULAW = 369,
		WAVE_FORMAT_UNISYS_NAP_ALAW = 370,
		WAVE_FORMAT_UNISYS_NAP_16K = 371,
		WAVE_FORMAT_CREATIVE_ADPCM = 512,
		WAVE_FORMAT_CREATIVE_FASTSPEECH8 = 514,
		WAVE_FORMAT_CREATIVE_FASTSPEECH10 = 515,
		WAVE_FORMAT_UHER_ADPCM = 528,
		WAVE_FORMAT_QUARTERDECK = 544,
		WAVE_FORMAT_ILINK_VC = 560,
		WAVE_FORMAT_RAW_SPORT = 576,
		WAVE_FORMAT_ESST_AC3 = 577,
		WAVE_FORMAT_IPI_HSX = 592,
		WAVE_FORMAT_IPI_RPELP = 593,
		WAVE_FORMAT_CS2 = 608,
		WAVE_FORMAT_SONY_SCX = 624,
		WAVE_FORMAT_FM_TOWNS_SND = 768,
		WAVE_FORMAT_BTV_DIGITAL = 1024,
		WAVE_FORMAT_QDESIGN_MUSIC = 1104,
		WAVE_FORMAT_VME_VMPCM = 1664,
		WAVE_FORMAT_TPC = 1665,
		WAVE_FORMAT_OLIGSM = 4096,
		WAVE_FORMAT_OLIADPCM = 4097,
		WAVE_FORMAT_OLICELP = 4098,
		WAVE_FORMAT_OLISBC = 4099,
		WAVE_FORMAT_OLIOPR = 4100,
		WAVE_FORMAT_LH_CODEC = 4352,
		WAVE_FORMAT_NORRIS = 5120,
		WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS = 5376,
		MPEG_ADTS_AAC = 5632,
		MPEG_RAW_AAC = 5633,
		MPEG_LOAS = 5634,
		NOKIA_MPEG_ADTS_AAC = 5640,
		NOKIA_MPEG_RAW_AAC = 5641,
		VODAFONE_MPEG_ADTS_AAC = 5642,
		VODAFONE_MPEG_RAW_AAC = 5643,
		MPEG_HEAAC = 5648,
		WAVE_FORMAT_DVM = 8192,
		Vorbis1 = 26447,
		Vorbis2 = 26448,
		Vorbis3 = 26449,
		Vorbis1P = 26479,
		Vorbis2P = 26480,
		Vorbis3P = 26481,
		Extensible = 65534,
		WAVE_FORMAT_DEVELOPMENT = ushort.MaxValue
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class WaveFormatExtensible : WaveFormat
	{
		private short wValidBitsPerSample;

		private int dwChannelMask;

		private Guid subFormat;

		public Guid SubFormat => subFormat;

		private WaveFormatExtensible()
		{
		}

		public WaveFormatExtensible(int rate, int bits, int channels)
			: base(rate, bits, channels)
		{
			waveFormatTag = WaveFormatEncoding.Extensible;
			extraSize = 22;
			wValidBitsPerSample = (short)bits;
			for (int i = 0; i < channels; i++)
			{
				dwChannelMask |= 1 << i;
			}
			if (bits == 32)
			{
				subFormat = AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT;
			}
			else
			{
				subFormat = AudioMediaSubtypes.MEDIASUBTYPE_PCM;
			}
		}

		public WaveFormat ToStandardWaveFormat()
		{
			if (subFormat == AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT && bitsPerSample == 32)
			{
				return WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channels);
			}
			if (subFormat == AudioMediaSubtypes.MEDIASUBTYPE_PCM)
			{
				return new WaveFormat(sampleRate, bitsPerSample, channels);
			}
			return this;
		}

		public override void Serialize(BinaryWriter writer)
		{
			base.Serialize(writer);
			writer.Write(wValidBitsPerSample);
			writer.Write(dwChannelMask);
			byte[] array = subFormat.ToByteArray();
			writer.Write(array, 0, array.Length);
		}

		public override string ToString()
		{
			return "WAVE_FORMAT_EXTENSIBLE " + AudioMediaSubtypes.GetAudioSubtypeName(subFormat) + " " + $"{base.SampleRate}Hz {base.Channels} channels {base.BitsPerSample} bit";
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class WaveFormatExtraData : WaveFormat
	{
		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
		private byte[] extraData = new byte[100];

		public byte[] ExtraData => extraData;

		internal WaveFormatExtraData()
		{
		}

		public WaveFormatExtraData(BinaryReader reader)
			: base(reader)
		{
			ReadExtraData(reader);
		}

		internal void ReadExtraData(BinaryReader reader)
		{
			if (extraSize > 0)
			{
				reader.Read(extraData, 0, extraSize);
			}
		}

		public override void Serialize(BinaryWriter writer)
		{
			base.Serialize(writer);
			if (extraSize > 0)
			{
				writer.Write(extraData, 0, extraSize);
			}
		}
	}
	public interface IWaveIn : IDisposable
	{
		WaveFormat WaveFormat { get; set; }

		event EventHandler<WaveInEventArgs> DataAvailable;

		event EventHandler<StoppedEventArgs> RecordingStopped;

		void StartRecording();

		void StopRecording();
	}
	public class WaveInEventArgs : EventArgs
	{
		private byte[] buffer;

		private int bytes;

		public byte[] Buffer => buffer;

		public int BytesRecorded => bytes;

		public WaveInEventArgs(byte[] buffer, int bytes)
		{
			this.buffer = buffer;
			this.bytes = bytes;
		}
	}
	public class AiffFileWriter : Stream
	{
		private Stream outStream;

		private BinaryWriter writer;

		private long dataSizePos;

		private long commSampleCountPos;

		private long dataChunkSize = 8L;

		private WaveFormat format;

		private string filename;

		private byte[] value24 = new byte[3];

		public string Filename => filename;

		public override long Length => dataChunkSize;

		public WaveFormat WaveFormat => format;

		public override bool CanRead => false;

		public override bool CanWrite => true;

		public override bool CanSeek => false;

		public override long Position
		{
			get
			{
				return dataChunkSize;
			}
			set
			{
				throw new InvalidOperationException("Repositioning an AiffFileWriter is not supported");
			}
		}

		public static void CreateAiffFile(string filename, WaveStream sourceProvider)
		{
			using AiffFileWriter aiffFileWriter = new AiffFileWriter(filename, sourceProvider.WaveFormat);
			byte[] array = new byte[16384];
			while (sourceProvider.Position < sourceProvider.Length)
			{
				int count = Math.Min((int)(sourceProvider.Length - sourceProvider.Position), array.Length);
				int num = sourceProvider.Read(array, 0, count);
				if (num == 0)
				{
					break;
				}
				aiffFileWriter.Write(array, 0, num);
			}
		}

		public AiffFileWriter(Stream outStream, WaveFormat format)
		{
			this.outStream = outStream;
			this.format = format;
			writer = new BinaryWriter(outStream, Encoding.UTF8);
			writer.Write(Encoding.UTF8.GetBytes("FORM"));
			writer.Write(0);
			writer.Write(Encoding.UTF8.GetBytes("AIFF"));
			CreateCommChunk();
			WriteSsndChunkHeader();
		}

		public AiffFileWriter(string filename, WaveFormat format)
			: this(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read), format)
		{
			this.filename = filename;
		}

		private void WriteSsndChunkHeader()
		{
			writer.Write(Encoding.UTF8.GetBytes("SSND"));
			dataSizePos = outStream.Position;
			writer.Write(0);
			writer.Write(0);
			writer.Write(SwapEndian(format.BlockAlign));
		}

		private byte[] SwapEndian(short n)
		{
			return new byte[2]
			{
				(byte)(n >> 8),
				(byte)((uint)n & 0xFFu)
			};
		}

		private byte[] SwapEndian(int n)
		{
			return new byte[4]
			{
				(byte)((uint)(n >> 24) & 0xFFu),
				(byte)((uint)(n >> 16) & 0xFFu),
				(byte)((uint)(n >> 8) & 0xFFu),
				(byte)((uint)n & 0xFFu)
			};
		}

		private void CreateCommChunk()
		{
			writer.Write(Encoding.UTF8.GetBytes("COMM"));
			writer.Write(SwapEndian(18));
			writer.Write(SwapEndian((short)format.Channels));
			commSampleCountPos = outStream.Position;
			writer.Write(0);
			writer.Write(SwapEndian((short)format.BitsPerSample));
			writer.Write(IEEE.ConvertToIeeeExtended(format.SampleRate));
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			throw new InvalidOperationException("Cannot read from an AiffFileWriter");
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			throw new InvalidOperationException("Cannot seek within an AiffFileWriter");
		}

		public override void SetLength(long value)
		{
			throw new InvalidOperationException("Cannot set length of an AiffFileWriter");
		}

		public override void Write(byte[] data, int offset, int count)
		{
			byte[] array = new byte[data.Length];
			int num = format.BitsPerSample / 8;
			for (int i = 0; i < data.Length; i++)
			{
				int num2 = (int)Math.Floor((double)i / (double)num) * num + (num - i % num - 1);
				array[i] = data[num2];
			}
			outStream.Write(array, offset, count);
			dataChunkSize += count;
		}

		public void WriteSample(float sample)
		{
			if (WaveFormat.BitsPerSample == 16)
			{
				writer.Write(SwapEndian((short)(32767f * sample)));
				dataChunkSize += 2L;
			}
			else if (WaveFormat.BitsPerSample == 24)
			{
				byte[] bytes = BitConverter.GetBytes((int)(2.1474836E+09f * sample));
				value24[2] = bytes[1];
				value24[1] = bytes[2];
				value24[0] = bytes[3];
				writer.Write(value24);
				dataChunkSize += 3L;
			}
			else
			{
				if (WaveFormat.BitsPerSample != 32 || WaveFormat.Encoding != WaveFormatEncoding.Extensible)
				{
					throw new InvalidOperationException("Only 16, 24 or 32 bit PCM or IEEE float audio data supported");
				}
				writer.Write(SwapEndian(65535 * (int)sample));
				dataChunkSize += 4L;
			}
		}

		public void WriteSamples(float[] samples, int offset, int count)
		{
			for (int i = 0; i < count; i++)
			{
				WriteSample(samples[offset + i]);
			}
		}

		public void WriteSamples(short[] samples, int offset, int count)
		{
			if (WaveFormat.BitsPerSample == 16)
			{
				for (int i = 0; i < count; i++)
				{
					writer.Write(SwapEndian(samples[i + offset]));
				}
				dataChunkSize += count * 2;
			}
			else if (WaveFormat.BitsPerSample == 24)
			{
				for (int j = 0; j < count; j++)
				{
					byte[] bytes = BitConverter.GetBytes(65535 * samples[j + offset]);
					value24[2] = bytes[1];
					value24[1] = bytes[2];
					value24[0] = bytes[3];
					writer.Write(value24);
				}
				dataChunkSize += count * 3;
			}
			else
			{
				if (WaveFormat.BitsPerSample != 32 || WaveFormat.Encoding != WaveFormatEncoding.Extensible)
				{
					throw new InvalidOperationException("Only 16, 24 or 32 bit PCM audio data supported");
				}
				for (int k = 0; k < count; k++)
				{
					writer.Write(SwapEndian(65535 * samples[k + offset]));
				}
				dataChunkSize += count * 4;
			}
		}

		public override void Flush()
		{
			writer.Flush();
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && outStream != null)
			{
				try
				{
					UpdateHeader(writer);
				}
				finally
				{
					outStream.Dispose();
					outStream = null;
				}
			}
		}

		protected virtual void UpdateHeader(BinaryWriter writer)
		{
			Flush();
			writer.Seek(4, SeekOrigin.Begin);
			writer.Write(SwapEndian((int)(outStream.Length - 8)));
			UpdateCommChunk(writer);
			UpdateSsndChunk(writer);
		}

		private void UpdateCommChunk(BinaryWriter writer)
		{
			writer.Seek((int)commSampleCountPos, SeekOrigin.Begin);
			writer.Write(SwapEndian((int)(dataChunkSize * 8 / format.BitsPerSample / format.Channels)));
		}

		private void UpdateSsndChunk(BinaryWriter writer)
		{
			writer.Seek((int)dataSizePos, SeekOrigin.Begin);
			writer.Write(SwapEndian((int)dataChunkSize));
		}

		~AiffFileWriter()
		{
			Dispose(disposing: false);
		}
	}
	public class BextChunkInfo
	{
		public string Description { get; set; }

		public string Originator { get; set; }

		public string OriginatorReference { get; set; }

		public DateTime OriginationDateTime { get; set; }

		public string OriginationDate => OriginationDateTime.ToString("yyyy-MM-dd");

		public string OriginationTime => OriginationDateTime.ToString("HH:mm:ss");

		public long TimeReference { get; set; }

		public ushort Version => 1;

		public string UniqueMaterialIdentifier { get; set; }

		public byte[] Reserved { get; }

		public string CodingHistory { get; set; }

		public BextChunkInfo()
		{
			Reserved = new byte[190];
		}
	}
	public class BwfWriter : IDisposable
	{
		private readonly WaveFormat format;

		private readonly BinaryWriter writer;

		private readonly long dataChunkSizePosition;

		private long dataLength;

		private bool isDisposed;

		public BwfWriter(string filename, WaveFormat format, BextChunkInfo bextChunkInfo)
		{
			this.format = format;
			writer = new BinaryWriter(File.OpenWrite(filename));
			writer.Write(Encoding.UTF8.GetBytes("RIFF"));
			writer.Write(0);
			writer.Write(Encoding.UTF8.GetBytes("WAVE"));
			writer.Write(Encoding.UTF8.GetBytes("JUNK"));
			writer.Write(28);
			writer.Write(0L);
			writer.Write(0L);
			writer.Write(0L);
			writer.Write(0);
			writer.Write(Encoding.UTF8.GetBytes("bext"));
			byte[] bytes = Encoding.ASCII.GetBytes(bextChunkInfo.CodingHistory ?? "");
			int num = 602 + bytes.Length;
			if (num % 2 != 0)
			{
				num++;
			}
			writer.Write(num);
			_ = writer.BaseStream.Position;
			writer.Write(GetAsBytes(bextChunkInfo.Description, 256));
			writer.Write(GetAsBytes(bextChunkInfo.Originator, 32));
			writer.Write(GetAsBytes(bextChunkInfo.OriginatorReference, 32));
			writer.Write(GetAsBytes(bextChunkInfo.OriginationDate, 10));
			writer.Write(GetAsBytes(bextChunkInfo.OriginationTime, 8));
			writer.Write(bextChunkInfo.TimeReference);
			writer.Write(bextChunkInfo.Version);
			writer.Write(GetAsBytes(bextChunkInfo.UniqueMaterialIdentifier, 64));
			writer.Write(bextChunkInfo.Reserved);
			writer.Write(bytes);
			if (bytes.Length % 2 != 0)
			{
				writer.Write((byte)0);
			}
			writer.Write(Encoding.UTF8.GetBytes("fmt "));
			format.Serialize(writer);
			writer.Write(Encoding.UTF8.GetBytes("data"));
			dataChunkSizePosition = writer.BaseStream.Position;
			writer.Write(-1);
		}

		public void Write(byte[] buffer, int offset, int count)
		{
			if (isDisposed)
			{
				throw new ObjectDisposedException("This BWF Writer already disposed");
			}
			writer.Write(buffer, offset, count);
			dataLength += count;
		}

		public void Flush()
		{
			if (isDisposed)
			{
				throw new ObjectDisposedException("This BWF Writer already disposed");
			}
			writer.Flush();
			FixUpChunkSizes(restorePosition: true);
		}

		private void FixUpChunkSizes(bool restorePosition)
		{
			long position = writer.BaseStream.Position;
			bool num = dataLength > int.MaxValue;
			long num2 = writer.BaseStream.Length - 8;
			if (num)
			{
				int num3 = format.BitsPerSample / 8 * format.Channels;
				writer.BaseStream.Position = 0L;
				writer.Write(Encoding.UTF8.GetBytes("RF64"));
				writer.Write(-1);
				writer.BaseStream.Position += 4L;
				writer.Write(Encoding.UTF8.GetBytes("ds64"));
				writer.BaseStream.Position += 4L;
				writer.Write(num2);
				writer.Write(dataLength);
				writer.Write(dataLength / num3);
			}
			else
			{
				writer.BaseStream.Position = 4L;
				writer.Write((uint)num2);
				writer.BaseStream.Position = dataChunkSizePosition;
				writer.Write((uint)dataLength);
			}
			if (restorePosition)
			{
				writer.BaseStream.Position = position;
			}
		}

		public void Dispose()
		{
			if (!isDisposed)
			{
				FixUpChunkSizes(restorePosition: false);
				writer.Dispose();
				isDisposed = true;
			}
		}

		private static byte[] GetAsBytes(string message, int byteSize)
		{
			byte[] array = new byte[byteSize];
			byte[] bytes = Encoding.ASCII.GetBytes(message ?? "");
			Array.Copy(bytes, array, Math.Min(bytes.Length, byteSize));
			return array;
		}
	}
	public class CueWaveFileWriter : WaveFileWriter
	{
		private CueList cues;

		public CueWaveFileWriter(string fileName, WaveFormat waveFormat)
			: base(fileName, waveFormat)
		{
		}

		public void AddCue(int position, string label)
		{
			if (cues == null)
			{
				cues = new CueList();
			}
			cues.Add(new Cue(position, label));
		}

		private void WriteCues(BinaryWriter w)
		{
			if (cues != null)
			{
				int count = cues.GetRiffChunks().Length;
				w.Seek(0, SeekOrigin.End);
				if (w.BaseStream.Length % 2 == 1)
				{
					w.Write((byte)0);
				}
				w.Write(cues.GetRiffChunks(), 0, count);
				w.Seek(4, SeekOrigin.Begin);
				w.Write((int)(w.BaseStream.Length - 8));
			}
		}

		protected override void UpdateHeader(BinaryWriter writer)
		{
			base.UpdateHeader(writer);
			WriteCues(writer);
		}
	}
	public class DirectSoundOut : IWavePlayer, IDisposable
	{
		[StructLayout(LayoutKind.Sequential, Pack = 2)]
		internal class BufferDescription
		{
			public int dwSize;

			[MarshalAs(UnmanagedType.U4)]
			public DirectSoundBufferCaps dwFlags;

			public uint dwBufferBytes;

			public int dwReserved;

			public IntPtr lpwfxFormat;

			public Guid guidAlgo;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 2)]
		internal class BufferCaps
		{
			public int dwSize;

			public int dwFlags;

			public int dwBufferBytes;

			public int dwUnlockTransferRate;

			public int dwPlayCpuOverhead;
		}

		internal enum DirectSoundCooperativeLevel : uint
		{
			DSSCL_NORMAL = 1u,
			DSSCL_PRIORITY,
			DSSCL_EXCLUSIVE,
			DSSCL_WRITEPRIMARY
		}

		[Flags]
		internal enum DirectSoundPlayFlags : uint
		{
			DSBPLAY_LOOPING = 1u,
			DSBPLAY_LOCHARDWARE = 2u,
			DSBPLAY_LOCSOFTWARE = 4u,
			DSBPLAY_TERMINATEBY_TIME = 8u,
			DSBPLAY_TERMINATEBY_DISTANCE = 0x10u,
			DSBPLAY_TERMINATEBY_PRIORITY = 0x20u
		}

		internal enum DirectSoundBufferLockFlag : uint
		{
			None,
			FromWriteCursor,
			EntireBuffer
		}

		[Flags]
		internal enum DirectSoundBufferStatus : uint
		{
			DSBSTATUS_PLAYING = 1u,
			DSBSTATUS_BUFFERLOST = 2u,
			DSBSTATUS_LOOPING = 4u,
			DSBSTATUS_LOCHARDWARE = 8u,
			DSBSTATUS_LOCSOFTWARE = 0x10u,
			DSBSTATUS_TERMINATED = 0x20u
		}

		[Flags]
		internal enum DirectSoundBufferCaps : uint
		{
			DSBCAPS_PRIMARYBUFFER = 1u,
			DSBCAPS_STATIC = 2u,
			DSBCAPS_LOCHARDWARE = 4u,
			DSBCAPS_LOCSOFTWARE = 8u,
			DSBCAPS_CTRL3D = 0x10u,
			DSBCAPS_CTRLFREQUENCY = 0x20u,
			DSBCAPS_CTRLPAN = 0x40u,
			DSBCAPS_CTRLVOLUME = 0x80u,
			DSBCAPS_CTRLPOSITIONNOTIFY = 0x100u,
			DSBCAPS_CTRLFX = 0x200u,
			DSBCAPS_STICKYFOCUS = 0x4000u,
			DSBCAPS_GLOBALFOCUS = 0x8000u,
			DSBCAPS_GETCURRENTPOSITION2 = 0x10000u,
			DSBCAPS_MUTE3DATMAXDISTANCE = 0x20000u,
			DSBCAPS_LOCDEFER = 0x40000u
		}

		internal struct DirectSoundBufferPositionNotify
		{
			public uint dwOffset;

			public IntPtr hEventNotify;
		}

		[ComImport]
		[Guid("279AFA83-4981-11CE-A521-0020AF0BE560")]
		[SuppressUnmanagedCodeSecurity]
		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
		internal interface IDirectSound
		{
			void CreateSoundBuffer([In] BufferDescription desc, [MarshalAs(UnmanagedType.Interface)] out object dsDSoundBuffer, IntPtr pUnkOuter);

			void GetCaps(IntPtr caps);

			void DuplicateSoundBuffer([In][MarshalAs(UnmanagedType.Interface)] IDirectSoundBuffer bufferOriginal, [In][MarshalAs(UnmanagedType.Interface)] IDirectSoundBuffer bufferDuplicate);

			void SetCooperativeLevel(IntPtr HWND, [In][MarshalAs(UnmanagedType.U4)] DirectSoundCooperativeLevel dwLevel);

			void Compact();

			void GetSpeakerConfig(IntPtr pdwSpeakerConfig);

			void SetSpeakerConfig(uint pdwSpeakerConfig);

			void Initialize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guid);
		}

		[ComImport]
		[Guid("279AFA85-4981-11CE-A521-0020AF0BE560")]
		[SuppressUnmanagedCodeSecurity]
		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
		internal interface IDirectSoundBuffer
		{
			void GetCaps([MarshalAs(UnmanagedType.LPStruct)] BufferCaps pBufferCaps);

			void GetCurrentPosition(out uint currentPlayCursor, out uint currentWriteCursor);

			void GetFormat();

			[return: MarshalAs(UnmanagedType.I4)]
			int GetVolume();

			void GetPan(out uint pan);

			[return: MarshalAs(UnmanagedType.I4)]
			int GetFrequency();

			[return: MarshalAs(UnmanagedType.U4)]
			DirectSoundBufferStatus GetStatus();

			void Initialize([In][MarshalAs(UnmanagedType.Interface)] IDirectSound directSound, [In] BufferDescription desc);

			void Lock(int dwOffset, uint dwBytes, out IntPtr audioPtr1, out int audioBytes1, out IntPtr audioPtr2, out int audioBytes2, [MarshalAs(UnmanagedType.U4)] DirectSoundBufferLockFlag dwFlags);

			void Play(uint dwReserved1, uint dwPriority, [In][MarshalAs(UnmanagedType.U4)] DirectSoundPlayFlags dwFlags);

			void SetCurrentPosition(uint dwNewPosition);

			void SetFormat([In] WaveFormat pcfxFormat);

			void SetVolume(int volume);

			void SetPan(uint pan);

			void SetFrequency(uint frequency);

			void Stop();

			void Unlock(IntPtr pvAudioPtr1, int dwAudioBytes1, IntPtr pvAudioPtr2, int dwAudioBytes2);

			void Restore();
		}

		[ComImport]
		[Guid("b0210783-89cd-11d0-af08-00a0c925cd16")]
		[SuppressUnmanagedCodeSecurity]
		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
		internal interface IDirectSoundNotify
		{
			void SetNotificationPositions(uint dwPositionNotifies, [In][MarshalAs(UnmanagedType.LPArray)] DirectSoundBufferPositionNotify[] pcPositionNotifies);
		}

		private delegate bool DSEnumCallback(IntPtr lpGuid, IntPtr lpcstrDescription, IntPtr lpcstrModule, IntPtr lpContext);

		private PlaybackState playbackState;

		private WaveFormat waveFormat;

		private int samplesTotalSize;

		private int samplesFrameSize;

		private int nextSamplesWriteIndex;

		private int desiredLatency;

		private Guid device;

		private byte[] samples;

		private IWaveProvider waveStream;

		private IDirectSound directSound;

		private IDirectSoundBuffer primarySoundBuffer;

		private IDirectSoundBuffer sec

plugins/NAudio.WinMM.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading;
using Microsoft.Win32;
using NAudio.CoreAudioApi;
using NAudio.Mixer;
using NAudio.Utils;
using NAudio.Wave.Compression;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("NAudio.WinMM")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Mark Heath 2023")]
[assembly: AssemblyFileVersion("2.2.1.0")]
[assembly: AssemblyInformationalVersion("2.2.1")]
[assembly: AssemblyProduct("NAudio.WinMM")]
[assembly: AssemblyTitle("NAudio.WinMM")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")]
[assembly: AssemblyVersion("2.2.1.0")]
namespace NAudio.Mixer
{
	public class BooleanMixerControl : MixerControl
	{
		private MixerInterop.MIXERCONTROLDETAILS_BOOLEAN boolDetails;

		public bool Value
		{
			get
			{
				GetControlDetails();
				return boolDetails.fValue == 1;
			}
			set
			{
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				boolDetails.fValue = (value ? 1 : 0);
				mixerControlDetails.paDetails = Marshal.AllocHGlobal(Marshal.SizeOf(boolDetails));
				Marshal.StructureToPtr(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 = Marshal.PtrToStructure<MixerInterop.MIXERCONTROLDETAILS_BOOLEAN>(pDetails);
		}
	}
	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)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (mixerIndex < 0 || mixerIndex >= NumberOfDevices)
			{
				throw new ArgumentOutOfRangeException("mixerID");
			}
			caps = default(MixerInterop.MIXERCAPS);
			MmException.Try(MixerInterop.mixerGetDevCaps((IntPtr)mixerIndex, ref caps, Marshal.SizeOf(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)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			List<MixerControl> list = new List<MixerControl>();
			if (mixerLine.ControlsCount > 0)
			{
				int num = Marshal.SizeOf<MixerInterop.MIXERCONTROL>();
				MixerInterop.MIXERLINECONTROLS mixerLineControls = default(MixerInterop.MIXERLINECONTROLS);
				IntPtr intPtr = Marshal.AllocHGlobal(num * mixerLine.ControlsCount);
				mixerLineControls.cbStruct = Marshal.SizeOf(mixerLineControls);
				mixerLineControls.dwLineID = mixerLine.LineId;
				mixerLineControls.cControls = mixerLine.ControlsCount;
				mixerLineControls.pamxctrl = intPtr;
				mixerLineControls.cbmxctrl = Marshal.SizeOf<MixerInterop.MIXERCONTROL>();
				try
				{
					MmResult val = MixerInterop.mixerGetLineControls(mixerHandle, ref mixerLineControls, MixerFlags.Mixer | mixerHandleType);
					if ((int)val != 0)
					{
						throw new MmException(val, "mixerGetLineControls");
					}
					for (int i = 0; i < mixerLineControls.cControls; i++)
					{
						MixerInterop.MIXERCONTROL mIXERCONTROL = Marshal.PtrToStructure<MixerInterop.MIXERCONTROL>((IntPtr)(intPtr.ToInt64() + num * i));
						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)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			MixerInterop.MIXERLINECONTROLS mixerLineControls = default(MixerInterop.MIXERLINECONTROLS);
			MixerInterop.MIXERCONTROL structure = default(MixerInterop.MIXERCONTROL);
			IntPtr intPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(structure));
			mixerLineControls.cbStruct = Marshal.SizeOf(mixerLineControls);
			mixerLineControls.cControls = 1;
			mixerLineControls.dwControlID = controlId;
			mixerLineControls.cbmxctrl = Marshal.SizeOf(structure);
			mixerLineControls.pamxctrl = intPtr;
			mixerLineControls.dwLineID = nLineId;
			MmResult val = MixerInterop.mixerGetLineControls(mixerHandle, ref mixerLineControls, MixerFlags.ListText | mixerFlags);
			if ((int)val != 0)
			{
				Marshal.FreeCoTaskMem(intPtr);
				throw new MmException(val, "mixerGetLineControls");
			}
			structure = Marshal.PtrToStructure<MixerInterop.MIXERCONTROL>(mixerLineControls.pamxctrl);
			Marshal.FreeCoTaskMem(intPtr);
			if (IsControlBoolean(structure.dwControlType))
			{
				return new BooleanMixerControl(structure, mixerHandle, mixerFlags, nChannels);
			}
			if (IsControlSigned(structure.dwControlType))
			{
				return new SignedMixerControl(structure, mixerHandle, mixerFlags, nChannels);
			}
			if (IsControlUnsigned(structure.dwControlType))
			{
				return new UnsignedMixerControl(structure, mixerHandle, mixerFlags, nChannels);
			}
			if (IsControlListText(structure.dwControlType))
			{
				return new ListTextMixerControl(structure, mixerHandle, mixerFlags, nChannels);
			}
			if (IsControlCustom(structure.dwControlType))
			{
				return new CustomMixerControl(structure, mixerHandle, mixerFlags, nChannels);
			}
			throw new InvalidOperationException($"Unknown mixer control type {structure.dwControlType}");
		}

		protected void GetControlDetails()
		{
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			mixerControlDetails.cbStruct = Marshal.SizeOf(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<MixerInterop.MIXERCONTROLDETAILS_BOOLEAN>();
			}
			else if (IsListText)
			{
				mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_LISTTEXT>();
			}
			else if (IsSigned)
			{
				mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_SIGNED>();
			}
			else if (IsUnsigned)
			{
				mixerControlDetails.cbDetails = Marshal.SizeOf<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 val = MixerInterop.mixerGetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType);
			if ((int)val == 0)
			{
				GetDetails(mixerControlDetails.paDetails);
			}
			Marshal.FreeCoTaskMem(intPtr);
			if ((int)val != 0)
			{
				throw new MmException(val, "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
	}
	[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 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)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			this.mixerHandle = mixerHandle;
			this.mixerHandleType = mixerHandleType;
			mixerLine = default(MixerInterop.MIXERLINE);
			mixerLine.cbStruct = Marshal.SizeOf(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)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			this.mixerHandle = mixerHandle;
			this.mixerHandleType = mixerHandleType;
			mixerLine = default(MixerInterop.MIXERLINE);
			mixerLine.cbStruct = Marshal.SizeOf(mixerLine);
			mixerLine.dwDestination = destinationIndex;
			mixerLine.dwSource = sourceIndex;
			MmException.Try(MixerInterop.mixerGetLineInfo(mixerHandle, ref mixerLine, mixerHandleType | MixerFlags.ListText), "mixerGetLineInfo");
		}

		public static int GetMixerIdForWaveIn(int waveInDevice)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			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})";
		}
	}
	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
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				signedDetails.lValue = value;
				mixerControlDetails.paDetails = Marshal.AllocHGlobal(Marshal.SizeOf(signedDetails));
				Marshal.StructureToPtr(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 = Marshal.PtrToStructure<MixerInterop.MIXERCONTROLDETAILS_SIGNED>(mixerControlDetails.paDetails);
		}

		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
			{
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				int num = Marshal.SizeOf(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(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] = Marshal.PtrToStructure<MixerInterop.MIXERCONTROLDETAILS_UNSIGNED>(mixerControlDetails.paDetails);
			}
		}

		public override string ToString()
		{
			return $"{base.ToString()} {Percent}%";
		}
	}
}
namespace NAudio.Wave
{
	internal enum AcmMetrics
	{
		CountDrivers = 1,
		CountCodecs = 2,
		CountConverters = 3,
		CountFilters = 4,
		CountDisabled = 5,
		CountHardware = 6,
		CountLocalDrivers = 20,
		CountLocalCodecs = 21,
		CountLocalConverters = 22,
		CountLocalFilters = 23,
		CountLocalDisabled = 24,
		HardwareWaveInput = 30,
		HardwareWaveOutput = 31,
		MaxSizeFormat = 50,
		MaxSizeFilter = 51,
		DriverSupport = 100,
		DriverPriority = 101
	}
	[Flags]
	internal enum AcmStreamConvertFlags
	{
		BlockAlign = 4,
		Start = 0x10,
		End = 0x20
	}
	[StructLayout(LayoutKind.Explicit)]
	public struct MmTime
	{
		public const int TIME_MS = 1;

		public const int TIME_SAMPLES = 2;

		public const int TIME_BYTES = 4;

		[FieldOffset(0)]
		public uint wType;

		[FieldOffset(4)]
		public uint ms;

		[FieldOffset(4)]
		public uint sample;

		[FieldOffset(4)]
		public uint cb;

		[FieldOffset(4)]
		public uint ticks;

		[FieldOffset(4)]
		public byte smpteHour;

		[FieldOffset(5)]
		public byte smpteMin;

		[FieldOffset(6)]
		public byte smpteSec;

		[FieldOffset(7)]
		public byte smpteFrame;

		[FieldOffset(8)]
		public byte smpteFps;

		[FieldOffset(9)]
		public byte smpteDummy;

		[FieldOffset(10)]
		public byte smptePad0;

		[FieldOffset(11)]
		public byte smptePad1;

		[FieldOffset(4)]
		public uint midiSongPtrPos;
	}
	public enum WaveCallbackStrategy
	{
		FunctionCallback,
		NewWindow,
		ExistingWindow,
		Event
	}
	[StructLayout(LayoutKind.Sequential)]
	public sealed class WaveHeader
	{
		public IntPtr dataBuffer;

		public int bufferLength;

		public int bytesRecorded;

		public IntPtr userData;

		public WaveHeaderFlags flags;

		public int loops;

		public IntPtr next;

		public IntPtr reserved;
	}
	[Flags]
	public enum WaveHeaderFlags
	{
		BeginLoop = 4,
		Done = 1,
		EndLoop = 8,
		InQueue = 0x10,
		Prepared = 2
	}
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
	public struct WaveInCapabilities
	{
		private short manufacturerId;

		private short productId;

		private int driverVersion;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
		private string productName;

		private SupportedWaveFormat supportedFormats;

		private short channels;

		private short reserved;

		private Guid manufacturerGuid;

		private Guid productGuid;

		private Guid nameGuid;

		private const int MaxProductNameLength = 32;

		public int Channels => channels;

		public string ProductName => productName;

		public Guid NameGuid => nameGuid;

		public Guid ProductGuid => productGuid;

		public Guid ManufacturerGuid => manufacturerGuid;

		public bool SupportsWaveFormat(SupportedWaveFormat waveFormat)
		{
			return (supportedFormats & waveFormat) == waveFormat;
		}
	}
	public static class WaveCapabilitiesHelpers
	{
		public static readonly Guid MicrosoftDefaultManufacturerId = new Guid("d5a47fa8-6d98-11d1-a21a-00a0c9223196");

		public static readonly Guid DefaultWaveOutGuid = new Guid("E36DC310-6D9A-11D1-A21A-00A0C9223196");

		public static readonly Guid DefaultWaveInGuid = new Guid("E36DC311-6D9A-11D1-A21A-00A0C9223196");

		public static string GetNameFromGuid(Guid guid)
		{
			string result = null;
			using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Control\\MediaCategories"))
			{
				using RegistryKey registryKey2 = registryKey.OpenSubKey(guid.ToString("B"));
				if (registryKey2 != null)
				{
					result = registryKey2.GetValue("Name") as string;
				}
			}
			return result;
		}
	}
	public class WaveInterop
	{
		[Flags]
		public enum WaveInOutOpenFlags
		{
			CallbackNull = 0,
			CallbackFunction = 0x30000,
			CallbackEvent = 0x50000,
			CallbackWindow = 0x10000,
			CallbackThread = 0x20000
		}

		public enum WaveMessage
		{
			WaveInOpen = 958,
			WaveInClose = 959,
			WaveInData = 960,
			WaveOutClose = 956,
			WaveOutDone = 957,
			WaveOutOpen = 955
		}

		public delegate void WaveCallback(IntPtr hWaveOut, WaveMessage message, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved);

		[DllImport("winmm.dll")]
		public static extern int mmioStringToFOURCC([MarshalAs(UnmanagedType.LPStr)] string s, int flags);

		[DllImport("winmm.dll")]
		public static extern int waveOutGetNumDevs();

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutPrepareHeader(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutUnprepareHeader(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutWrite(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutOpen(out IntPtr hWaveOut, IntPtr uDeviceID, WaveFormat lpFormat, WaveCallback dwCallback, IntPtr dwInstance, WaveInOutOpenFlags dwFlags);

		[DllImport("winmm.dll", EntryPoint = "waveOutOpen")]
		public static extern MmResult waveOutOpenWindow(out IntPtr hWaveOut, IntPtr uDeviceID, WaveFormat lpFormat, IntPtr callbackWindowHandle, IntPtr dwInstance, WaveInOutOpenFlags dwFlags);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutReset(IntPtr hWaveOut);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutClose(IntPtr hWaveOut);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutPause(IntPtr hWaveOut);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutRestart(IntPtr hWaveOut);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutGetPosition(IntPtr hWaveOut, ref MmTime mmTime, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutSetVolume(IntPtr hWaveOut, int dwVolume);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutGetVolume(IntPtr hWaveOut, out int dwVolume);

		[DllImport("winmm.dll", CharSet = CharSet.Auto)]
		public static extern MmResult waveOutGetDevCaps(IntPtr deviceID, out WaveOutCapabilities waveOutCaps, int waveOutCapsSize);

		[DllImport("winmm.dll")]
		public static extern int waveInGetNumDevs();

		[DllImport("winmm.dll", CharSet = CharSet.Auto)]
		public static extern MmResult waveInGetDevCaps(IntPtr deviceID, out WaveInCapabilities waveInCaps, int waveInCapsSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInAddBuffer(IntPtr hWaveIn, WaveHeader pwh, int cbwh);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInClose(IntPtr hWaveIn);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInOpen(out IntPtr hWaveIn, IntPtr uDeviceID, WaveFormat lpFormat, WaveCallback dwCallback, IntPtr dwInstance, WaveInOutOpenFlags dwFlags);

		[DllImport("winmm.dll", EntryPoint = "waveInOpen")]
		public static extern MmResult waveInOpenWindow(out IntPtr hWaveIn, IntPtr uDeviceID, WaveFormat lpFormat, IntPtr callbackWindowHandle, IntPtr dwInstance, WaveInOutOpenFlags dwFlags);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInPrepareHeader(IntPtr hWaveIn, WaveHeader lpWaveInHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInUnprepareHeader(IntPtr hWaveIn, WaveHeader lpWaveInHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInReset(IntPtr hWaveIn);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInStart(IntPtr hWaveIn);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInStop(IntPtr hWaveIn);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInGetPosition(IntPtr hWaveIn, out MmTime mmTime, int uSize);
	}
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
	public struct WaveOutCapabilities
	{
		private short manufacturerId;

		private short productId;

		private int driverVersion;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
		private string productName;

		private SupportedWaveFormat supportedFormats;

		private short channels;

		private short reserved;

		private WaveOutSupport support;

		private Guid manufacturerGuid;

		private Guid productGuid;

		private Guid nameGuid;

		private const int MaxProductNameLength = 32;

		public int Channels => channels;

		public bool SupportsPlaybackRateControl => (support & WaveOutSupport.PlaybackRate) == WaveOutSupport.PlaybackRate;

		public string ProductName => productName;

		public Guid NameGuid => nameGuid;

		public Guid ProductGuid => productGuid;

		public Guid ManufacturerGuid => manufacturerGuid;

		public bool SupportsWaveFormat(SupportedWaveFormat waveFormat)
		{
			return (supportedFormats & waveFormat) == waveFormat;
		}
	}
	[Flags]
	public enum SupportedWaveFormat
	{
		WAVE_FORMAT_1M08 = 1,
		WAVE_FORMAT_1S08 = 2,
		WAVE_FORMAT_1M16 = 4,
		WAVE_FORMAT_1S16 = 8,
		WAVE_FORMAT_2M08 = 0x10,
		WAVE_FORMAT_2S08 = 0x20,
		WAVE_FORMAT_2M16 = 0x40,
		WAVE_FORMAT_2S16 = 0x80,
		WAVE_FORMAT_4M08 = 0x100,
		WAVE_FORMAT_4S08 = 0x200,
		WAVE_FORMAT_4M16 = 0x400,
		WAVE_FORMAT_4S16 = 0x800,
		WAVE_FORMAT_44M08 = 0x100,
		WAVE_FORMAT_44S08 = 0x200,
		WAVE_FORMAT_44M16 = 0x400,
		WAVE_FORMAT_44S16 = 0x800,
		WAVE_FORMAT_48M08 = 0x1000,
		WAVE_FORMAT_48S08 = 0x2000,
		WAVE_FORMAT_48M16 = 0x4000,
		WAVE_FORMAT_48S16 = 0x8000,
		WAVE_FORMAT_96M08 = 0x10000,
		WAVE_FORMAT_96S08 = 0x20000,
		WAVE_FORMAT_96M16 = 0x40000,
		WAVE_FORMAT_96S16 = 0x80000
	}
	[Flags]
	internal enum WaveOutSupport
	{
		Pitch = 1,
		PlaybackRate = 2,
		Volume = 4,
		LRVolume = 8,
		Sync = 0x10,
		SampleAccurate = 0x20
	}
	public class AcmMp3FrameDecompressor : IMp3FrameDecompressor, IDisposable
	{
		private readonly AcmStream conversionStream;

		private readonly WaveFormat pcmFormat;

		private bool disposed;

		public WaveFormat OutputFormat => pcmFormat;

		public AcmMp3FrameDecompressor(WaveFormat sourceFormat)
		{
			pcmFormat = AcmStream.SuggestPcmFormat(sourceFormat);
			try
			{
				conversionStream = new AcmStream(sourceFormat, pcmFormat);
			}
			catch (Exception)
			{
				disposed = true;
				GC.SuppressFinalize(this);
				throw;
			}
		}

		public int DecompressFrame(Mp3Frame frame, byte[] dest, int destOffset)
		{
			if (frame == null)
			{
				throw new ArgumentNullException("frame", "You must provide a non-null Mp3Frame to decompress");
			}
			Array.Copy(frame.RawData, conversionStream.SourceBuffer, frame.FrameLength);
			int sourceBytesConverted;
			int num = conversionStream.Convert(frame.FrameLength, out sourceBytesConverted);
			if (sourceBytesConverted != frame.FrameLength)
			{
				throw new InvalidOperationException($"Couldn't convert the whole MP3 frame (converted {sourceBytesConverted}/{frame.FrameLength})");
			}
			Array.Copy(conversionStream.DestBuffer, 0, dest, destOffset, num);
			return num;
		}

		public void Reset()
		{
			conversionStream.Reposition();
		}

		public void Dispose()
		{
			if (!disposed)
			{
				disposed = true;
				if (conversionStream != null)
				{
					conversionStream.Dispose();
				}
				GC.SuppressFinalize(this);
			}
		}

		~AcmMp3FrameDecompressor()
		{
			Dispose();
		}
	}
	public class WaveFormatConversionProvider : IWaveProvider, IDisposable
	{
		private readonly AcmStream conversionStream;

		private readonly IWaveProvider sourceProvider;

		private readonly int preferredSourceReadSize;

		private int leftoverDestBytes;

		private int leftoverDestOffset;

		private int leftoverSourceBytes;

		private bool isDisposed;

		public WaveFormat WaveFormat { get; }

		public WaveFormatConversionProvider(WaveFormat targetFormat, IWaveProvider sourceProvider)
		{
			this.sourceProvider = sourceProvider;
			WaveFormat = targetFormat;
			conversionStream = new AcmStream(sourceProvider.WaveFormat, targetFormat);
			preferredSourceReadSize = Math.Min(sourceProvider.WaveFormat.AverageBytesPerSecond, conversionStream.SourceBuffer.Length);
			preferredSourceReadSize -= preferredSourceReadSize % sourceProvider.WaveFormat.BlockAlign;
		}

		public void Reposition()
		{
			leftoverDestBytes = 0;
			leftoverDestOffset = 0;
			leftoverSourceBytes = 0;
			conversionStream.Reposition();
		}

		public int Read(byte[] buffer, int offset, int count)
		{
			int i = 0;
			if (count % WaveFormat.BlockAlign != 0)
			{
				count -= count % WaveFormat.BlockAlign;
			}
			int num5;
			for (; i < count; i += num5)
			{
				int num = Math.Min(count - i, leftoverDestBytes);
				if (num > 0)
				{
					Array.Copy(conversionStream.DestBuffer, leftoverDestOffset, buffer, offset + i, num);
					leftoverDestOffset += num;
					leftoverDestBytes -= num;
					i += num;
				}
				if (i >= count)
				{
					break;
				}
				int num2 = Math.Min(preferredSourceReadSize, conversionStream.SourceBuffer.Length - leftoverSourceBytes);
				int num3 = sourceProvider.Read(conversionStream.SourceBuffer, leftoverSourceBytes, num2) + leftoverSourceBytes;
				if (num3 == 0)
				{
					break;
				}
				int sourceBytesConverted;
				int num4 = conversionStream.Convert(num3, out sourceBytesConverted);
				if (sourceBytesConverted == 0)
				{
					break;
				}
				leftoverSourceBytes = num3 - sourceBytesConverted;
				if (leftoverSourceBytes > 0)
				{
					Buffer.BlockCopy(conversionStream.SourceBuffer, sourceBytesConverted, conversionStream.SourceBuffer, 0, leftoverSourceBytes);
				}
				if (num4 <= 0)
				{
					break;
				}
				int val = count - i;
				num5 = Math.Min(num4, val);
				if (num5 < num4)
				{
					leftoverDestBytes = num4 - num5;
					leftoverDestOffset = num5;
				}
				Array.Copy(conversionStream.DestBuffer, 0, buffer, i + offset, num5);
			}
			return i;
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!isDisposed)
			{
				isDisposed = true;
				conversionStream?.Dispose();
			}
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			Dispose(disposing: true);
		}

		~WaveFormatConversionProvider()
		{
			Dispose(disposing: false);
		}
	}
	public class WaveFormatConversionStream : WaveStream
	{
		private readonly WaveFormatConversionProvider conversionProvider;

		private readonly WaveFormat targetFormat;

		private readonly long length;

		private long position;

		private readonly WaveStream sourceStream;

		private bool isDisposed;

		public override long Position
		{
			get
			{
				return position;
			}
			set
			{
				value -= value % ((WaveStream)this).BlockAlign;
				long num = EstimateDestToSource(value);
				((Stream)(object)sourceStream).Position = num;
				position = EstimateSourceToDest(((Stream)(object)sourceStream).Position);
				conversionProvider.Reposition();
			}
		}

		public override long Length => length;

		public override WaveFormat WaveFormat => targetFormat;

		public WaveFormatConversionStream(WaveFormat targetFormat, WaveStream sourceStream)
		{
			this.sourceStream = sourceStream;
			this.targetFormat = targetFormat;
			conversionProvider = new WaveFormatConversionProvider(targetFormat, (IWaveProvider)(object)sourceStream);
			length = EstimateSourceToDest((int)((Stream)(object)sourceStream).Length);
			position = 0L;
		}

		public static WaveStream CreatePcmStream(WaveStream sourceStream)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			if ((int)sourceStream.WaveFormat.Encoding == 1)
			{
				return sourceStream;
			}
			WaveFormat val = AcmStream.SuggestPcmFormat(sourceStream.WaveFormat);
			if (val.SampleRate < 8000)
			{
				if ((int)sourceStream.WaveFormat.Encoding != 163)
				{
					throw new InvalidOperationException("Invalid suggested output format, please explicitly provide a target format");
				}
				val = new WaveFormat(8000, 16, 1);
			}
			return (WaveStream)(object)new WaveFormatConversionStream(val, sourceStream);
		}

		[Obsolete("can be unreliable, use of this method not encouraged")]
		public int SourceToDest(int source)
		{
			return (int)EstimateSourceToDest(source);
		}

		private long EstimateSourceToDest(long source)
		{
			long num = source * targetFormat.AverageBytesPerSecond / sourceStream.WaveFormat.AverageBytesPerSecond;
			return num - num % targetFormat.BlockAlign;
		}

		private long EstimateDestToSource(long dest)
		{
			long num = dest * sourceStream.WaveFormat.AverageBytesPerSecond / targetFormat.AverageBytesPerSecond;
			return (int)(num - num % sourceStream.WaveFormat.BlockAlign);
		}

		[Obsolete("can be unreliable, use of this method not encouraged")]
		public int DestToSource(int dest)
		{
			return (int)EstimateDestToSource(dest);
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			int num = conversionProvider.Read(buffer, offset, count);
			position += num;
			return num;
		}

		protected override void Dispose(bool disposing)
		{
			if (!isDisposed)
			{
				isDisposed = true;
				if (disposing)
				{
					((Stream)(object)sourceStream).Dispose();
					conversionProvider.Dispose();
				}
			}
			((Stream)this).Dispose(disposing);
		}
	}
	public class WaveInBuffer : IDisposable
	{
		private readonly WaveHeader header;

		private readonly int bufferSize;

		private readonly byte[] buffer;

		private GCHandle hBuffer;

		private IntPtr waveInHandle;

		private GCHandle hHeader;

		private GCHandle hThis;

		public byte[] Data => buffer;

		public bool Done => (header.flags & WaveHeaderFlags.Done) == WaveHeaderFlags.Done;

		public bool InQueue => (header.flags & WaveHeaderFlags.InQueue) == WaveHeaderFlags.InQueue;

		public int BytesRecorded => header.bytesRecorded;

		public int BufferSize => bufferSize;

		public WaveInBuffer(IntPtr waveInHandle, int bufferSize)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			this.bufferSize = bufferSize;
			buffer = new byte[bufferSize];
			hBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
			this.waveInHandle = waveInHandle;
			header = new WaveHeader();
			hHeader = GCHandle.Alloc(header, GCHandleType.Pinned);
			header.dataBuffer = hBuffer.AddrOfPinnedObject();
			header.bufferLength = bufferSize;
			header.loops = 1;
			hThis = GCHandle.Alloc(this);
			header.userData = (IntPtr)hThis;
			MmException.Try(WaveInterop.waveInPrepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveInPrepareHeader");
		}

		public void Reuse()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			MmException.Try(WaveInterop.waveInUnprepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveUnprepareHeader");
			MmException.Try(WaveInterop.waveInPrepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveInPrepareHeader");
			MmException.Try(WaveInterop.waveInAddBuffer(waveInHandle, header, Marshal.SizeOf(header)), "waveInAddBuffer");
		}

		~WaveInBuffer()
		{
			Dispose(disposing: false);
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			Dispose(disposing: true);
		}

		protected void Dispose(bool disposing)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (waveInHandle != IntPtr.Zero)
			{
				WaveInterop.waveInUnprepareHeader(waveInHandle, header, Marshal.SizeOf(header));
				waveInHandle = IntPtr.Zero;
			}
			if (hHeader.IsAllocated)
			{
				hHeader.Free();
			}
			if (hBuffer.IsAllocated)
			{
				hBuffer.Free();
			}
			if (hThis.IsAllocated)
			{
				hThis.Free();
			}
		}
	}
	public class WaveInEvent : IWaveIn, IDisposable
	{
		private readonly AutoResetEvent callbackEvent;

		private readonly SynchronizationContext syncContext;

		private IntPtr waveInHandle;

		private volatile CaptureState captureState;

		private WaveInBuffer[] buffers;

		public static int DeviceCount => WaveInterop.waveInGetNumDevs();

		public int BufferMilliseconds { get; set; }

		public int NumberOfBuffers { get; set; }

		public int DeviceNumber { get; set; }

		public WaveFormat WaveFormat { get; set; }

		public event EventHandler<WaveInEventArgs> DataAvailable;

		public event EventHandler<StoppedEventArgs> RecordingStopped;

		public WaveInEvent()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			callbackEvent = new AutoResetEvent(initialState: false);
			syncContext = SynchronizationContext.Current;
			DeviceNumber = 0;
			WaveFormat = new WaveFormat(8000, 16, 1);
			BufferMilliseconds = 100;
			NumberOfBuffers = 3;
			captureState = (CaptureState)0;
		}

		public static WaveInCapabilities GetCapabilities(int devNumber)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			WaveInCapabilities waveInCaps = default(WaveInCapabilities);
			int waveInCapsSize = Marshal.SizeOf(waveInCaps);
			MmException.Try(WaveInterop.waveInGetDevCaps((IntPtr)devNumber, out waveInCaps, waveInCapsSize), "waveInGetDevCaps");
			return waveInCaps;
		}

		private void CreateBuffers()
		{
			int num = BufferMilliseconds * WaveFormat.AverageBytesPerSecond / 1000;
			if (num % WaveFormat.BlockAlign != 0)
			{
				num -= num % WaveFormat.BlockAlign;
			}
			buffers = new WaveInBuffer[NumberOfBuffers];
			for (int i = 0; i < buffers.Length; i++)
			{
				buffers[i] = new WaveInBuffer(waveInHandle, num);
			}
		}

		private void OpenWaveInDevice()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			CloseWaveInDevice();
			MmException.Try(WaveInterop.waveInOpenWindow(out waveInHandle, (IntPtr)DeviceNumber, WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent), "waveInOpen");
			CreateBuffers();
		}

		public void StartRecording()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if ((int)captureState != 0)
			{
				throw new InvalidOperationException("Already recording");
			}
			OpenWaveInDevice();
			MmException.Try(WaveInterop.waveInStart(waveInHandle), "waveInStart");
			captureState = (CaptureState)1;
			ThreadPool.QueueUserWorkItem(delegate
			{
				RecordThread();
			}, null);
		}

		private void RecordThread()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Exception e = null;
			try
			{
				DoRecording();
			}
			catch (Exception ex)
			{
				e = ex;
			}
			finally
			{
				captureState = (CaptureState)0;
				RaiseRecordingStoppedEvent(e);
			}
		}

		private void DoRecording()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Invalid comparison between Unknown and I4
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Invalid comparison between Unknown and I4
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			captureState = (CaptureState)2;
			WaveInBuffer[] array = buffers;
			foreach (WaveInBuffer waveInBuffer in array)
			{
				if (!waveInBuffer.InQueue)
				{
					waveInBuffer.Reuse();
				}
			}
			while ((int)captureState == 2)
			{
				if (!callbackEvent.WaitOne())
				{
					continue;
				}
				array = buffers;
				foreach (WaveInBuffer waveInBuffer2 in array)
				{
					if (waveInBuffer2.Done)
					{
						if (waveInBuffer2.BytesRecorded > 0)
						{
							this.DataAvailable?.Invoke(this, new WaveInEventArgs(waveInBuffer2.Data, waveInBuffer2.BytesRecorded));
						}
						if ((int)captureState == 2)
						{
							waveInBuffer2.Reuse();
						}
					}
				}
			}
		}

		private void RaiseRecordingStoppedEvent(Exception e)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			EventHandler<StoppedEventArgs> handler = this.RecordingStopped;
			if (handler == null)
			{
				return;
			}
			if (syncContext == null)
			{
				handler(this, new StoppedEventArgs(e));
				return;
			}
			syncContext.Post(delegate
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				handler(this, new StoppedEventArgs(e));
			}, null);
		}

		public void StopRecording()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if ((int)captureState != 0)
			{
				captureState = (CaptureState)3;
				MmException.Try(WaveInterop.waveInStop(waveInHandle), "waveInStop");
				MmException.Try(WaveInterop.waveInReset(waveInHandle), "waveInReset");
				callbackEvent.Set();
			}
		}

		public long GetPosition()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			MmTime mmTime = default(MmTime);
			mmTime.wType = 4u;
			MmException.Try(WaveInterop.waveInGetPosition(waveInHandle, out mmTime, Marshal.SizeOf(mmTime)), "waveInGetPosition");
			if (mmTime.wType != 4)
			{
				throw new Exception($"waveInGetPosition: wType -> Expected {4}, Received {mmTime.wType}");
			}
			return mmTime.cb;
		}

		protected virtual void Dispose(bool disposing)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			if (disposing)
			{
				if ((int)captureState != 0)
				{
					StopRecording();
				}
				CloseWaveInDevice();
			}
		}

		private void CloseWaveInDevice()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			WaveInterop.waveInReset(waveInHandle);
			if (buffers != null)
			{
				for (int i = 0; i < buffers.Length; i++)
				{
					buffers[i].Dispose();
				}
				buffers = null;
			}
			WaveInterop.waveInClose(waveInHandle);
			waveInHandle = IntPtr.Zero;
		}

		public MixerLine GetMixerLine()
		{
			if (waveInHandle != IntPtr.Zero)
			{
				return new MixerLine(waveInHandle, 0, MixerFlags.WaveInHandle);
			}
			return new MixerLine((IntPtr)DeviceNumber, 0, MixerFlags.WaveIn);
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}
	}
	public class WaveOutBuffer : IDisposable
	{
		private readonly WaveHeader header;

		private readonly int bufferSize;

		private readonly byte[] buffer;

		private readonly IWaveProvider waveStream;

		private readonly object waveOutLock;

		private GCHandle hBuffer;

		private IntPtr hWaveOut;

		private GCHandle hHeader;

		private GCHandle hThis;

		public bool InQueue => (header.flags & WaveHeaderFlags.InQueue) == WaveHeaderFlags.InQueue;

		public int BufferSize => bufferSize;

		public WaveOutBuffer(IntPtr hWaveOut, int bufferSize, IWaveProvider bufferFillStream, object waveOutLock)
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			this.bufferSize = bufferSize;
			buffer = new byte[bufferSize];
			hBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
			this.hWaveOut = hWaveOut;
			waveStream = bufferFillStream;
			this.waveOutLock = waveOutLock;
			header = new WaveHeader();
			hHeader = GCHandle.Alloc(header, GCHandleType.Pinned);
			header.dataBuffer = hBuffer.AddrOfPinnedObject();
			header.bufferLength = bufferSize;
			header.loops = 1;
			hThis = GCHandle.Alloc(this);
			header.userData = (IntPtr)hThis;
			lock (waveOutLock)
			{
				MmException.Try(WaveInterop.waveOutPrepareHeader(hWaveOut, header, Marshal.SizeOf(header)), "waveOutPrepareHeader");
			}
		}

		~WaveOutBuffer()
		{
			Dispose(disposing: false);
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			Dispose(disposing: true);
		}

		protected void Dispose(bool disposing)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (hHeader.IsAllocated)
			{
				hHeader.Free();
			}
			if (hBuffer.IsAllocated)
			{
				hBuffer.Free();
			}
			if (hThis.IsAllocated)
			{
				hThis.Free();
			}
			if (hWaveOut != IntPtr.Zero)
			{
				lock (waveOutLock)
				{
					WaveInterop.waveOutUnprepareHeader(hWaveOut, header, Marshal.SizeOf(header));
				}
				hWaveOut = IntPtr.Zero;
			}
		}

		public bool OnDone()
		{
			int num;
			lock (waveStream)
			{
				num = waveStream.Read(buffer, 0, buffer.Length);
			}
			if (num == 0)
			{
				return false;
			}
			for (int i = num; i < buffer.Length; i++)
			{
				buffer[i] = 0;
			}
			WriteToWaveOut();
			return true;
		}

		private void WriteToWaveOut()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			MmResult val;
			lock (waveOutLock)
			{
				val = WaveInterop.waveOutWrite(hWaveOut, header, Marshal.SizeOf(header));
			}
			if ((int)val != 0)
			{
				throw new MmException(val, "waveOutWrite");
			}
			GC.KeepAlive(this);
		}
	}
	public class WaveOutEvent : IWavePlayer, IDisposable, IWavePosition
	{
		private readonly object waveOutLock;

		private readonly SynchronizationContext syncContext;

		private IntPtr hWaveOut;

		private WaveOutBuffer[] buffers;

		private IWaveProvider waveStream;

		private volatile PlaybackState playbackState;

		private AutoResetEvent callbackEvent;

		public int DesiredLatency { get; set; }

		public int NumberOfBuffers { get; set; }

		public int DeviceNumber { get; set; } = -1;


		public WaveFormat OutputWaveFormat => waveStream.WaveFormat;

		public PlaybackState PlaybackState => playbackState;

		public float Volume
		{
			get
			{
				return WaveOutUtils.GetWaveOutVolume(hWaveOut, waveOutLock);
			}
			set
			{
				WaveOutUtils.SetWaveOutVolume(value, hWaveOut, waveOutLock);
			}
		}

		public event EventHandler<StoppedEventArgs> PlaybackStopped;

		public WaveOutEvent()
		{
			syncContext = SynchronizationContext.Current;
			if (syncContext != null && (syncContext.GetType().Name == "LegacyAspNetSynchronizationContext" || syncContext.GetType().Name == "AspNetSynchronizationContext"))
			{
				syncContext = null;
			}
			DesiredLatency = 300;
			NumberOfBuffers = 2;
			waveOutLock = new object();
		}

		public void Init(IWaveProvider waveProvider)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			if ((int)playbackState != 0)
			{
				throw new InvalidOperationException("Can't re-initialize during playback");
			}
			if (hWaveOut != IntPtr.Zero)
			{
				DisposeBuffers();
				CloseWaveOut();
			}
			callbackEvent = new AutoResetEvent(initialState: false);
			waveStream = waveProvider;
			int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers);
			MmResult val;
			lock (waveOutLock)
			{
				val = WaveInterop.waveOutOpenWindow(out hWaveOut, (IntPtr)DeviceNumber, waveStream.WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent);
			}
			MmException.Try(val, "waveOutOpen");
			buffers = new WaveOutBuffer[NumberOfBuffers];
			playbackState = (PlaybackState)0;
			for (int i = 0; i < NumberOfBuffers; i++)
			{
				buffers[i] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock);
			}
		}

		public void Play()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (buffers == null || waveStream == null)
			{
				throw new InvalidOperationException("Must call Init first");
			}
			if ((int)playbackState == 0)
			{
				playbackState = (PlaybackState)1;
				callbackEvent.Set();
				ThreadPool.QueueUserWorkItem(delegate
				{
					PlaybackThread();
				}, null);
			}
			else if ((int)playbackState == 2)
			{
				Resume();
				callbackEvent.Set();
			}
		}

		private void PlaybackThread()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Exception e = null;
			try
			{
				DoPlayback();
			}
			catch (Exception ex)
			{
				e = ex;
			}
			finally
			{
				playbackState = (PlaybackState)0;
				RaisePlaybackStoppedEvent(e);
			}
		}

		private void DoPlayback()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			while ((int)playbackState != 0)
			{
				if (!callbackEvent.WaitOne(DesiredLatency))
				{
					_ = playbackState;
					_ = 1;
				}
				if ((int)playbackState != 1)
				{
					continue;
				}
				int num = 0;
				WaveOutBuffer[] array = buffers;
				foreach (WaveOutBuffer waveOutBuffer in array)
				{
					if (waveOutBuffer.InQueue || waveOutBuffer.OnDone())
					{
						num++;
					}
				}
				if (num == 0)
				{
					playbackState = (PlaybackState)0;
					callbackEvent.Set();
				}
			}
		}

		public void Pause()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if ((int)playbackState == 1)
			{
				playbackState = (PlaybackState)2;
				MmResult val;
				lock (waveOutLock)
				{
					val = WaveInterop.waveOutPause(hWaveOut);
				}
				if ((int)val != 0)
				{
					throw new MmException(val, "waveOutPause");
				}
			}
		}

		private void Resume()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if ((int)playbackState == 2)
			{
				MmResult val;
				lock (waveOutLock)
				{
					val = WaveInterop.waveOutRestart(hWaveOut);
				}
				if ((int)val != 0)
				{
					throw new MmException(val, "waveOutRestart");
				}
				playbackState = (PlaybackState)1;
			}
		}

		public void Stop()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if ((int)playbackState != 0)
			{
				playbackState = (PlaybackState)0;
				MmResult val;
				lock (waveOutLock)
				{
					val = WaveInterop.waveOutReset(hWaveOut);
				}
				if ((int)val != 0)
				{
					throw new MmException(val, "waveOutReset");
				}
				callbackEvent.Set();
			}
		}

		public long GetPosition()
		{
			return WaveOutUtils.GetPositionBytes(hWaveOut, waveOutLock);
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			Dispose(disposing: true);
		}

		protected void Dispose(bool disposing)
		{
			Stop();
			if (disposing)
			{
				DisposeBuffers();
			}
			CloseWaveOut();
		}

		private void CloseWaveOut()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (callbackEvent != null)
			{
				callbackEvent.Close();
				callbackEvent = null;
			}
			lock (waveOutLock)
			{
				if (hWaveOut != IntPtr.Zero)
				{
					WaveInterop.waveOutClose(hWaveOut);
					hWaveOut = IntPtr.Zero;
				}
			}
		}

		private void DisposeBuffers()
		{
			if (buffers != null)
			{
				WaveOutBuffer[] array = buffers;
				for (int i = 0; i < array.Length; i++)
				{
					array[i].Dispose();
				}
				buffers = null;
			}
		}

		~WaveOutEvent()
		{
			Dispose(disposing: false);
		}

		private void RaisePlaybackStoppedEvent(Exception e)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			EventHandler<StoppedEventArgs> handler = this.PlaybackStopped;
			if (handler == null)
			{
				return;
			}
			if (syncContext == null)
			{
				handler(this, new StoppedEventArgs(e));
				return;
			}
			syncContext.Post(delegate
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				handler(this, new StoppedEventArgs(e));
			}, null);
		}
	}
	public static class WaveOutUtils
	{
		public static float GetWaveOutVolume(IntPtr hWaveOut, object lockObject)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			MmResult val;
			int dwVolume;
			lock (lockObject)
			{
				val = WaveInterop.waveOutGetVolume(hWaveOut, out dwVolume);
			}
			MmException.Try(val, "waveOutGetVolume");
			return (float)(dwVolume & 0xFFFF) / 65535f;
		}

		public static void SetWaveOutVolume(float value, IntPtr hWaveOut, object lockObject)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (value < 0f)
			{
				throw new ArgumentOutOfRangeException("value", "Volume must be between 0.0 and 1.0");
			}
			if (value > 1f)
			{
				throw new ArgumentOutOfRangeException("value", "Volume must be between 0.0 and 1.0");
			}
			int dwVolume = (int)(value * 65535f) + ((int)(value * 65535f) << 16);
			MmResult val;
			lock (lockObject)
			{
				val = WaveInterop.waveOutSetVolume(hWaveOut, dwVolume);
			}
			MmException.Try(val, "waveOutSetVolume");
		}

		public static long GetPositionBytes(IntPtr hWaveOut, object lockObject)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			lock (lockObject)
			{
				MmTime mmTime = default(MmTime);
				mmTime.wType = 4u;
				MmException.Try(WaveInterop.waveOutGetPosition(hWaveOut, ref mmTime, Marshal.SizeOf(mmTime)), "waveOutGetPosition");
				if (mmTime.wType != 4)
				{
					throw new Exception($"waveOutGetPosition: wType -> Expected {4}, Received {mmTime.wType}");
				}
				return mmTime.cb;
			}
		}
	}
}
namespace NAudio.Wave.Compression
{
	public class AcmDriver : IDisposable
	{
		private static List<AcmDriver> drivers;

		private AcmDriverDetails details;

		private IntPtr driverId;

		private IntPtr driverHandle;

		private List<AcmFormatTag> formatTags;

		private List<AcmFormat> tempFormatsList;

		private IntPtr localDllHandle;

		public int MaxFormatSize
		{
			get
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				MmException.Try(AcmInterop.acmMetrics(driverHandle, AcmMetrics.MaxSizeFormat, out var output), "acmMetrics");
				return output;
			}
		}

		public string ShortName => details.shortName;

		public string LongName => details.longName;

		public IntPtr DriverId => driverId;

		public IEnumerable<AcmFormatTag> FormatTags
		{
			get
			{
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				if (formatTags == null)
				{
					if (driverHandle == IntPtr.Zero)
					{
						throw new InvalidOperationException("Driver must be opened first");
					}
					formatTags = new List<AcmFormatTag>();
					AcmFormatTagDetails formatTagDetails = default(AcmFormatTagDetails);
					formatTagDetails.structureSize = Marshal.SizeOf(formatTagDetails);
					MmException.Try(AcmInterop.acmFormatTagEnum(driverHandle, ref formatTagDetails, AcmFormatTagEnumCallback, IntPtr.Zero, 0), "acmFormatTagEnum");
				}
				return formatTags;
			}
		}

		public static bool IsCodecInstalled(string shortName)
		{
			foreach (AcmDriver item in EnumerateAcmDrivers())
			{
				if (item.ShortName == shortName)
				{
					return true;
				}
			}
			return false;
		}

		public static AcmDriver AddLocalDriver(string driverFile)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			IntPtr intPtr = NativeMethods.LoadLibrary(driverFile);
			if (intPtr == IntPtr.Zero)
			{
				throw new ArgumentException("Failed to load driver file");
			}
			IntPtr procAddress = NativeMethods.GetProcAddress(intPtr, "DriverProc");
			if (procAddress == IntPtr.Zero)
			{
				NativeMethods.FreeLibrary(intPtr);
				throw new ArgumentException("Failed to discover DriverProc");
			}
			IntPtr hAcmDriver;
			MmResult val = AcmInterop.acmDriverAdd(out hAcmDriver, intPtr, procAddress, 0, AcmDriverAddFlags.Function);
			if ((int)val != 0)
			{
				NativeMethods.FreeLibrary(intPtr);
				throw new MmException(val, "acmDriverAdd");
			}
			AcmDriver acmDriver = new AcmDriver(hAcmDriver);
			if (string.IsNullOrEmpty(acmDriver.details.longName))
			{
				acmDriver.details.longName = "Local driver: " + Path.GetFileName(driverFile);
				acmDriver.localDllHandle = intPtr;
			}
			return acmDriver;
		}

		public static void RemoveLocalDriver(AcmDriver localDriver)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (localDriver.localDllHandle == IntPtr.Zero)
			{
				throw new ArgumentException("Please pass in the AcmDriver returned by the AddLocalDriver method");
			}
			MmResult val = AcmInterop.acmDriverRemove(localDriver.driverId, 0);
			NativeMethods.FreeLibrary(localDriver.localDllHandle);
			MmException.Try(val, "acmDriverRemove");
		}

		public static bool ShowFormatChooseDialog(IntPtr ownerWindowHandle, string windowTitle, AcmFormatEnumFlags enumFlags, WaveFormat enumFormat, out WaveFormat selectedFormat, out string selectedFormatDescription, out string selectedFormatTagDescription)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Invalid comparison between Unknown and I4
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Invalid comparison between Unknown and I4
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			AcmFormatChoose formatChoose = default(AcmFormatChoose);
			formatChoose.structureSize = Marshal.SizeOf(formatChoose);
			formatChoose.styleFlags = AcmFormatChooseStyleFlags.None;
			formatChoose.ownerWindowHandle = ownerWindowHandle;
			int num = 200;
			formatChoose.selectedWaveFormatPointer = Marshal.AllocHGlobal(num);
			formatChoose.selectedWaveFormatByteSize = num;
			formatChoose.title = windowTitle;
			formatChoose.name = null;
			formatChoose.formatEnumFlags = enumFlags;
			formatChoose.waveFormatEnumPointer = IntPtr.Zero;
			if (enumFormat != null)
			{
				IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf<WaveFormat>(enumFormat));
				Marshal.StructureToPtr<WaveFormat>(enumFormat, intPtr, fDeleteOld: false);
				formatChoose.waveFormatEnumPointer = intPtr;
			}
			formatChoose.instanceHandle = IntPtr.Zero;
			formatChoose.templateName = null;
			MmResult val = AcmInterop.acmFormatChoose(ref formatChoose);
			selectedFormat = null;
			selectedFormatDescription = null;
			selectedFormatTagDescription = null;
			if ((int)val == 0)
			{
				selectedFormat = WaveFormat.MarshalFromPtr(formatChoose.selectedWaveFormatPointer);
				selectedFormatDescription = formatChoose.formatDescription;
				selectedFormatTagDescription = formatChoose.formatTagDescription;
			}
			Marshal.FreeHGlobal(formatChoose.waveFormatEnumPointer);
			Marshal.FreeHGlobal(formatChoose.selectedWaveFormatPointer);
			if ((int)val != 515 && (int)val != 0)
			{
				throw new MmException(val, "acmFormatChoose");
			}
			return (int)val == 0;
		}

		public static AcmDriver FindByShortName(string shortName)
		{
			foreach (AcmDriver item in EnumerateAcmDrivers())
			{
				if (item.ShortName == shortName)
				{
					return item;
				}
			}
			return null;
		}

		public static IEnumerable<AcmDriver> EnumerateAcmDrivers()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			drivers = new List<AcmDriver>();
			MmException.Try(AcmInterop.acmDriverEnum(DriverEnumCallback, IntPtr.Zero, (AcmDriverEnumFlags)0), "acmDriverEnum");
			return drivers;
		}

		private static bool DriverEnumCallback(IntPtr hAcmDriver, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags)
		{
			drivers.Add(new AcmDriver(hAcmDriver));
			return true;
		}

		private AcmDriver(IntPtr hAcmDriver)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			driverId = hAcmDriver;
			details = default(AcmDriverDetails);
			details.structureSize = Marshal.SizeOf(details);
			MmException.Try(AcmInterop.acmDriverDetails(hAcmDriver, ref details, 0), "acmDriverDetails");
		}

		public override string ToString()
		{
			return LongName;
		}

		public IEnumerable<AcmFormat> GetFormats(AcmFormatTag formatTag)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected I4, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (driverHandle == IntPtr.Zero)
			{
				throw new InvalidOperationException("Driver must be opened first");
			}
			tempFormatsList = new List<AcmFormat>();
			AcmFormatDetails formatDetails = default(AcmFormatDetails);
			formatDetails.structSize = Marshal.SizeOf(formatDetails);
			formatDetails.waveFormatByteSize = 1024;
			formatDetails.waveFormatPointer = Marshal.AllocHGlobal(formatDetails.waveFormatByteSize);
			formatDetails.formatTag = (int)formatTag.FormatTag;
			MmResult val = AcmInterop.acmFormatEnum(driverHandle, ref formatDetails, AcmFormatEnumCallback, IntPtr.Zero, AcmFormatEnumFlags.None);
			Marshal.FreeHGlobal(formatDetails.waveFormatPointer);
			MmException.Try(val, "acmFormatEnum");
			return tempFormatsList;
		}

		public void Open()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (driverHandle == IntPtr.Zero)
			{
				MmException.Try(AcmInterop.acmDriverOpen(out driverHandle, DriverId, 0), "acmDriverOpen");
			}
		}

		public void Close()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (driverHandle != IntPtr.Zero)
			{
				MmException.Try(AcmInterop.acmDriverClose(driverHandle, 0), "acmDriverClose");
				driverHandle = IntPtr.Zero;
			}
		}

		private bool AcmFormatTagEnumCallback(IntPtr hAcmDriverId, ref AcmFormatTagDetails formatTagDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags)
		{
			formatTags.Add(new AcmFormatTag(formatTagDetails));
			return true;
		}

		private bool AcmFormatEnumCallback(IntPtr hAcmDriverId, ref AcmFormatDetails formatDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags)
		{
			tempFormatsList.Add(new AcmFormat(formatDetails));
			return true;
		}

		public void Dispose()
		{
			if (driverHandle != IntPtr.Zero)
			{
				Close();
				GC.SuppressFinalize(this);
			}
		}
	}
	internal enum AcmDriverAddFlags
	{
		Local = 0,
		Global = 8,
		Function = 3,
		NotifyWindowHandle = 4
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	internal struct AcmDriverDetails
	{
		public int structureSize;

		public uint fccType;

		public uint fccComp;

		public ushort manufacturerId;

		public ushort productId;

		public uint acmVersion;

		public uint driverVersion;

		public AcmDriverDetailsSupportFlags supportFlags;

		public int formatTagsCount;

		public int filterTagsCount;

		public IntPtr hicon;

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

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
		public string longName;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
		public string copyright;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
		public string licensing;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)]
		public string features;

		private const int ShortNameChars = 32;

		private const int LongNameChars = 128;

		private const int CopyrightChars = 80;

		private const int LicensingChars = 128;

		private const int FeaturesChars = 512;
	}
	[Flags]
	public enum AcmDriverDetailsSupportFlags
	{
		Codec = 1,
		Converter = 2,
		Filter = 4,
		Hardware = 8,
		Async = 0x10,
		Local = 0x40000000,
		Disabled = int.MinValue
	}
	[Flags]
	internal enum AcmDriverEnumFlags
	{
		NoLocal = 0x40000000,
		Disabled = int.MinValue
	}
	public class AcmFormat
	{
		private readonly AcmFormatDetails formatDetails;

		public int FormatIndex => formatDetails.formatIndex;

		public WaveFormatEncoding FormatTag => (WaveFormatEncoding)(ushort)formatDetails.formatTag;

		public AcmDriverDetailsSupportFlags SupportFlags => formatDetails.supportFlags;

		public WaveFormat WaveFormat { get; private set; }

		public int WaveFormatByteSize => formatDetails.waveFormatByteSize;

		public string FormatDescription => formatDetails.formatDescription;

		internal AcmFormat(AcmFormatDetails formatDetails)
		{
			this.formatDetails = formatDetails;
			WaveFormat = WaveFormat.MarshalFromPtr(formatDetails.waveFormatPointer);
		}
	}
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
	internal struct AcmFormatChoose
	{
		public int structureSize;

		public AcmFormatChooseStyleFlags styleFlags;

		public IntPtr ownerWindowHandle;

		public IntPtr selectedWaveFormatPointer;

		public int selectedWaveFormatByteSize;

		[MarshalAs(UnmanagedType.LPTStr)]
		public string title;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
		public string formatTagDescription;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
		public string formatDescription;

		[MarshalAs(UnmanagedType.LPTStr)]
		public string name;

		public int nameByteSize;

		public AcmFormatEnumFlags formatEnumFlags;

		public IntPtr waveFormatEnumPointer;

		public IntPtr instanceHandle;

		[MarshalAs(UnmanagedType.LPTStr)]
		public string templateName;

		public IntPtr customData;

		public AcmInterop.AcmFormatChooseHookProc windowCallbackFunction;
	}
	[Flags]
	internal enum AcmFormatChooseStyleFlags
	{
		None = 0,
		ShowHelp = 4,
		EnableHook = 8,
		EnableTemplate = 0x10,
		EnableTemplateHandle = 0x20,
		InitToWfxStruct = 0x40,
		ContextHelp = 0x80
	}
	[StructLayout(LayoutKind.Sequential, Pack = 4)]
	internal struct AcmFormatDetails
	{
		public int structSize;

		public int formatIndex;

		public int formatTag;

		public AcmDriverDetailsSupportFlags supportFlags;

		public IntPtr waveFormatPointer;

		public int waveFormatByteSize;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
		public string formatDescription;

		public const int FormatDescriptionChars = 128;
	}
	[Flags]
	public enum AcmFormatEnumFlags
	{
		None = 0,
		Convert = 0x100000,
		Hardware = 0x400000,
		Input = 0x800000,
		Channels = 0x20000,
		SamplesPerSecond = 0x40000,
		Output = 0x1000000,
		Suggest = 0x200000,
		BitsPerSample = 0x80000,
		FormatTag = 0x10000
	}
	[Flags]
	internal enum AcmFormatSuggestFlags
	{
		FormatTag = 0x10000,
		Channels = 0x20000,
		SamplesPerSecond = 0x40000,
		BitsPerSample = 0x80000,
		TypeMask = 0xFF0000
	}
	public class AcmFormatTag
	{
		private AcmFormatTagDetails formatTagDetails;

		public int FormatTagIndex => formatTagDetails.formatTagIndex;

		public WaveFormatEncoding FormatTag => (WaveFormatEncoding)(ushort)formatTagDetails.formatTag;

		public int FormatSize => formatTagDetails.formatSize;

		public AcmDriverDetailsSupportFlags SupportFlags => formatTagDetails.supportFlags;

		public int StandardFormatsCount => formatTagDetails.standardFormatsCount;

		public string FormatDescription => formatTagDetails.formatDescription;

		internal AcmFormatTag(AcmFormatTagDetails formatTagDetails)
		{
			this.formatTagDetails = formatTagDetails;
		}
	}
	internal struct AcmFormatTagDetails
	{
		public int structureSize;

		public int formatTagIndex;

		public int formatTag;

		public int formatSize;

		public AcmDriverDetailsSupportFlags supportFlags;

		public int standardFormatsCount;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
		public string formatDescription;

		public const int FormatTagDescriptionChars = 48;
	}
	internal class AcmInterop
	{
		public delegate bool AcmDriverEnumCallback(IntPtr hAcmDriverId, IntPtr instance, AcmDriverDetailsSupportFlags flags);

		public delegate bool AcmFormatEnumCallback(IntPtr hAcmDriverId, ref AcmFormatDetails formatDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags);

		public delegate bool AcmFormatTagEnumCallback(IntPtr hAcmDriverId, ref AcmFormatTagDetails formatTagDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags);

		public delegate bool AcmFormatChooseHookProc(IntPtr windowHandle, int message, IntPtr wParam, IntPtr lParam);

		[DllImport("msacm32.dll")]
		public static extern MmResult acmDriverAdd(out IntPtr driverHandle, IntPtr driverModule, IntPtr driverFunctionAddress, int priority, AcmDriverAddFlags flags);

		[DllImport("msacm32.dll")]
		public static extern MmResult acmDriverRemove(IntPtr driverHandle, int removeFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmDriverClose(IntPtr hAcmDriver, int closeFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmDriverEnum(AcmDriverEnumCallback fnCallback, IntPtr dwInstance, AcmDriverEnumFlags flags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmDriverDetails(IntPtr hAcmDriver, ref AcmDriverDetails driverDetails, int reserved);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmDriverOpen(out IntPtr pAcmDriver, IntPtr hAcmDriverId, int openFlags);

		[DllImport("Msacm32.dll", EntryPoint = "acmFormatChooseW")]
		public static extern MmResult acmFormatChoose(ref AcmFormatChoose formatChoose);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmFormatEnum(IntPtr hAcmDriver, ref AcmFormatDetails formatDetails, AcmFormatEnumCallback callback, IntPtr instance, AcmFormatEnumFlags flags);

		[DllImport("Msacm32.dll", EntryPoint = "acmFormatSuggest")]
		public static extern MmResult acmFormatSuggest2(IntPtr hAcmDriver, IntPtr sourceFormatPointer, IntPtr destFormatPointer, int sizeDestFormat, AcmFormatSuggestFlags suggestFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmFormatTagEnum(IntPtr hAcmDriver, ref AcmFormatTagDetails formatTagDetails, AcmFormatTagEnumCallback callback, IntPtr instance, int reserved);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmMetrics(IntPtr hAcmObject, AcmMetrics metric, out int output);

		[DllImport("Msacm32.dll", EntryPoint = "acmStreamOpen")]
		public static extern MmResult acmStreamOpen2(out IntPtr hAcmStream, IntPtr hAcmDriver, IntPtr sourceFormatPointer, IntPtr destFormatPointer, [In] WaveFilter waveFilter, IntPtr callback, IntPtr instance, AcmStreamOpenFlags openFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmStreamClose(IntPtr hAcmStream, int closeFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmStreamConvert(IntPtr hAcmStream, [In][Out] AcmStreamHeaderStruct streamHeader, AcmStreamConvertFlags streamConvertFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmStreamPrepareHeader(IntPtr hAcmStream, [In][Out] AcmStreamHeaderStruct streamHeader, int prepareFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmStreamReset(IntPtr hAcmStream, int resetFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmStreamSize(IntPtr hAcmStream, int inputBufferSize, out int outputBufferSize, AcmStreamSizeFlags flags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmStreamUnprepareHeader(IntPtr hAcmStream, [In][Out] AcmStreamHeaderStruct streamHeader, int flags);
	}
	public class AcmStream : IDisposable
	{
		private IntPtr streamHandle;

		private IntPtr driverHandle;

		private AcmStreamHeader streamHeader;

		private readonly WaveFormat sourceFormat;

		public byte[] SourceBuffer => streamHeader.SourceBuffer;

		public byte[] DestBuffer => streamHeader.DestBuffer;

		public AcmStream(WaveFormat sourceFormat, WaveFormat destFormat)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				streamHandle = IntPtr.Zero;
				this.sourceFormat = sourceFormat;
				int num = Math.Max(65536, sourceFormat.AverageBytesPerSecond);
				num -= num % sourceFormat.BlockAlign;
				IntPtr intPtr = WaveFormat.MarshalToPtr(sourceFormat);
				IntPtr intPtr2 = WaveFormat.MarshalToPtr(destFormat);
				try
				{
					MmException.Try(AcmInterop.acmStreamOpen2(out streamHandle, IntPtr.Zero, intPtr, intPtr2, null, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.NonRealTime), "acmStreamOpen");
				}
				finally
				{
					Marshal.FreeHGlobal(intPtr);
					Marshal.FreeHGlobal(intPtr2);
				}
				int destBufferLength = SourceToDest(num);
				streamHeader = new AcmStreamHeader(streamHandle, num, destBufferLength);
				driverHandle = IntPtr.Zero;
			}
			catch
			{
				Dispose();
				throw;
			}
		}

		public AcmStream(IntPtr driverId, WaveFormat sourceFormat, WaveFilter waveFilter)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			int num = Math.Max(16384, sourceFormat.AverageBytesPerSecond);
			this.sourceFormat = sourceFormat;
			num -= num % sourceFormat.BlockAlign;
			MmException.Try(AcmInterop.acmDriverOpen(out driverHandle, driverId, 0), "acmDriverOpen");
			IntPtr intPtr = WaveFormat.MarshalToPtr(sourceFormat);
			try
			{
				MmException.Try(AcmInterop.acmStreamOpen2(out streamHandle, driverHandle, intPtr, intPtr, waveFilter, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.NonRealTime), "acmStreamOpen");
			}
			finally
			{
				Marshal.FreeHGlobal(intPtr);
			}
			streamHeader = new AcmStreamHeader(streamHandle, num, SourceToDest(num));
		}

		public int SourceToDest(int source)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (source == 0)
			{
				return 0;
			}
			MmException.Try(AcmInterop.acmStreamSize(streamHandle, source, out var outputBufferSize, AcmStreamSizeFlags.Source), "acmStreamSize");
			return outputBufferSize;
		}

		public int DestToSource(int dest)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (dest == 0)
			{
				return 0;
			}
			MmException.Try(AcmInterop.acmStreamSize(streamHandle, dest, out var outputBufferSize, AcmStreamSizeFlags.Destination), "acmStreamSize");
			return outputBufferSize;
		}

		public static WaveFormat SuggestPcmFormat(WaveFormat compressedFormat)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			WaveFormat val = new WaveFormat(compressedFormat.SampleRate, 16, compressedFormat.Channels);
			IntPtr intPtr = WaveFormat.MarshalToPtr(val);
			IntPtr intPtr2 = WaveFormat.MarshalToPtr(compressedFormat);
			try
			{
				MmResult val2 = AcmInterop.acmFormatSuggest2(IntPtr.Zero, intPtr2, intPtr, Marshal.SizeOf<WaveFormat>(val), AcmFormatSuggestFlags.FormatTag);
				val = WaveFormat.MarshalFromPtr(intPtr);
				MmException.Try(val2, "acmFormatSuggest");
				return val;
			}
			finally
			{
				Marshal.FreeHGlobal(intPtr);
				Marshal.FreeHGlobal(intPtr2);
			}
		}

		public void Reposition()
		{
			streamHeader.Reposition();
		}

		public int Convert(int bytesToConvert, out int sourceBytesConverted)
		{
			if (bytesToConvert % sourceFormat.BlockAlign != 0)
			{
				bytesToConvert -= bytesToConvert % sourceFormat.BlockAlign;
			}
			return streamHeader.Convert(bytesToConvert, out sourceBytesConverted);
		}

		[Obsolete("Call the version returning sourceBytesConverted instead")]
		public int Convert(int bytesToConvert)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			int sourceBytesConverted;
			int result = Convert(bytesToConvert, out sourceBytesConverted);
			if (sourceBytesConverted != bytesToConvert)
			{
				throw new MmException((MmResult)8, "AcmStreamHeader.Convert didn't convert everything");
			}
			return result;
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (disposing && streamHeader != null)
			{
				streamHeader.Dispose();
				streamHeader = null;
			}
			if (streamHandle != IntPtr.Zero)
			{
				MmResult val = AcmInterop.acmStreamClose(streamHandle, 0);
				streamHandle = IntPtr.Zero;
				if ((int)val != 0)
				{
					throw new MmException(val, "acmStreamClose");
				}
			}
			if (driverHandle != IntPtr.Zero)
			{
				AcmInterop.acmDriverClose(driverHandle, 0);
				driverHandle = IntPtr.Zero;
			}
		}

		~AcmStream()
		{
			Dispose(disposing: false);
		}
	}
	internal class AcmStreamHeader : IDisposable
	{
		private AcmStreamHeaderStruct streamHeader;

		private GCHandle hSourceBuffer;

		private GCHandle hDestBuffer;

		private IntPtr streamHandle;

		private bool firstTime;

		private bool disposed;

		public byte[] SourceBuffer { get; private set; }

		public byte[] DestBuffer { get; private set; }

		public AcmStreamHeader(IntPtr streamHandle, int sourceBufferLength, int destBufferLength)
		{
			streamHeader = new AcmStreamHeaderStruct();
			SourceBuffer = new byte[sourceBufferLength];
			hSourceBuffer = GCHandle.Alloc(SourceBuffer, GCHandleType.Pinned);
			DestBuffer = new byte[destBufferLength];
			hDestBuffer = GCHandle.Alloc(DestBuffer, GCHandleType.Pinned);
			this.streamHandle = streamHandle;
			firstTime = true;
		}

		private void Prepare()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			streamHeader.cbStruct = Marshal.SizeOf(streamHeader);
			streamHeader.sourceBufferLength = SourceBuffer.Length;
			streamHeader.sourceBufferPointer = hSourceBuffer.AddrOfPinnedObject();
			streamHeader.destBufferLength = DestBuffer.Length;
			streamHeader.destBufferPointer = hDestBuffer.AddrOfPinnedObject();
			MmException.Try(AcmInterop.acmStreamPrepareHeader(streamHandle, streamHeader, 0), "acmStreamPrepareHeader");
		}

		private void Unprepare()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			streamHeader.sourceBufferLength = SourceBuffer.Length;
			streamHeader.sourceBufferPointer = hSourceBuffer.AddrOfPinnedObject();
			streamHeader.destBufferLength = DestBuffer.Length;
			streamHeader.destBufferPointer = hDestBuffer.AddrOfPinnedObject();
			MmResult val = AcmInterop.acmStreamUnprepareHeader(streamHandle, streamHeader, 0);
			if ((int)val != 0)
			{
				throw new MmException(val, "acmStreamUnprepareHeader");
			}
		}

		public void Reposition()
		{
			firstTime = true;
		}

		public int Convert(int bytesToConvert, out int sourceBytesConverted)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Prepare();
			try
			{
				streamHeader.sourceBufferLength = bytesToConvert;
				streamHeader.sourceBufferLengthUsed = bytesToConvert;
				AcmStreamConvertFlags streamConvertFlags = (firstTime ? (AcmStreamConvertFlags.BlockAlign | AcmStreamConvertFlags.Start) : AcmStreamConvertFlags.BlockAlign);
				MmException.Try(AcmInterop.acmStreamConvert(streamHandle, streamHeader, streamConvertFlags), "acmStreamConvert");
				firstTime = false;
				sourceBytesConverted = streamHeader.sourceBufferLengthUsed;
			}
			finally
			{
				Unprepare();
			}
			return streamHeader.destBufferLengthUsed;
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			Dispose(disposing: true);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!disposed)
			{
				SourceBuffer = null;
				DestBuffer = null;
				hSourceBuffer.Free();
				hDestBuffer.Free();
			}
			disposed = true;
		}

		~AcmStreamHeader()
		{
			Dispose(disposing: false);
		}
	}
	[Flags]
	internal enum AcmStreamHeaderStatusFlags
	{
		Done = 0x10000,
		Prepared = 0x20000,
		InQueue = 0x100000
	}
	[StructLayout(LayoutKind.Sequential, Size = 128)]
	internal class AcmStreamHeaderStruct
	{
		public int cbStruct;

		public AcmStreamHeaderStatusFlags fdwStatus;

		public IntPtr userData;

		public IntPtr sourceBufferPointer;

		public int sourceBufferLength;

		public int sourceBufferLengthUsed;

		public IntPtr sourceUserData;

		public IntPtr destBufferPointer;

		public int destBufferLength;

		public int destBufferLengthUsed;

		public IntPtr destUserData;
	}
	[Flags]
	internal enum AcmStreamOpenFlags
	{
		Query = 1,
		Async = 2,
		NonRealTime = 4,
		CallbackTypeMask = 0x70000,
		CallbackNull = 0,
		CallbackWindow = 0x10000,
		CallbackTask = 0x20000,
		CallbackFunction = 0x30000,
		CallbackThread = 0x20000,
		CallbackEvent = 0x50000
	}
	internal enum AcmStreamSizeFlags
	{
		Source,
		Destination
	}
	[StructLayout(LayoutKind.Sequential)]
	public class WaveFilter
	{
		public int StructureSize = Marshal.SizeOf(typeof(WaveFilter));

		public int FilterTag;

		public int Filter;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
		public int[] Reserved;
	}
}

plugins/NVorbis.dll

Decompiled a month 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.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using NVorbis.Contracts;
using NVorbis.Contracts.Ogg;
using NVorbis.Ogg;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyCompany("Andrew Ward")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © Andrew Ward 2021")]
[assembly: AssemblyDescription("A fully managed implementation of a Xiph.org Foundation Ogg Vorbis decoder.")]
[assembly: AssemblyFileVersion("0.10.5.0")]
[assembly: AssemblyInformationalVersion("0.10.5")]
[assembly: AssemblyProduct("NVorbis")]
[assembly: AssemblyTitle("NVorbis")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/NVorbis/NVorbis")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: AssemblyVersion("0.10.5.0")]
namespace NVorbis
{
	internal class Codebook : ICodebook
	{
		private class FastRange : IReadOnlyList<int>, IReadOnlyCollection<int>, IEnumerable<int>, IEnumerable
		{
			[ThreadStatic]
			private static FastRange _cachedRange;

			private int _start;

			private int _count;

			public int this[int index]
			{
				get
				{
					if (index > _count)
					{
						throw new ArgumentOutOfRangeException();
					}
					return _start + index;
				}
			}

			public int Count => _count;

			internal static FastRange Get(int start, int count)
			{
				FastRange obj = _cachedRange ?? (_cachedRange = new FastRange());
				obj._start = start;
				obj._count = count;
				return obj;
			}

			private FastRange()
			{
			}

			public IEnumerator<int> GetEnumerator()
			{
				throw new NotSupportedException();
			}

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

		private int[] _lengths;

		private float[] _lookupTable;

		private IReadOnlyList<HuffmanListNode> _overflowList;

		private IReadOnlyList<HuffmanListNode> _prefixList;

		private int _prefixBitLength;

		private int _maxBits;

		public float this[int entry, int dim] => _lookupTable[entry * Dimensions + dim];

		public int Dimensions { get; private set; }

		public int Entries { get; private set; }

		public int MapType { get; private set; }

		public void Init(IPacket packet, IHuffman huffman)
		{
			if (packet.ReadBits(24) != 5653314)
			{
				throw new InvalidDataException("Book header had invalid signature!");
			}
			Dimensions = (int)packet.ReadBits(16);
			Entries = (int)packet.ReadBits(24);
			_lengths = new int[Entries];
			InitTree(packet, huffman);
			InitLookupTable(packet);
		}

		private void InitTree(IPacket packet, IHuffman huffman)
		{
			int num = 0;
			bool flag;
			int num5;
			if (packet.ReadBit())
			{
				int num2 = (int)packet.ReadBits(5) + 1;
				int num3 = 0;
				while (num3 < Entries)
				{
					int num4 = (int)packet.ReadBits(Utils.ilog(Entries - num3));
					while (--num4 >= 0)
					{
						_lengths[num3++] = num2;
					}
					num2++;
				}
				num = 0;
				flag = false;
				num5 = num2;
			}
			else
			{
				num5 = -1;
				flag = packet.ReadBit();
				for (int i = 0; i < Entries; i++)
				{
					if (!flag || packet.ReadBit())
					{
						_lengths[i] = (int)packet.ReadBits(5) + 1;
						num++;
					}
					else
					{
						_lengths[i] = -1;
					}
					if (_lengths[i] > num5)
					{
						num5 = _lengths[i];
					}
				}
			}
			if ((_maxBits = num5) > -1)
			{
				int[] array = null;
				if (flag && num >= Entries >> 2)
				{
					array = new int[Entries];
					Array.Copy(_lengths, array, Entries);
					flag = false;
				}
				int num6 = (flag ? num : 0);
				int[] array2 = null;
				int[] array3 = null;
				if (!flag)
				{
					array3 = new int[Entries];
				}
				else if (num6 != 0)
				{
					array = new int[num6];
					array3 = new int[num6];
					array2 = new int[num6];
				}
				if (!ComputeCodewords(flag, array3, array, _lengths, Entries, array2))
				{
					throw new InvalidDataException();
				}
				IReadOnlyList<int> readOnlyList = array2;
				IReadOnlyList<int> value = readOnlyList ?? FastRange.Get(0, array3.Length);
				huffman.GenerateTable(value, array ?? _lengths, array3);
				_prefixList = huffman.PrefixTree;
				_prefixBitLength = huffman.TableBits;
				_overflowList = huffman.OverflowList;
			}
		}

		private bool ComputeCodewords(bool sparse, int[] codewords, int[] codewordLengths, int[] len, int n, int[] values)
		{
			int num = 0;
			uint[] array = new uint[32];
			int i;
			for (i = 0; i < n && len[i] <= 0; i++)
			{
			}
			if (i == n)
			{
				return true;
			}
			AddEntry(sparse, codewords, codewordLengths, 0u, i, num++, len[i], values);
			for (int j = 1; j <= len[i]; j++)
			{
				array[j] = (uint)(1 << 32 - j);
			}
			for (int j = i + 1; j < n; j++)
			{
				int num2 = len[j];
				if (num2 <= 0)
				{
					continue;
				}
				while (num2 > 0 && array[num2] == 0)
				{
					num2--;
				}
				if (num2 == 0)
				{
					return false;
				}
				uint num3 = array[num2];
				array[num2] = 0u;
				AddEntry(sparse, codewords, codewordLengths, Utils.BitReverse(num3), j, num++, len[j], values);
				if (num2 != len[j])
				{
					for (int num4 = len[j]; num4 > num2; num4--)
					{
						array[num4] = num3 + (uint)(1 << 32 - num4);
					}
				}
			}
			return true;
		}

		private void AddEntry(bool sparse, int[] codewords, int[] codewordLengths, uint huffCode, int symbol, int count, int len, int[] values)
		{
			if (sparse)
			{
				codewords[count] = (int)huffCode;
				codewordLengths[count] = len;
				values[count] = symbol;
			}
			else
			{
				codewords[symbol] = (int)huffCode;
			}
		}

		private void InitLookupTable(IPacket packet)
		{
			MapType = (int)packet.ReadBits(4);
			if (MapType == 0)
			{
				return;
			}
			float num = Utils.ConvertFromVorbisFloat32((uint)packet.ReadBits(32));
			float num2 = Utils.ConvertFromVorbisFloat32((uint)packet.ReadBits(32));
			int count = (int)packet.ReadBits(4) + 1;
			bool flag = packet.ReadBit();
			int num3 = Entries * Dimensions;
			float[] array = new float[num3];
			if (MapType == 1)
			{
				num3 = lookup1_values();
			}
			uint[] array2 = new uint[num3];
			for (int i = 0; i < num3; i++)
			{
				array2[i] = (uint)packet.ReadBits(count);
			}
			if (MapType == 1)
			{
				for (int j = 0; j < Entries; j++)
				{
					double num4 = 0.0;
					int num5 = 1;
					for (int k = 0; k < Dimensions; k++)
					{
						int num6 = j / num5 % num3;
						double num7 = (double)((float)array2[num6] * num2 + num) + num4;
						array[j * Dimensions + k] = (float)num7;
						if (flag)
						{
							num4 = num7;
						}
						num5 *= num3;
					}
				}
			}
			else
			{
				for (int l = 0; l < Entries; l++)
				{
					double num8 = 0.0;
					int num9 = l * Dimensions;
					for (int m = 0; m < Dimensions; m++)
					{
						double num10 = (double)((float)array2[num9] * num2 + num) + num8;
						array[l * Dimensions + m] = (float)num10;
						if (flag)
						{
							num8 = num10;
						}
						num9++;
					}
				}
			}
			_lookupTable = array;
		}

		private int lookup1_values()
		{
			int num = (int)Math.Floor(Math.Exp(Math.Log(Entries) / (double)Dimensions));
			if (Math.Floor(Math.Pow(num + 1, Dimensions)) <= (double)Entries)
			{
				num++;
			}
			return num;
		}

		public int DecodeScalar(IPacket packet)
		{
			int index = (int)packet.TryPeekBits(_prefixBitLength, out var bitsRead);
			if (bitsRead == 0)
			{
				return -1;
			}
			HuffmanListNode huffmanListNode = _prefixList[index];
			if (huffmanListNode != null)
			{
				packet.SkipBits(huffmanListNode.Length);
				return huffmanListNode.Value;
			}
			index = (int)packet.TryPeekBits(_maxBits, out var _);
			for (int i = 0; i < _overflowList.Count; i++)
			{
				huffmanListNode = _overflowList[i];
				if (huffmanListNode.Bits == (index & huffmanListNode.Mask))
				{
					packet.SkipBits(huffmanListNode.Length);
					return huffmanListNode.Value;
				}
			}
			return -1;
		}
	}
	public abstract class DataPacket : IPacket
	{
		[Flags]
		protected enum PacketFlags : byte
		{
			IsResync = 1,
			IsEndOfStream = 2,
			IsShort = 4,
			User0 = 8,
			User1 = 0x10,
			User2 = 0x20,
			User3 = 0x40,
			User4 = 0x80
		}

		private ulong _bitBucket;

		private int _bitCount;

		private byte _overflowBits;

		private PacketFlags _packetFlags;

		private int _readBits;

		public int ContainerOverheadBits { get; set; }

		public long? GranulePosition { get; set; }

		public bool IsResync
		{
			get
			{
				return GetFlag(PacketFlags.IsResync);
			}
			set
			{
				SetFlag(PacketFlags.IsResync, value);
			}
		}

		public bool IsShort
		{
			get
			{
				return GetFlag(PacketFlags.IsShort);
			}
			private set
			{
				SetFlag(PacketFlags.IsShort, value);
			}
		}

		public bool IsEndOfStream
		{
			get
			{
				return GetFlag(PacketFlags.IsEndOfStream);
			}
			set
			{
				SetFlag(PacketFlags.IsEndOfStream, value);
			}
		}

		public int BitsRead => _readBits;

		public int BitsRemaining => TotalBits - _readBits;

		protected abstract int TotalBits { get; }

		private bool GetFlag(PacketFlags flag)
		{
			return _packetFlags.HasFlag(flag);
		}

		private void SetFlag(PacketFlags flag, bool value)
		{
			if (value)
			{
				_packetFlags |= flag;
			}
			else
			{
				_packetFlags &= (PacketFlags)(byte)(~(int)flag);
			}
		}

		protected abstract int ReadNextByte();

		public virtual void Done()
		{
		}

		public virtual void Reset()
		{
			_bitBucket = 0uL;
			_bitCount = 0;
			_overflowBits = 0;
			_readBits = 0;
		}

		ulong IPacket.ReadBits(int count)
		{
			if (count == 0)
			{
				return 0uL;
			}
			int bitsRead;
			ulong result = TryPeekBits(count, out bitsRead);
			SkipBits(count);
			return result;
		}

		public ulong TryPeekBits(int count, out int bitsRead)
		{
			switch (count)
			{
			default:
				throw new ArgumentOutOfRangeException("count");
			case 0:
				bitsRead = 0;
				return 0uL;
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
			case 11:
			case 12:
			case 13:
			case 14:
			case 15:
			case 16:
			case 17:
			case 18:
			case 19:
			case 20:
			case 21:
			case 22:
			case 23:
			case 24:
			case 25:
			case 26:
			case 27:
			case 28:
			case 29:
			case 30:
			case 31:
			case 32:
			case 33:
			case 34:
			case 35:
			case 36:
			case 37:
			case 38:
			case 39:
			case 40:
			case 41:
			case 42:
			case 43:
			case 44:
			case 45:
			case 46:
			case 47:
			case 48:
			case 49:
			case 50:
			case 51:
			case 52:
			case 53:
			case 54:
			case 55:
			case 56:
			case 57:
			case 58:
			case 59:
			case 60:
			case 61:
			case 62:
			case 63:
			case 64:
				break;
			}
			while (_bitCount < count)
			{
				int num = ReadNextByte();
				if (num == -1)
				{
					bitsRead = _bitCount;
					return _bitBucket;
				}
				_bitBucket = (ulong)((long)(num & 0xFF) << _bitCount) | _bitBucket;
				_bitCount += 8;
				if (_bitCount > 64)
				{
					_overflowBits = (byte)(num >> 72 - _bitCount);
				}
			}
			ulong num2 = _bitBucket;
			if (count < 64)
			{
				num2 &= (ulong)((1L << count) - 1);
			}
			bitsRead = count;
			return num2;
		}

		public void SkipBits(int count)
		{
			if (count <= 0)
			{
				return;
			}
			if (_bitCount > count)
			{
				if (count > 63)
				{
					_bitBucket = 0uL;
				}
				else
				{
					_bitBucket >>= count;
				}
				if (_bitCount > 64)
				{
					int num = _bitCount - 64;
					_bitBucket |= (ulong)_overflowBits << _bitCount - count - num;
					if (num > count)
					{
						_overflowBits = (byte)(_overflowBits >> count);
					}
				}
				_bitCount -= count;
				_readBits += count;
				return;
			}
			if (_bitCount == count)
			{
				_bitBucket = 0uL;
				_bitCount = 0;
				_readBits += count;
				return;
			}
			count -= _bitCount;
			_readBits += _bitCount;
			_bitCount = 0;
			_bitBucket = 0uL;
			while (count > 8)
			{
				if (ReadNextByte() == -1)
				{
					count = 0;
					IsShort = true;
					break;
				}
				count -= 8;
				_readBits += 8;
			}
			if (count > 0)
			{
				int num2 = ReadNextByte();
				if (num2 == -1)
				{
					IsShort = true;
					return;
				}
				_bitBucket = (ulong)(num2 >> count);
				_bitCount = 8 - count;
				_readBits += count;
			}
		}
	}
	public static class Extensions
	{
		public static int Read(this IPacket packet, byte[] buffer, int index, int count)
		{
			if (index < 0 || index >= buffer.Length)
			{
				throw new ArgumentOutOfRangeException("index");
			}
			if (count < 0 || index + count > buffer.Length)
			{
				throw new ArgumentOutOfRangeException("count");
			}
			for (int i = 0; i < count; i++)
			{
				int bitsRead;
				byte b = (byte)packet.TryPeekBits(8, out bitsRead);
				if (bitsRead == 0)
				{
					return i;
				}
				buffer[index++] = b;
				packet.SkipBits(8);
			}
			return count;
		}

		public static byte[] ReadBytes(this IPacket packet, int count)
		{
			byte[] array = new byte[count];
			int num = packet.Read(array, 0, count);
			if (num < count)
			{
				byte[] array2 = new byte[num];
				Buffer.BlockCopy(array, 0, array2, 0, num);
				return array2;
			}
			return array;
		}

		public static bool ReadBit(this IPacket packet)
		{
			return packet.ReadBits(1) == 1;
		}

		public static byte PeekByte(this IPacket packet)
		{
			int bitsRead;
			return (byte)packet.TryPeekBits(8, out bitsRead);
		}

		public static byte ReadByte(this IPacket packet)
		{
			return (byte)packet.ReadBits(8);
		}

		public static short ReadInt16(this IPacket packet)
		{
			return (short)packet.ReadBits(16);
		}

		public static int ReadInt32(this IPacket packet)
		{
			return (int)packet.ReadBits(32);
		}

		public static long ReadInt64(this IPacket packet)
		{
			return (long)packet.ReadBits(64);
		}

		public static ushort ReadUInt16(this IPacket packet)
		{
			return (ushort)packet.ReadBits(16);
		}

		public static uint ReadUInt32(this IPacket packet)
		{
			return (uint)packet.ReadBits(32);
		}

		public static ulong ReadUInt64(this IPacket packet)
		{
			return packet.ReadBits(64);
		}

		public static void SkipBytes(this IPacket packet, int count)
		{
			packet.SkipBits(count * 8);
		}
	}
	internal class Factory : IFactory
	{
		public IHuffman CreateHuffman()
		{
			return new Huffman();
		}

		public IMdct CreateMdct()
		{
			return new Mdct();
		}

		public ICodebook CreateCodebook()
		{
			return new Codebook();
		}

		public IFloor CreateFloor(IPacket packet)
		{
			return (int)packet.ReadBits(16) switch
			{
				0 => new Floor0(), 
				1 => new Floor1(), 
				_ => throw new InvalidDataException("Invalid floor type!"), 
			};
		}

		public IMapping CreateMapping(IPacket packet)
		{
			if (packet.ReadBits(16) != 0L)
			{
				throw new InvalidDataException("Invalid mapping type!");
			}
			return new Mapping();
		}

		public IMode CreateMode()
		{
			return new Mode();
		}

		public IResidue CreateResidue(IPacket packet)
		{
			return (int)packet.ReadBits(16) switch
			{
				0 => new Residue0(), 
				1 => new Residue1(), 
				2 => new Residue2(), 
				_ => throw new InvalidDataException("Invalid residue type!"), 
			};
		}
	}
	internal class Floor0 : IFloor
	{
		private class Data : IFloorData
		{
			internal float[] Coeff;

			internal float Amp;

			public bool ExecuteChannel
			{
				get
				{
					if (ForceEnergy || Amp > 0f)
					{
						return !ForceNoEnergy;
					}
					return false;
				}
			}

			public bool ForceEnergy { get; set; }

			public bool ForceNoEnergy { get; set; }
		}

		private int _order;

		private int _rate;

		private int _bark_map_size;

		private int _ampBits;

		private int _ampOfs;

		private int _ampDiv;

		private ICodebook[] _books;

		private int _bookBits;

		private Dictionary<int, float[]> _wMap;

		private Dictionary<int, int[]> _barkMaps;

		public void Init(IPacket packet, int channels, int block0Size, int block1Size, ICodebook[] codebooks)
		{
			_order = (int)packet.ReadBits(8);
			_rate = (int)packet.ReadBits(16);
			_bark_map_size = (int)packet.ReadBits(16);
			_ampBits = (int)packet.ReadBits(6);
			_ampOfs = (int)packet.ReadBits(8);
			_books = new ICodebook[(int)packet.ReadBits(4) + 1];
			if (_order < 1 || _rate < 1 || _bark_map_size < 1 || _books.Length == 0)
			{
				throw new InvalidDataException();
			}
			_ampDiv = (1 << _ampBits) - 1;
			for (int i = 0; i < _books.Length; i++)
			{
				int num = (int)packet.ReadBits(8);
				if (num < 0 || num >= codebooks.Length)
				{
					throw new InvalidDataException();
				}
				ICodebook codebook = codebooks[num];
				if (codebook.MapType == 0 || codebook.Dimensions < 1)
				{
					throw new InvalidDataException();
				}
				_books[i] = codebook;
			}
			_bookBits = Utils.ilog(_books.Length);
			_barkMaps = new Dictionary<int, int[]>
			{
				[block0Size] = SynthesizeBarkCurve(block0Size / 2),
				[block1Size] = SynthesizeBarkCurve(block1Size / 2)
			};
			_wMap = new Dictionary<int, float[]>
			{
				[block0Size] = SynthesizeWDelMap(block0Size / 2),
				[block1Size] = SynthesizeWDelMap(block1Size / 2)
			};
		}

		private int[] SynthesizeBarkCurve(int n)
		{
			float num = (float)_bark_map_size / toBARK(_rate / 2);
			int[] array = new int[n + 1];
			for (int i = 0; i < n - 1; i++)
			{
				array[i] = Math.Min(_bark_map_size - 1, (int)Math.Floor(toBARK((float)_rate / 2f / (float)n * (float)i) * num));
			}
			array[n] = -1;
			return array;
		}

		private static float toBARK(double lsp)
		{
			return (float)(13.1 * Math.Atan(0.00074 * lsp) + 2.24 * Math.Atan(1.85E-08 * lsp * lsp) + 0.0001 * lsp);
		}

		private float[] SynthesizeWDelMap(int n)
		{
			float num = (float)(Math.PI / (double)_bark_map_size);
			float[] array = new float[n];
			for (int i = 0; i < n; i++)
			{
				array[i] = 2f * (float)Math.Cos(num * (float)i);
			}
			return array;
		}

		public IFloorData Unpack(IPacket packet, int blockSize, int channel)
		{
			Data data = new Data
			{
				Coeff = new float[_order + 1]
			};
			data.Amp = packet.ReadBits(_ampBits);
			if (data.Amp > 0f)
			{
				Array.Clear(data.Coeff, 0, data.Coeff.Length);
				data.Amp = data.Amp / (float)_ampDiv * (float)_ampOfs;
				uint num = (uint)packet.ReadBits(_bookBits);
				if (num >= _books.Length)
				{
					data.Amp = 0f;
					return data;
				}
				ICodebook codebook = _books[num];
				int i = 0;
				while (i < _order)
				{
					int num2 = codebook.DecodeScalar(packet);
					if (num2 == -1)
					{
						data.Amp = 0f;
						return data;
					}
					int num3 = 0;
					for (; i < _order; i++)
					{
						if (num3 >= codebook.Dimensions)
						{
							break;
						}
						data.Coeff[i] = codebook[num2, num3];
						num3++;
					}
				}
				float num4 = 0f;
				int num5 = 0;
				while (num5 < _order)
				{
					int num6 = 0;
					while (num5 < _order && num6 < codebook.Dimensions)
					{
						data.Coeff[num5] += num4;
						num5++;
						num6++;
					}
					num4 = data.Coeff[num5 - 1];
				}
			}
			return data;
		}

		public void Apply(IFloorData floorData, int blockSize, float[] residue)
		{
			if (!(floorData is Data data))
			{
				throw new ArgumentException("Incorrect packet data!");
			}
			int num = blockSize / 2;
			if (data.Amp > 0f)
			{
				int[] array = _barkMaps[blockSize];
				float[] array2 = _wMap[blockSize];
				int num2 = 0;
				for (num2 = 0; num2 < _order; num2++)
				{
					data.Coeff[num2] = 2f * (float)Math.Cos(data.Coeff[num2]);
				}
				num2 = 0;
				while (num2 < num)
				{
					int num3 = array[num2];
					float num4 = 0.5f;
					float num5 = 0.5f;
					float num6 = array2[num3];
					int i;
					for (i = 1; i < _order; i += 2)
					{
						num5 *= num6 - data.Coeff[i - 1];
						num4 *= num6 - data.Coeff[i];
					}
					if (i == _order)
					{
						num5 *= num6 - data.Coeff[i - 1];
						num4 *= num4 * (4f - num6 * num6);
						num5 *= num5;
					}
					else
					{
						num4 *= num4 * (2f - num6);
						num5 *= num5 * (2f + num6);
					}
					num5 = data.Amp / (float)Math.Sqrt(num4 + num5) - (float)_ampOfs;
					num5 = (float)Math.Exp(num5 * 0.11512925f);
					residue[num2] *= num5;
					while (array[++num2] == num3)
					{
						residue[num2] *= num5;
					}
				}
			}
			else
			{
				Array.Clear(residue, 0, num);
			}
		}
	}
	internal class Floor1 : IFloor
	{
		private class Data : IFloorData
		{
			internal int[] Posts = new int[64];

			internal int PostCount;

			public bool ExecuteChannel
			{
				get
				{
					if (ForceEnergy || PostCount > 0)
					{
						return !ForceNoEnergy;
					}
					return false;
				}
			}

			public bool ForceEnergy { get; set; }

			public bool ForceNoEnergy { get; set; }
		}

		private int[] _partitionClass;

		private int[] _classDimensions;

		private int[] _classSubclasses;

		private int[] _xList;

		private int[] _classMasterBookIndex;

		private int[] _hNeigh;

		private int[] _lNeigh;

		private int[] _sortIdx;

		private int _multiplier;

		private int _range;

		private int _yBits;

		private ICodebook[] _classMasterbooks;

		private ICodebook[][] _subclassBooks;

		private int[][] _subclassBookIndex;

		private static readonly int[] _rangeLookup = new int[4] { 256, 128, 86, 64 };

		private static readonly int[] _yBitsLookup = new int[4] { 8, 7, 7, 6 };

		private static readonly float[] inverse_dB_table = new float[256]
		{
			1.0649863E-07f, 1.1341951E-07f, 1.2079015E-07f, 1.2863978E-07f, 1.369995E-07f, 1.459025E-07f, 1.5538409E-07f, 1.6548181E-07f, 1.7623574E-07f, 1.8768856E-07f,
			1.998856E-07f, 2.128753E-07f, 2.2670913E-07f, 2.4144197E-07f, 2.5713223E-07f, 2.7384212E-07f, 2.9163792E-07f, 3.1059022E-07f, 3.307741E-07f, 3.5226967E-07f,
			3.7516213E-07f, 3.995423E-07f, 4.255068E-07f, 4.5315863E-07f, 4.8260745E-07f, 5.1397E-07f, 5.4737063E-07f, 5.829419E-07f, 6.208247E-07f, 6.611694E-07f,
			7.041359E-07f, 7.4989464E-07f, 7.98627E-07f, 8.505263E-07f, 9.057983E-07f, 9.646621E-07f, 1.0273513E-06f, 1.0941144E-06f, 1.1652161E-06f, 1.2409384E-06f,
			1.3215816E-06f, 1.4074654E-06f, 1.4989305E-06f, 1.5963394E-06f, 1.7000785E-06f, 1.8105592E-06f, 1.9282195E-06f, 2.053526E-06f, 2.1869757E-06f, 2.3290977E-06f,
			2.4804558E-06f, 2.6416496E-06f, 2.813319E-06f, 2.9961443E-06f, 3.1908505E-06f, 3.39821E-06f, 3.619045E-06f, 3.8542307E-06f, 4.1047006E-06f, 4.371447E-06f,
			4.6555283E-06f, 4.958071E-06f, 5.280274E-06f, 5.623416E-06f, 5.988857E-06f, 6.3780467E-06f, 6.7925284E-06f, 7.2339453E-06f, 7.704048E-06f, 8.2047E-06f,
			8.737888E-06f, 9.305725E-06f, 9.910464E-06f, 1.0554501E-05f, 1.1240392E-05f, 1.1970856E-05f, 1.2748789E-05f, 1.3577278E-05f, 1.4459606E-05f, 1.5399271E-05f,
			1.6400005E-05f, 1.7465769E-05f, 1.8600793E-05f, 1.9809577E-05f, 2.1096914E-05f, 2.2467912E-05f, 2.3928002E-05f, 2.5482977E-05f, 2.7139005E-05f, 2.890265E-05f,
			3.078091E-05f, 3.2781227E-05f, 3.4911533E-05f, 3.718028E-05f, 3.9596467E-05f, 4.2169668E-05f, 4.491009E-05f, 4.7828602E-05f, 5.0936775E-05f, 5.424693E-05f,
			5.7772202E-05f, 6.152657E-05f, 6.552491E-05f, 6.9783084E-05f, 7.4317984E-05f, 7.914758E-05f, 8.429104E-05f, 8.976875E-05f, 9.560242E-05f, 0.00010181521f,
			0.00010843174f, 0.00011547824f, 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, 0.00015820454f, 0.00016848555f, 0.00017943469f, 0.00019109536f,
			0.00020351382f, 0.0002167393f, 0.00023082423f, 0.00024582449f, 0.00026179955f, 0.00027881275f, 0.00029693157f, 0.00031622787f, 0.00033677815f, 0.00035866388f,
			0.00038197188f, 0.00040679457f, 0.00043323037f, 0.0004613841f, 0.0004913675f, 0.00052329927f, 0.0005573062f, 0.0005935231f, 0.0006320936f, 0.0006731706f,
			0.000716917f, 0.0007635063f, 0.00081312325f, 0.00086596457f, 0.00092223985f, 0.0009821722f, 0.0010459992f, 0.0011139743f, 0.0011863665f, 0.0012634633f,
			0.0013455702f, 0.0014330129f, 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, 0.0019632196f, 0.0020908006f, 0.0022266726f, 0.0023713743f,
			0.0025254795f, 0.0026895993f, 0.0028643848f, 0.0030505287f, 0.003248769f, 0.0034598925f, 0.0036847359f, 0.0039241905f, 0.0041792067f, 0.004450795f,
			0.004740033f, 0.005048067f, 0.0053761187f, 0.005725489f, 0.0060975635f, 0.0064938175f, 0.0069158226f, 0.0073652514f, 0.007843887f, 0.008353627f,
			0.008896492f, 0.009474637f, 0.010090352f, 0.01074608f, 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, 0.014722068f, 0.015678791f,
			0.016697686f, 0.017782796f, 0.018938422f, 0.020169148f, 0.021479854f, 0.022875736f, 0.02436233f, 0.025945531f, 0.027631618f, 0.029427277f,
			0.031339627f, 0.03337625f, 0.035545226f, 0.037855156f, 0.0403152f, 0.042935107f, 0.045725275f, 0.048696756f, 0.05186135f, 0.05523159f,
			0.05882085f, 0.062643364f, 0.06671428f, 0.07104975f, 0.075666964f, 0.08058423f, 0.08582105f, 0.09139818f, 0.097337745f, 0.1036633f,
			0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f, 0.14201812f, 0.15124726f, 0.16107617f, 0.1715438f, 0.18269168f, 0.19456401f,
			0.20720787f, 0.22067343f, 0.23501402f, 0.25028655f, 0.26655158f, 0.28387362f, 0.3023213f, 0.32196787f, 0.34289113f, 0.36517414f,
			0.3889052f, 0.41417846f, 0.44109413f, 0.4697589f, 0.50028646f, 0.53279793f, 0.5674221f, 0.6042964f, 0.64356697f, 0.6853896f,
			0.72993004f, 0.777365f, 0.8278826f, 0.88168305f, 0.9389798f, 1f
		};

		public void Init(IPacket packet, int channels, int block0Size, int block1Size, ICodebook[] codebooks)
		{
			int num = -1;
			_partitionClass = new int[(uint)packet.ReadBits(5)];
			for (int i = 0; i < _partitionClass.Length; i++)
			{
				_partitionClass[i] = (int)packet.ReadBits(4);
				if (_partitionClass[i] > num)
				{
					num = _partitionClass[i];
				}
			}
			_classDimensions = new int[++num];
			_classSubclasses = new int[num];
			_classMasterbooks = new ICodebook[num];
			_classMasterBookIndex = new int[num];
			_subclassBooks = new ICodebook[num][];
			_subclassBookIndex = new int[num][];
			for (int j = 0; j < num; j++)
			{
				_classDimensions[j] = (int)packet.ReadBits(3) + 1;
				_classSubclasses[j] = (int)packet.ReadBits(2);
				if (_classSubclasses[j] > 0)
				{
					_classMasterBookIndex[j] = (int)packet.ReadBits(8);
					_classMasterbooks[j] = codebooks[_classMasterBookIndex[j]];
				}
				_subclassBooks[j] = new ICodebook[1 << _classSubclasses[j]];
				_subclassBookIndex[j] = new int[_subclassBooks[j].Length];
				for (int k = 0; k < _subclassBooks[j].Length; k++)
				{
					int num2 = (int)packet.ReadBits(8) - 1;
					if (num2 >= 0)
					{
						_subclassBooks[j][k] = codebooks[num2];
					}
					_subclassBookIndex[j][k] = num2;
				}
			}
			_multiplier = (int)packet.ReadBits(2);
			_range = _rangeLookup[_multiplier];
			_yBits = _yBitsLookup[_multiplier];
			_multiplier++;
			int num3 = (int)packet.ReadBits(4);
			List<int> list = new List<int>();
			list.Add(0);
			list.Add(1 << num3);
			for (int l = 0; l < _partitionClass.Length; l++)
			{
				int num4 = _partitionClass[l];
				for (int m = 0; m < _classDimensions[num4]; m++)
				{
					list.Add((int)packet.ReadBits(num3));
				}
			}
			_xList = list.ToArray();
			_lNeigh = new int[list.Count];
			_hNeigh = new int[list.Count];
			_sortIdx = new int[list.Count];
			_sortIdx[0] = 0;
			_sortIdx[1] = 1;
			for (int n = 2; n < _lNeigh.Length; n++)
			{
				_lNeigh[n] = 0;
				_hNeigh[n] = 1;
				_sortIdx[n] = n;
				for (int num5 = 2; num5 < n; num5++)
				{
					int num6 = _xList[num5];
					if (num6 < _xList[n])
					{
						if (num6 > _xList[_lNeigh[n]])
						{
							_lNeigh[n] = num5;
						}
					}
					else if (num6 < _xList[_hNeigh[n]])
					{
						_hNeigh[n] = num5;
					}
				}
			}
			for (int num7 = 0; num7 < _sortIdx.Length - 1; num7++)
			{
				for (int num8 = num7 + 1; num8 < _sortIdx.Length; num8++)
				{
					if (_xList[num7] == _xList[num8])
					{
						throw new InvalidDataException();
					}
					if (_xList[_sortIdx[num7]] > _xList[_sortIdx[num8]])
					{
						int num9 = _sortIdx[num7];
						_sortIdx[num7] = _sortIdx[num8];
						_sortIdx[num8] = num9;
					}
				}
			}
		}

		public IFloorData Unpack(IPacket packet, int blockSize, int channel)
		{
			Data data = new Data();
			if (packet.ReadBit())
			{
				int num = 2;
				data.Posts[0] = (int)packet.ReadBits(_yBits);
				data.Posts[1] = (int)packet.ReadBits(_yBits);
				for (int i = 0; i < _partitionClass.Length; i++)
				{
					int num2 = _partitionClass[i];
					int num3 = _classDimensions[num2];
					int num4 = _classSubclasses[num2];
					int num5 = (1 << num4) - 1;
					uint num6 = 0u;
					if (num4 > 0 && (num6 = (uint)_classMasterbooks[num2].DecodeScalar(packet)) == uint.MaxValue)
					{
						num = 0;
						break;
					}
					for (int j = 0; j < num3; j++)
					{
						ICodebook codebook = _subclassBooks[num2][num6 & num5];
						num6 >>= num4;
						if (codebook != null && (data.Posts[num] = codebook.DecodeScalar(packet)) == -1)
						{
							num = 0;
							i = _partitionClass.Length;
							break;
						}
						num++;
					}
				}
				data.PostCount = num;
			}
			return data;
		}

		public void Apply(IFloorData floorData, int blockSize, float[] residue)
		{
			if (!(floorData is Data data))
			{
				throw new ArgumentException("Incorrect packet data!", "packetData");
			}
			int num = blockSize / 2;
			if (data.PostCount > 0)
			{
				bool[] array = UnwrapPosts(data);
				int num2 = 0;
				int num3 = data.Posts[0] * _multiplier;
				for (int i = 1; i < data.PostCount; i++)
				{
					int num4 = _sortIdx[i];
					if (array[num4])
					{
						int num5 = _xList[num4];
						int num6 = data.Posts[num4] * _multiplier;
						if (num2 < num)
						{
							RenderLineMulti(num2, num3, Math.Min(num5, num), num6, residue);
						}
						num2 = num5;
						num3 = num6;
					}
					if (num2 >= num)
					{
						break;
					}
				}
				if (num2 < num)
				{
					RenderLineMulti(num2, num3, num, num3, residue);
				}
			}
			else
			{
				Array.Clear(residue, 0, num);
			}
		}

		private bool[] UnwrapPosts(Data data)
		{
			bool[] array = new bool[64];
			array[0] = true;
			array[1] = true;
			int[] array2 = new int[64];
			array2[0] = data.Posts[0];
			array2[1] = data.Posts[1];
			for (int i = 2; i < data.PostCount; i++)
			{
				int num = _lNeigh[i];
				int num2 = _hNeigh[i];
				int num3 = RenderPoint(_xList[num], array2[num], _xList[num2], array2[num2], _xList[i]);
				int num4 = data.Posts[i];
				int num5 = _range - num3;
				int num6 = num3;
				int num7 = ((num5 >= num6) ? (num6 * 2) : (num5 * 2));
				if (num4 != 0)
				{
					array[num] = true;
					array[num2] = true;
					array[i] = true;
					if (num4 >= num7)
					{
						if (num5 > num6)
						{
							array2[i] = num4 - num6 + num3;
						}
						else
						{
							array2[i] = num3 - num4 + num5 - 1;
						}
					}
					else if (num4 % 2 == 1)
					{
						array2[i] = num3 - (num4 + 1) / 2;
					}
					else
					{
						array2[i] = num3 + num4 / 2;
					}
				}
				else
				{
					array[i] = false;
					array2[i] = num3;
				}
			}
			for (int j = 0; j < data.PostCount; j++)
			{
				data.Posts[j] = array2[j];
			}
			return array;
		}

		private int RenderPoint(int x0, int y0, int x1, int y1, int X)
		{
			int num = y1 - y0;
			int num2 = x1 - x0;
			int num3 = Math.Abs(num) * (X - x0) / num2;
			if (num < 0)
			{
				return y0 - num3;
			}
			return y0 + num3;
		}

		private void RenderLineMulti(int x0, int y0, int x1, int y1, float[] v)
		{
			int num = y1 - y0;
			int num2 = x1 - x0;
			int num3 = Math.Abs(num);
			int num4 = 1 - ((num >> 31) & 1) * 2;
			int num5 = num / num2;
			int num6 = x0;
			int num7 = y0;
			int num8 = -num2;
			v[x0] *= inverse_dB_table[y0];
			num3 -= Math.Abs(num5) * num2;
			while (++num6 < x1)
			{
				num7 += num5;
				num8 += num3;
				if (num8 >= 0)
				{
					num8 -= num2;
					num7 += num4;
				}
				v[num6] *= inverse_dB_table[num7];
			}
		}
	}
	internal class Huffman : IHuffman, IComparer<HuffmanListNode>
	{
		private const int MAX_TABLE_BITS = 10;

		public int TableBits { get; private set; }

		public IReadOnlyList<HuffmanListNode> PrefixTree { get; private set; }

		public IReadOnlyList<HuffmanListNode> OverflowList { get; private set; }

		public void GenerateTable(IReadOnlyList<int> values, int[] lengthList, int[] codeList)
		{
			HuffmanListNode[] array = new HuffmanListNode[lengthList.Length];
			int num = 0;
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new HuffmanListNode
				{
					Value = values[i],
					Length = ((lengthList[i] <= 0) ? 99999 : lengthList[i]),
					Bits = codeList[i],
					Mask = (1 << lengthList[i]) - 1
				};
				if (lengthList[i] > 0 && num < lengthList[i])
				{
					num = lengthList[i];
				}
			}
			Array.Sort(array, 0, array.Length, this);
			int num2 = ((num > 10) ? 10 : num);
			List<HuffmanListNode> list = new List<HuffmanListNode>(1 << num2);
			List<HuffmanListNode> list2 = null;
			for (int j = 0; j < array.Length && array[j].Length < 99999; j++)
			{
				int length = array[j].Length;
				if (length > num2)
				{
					list2 = new List<HuffmanListNode>(array.Length - j);
					for (; j < array.Length && array[j].Length < 99999; j++)
					{
						list2.Add(array[j]);
					}
					continue;
				}
				int num3 = 1 << num2 - length;
				HuffmanListNode huffmanListNode = array[j];
				for (int k = 0; k < num3; k++)
				{
					int num4 = (k << length) | huffmanListNode.Bits;
					while (list.Count <= num4)
					{
						list.Add(null);
					}
					list[num4] = huffmanListNode;
				}
			}
			while (list.Count < 1 << num2)
			{
				list.Add(null);
			}
			TableBits = num2;
			PrefixTree = list;
			OverflowList = list2;
		}

		int IComparer<HuffmanListNode>.Compare(HuffmanListNode x, HuffmanListNode y)
		{
			int num = x.Length - y.Length;
			if (num == 0)
			{
				return x.Bits - y.Bits;
			}
			return num;
		}
	}
	[Obsolete("Moved to NVorbis.Contracts.IContainerReader", true)]
	public interface IContainerReader : NVorbis.Contracts.IContainerReader, IDisposable
	{
		[Obsolete("Use Streams.Select(s => s.StreamSerial).ToArray() instead.", true)]
		int[] StreamSerials { get; }

		[Obsolete("No longer supported.", true)]
		int PagesRead { get; }

		[Obsolete("Moved to NewStreamCallback.", true)]
		event EventHandler<NewStreamEventArgs> NewStream;

		[Obsolete("Renamed to TryInit().", true)]
		bool Init();

		[Obsolete("No longer supported.", true)]
		int GetTotalPageCount();
	}
	[Obsolete("Moved to NVorbis.Contracts.IPacketProvider", true)]
	public interface IPacketProvider : NVorbis.Contracts.IPacketProvider
	{
		[Obsolete("Moved to per-stream IStreamStats instance on IStreamDecoder.Stats or VorbisReader.Stats.", true)]
		long ContainerBits { get; }

		[Obsolete("No longer supported.", true)]
		event EventHandler ParameterChange;

		[Obsolete("No longer supported.", true)]
		int GetTotalPageCount();

		[Obsolete("Getting a packet by index is no longer supported.", true)]
		DataPacket GetPacket(int packetIndex);

		[Obsolete("Moved to long SeekTo(long, int, GetPacketGranuleCount)", true)]
		DataPacket FindPacket(long granulePos, Func<DataPacket, DataPacket, int> packetGranuleCountCallback);

		[Obsolete("Seeking to a specified packet is no longer supported.  See SeekTo(...) instead.", true)]
		void SeekToPacket(DataPacket packet, int preRoll);
	}
	[Obsolete("Moved to NVorbis.Contracts.IStreamStats", true)]
	public interface IVorbisStreamStatus : IStreamStats
	{
		[Obsolete("No longer supported.", true)]
		TimeSpan PageLatency { get; }

		[Obsolete("No longer supported.", true)]
		TimeSpan PacketLatency { get; }

		[Obsolete("No longer supported.", true)]
		TimeSpan SecondLatency { get; }

		[Obsolete("No longer supported.", true)]
		int PagesRead { get; }

		[Obsolete("No longer supported.", true)]
		int TotalPages { get; }

		[Obsolete("Use IStreamDecoder.HasClipped instead.  VorbisReader.HasClipped will return the same value for the stream it is handling.", true)]
		bool Clipped { get; }
	}
	internal class Mapping : IMapping
	{
		private IMdct _mdct;

		private int[] _couplingAngle;

		private int[] _couplingMangitude;

		private IFloor[] _submapFloor;

		private IResidue[] _submapResidue;

		private IFloor[] _channelFloor;

		private IResidue[] _channelResidue;

		public void Init(IPacket packet, int channels, IFloor[] floors, IResidue[] residues, IMdct mdct)
		{
			int num = 1;
			if (packet.ReadBit())
			{
				num += (int)packet.ReadBits(4);
			}
			int num2 = 0;
			if (packet.ReadBit())
			{
				num2 = (int)packet.ReadBits(8) + 1;
			}
			int count = Utils.ilog(channels - 1);
			_couplingAngle = new int[num2];
			_couplingMangitude = new int[num2];
			for (int i = 0; i < num2; i++)
			{
				int num3 = (int)packet.ReadBits(count);
				int num4 = (int)packet.ReadBits(count);
				if (num3 == num4 || num3 > channels - 1 || num4 > channels - 1)
				{
					throw new InvalidDataException("Invalid magnitude or angle in mapping header!");
				}
				_couplingAngle[i] = num4;
				_couplingMangitude[i] = num3;
			}
			if (packet.ReadBits(2) != 0L)
			{
				throw new InvalidDataException("Reserved bits not 0 in mapping header.");
			}
			int[] array = new int[channels];
			if (num > 1)
			{
				for (int j = 0; j < channels; j++)
				{
					array[j] = (int)packet.ReadBits(4);
					if (array[j] > num)
					{
						throw new InvalidDataException("Invalid channel mux submap index in mapping header!");
					}
				}
			}
			_submapFloor = new IFloor[num];
			_submapResidue = new IResidue[num];
			for (int k = 0; k < num; k++)
			{
				packet.SkipBits(8);
				int num5 = (int)packet.ReadBits(8);
				if (num5 >= floors.Length)
				{
					throw new InvalidDataException("Invalid floor number in mapping header!");
				}
				int num6 = (int)packet.ReadBits(8);
				if (num6 >= residues.Length)
				{
					throw new InvalidDataException("Invalid residue number in mapping header!");
				}
				_submapFloor[k] = floors[num5];
				_submapResidue[k] = residues[num6];
			}
			_channelFloor = new IFloor[channels];
			_channelResidue = new IResidue[channels];
			for (int l = 0; l < channels; l++)
			{
				_channelFloor[l] = _submapFloor[array[l]];
				_channelResidue[l] = _submapResidue[array[l]];
			}
			_mdct = mdct;
		}

		public void DecodePacket(IPacket packet, int blockSize, int channels, float[][] buffer)
		{
			int num = blockSize >> 1;
			IFloorData[] array = new IFloorData[_channelFloor.Length];
			bool[] array2 = new bool[_channelFloor.Length];
			for (int i = 0; i < _channelFloor.Length; i++)
			{
				array[i] = _channelFloor[i].Unpack(packet, blockSize, i);
				array2[i] = !array[i].ExecuteChannel;
				Array.Clear(buffer[i], 0, num);
			}
			for (int j = 0; j < _couplingAngle.Length; j++)
			{
				if (array[_couplingAngle[j]].ExecuteChannel || array[_couplingMangitude[j]].ExecuteChannel)
				{
					array[_couplingAngle[j]].ForceEnergy = true;
					array[_couplingMangitude[j]].ForceEnergy = true;
				}
			}
			for (int k = 0; k < _submapFloor.Length; k++)
			{
				for (int l = 0; l < _channelFloor.Length; l++)
				{
					if (_submapFloor[k] != _channelFloor[l] || _submapResidue[k] != _channelResidue[l])
					{
						array[l].ForceNoEnergy = true;
					}
				}
				_submapResidue[k].Decode(packet, array2, blockSize, buffer);
			}
			for (int num2 = _couplingAngle.Length - 1; num2 >= 0; num2--)
			{
				if (array[_couplingAngle[num2]].ExecuteChannel || array[_couplingMangitude[num2]].ExecuteChannel)
				{
					float[] array3 = buffer[_couplingMangitude[num2]];
					float[] array4 = buffer[_couplingAngle[num2]];
					for (int m = 0; m < num; m++)
					{
						float num3 = array3[m];
						float num4 = array4[m];
						float num5;
						float num6;
						if (num3 > 0f)
						{
							if (num4 > 0f)
							{
								num5 = num3;
								num6 = num3 - num4;
							}
							else
							{
								num6 = num3;
								num5 = num3 + num4;
							}
						}
						else if (num4 > 0f)
						{
							num5 = num3;
							num6 = num3 + num4;
						}
						else
						{
							num6 = num3;
							num5 = num3 - num4;
						}
						array3[m] = num5;
						array4[m] = num6;
					}
				}
			}
			for (int n = 0; n < _channelFloor.Length; n++)
			{
				if (array[n].ExecuteChannel)
				{
					_channelFloor[n].Apply(array[n], blockSize, buffer[n]);
					_mdct.Reverse(buffer[n], blockSize);
				}
				else
				{
					Array.Clear(buffer[n], num, num);
				}
			}
		}
	}
	internal class Mdct : IMdct
	{
		private class MdctImpl
		{
			private readonly int _n;

			private readonly int _n2;

			private readonly int _n4;

			private readonly int _n8;

			private readonly int _ld;

			private readonly float[] _a;

			private readonly float[] _b;

			private readonly float[] _c;

			private readonly ushort[] _bitrev;

			public MdctImpl(int n)
			{
				_n = n;
				_n2 = n >> 1;
				_n4 = _n2 >> 1;
				_n8 = _n4 >> 1;
				_ld = Utils.ilog(n) - 1;
				_a = new float[_n2];
				_b = new float[_n2];
				_c = new float[_n4];
				int num;
				int num2 = (num = 0);
				while (num2 < _n4)
				{
					_a[num] = (float)Math.Cos((float)(4 * num2) * (float)Math.PI / (float)n);
					_a[num + 1] = (float)(0.0 - Math.Sin((float)(4 * num2) * (float)Math.PI / (float)n));
					_b[num] = (float)Math.Cos((float)(num + 1) * (float)Math.PI / (float)n / 2f) * 0.5f;
					_b[num + 1] = (float)Math.Sin((float)(num + 1) * (float)Math.PI / (float)n / 2f) * 0.5f;
					num2++;
					num += 2;
				}
				num2 = (num = 0);
				while (num2 < _n8)
				{
					_c[num] = (float)Math.Cos((float)(2 * (num + 1)) * (float)Math.PI / (float)n);
					_c[num + 1] = (float)(0.0 - Math.Sin((float)(2 * (num + 1)) * (float)Math.PI / (float)n));
					num2++;
					num += 2;
				}
				_bitrev = new ushort[_n8];
				for (int i = 0; i < _n8; i++)
				{
					_bitrev[i] = (ushort)(Utils.BitReverse((uint)i, _ld - 3) << 2);
				}
			}

			internal void CalcReverse(float[] buffer)
			{
				float[] array = new float[_n2];
				int num = _n2 - 2;
				int num2 = 0;
				int i = 0;
				for (int n = _n2; i != n; i += 4)
				{
					array[num + 1] = buffer[i] * _a[num2] - buffer[i + 2] * _a[num2 + 1];
					array[num] = buffer[i] * _a[num2 + 1] + buffer[i + 2] * _a[num2];
					num -= 2;
					num2 += 2;
				}
				i = _n2 - 3;
				while (num >= 0)
				{
					array[num + 1] = (0f - buffer[i + 2]) * _a[num2] - (0f - buffer[i]) * _a[num2 + 1];
					array[num] = (0f - buffer[i + 2]) * _a[num2 + 1] + (0f - buffer[i]) * _a[num2];
					num -= 2;
					num2 += 2;
					i -= 4;
				}
				float[] array2 = array;
				int num3 = _n2 - 8;
				int num4 = _n4;
				int num5 = 0;
				int num6 = _n4;
				int num7 = 0;
				while (num3 >= 0)
				{
					float num8 = array2[num4 + 1] - array2[num5 + 1];
					float num9 = array2[num4] - array2[num5];
					buffer[num6 + 1] = array2[num4 + 1] + array2[num5 + 1];
					buffer[num6] = array2[num4] + array2[num5];
					buffer[num7 + 1] = num8 * _a[num3 + 4] - num9 * _a[num3 + 5];
					buffer[num7] = num9 * _a[num3 + 4] + num8 * _a[num3 + 5];
					num8 = array2[num4 + 3] - array2[num5 + 3];
					num9 = array2[num4 + 2] - array2[num5 + 2];
					buffer[num6 + 3] = array2[num4 + 3] + array2[num5 + 3];
					buffer[num6 + 2] = array2[num4 + 2] + array2[num5 + 2];
					buffer[num7 + 3] = num8 * _a[num3] - num9 * _a[num3 + 1];
					buffer[num7 + 2] = num9 * _a[num3] + num8 * _a[num3 + 1];
					num3 -= 8;
					num6 += 4;
					num7 += 4;
					num4 += 4;
					num5 += 4;
				}
				int n2 = _n >> 4;
				int num10 = _n2 - 1;
				_ = _n4;
				step3_iter0_loop(n2, buffer, num10 - 0, -_n8);
				step3_iter0_loop(_n >> 4, buffer, _n2 - 1 - _n4, -_n8);
				int lim = _n >> 5;
				int num11 = _n2 - 1;
				_ = _n8;
				step3_inner_r_loop(lim, buffer, num11 - 0, -(_n >> 4), 16);
				step3_inner_r_loop(_n >> 5, buffer, _n2 - 1 - _n8, -(_n >> 4), 16);
				step3_inner_r_loop(_n >> 5, buffer, _n2 - 1 - _n8 * 2, -(_n >> 4), 16);
				step3_inner_r_loop(_n >> 5, buffer, _n2 - 1 - _n8 * 3, -(_n >> 4), 16);
				int j;
				for (j = 2; j < _ld - 3 >> 1; j++)
				{
					int num12 = _n >> j + 2;
					int num13 = num12 >> 1;
					int num14 = 1 << j + 1;
					for (int k = 0; k < num14; k++)
					{
						step3_inner_r_loop(_n >> j + 4, buffer, _n2 - 1 - num12 * k, -num13, 1 << j + 3);
					}
				}
				for (; j < _ld - 6; j++)
				{
					int num15 = _n >> j + 2;
					int num16 = 1 << j + 3;
					int num17 = num15 >> 1;
					int num18 = _n >> j + 6;
					int n3 = 1 << j + 1;
					int num19 = _n2 - 1;
					int num20 = 0;
					for (int num21 = num18; num21 > 0; num21--)
					{
						step3_inner_s_loop(n3, buffer, num19, -num17, num20, num16, num15);
						num20 += num16 * 4;
						num19 -= 8;
					}
				}
				step3_inner_s_loop_ld654(_n >> 5, buffer, _n2 - 1, _n);
				int num22 = 0;
				int num23 = _n4 - 4;
				int num24 = _n2 - 4;
				while (num23 >= 0)
				{
					int num25 = _bitrev[num22];
					array2[num24 + 3] = buffer[num25];
					array2[num24 + 2] = buffer[num25 + 1];
					array2[num23 + 3] = buffer[num25 + 2];
					array2[num23 + 2] = buffer[num25 + 3];
					num25 = _bitrev[num22 + 1];
					array2[num24 + 1] = buffer[num25];
					array2[num24] = buffer[num25 + 1];
					array2[num23 + 1] = buffer[num25 + 2];
					array2[num23] = buffer[num25 + 3];
					num23 -= 4;
					num24 -= 4;
					num22 += 2;
				}
				int num26 = 0;
				int num27 = 0;
				int num28 = _n2 - 4;
				while (num27 < num28)
				{
					float num29 = array2[num27] - array2[num28 + 2];
					float num30 = array2[num27 + 1] + array2[num28 + 3];
					float num31 = _c[num26 + 1] * num29 + _c[num26] * num30;
					float num32 = _c[num26 + 1] * num30 - _c[num26] * num29;
					float num33 = array2[num27] + array2[num28 + 2];
					float num34 = array2[num27 + 1] - array2[num28 + 3];
					array2[num27] = num33 + num31;
					array2[num27 + 1] = num34 + num32;
					array2[num28 + 2] = num33 - num31;
					array2[num28 + 3] = num32 - num34;
					num29 = array2[num27 + 2] - array2[num28];
					num30 = array2[num27 + 3] + array2[num28 + 1];
					num31 = _c[num26 + 3] * num29 + _c[num26 + 2] * num30;
					num32 = _c[num26 + 3] * num30 - _c[num26 + 2] * num29;
					num33 = array2[num27 + 2] + array2[num28];
					num34 = array2[num27 + 3] - array2[num28 + 1];
					array2[num27 + 2] = num33 + num31;
					array2[num27 + 3] = num34 + num32;
					array2[num28] = num33 - num31;
					array2[num28 + 1] = num32 - num34;
					num26 += 4;
					num27 += 4;
					num28 -= 4;
				}
				int num35 = _n2 - 8;
				int num36 = _n2 - 8;
				int num37 = 0;
				int num38 = _n2 - 4;
				int num39 = _n2;
				int num40 = _n - 4;
				while (num36 >= 0)
				{
					float num41 = array[num36 + 6] * _b[num35 + 7] - array[num36 + 7] * _b[num35 + 6];
					float num42 = (0f - array[num36 + 6]) * _b[num35 + 6] - array[num36 + 7] * _b[num35 + 7];
					buffer[num37] = num41;
					buffer[num38 + 3] = 0f - num41;
					buffer[num39] = num42;
					buffer[num40 + 3] = num42;
					float num43 = array[num36 + 4] * _b[num35 + 5] - array[num36 + 5] * _b[num35 + 4];
					float num44 = (0f - array[num36 + 4]) * _b[num35 + 4] - array[num36 + 5] * _b[num35 + 5];
					buffer[num37 + 1] = num43;
					buffer[num38 + 2] = 0f - num43;
					buffer[num39 + 1] = num44;
					buffer[num40 + 2] = num44;
					num41 = array[num36 + 2] * _b[num35 + 3] - array[num36 + 3] * _b[num35 + 2];
					num42 = (0f - array[num36 + 2]) * _b[num35 + 2] - array[num36 + 3] * _b[num35 + 3];
					buffer[num37 + 2] = num41;
					buffer[num38 + 1] = 0f - num41;
					buffer[num39 + 2] = num42;
					buffer[num40 + 1] = num42;
					num43 = array[num36] * _b[num35 + 1] - array[num36 + 1] * _b[num35];
					num44 = (0f - array[num36]) * _b[num35] - array[num36 + 1] * _b[num35 + 1];
					buffer[num37 + 3] = num43;
					buffer[num38] = 0f - num43;
					buffer[num39 + 3] = num44;
					buffer[num40] = num44;
					num35 -= 8;
					num36 -= 8;
					num37 += 4;
					num39 += 4;
					num38 -= 4;
					num40 -= 4;
				}
			}

			private void step3_iter0_loop(int n, float[] e, int i_off, int k_off)
			{
				int num = i_off;
				int num2 = num + k_off;
				int num3 = 0;
				for (int num4 = n >> 2; num4 > 0; num4--)
				{
					float num5 = e[num] - e[num2];
					float num6 = e[num - 1] - e[num2 - 1];
					e[num] += e[num2];
					e[num - 1] += e[num2 - 1];
					e[num2] = num5 * _a[num3] - num6 * _a[num3 + 1];
					e[num2 - 1] = num6 * _a[num3] + num5 * _a[num3 + 1];
					num3 += 8;
					num5 = e[num - 2] - e[num2 - 2];
					num6 = e[num - 3] - e[num2 - 3];
					e[num - 2] += e[num2 - 2];
					e[num - 3] += e[num2 - 3];
					e[num2 - 2] = num5 * _a[num3] - num6 * _a[num3 + 1];
					e[num2 - 3] = num6 * _a[num3] + num5 * _a[num3 + 1];
					num3 += 8;
					num5 = e[num - 4] - e[num2 - 4];
					num6 = e[num - 5] - e[num2 - 5];
					e[num - 4] += e[num2 - 4];
					e[num - 5] += e[num2 - 5];
					e[num2 - 4] = num5 * _a[num3] - num6 * _a[num3 + 1];
					e[num2 - 5] = num6 * _a[num3] + num5 * _a[num3 + 1];
					num3 += 8;
					num5 = e[num - 6] - e[num2 - 6];
					num6 = e[num - 7] - e[num2 - 7];
					e[num - 6] += e[num2 - 6];
					e[num - 7] += e[num2 - 7];
					e[num2 - 6] = num5 * _a[num3] - num6 * _a[num3 + 1];
					e[num2 - 7] = num6 * _a[num3] + num5 * _a[num3 + 1];
					num3 += 8;
					num -= 8;
					num2 -= 8;
				}
			}

			private void step3_inner_r_loop(int lim, float[] e, int d0, int k_off, int k1)
			{
				int num = d0;
				int num2 = num + k_off;
				int num3 = 0;
				for (int num4 = lim >> 2; num4 > 0; num4--)
				{
					float num5 = e[num] - e[num2];
					float num6 = e[num - 1] - e[num2 - 1];
					e[num] += e[num2];
					e[num - 1] += e[num2 - 1];
					e[num2] = num5 * _a[num3] - num6 * _a[num3 + 1];
					e[num2 - 1] = num6 * _a[num3] + num5 * _a[num3 + 1];
					num3 += k1;
					num5 = e[num - 2] - e[num2 - 2];
					num6 = e[num - 3] - e[num2 - 3];
					e[num - 2] += e[num2 - 2];
					e[num - 3] += e[num2 - 3];
					e[num2 - 2] = num5 * _a[num3] - num6 * _a[num3 + 1];
					e[num2 - 3] = num6 * _a[num3] + num5 * _a[num3 + 1];
					num3 += k1;
					num5 = e[num - 4] - e[num2 - 4];
					num6 = e[num - 5] - e[num2 - 5];
					e[num - 4] += e[num2 - 4];
					e[num - 5] += e[num2 - 5];
					e[num2 - 4] = num5 * _a[num3] - num6 * _a[num3 + 1];
					e[num2 - 5] = num6 * _a[num3] + num5 * _a[num3 + 1];
					num3 += k1;
					num5 = e[num - 6] - e[num2 - 6];
					num6 = e[num - 7] - e[num2 - 7];
					e[num - 6] += e[num2 - 6];
					e[num - 7] += e[num2 - 7];
					e[num2 - 6] = num5 * _a[num3] - num6 * _a[num3 + 1];
					e[num2 - 7] = num6 * _a[num3] + num5 * _a[num3 + 1];
					num3 += k1;
					num -= 8;
					num2 -= 8;
				}
			}

			private void step3_inner_s_loop(int n, float[] e, int i_off, int k_off, int a, int a_off, int k0)
			{
				float num = _a[a];
				float num2 = _a[a + 1];
				float num3 = _a[a + a_off];
				float num4 = _a[a + a_off + 1];
				float num5 = _a[a + a_off * 2];
				float num6 = _a[a + a_off * 2 + 1];
				float num7 = _a[a + a_off * 3];
				float num8 = _a[a + a_off * 3 + 1];
				int num9 = i_off;
				int num10 = num9 + k_off;
				for (int num11 = n; num11 > 0; num11--)
				{
					float num12 = e[num9] - e[num10];
					float num13 = e[num9 - 1] - e[num10 - 1];
					e[num9] += e[num10];
					e[num9 - 1] += e[num10 - 1];
					e[num10] = num12 * num - num13 * num2;
					e[num10 - 1] = num13 * num + num12 * num2;
					num12 = e[num9 - 2] - e[num10 - 2];
					num13 = e[num9 - 3] - e[num10 - 3];
					e[num9 - 2] += e[num10 - 2];
					e[num9 - 3] += e[num10 - 3];
					e[num10 - 2] = num12 * num3 - num13 * num4;
					e[num10 - 3] = num13 * num3 + num12 * num4;
					num12 = e[num9 - 4] - e[num10 - 4];
					num13 = e[num9 - 5] - e[num10 - 5];
					e[num9 - 4] += e[num10 - 4];
					e[num9 - 5] += e[num10 - 5];
					e[num10 - 4] = num12 * num5 - num13 * num6;
					e[num10 - 5] = num13 * num5 + num12 * num6;
					num12 = e[num9 - 6] - e[num10 - 6];
					num13 = e[num9 - 7] - e[num10 - 7];
					e[num9 - 6] += e[num10 - 6];
					e[num9 - 7] += e[num10 - 7];
					e[num10 - 6] = num12 * num7 - num13 * num8;
					e[num10 - 7] = num13 * num7 + num12 * num8;
					num9 -= k0;
					num10 -= k0;
				}
			}

			private void step3_inner_s_loop_ld654(int n, float[] e, int i_off, int base_n)
			{
				int num = base_n >> 3;
				float num2 = _a[num];
				int num3 = i_off;
				int num4 = num3 - 16 * n;
				while (num3 > num4)
				{
					float num5 = e[num3] - e[num3 - 8];
					float num6 = e[num3 - 1] - e[num3 - 9];
					e[num3] += e[num3 - 8];
					e[num3 - 1] += e[num3 - 9];
					e[num3 - 8] = num5;
					e[num3 - 9] = num6;
					num5 = e[num3 - 2] - e[num3 - 10];
					num6 = e[num3 - 3] - e[num3 - 11];
					e[num3 - 2] += e[num3 - 10];
					e[num3 - 3] += e[num3 - 11];
					e[num3 - 10] = (num5 + num6) * num2;
					e[num3 - 11] = (num6 - num5) * num2;
					num5 = e[num3 - 12] - e[num3 - 4];
					num6 = e[num3 - 5] - e[num3 - 13];
					e[num3 - 4] += e[num3 - 12];
					e[num3 - 5] += e[num3 - 13];
					e[num3 - 12] = num6;
					e[num3 - 13] = num5;
					num5 = e[num3 - 14] - e[num3 - 6];
					num6 = e[num3 - 7] - e[num3 - 15];
					e[num3 - 6] += e[num3 - 14];
					e[num3 - 7] += e[num3 - 15];
					e[num3 - 14] = (num5 + num6) * num2;
					e[num3 - 15] = (num5 - num6) * num2;
					iter_54(e, num3);
					iter_54(e, num3 - 8);
					num3 -= 16;
				}
			}

			private void iter_54(float[] e, int z)
			{
				float num = e[z] - e[z - 4];
				float num2 = e[z] + e[z - 4];
				float num3 = e[z - 2] + e[z - 6];
				float num4 = e[z - 2] - e[z - 6];
				e[z] = num2 + num3;
				e[z - 2] = num2 - num3;
				float num5 = e[z - 3] - e[z - 7];
				e[z - 4] = num + num5;
				e[z - 6] = num - num5;
				float num6 = e[z - 1] - e[z - 5];
				float num7 = e[z - 1] + e[z - 5];
				float num8 = e[z - 3] + e[z - 7];
				e[z - 1] = num7 + num8;
				e[z - 3] = num7 - num8;
				e[z - 5] = num6 - num4;
				e[z - 7] = num6 + num4;
			}
		}

		private const float M_PI = (float)Math.PI;

		private Dictionary<int, MdctImpl> _setupCache = new Dictionary<int, MdctImpl>();

		public void Reverse(float[] samples, int sampleCount)
		{
			if (!_setupCache.TryGetValue(sampleCount, out var value))
			{
				value = new MdctImpl(sampleCount);
				_setupCache[sampleCount] = value;
			}
			value.CalcReverse(samples);
		}
	}
	internal class Mode : IMode
	{
		private struct OverlapInfo
		{
			public int PacketStartIndex;

			public int PacketTotalLength;

			public int PacketValidLength;
		}

		private const float M_PI2 = (float)Math.PI / 2f;

		private int _channels;

		private bool _blockFlag;

		private int _blockSize;

		private IMapping _mapping;

		private float[][] _windows;

		private OverlapInfo[] _overlapInfo;

		public void Init(IPacket packet, int channels, int block0Size, int block1Size, IMapping[] mappings)
		{
			_channels = channels;
			_blockFlag = packet.ReadBit();
			if (packet.ReadBits(32) != 0L)
			{
				throw new InvalidDataException("Mode header had invalid window or transform type!");
			}
			int num = (int)packet.ReadBits(8);
			if (num >= mappings.Length)
			{
				throw new InvalidDataException("Mode header had invalid mapping index!");
			}
			_mapping = mappings[num];
			if (_blockFlag)
			{
				_blockSize = block1Size;
				_windows = new float[4][]
				{
					CalcWindow(block0Size, block1Size, block0Size),
					CalcWindow(block1Size, block1Size, block0Size),
					CalcWindow(block0Size, block1Size, block1Size),
					CalcWindow(block1Size, block1Size, block1Size)
				};
				_overlapInfo = new OverlapInfo[4]
				{
					CalcOverlap(block0Size, block1Size, block0Size),
					CalcOverlap(block1Size, block1Size, block0Size),
					CalcOverlap(block0Size, block1Size, block1Size),
					CalcOverlap(block1Size, block1Size, block1Size)
				};
			}
			else
			{
				_blockSize = block0Size;
				_windows = new float[1][] { CalcWindow(block0Size, block0Size, block0Size) };
			}
		}

		private static float[] CalcWindow(int prevBlockSize, int blockSize, int nextBlockSize)
		{
			float[] array = new float[blockSize];
			int num = prevBlockSize / 2;
			int num2 = nextBlockSize / 2;
			int num3 = blockSize / 4 - num / 2;
			int num4 = blockSize - blockSize / 4 - num2 / 2;
			for (int i = 0; i < num; i++)
			{
				float num5 = (float)Math.Sin(((double)i + 0.5) / (double)num * 1.5707963705062866);
				num5 *= num5;
				array[num3 + i] = (float)Math.Sin(num5 * ((float)Math.PI / 2f));
			}
			for (int j = num3 + num; j < num4; j++)
			{
				array[j] = 1f;
			}
			for (int k = 0; k < num2; k++)
			{
				float num6 = (float)Math.Sin(((double)(num2 - k) - 0.5) / (double)num2 * 1.5707963705062866);
				num6 *= num6;
				array[num4 + k] = (float)Math.Sin(num6 * ((float)Math.PI / 2f));
			}
			return array;
		}

		private static OverlapInfo CalcOverlap(int prevBlockSize, int blockSize, int nextBlockSize)
		{
			int num = prevBlockSize / 4;
			int num2 = nextBlockSize / 4;
			int packetStartIndex = blockSize / 4 - num;
			int num3 = blockSize / 4 * 3 + num2;
			int packetValidLength = num3 - num2 * 2;
			OverlapInfo result = default(OverlapInfo);
			result.PacketStartIndex = packetStartIndex;
			result.PacketValidLength = packetValidLength;
			result.PacketTotalLength = num3;
			return result;
		}

		private bool GetPacketInfo(IPacket packet, out int windowIndex, out int packetStartIndex, out int packetValidLength, out int packetTotalLength)
		{
			if (packet.IsShort)
			{
				windowIndex = 0;
				packetStartIndex = 0;
				packetValidLength = 0;
				packetTotalLength = 0;
				return false;
			}
			if (_blockFlag)
			{
				bool flag = packet.ReadBit();
				bool flag2 = packet.ReadBit();
				windowIndex = (flag ? 1 : 0) + (flag2 ? 2 : 0);
				OverlapInfo overlapInfo = _overlapInfo[windowIndex];
				packetStartIndex = overlapInfo.PacketStartIndex;
				packetValidLength = overlapInfo.PacketValidLength;
				packetTotalLength = overlapInfo.PacketTotalLength;
			}
			else
			{
				windowIndex = 0;
				packetStartIndex = 0;
				packetValidLength = _blockSize / 2;
				packetTotalLength = _blockSize;
			}
			return true;
		}

		public bool Decode(IPacket packet, float[][] buffer, out int packetStartindex, out int packetValidLength, out int packetTotalLength)
		{
			if (GetPacketInfo(packet, out var windowIndex, out packetStartindex, out packetValidLength, out packetTotalLength))
			{
				_mapping.DecodePacket(packet, _blockSize, _channels, buffer);
				float[] array = _windows[windowIndex];
				for (int i = 0; i < _blockSize; i++)
				{
					for (int j = 0; j < _channels; j++)
					{
						buffer[j][i] *= array[i];
					}
				}
				return true;
			}
			return false;
		}

		public int GetPacketSampleCount(IPacket packet)
		{
			GetPacketInfo(packet, out var _, out var packetStartIndex, out var packetValidLength, out var _);
			return packetValidLength - packetStartIndex;
		}
	}
	[Serializable]
	public class NewStreamEventArgs : EventArgs
	{
		public IStreamDecoder StreamDecoder { get; }

		public bool IgnoreStream { get; set; }

		public NewStreamEventArgs(IStreamDecoder streamDecoder)
		{
			StreamDecoder = streamDecoder ?? throw new ArgumentNullException("streamDecoder");
		}
	}
	internal class Residue0 : IResidue
	{
		private int _channels;

		private int _begin;

		private int _end;

		private int _partitionSize;

		private int _classifications;

		private int _maxStages;

		private ICodebook[][] _books;

		private ICodebook _classBook;

		private int[] _cascade;

		private int[][] _decodeMap;

		private static int icount(int v)
		{
			int num = 0;
			while (v != 0)
			{
				num += v & 1;
				v >>= 1;
			}
			return num;
		}

		public virtual void Init(IPacket packet, int channels, ICodebook[] codebooks)
		{
			_begin = (int)packet.ReadBits(24);
			_end = (int)packet.ReadBits(24);
			_partitionSize = (int)packet.ReadBits(24) + 1;
			_classifications = (int)packet.ReadBits(6) + 1;
			_classBook = codebooks[(uint)packet.ReadBits(8)];
			_cascade = new int[_classifications];
			int num = 0;
			for (int i = 0; i < _classifications; i++)
			{
				int num2 = (int)packet.ReadBits(3);
				if (packet.ReadBit())
				{
					_cascade[i] = ((int)packet.ReadBits(5) << 3) | num2;
				}
				else
				{
					_cascade[i] = num2;
				}
				num += icount(_cascade[i]);
			}
			int[] array = new int[num];
			for (int j = 0; j < num; j++)
			{
				array[j] = (int)packet.ReadBits(8);
				if (codebooks[array[j]].MapType == 0)
				{
					throw new InvalidDataException();
				}
			}
			int entries = _classBook.Entries;
			int num3 = _classBook.Dimensions;
			int num4 = 1;
			while (num3 > 0)
			{
				num4 *= _classifications;
				if (num4 > entries)
				{
					throw new InvalidDataException();
				}
				num3--;
			}
			_books = new ICodebook[_classifications][];
			num = 0;
			int num5 = 0;
			for (int k = 0; k < _classifications; k++)
			{
				int num6 = Utils.ilog(_cascade[k]);
				_books[k] = new ICodebook[num6];
				if (num6 <= 0)
				{
					continue;
				}
				num5 = Math.Max(num5, num6);
				for (int l = 0; l < num6; l++)
				{
					if ((_cascade[k] & (1 << l)) > 0)
					{
						_books[k][l] = codebooks[array[num++]];
					}
				}
			}
			_maxStages = num5;
			_decodeMap = new int[num4][];
			for (int m = 0; m < num4; m++)
			{
				int num7 = m;
				int num8 = num4 / _classifications;
				_decodeMap[m] = new int[_classBook.Dimensions];
				for (int n = 0; n < _classBook.Dimensions; n++)
				{
					int num9 = num7 / num8;
					num7 -= num9 * num8;
					num8 /= _classifications;
					_decodeMap[m][n] = num9;
				}
			}
			_channels = channels;
		}

		public virtual void Decode(IPacket packet, bool[] doNotDecodeChannel, int blockSize, float[][] buffer)
		{
			int num = ((_end < blockSize / 2) ? _end : (blockSize / 2)) - _begin;
			if (num <= 0 || Array.IndexOf(doNotDecodeChannel, value: false) == -1)
			{
				return;
			}
			int num2 = num / _partitionSize;
			int num3 = (num2 + _classBook.Dimensions - 1) / _classBook.Dimensions;
			int[,][] array = new int[_channels, num3][];
			for (int i = 0; i < _maxStages; i++)
			{
				int j = 0;
				int num4 = 0;
				while (j < num2)
				{
					if (i == 0)
					{
						for (int k = 0; k < _channels; k++)
						{
							int num5 = _classBook.DecodeScalar(packet);
							if (num5 >= 0 && num5 < _decodeMap.Length)
							{
								array[k, num4] = _decodeMap[num5];
								continue;
							}
							j = num2;
							i = _maxStages;
							break;
						}
					}
					int num6 = 0;
					for (; j < num2; j++)
					{
						if (num6 >= _classBook.Dimensions)
						{
							break;
						}
						int offset = _begin + j * _partitionSize;
						for (int l = 0; l < _channels; l++)
						{
							int num7 = array[l, num4][num6];
							if ((_cascade[num7] & (1 << i)) != 0)
							{
								ICodebook codebook = _books[num7][i];
								if (codebook != null && WriteVectors(codebook, packet, buffer, l, offset, _partitionSize))
								{
									j = num2;
									i = _maxStages;
									break;
								}
							}
						}
						num6++;
					}
					num4++;
				}
			}
		}

		protected virtual bool WriteVectors(ICodebook codebook, IPacket packet, float[][] residue, int channel, int offset, int partitionSize)
		{
			float[] array = residue[channel];
			int num = partitionSize / codebook.Dimensions;
			int[] array2 = new int[num];
			for (int i = 0; i < num; i++)
			{
				if ((array2[i] = codebook.DecodeScalar(packet)) == -1)
				{
					return true;
				}
			}
			for (int j = 0; j < codebook.Dimensions; j++)
			{
				int num2 = 0;
				while (num2 < num)
				{
					array[offset] += codebook[array2[num2], j];
					num2++;
					offset++;
				}
			}
			return false;
		}
	}
	internal class Residue1 : Residue0
	{
		protected override bool WriteVectors(ICodebook codebook, IPacket packet, float[][] residue, int channel, int offset, int partitionSize)
		{
			float[] array = residue[channel];
			int num = 0;
			while (num < partitionSize)
			{
				int num2 = codebook.DecodeScalar(packet);
				if (num2 == -1)
				{
					return true;
				}
				for (int i = 0; i < codebook.Dimensions; i++)
				{
					array[offset + num] += codebook[num2, i];
					num++;
				}
			}
			return false;
		}
	}
	internal class Residue2 : Residue0
	{
		private int _channels;

		public override void Init(IPacket packet, int channels, ICodebook[] codebooks)
		{
			_channels = channels;
			base.Init(packet, 1, codebooks);
		}

		public override void Decode(IPacket packet, bool[] doNotDecodeChannel, int blockSize, float[][] buffer)
		{
			base.Decode(packet, doNotDecodeChannel, blockSize * _channels, buffer);
		}

		protected override bool WriteVectors(ICodebook codebook, IPacket packet, float[][] residue, int channel, int offset, int partitionSize)
		{
			int num = 0;
			offset /= _channels;
			int num2 = 0;
			while (num2 < partitionSize)
			{
				int num3 = codebook.DecodeScalar(packet);
				if (num3 == -1)
				{
					return true;
				}
				int num4 = 0;
				while (num4 < codebook.Dimensions)
				{
					residue[num][offset] += codebook[num3, num4];
					if (++num == _channels)
					{
						num = 0;
						offset++;
					}
					num4++;
					num2++;
				}
			}
			return false;
		}
	}
	public sealed class StreamDecoder : IStreamDecoder, IDisposable
	{
		private NVorbis.Contracts.IPacketProvider _packetProvider;

		private IFactory _factory;

		private StreamStats _stats;

		private byte _channels;

		private int _sampleRate;

		private int _block0Size;

		private int _block1Size;

		private IMode[] _modes;

		private int _modeFieldBits;

		private string _vendor;

		private string[] _comments;

		private ITagData _tags;

		private long _currentPosition;

		private bool _hasClipped;

		private bool _hasPosition;

		private bool _eosFound;

		private float[][] _nextPacketBuf;

		private float[][] _prevPacketBuf;

		private int _prevPacketStart;

		private int _prevPacketEnd;

		private int _prevPacketStop;

		private static readonly byte[] PacketSignatureStream = new byte[11]
		{
			1, 118, 111, 114, 98, 105, 115, 0, 0, 0,
			0
		};

		private static readonly byte[] PacketSignatureComments = new byte[7] { 3, 118, 111, 114, 98, 105, 115 };

		private static readonly byte[] PacketSignatureBooks = new byte[7] { 5, 118, 111, 114, 98, 105, 115 };

		internal static Func<IFactory> CreateFactory { get; set; } = () => new Factory();


		public int Channels => _channels;

		public int SampleRate => _sampleRate;

		public int UpperBitrate { get; private set; }

		public int NominalBitrate { get; private set; }

		public int LowerBitrate { get; private set; }

		public ITagData Tags => _tags ?? (_tags = new TagData(_vendor, _comments));

		public TimeSpan TotalTime => TimeSpan.FromSeconds((double)TotalSamples / (double)_sampleRate);

		public long TotalSamples => (_packetProvider ?? throw new ObjectDisposedException("StreamDecoder")).GetGranuleCount();

		public TimeSpan TimePosition
		{
			get
			{
				return TimeSpan.FromSeconds((double)_currentPosition / (double)_sampleRate);
			}
			set
			{
				SeekTo(value);
			}
		}

		public long SamplePosition
		{
			get
			{
				return _currentPosition;
			}
			set
			{
				SeekTo(value);
			}
		}

		public bool ClipSamples { get; set; }

		public bool HasClipped => _hasClipped;

		public bool IsEndOfStream
		{
			get
			{
				if (_eosFound)
				{
					return _prevPacketBuf == null;
				}
				return false;
			}
		}

		public IStreamStats Stats => _stats;

		public StreamDecoder(NVorbis.Contracts.IPacketProvider packetProvider)
			: this(packetProvider, new Factory())
		{
		}

		internal StreamDecoder(NVorbis.Contracts.IPacketProvider packetProvider, IFactory factory)
		{
			_packetProvider = packetProvider ?? throw new ArgumentNullException("packetProvider");
			_factory = factory ?? throw new ArgumentNullException("factory");
			_stats = new StreamStats();
			_currentPosition = 0L;
			ClipSamples = true;
			IPacket packet = _packetProvider.PeekNextPacket();
			if (!ProcessHeaderPackets(packet))
			{
				_packetProvider = null;
				packet.Reset();
				throw GetInvalidStreamException(packet);
			}
		}

		private static Exception GetInvalidStreamException(IPacket packet)
		{
			try
			{
				ulong num = packet.ReadBits(64);
				if (num == 7233173838382854223L)
				{
					return new ArgumentException("Found OPUS bitstream.");
				}
				if ((num & 0xFF) == 127)
				{
					return new ArgumentException("Found FLAC bitstream.");
				}
				switch (num)
				{
				case 2314885909937746003uL:
					return new ArgumentException("Found Speex bitstream.");
				case 28254585843050854uL:
					return new ArgumentException("Found Skeleton metadata bitstream.");
				default:
					if ((num & 0xFFFFFFFFFFFF00L) == 27428895509214208L)
					{
						return new ArgumentException("Found Theora bitsream.");
					}
					return new ArgumentException("Could not find Vorbis data to decode.");
				}
			}
			finally
			{
				packet.Reset();
			}
		}

		private bool ProcessHeaderPackets(IPacket packet)
		{
			if (!ProcessHeaderPacket(packet, LoadStreamHeader, delegate
			{
				_packetProvider.GetNextPacket().Done();
			}))
			{
				return false;
			}
			if (!ProcessHeaderPacket(_packetProvider.GetNextPacket(), LoadComments, delegate(IPacket pkt)
			{
				pkt.Done();
			}))
			{
				return false;
			}
			if (!ProcessHeaderPacket(_packetProvider.GetNextPacket(), LoadBooks, delegate(IPacket pkt)
			{
				pkt.Done();
			}))
			{
				return false;
			}
			_currentPosition = 0L;
			ResetDecoder();
			return true;
		}

		private static bool ProcessHeaderPacket(IPacket packet, Func<IPacket, bool> processAction, Action<IPacket> doneAction)
		{
			if (packet != null)
			{
				try
				{
					return processAction(packet);
				}
				finally
				{
					doneAction(packet);
				}
			}
			return false;
		}

		private static bool ValidateHeader(IPacket packet, byte[] expected)
		{
			for (int i = 0; i < expected.Length; i++)
			{
				if (expected[i] != packet.ReadBits(8))
				{
					return false;
				}
			}
			return true;
		}

		private static string ReadString(IPacket packet)
		{
			int num = (int)packet.ReadBits(32);
			if (num == 0)
			{
				return string.Empty;
			}
			byte[] array = new byte[num];
			if (packet.Read(array, 0, num) < num)
			{
				throw new InvalidDataException("Could not read full string!");
			}
			return Encoding.UTF8.GetString(array);
		}

		private bool LoadStreamHeader(IPacket packet)
		{
			if (!ValidateHeader(packet, PacketSignatureStream))
			{
				return false;
			}
			_channels = (byte)packet.ReadBits(8);
			_sampleRate = (int)packet.ReadBits(32);
			UpperBitrate = (int)packet.ReadBits(32);
			NominalBitrate = (int)packet.ReadBits(32);
			LowerBitrate = (int)packet.ReadBits(32);
			_block0Size = 1 << (int)packet.ReadBits(4);
			_block1Size = 1 << (int)packet.ReadBits(4);
			if (NominalBitrate == 0 && UpperBitrate > 0 && LowerBitrate > 0)
			{
				NominalBitrate = (UpperBitrate + LowerBitrate) / 2;
			}
			_stats.SetSampleRate(_sampleRate);
			_stats.AddPacket(-1, packet.BitsRead, packet.BitsRemaining, packet.ContainerOverheadBits);
			return true;
		}

		private bool LoadComments(IPacket packet)
		{
			if (!ValidateHeader(packet, PacketSignatureComments))
			{
				return false;
			}
			_vendor = ReadString(packet);
			_comments = new string[packet.ReadBits(32)];
			for (int i = 0; i < _comments.Length; i++)
			{
				_comments[i] = ReadString(packet);
			}
			_stats.AddPacket(-1, packet.BitsRead, packet.BitsRemaining, packet.ContainerOverheadBits);
			return true;
		}

		private bool LoadBooks(IPacket packet)
		{
			if (!ValidateHeader(packet, PacketSignatureBooks))
			{
				return false;
			}
			IMdct mdct = _factory.CreateMdct();
			IHuffman huffman = _factory.CreateHuffman();
			ICodebook[] array = new ICodebook[packet.ReadBits(8) + 1];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = _factory.CreateCodebook();
				array[i].Init(packet, huffman);
			}
			int num = (int)packet.ReadBits(6) + 1;
			packet.SkipBits(16 * num);
			IFloor[] array2 = new IFloor[packet.ReadBits(6) + 1];
			for (int j = 0; j < array2.Length; j++)
			{
				array2[j] = _factory.CreateFloor(packet);
				array2[j].Init(packet, _channels, _block0Size, _block1Size, array);
			}
			IResidue[] array3 = new IResidue[packet.ReadBits(6) + 1];
			for (int k = 0; k < array3.Length; k++)
			{
				array3[k] = _factory.CreateResidue(packet);
				array3[k].Init(packet, _channels, array);
			}
			IMapping[] array4 = new IMapping[packet.ReadBits(6) + 1];
			for (int l = 0; l < array4.Length; l++)
			{
				array4[l] = _factory.CreateMapping(packet);
				array4[l].Init(packet, _channels, array2, array3, mdct);
			}
			_modes = new IMode[packet.ReadBits(6) + 1];
			for (int m = 0; m < _modes.Length; m++)
			{
				_modes[m] = _factory.CreateMode();
				_modes[m].Init(packet, _channels, _block0Size, _block1Size, array4);
			}
			if (!packet.ReadBit())
			{
				throw new InvalidDataException("Book packet did not end on correct bit!");
			}
			_modeFieldBits = Utils.ilog(_modes.Length - 1);
			_stats.AddPacket(-1, packet.BitsRead, packet.BitsRemaining, packet.ContainerOverheadBits);
			return true;
		}

		private void ResetDecoder()
		{
			_prevPacketBuf = null;
			_prevPacketStart = 0;
			_prevPacketEnd = 0;
			_prevPacketStop = 0;
			_nextPacketBuf = null;
			_eosFound = false;
			_hasClipped = false;
			_hasPosition = false;
		}

		public int Read(Span<float> buffer, int offset, int count)
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			if (offset < 0 || offset + count > buffer.Length)
			{
				throw new ArgumentOutOfRangeException("offset");
			}
			if (count % _channels != 0)
			{
				throw new ArgumentOutOfRangeException("count", "Must be a multiple of Channels!");
			}
			if (_packetProvider == null)
			{
				throw new ObjectDisposedException("StreamDecoder");
			}
			if (count == 0)
			{
				return 0;
			}
			int num = offset;
			int num2 = offset + count;
			while (num < num2)
			{
				if (_prevPacketStart == _prevPacketEnd)
				{
					if (_eosFound)
					{
						_nextPacketBuf = null;
						_prevPacketBuf = null;
						break;
					}
					if (!ReadNextPacket((num - offset) / _channels, out var samplePosition))
					{
						_prevPacketEnd = _prevPacketStop;
					}
					if (samplePosition.HasValue && !_hasPosition)
					{
						_hasPosition = true;
						_currentPosition = samplePosition.Value - (_prevPacketEnd - _prevPacketStart) - (num - offset) / _channels;
					}
				}
				int num3 = Math.Min((num2 - num) / _channels, _prevPacketEnd - _prevPacketStart);
				if (num3 > 0)
				{
					num = ((!ClipSamples) ? (num + CopyBuffer(buffer, num, num3)) : (num + ClippingCopyBuffer(buffer, num, num3)));
				}
			}
			count = num - offset;
			_currentPosition += count / _channels;
			return count;
		}

		private int ClippingCopyBuffer(Span<float> target, int targetIndex, int count)
		{
			int num = targetIndex;
			while (count > 0)
			{
				for (int i = 0; i < _channels; i++)
				{
					target[num++] = Utils.ClipValue(_prevPacketBuf[i][_prevPacketStart], ref _hasClipped);
				}
				_prevPacketStart++;
				count--;
			}
			return num - targetIndex;
		}

		private int CopyBuffer(Span<float> target, int targetIndex, int count)
		{
			int num = targetIndex;
			while (count > 0)
			{
				for (int i = 0; i < _channels; i++)
				{
					target[num++] = _prevPacketBuf[i][_prevPacketStart];
				}
				_prevPacketStart++;
				count--;
			}
			return num - targetIndex;
		}

		private bool ReadNextPacket(int bufferedSamples, out long? samplePosition)
		{
			int packetStartindex;
			int packetValidLength;
			int packetTotalLength;
			bool isEndOfStream;
			int bitsRead;
			int bitsRemaining;
			int containerOverheadBits;
			float[][] array = DecodeNextPacket(out packetStartindex, out packetValidLength, out packetTotalLength, out isEndOfStream, out samplePosition, out bitsRead, out bitsRemaining, out containerOverheadBits);
			_eosFound |= isEndOfStream;
			if (array == null)
			{
				_stats.AddPacket(0, bitsRead, bitsRemaining, containerOverheadBits);
				return false;
			}
			if (samplePosition.HasValue && isEndOfStream)
			{
				long num = _currentPosition + bufferedSamples + packetValidLength - packetStartindex;
				int num2 = (int)(samplePosition.Value - num);
				if (num2 < 0)
				{
					packetValidLength += num2;
				}
			}
			if (_prevPacketEnd > 0)
			{
				OverlapBuffers(_prevPacketBuf, array, _prevPacketStart, _prevPacketStop, packetStartindex, _channels);
				_prevPacketStart = packetStartindex;
			}
			else if (_prevPacketBuf == null)
			{
				_prevPacketStart = packetValidLength;
			}
			_stats.AddPacket(packetValidLength - _prevPacketStart, bitsRead, bitsRemaining, containerOverheadBits);
			_nextPacketBuf = _prevPacketBuf;
			_prevPacketEnd = packetValidLength;
			_prevPacketStop = packetTotalLength;
			_prevPacketBuf = array;
			return true;
		}

		private float[][] DecodeNextPacket(out int packetStartindex, out int packetValidLength, out int packetTotalLength, out bool isEndOfStream, out long? samplePosition, out int bitsRead, out int bitsRemaining, out int containerOverheadBits)
		{
			IPacket packet = null;
			try
			{
				if ((packet = _packetProvider.GetNextPacket()) == null)
				{
					isEndOfStream = true;
				}
				else
				{
					isEndOfStream = packet.IsEndOfStream;
					if (packet.IsResync)
					{
						_hasPosition = false;
					}
					containerOverheadBits = packet.ContainerOverheadBits;
					if (packet.ReadBit())
					{
						bitsRemaining = packet.BitsRemaining + 1;
					}
					else
					{
						IMode mode = _modes[(uint)packet.ReadBits(_modeFieldBits)];
						if (_nextPacketBuf == null)
						{
							_nextPacketBuf = new float[_channels][];
							for (int i = 0; i < _channels; i++)
							{
								_nextPacketBuf[i] = new float[_block1Size];
							}
						}
						if (mode.Decode(packet, _nextPacketBuf, out packetStartindex, out packetValidLength, out packetTotalLength))
						{
							samplePosition = packet.GranulePosition;
							bitsRead = packet.BitsRead;
							bitsRemaining = packet.BitsRemaining;
							return _nextPacketBuf;
						}
						bitsRemaining = packet.BitsRead + packet.BitsRemaining;
					}
				}
				packetStartindex = 0;
				packetValidLength = 0;
				packetTotalLength = 0;
				samplePosition = null;
				bitsRead = 0;
				bitsRemaining = 0;
				containerOverheadBits = 0;
				return null;
			}
			finally
			{
				packet?.Done();
			}
		}

		private static void OverlapBuffers(float[][] previous, float[][] next, int prevStart, int prevLen, int nextStart, int channels)
		{
			while (prevStart < prevLen)
			{
				for (int i = 0; i < channels; i++)
				{
					next[i][nextStart] += previous[i][prevStart];
				}
				prevStart++;
				nextStart++;
			}
		}

		public void SeekTo(TimeSpan timePosition, SeekOrigin seekOrigin = SeekOrigin.Begin)
		{
			SeekTo((long)((double)SampleRate * timePosition.TotalSeconds), seekOrigin);
		}

		public void SeekTo(long samplePosition, SeekOrigin seekOrigin = SeekOrigin.Begin)
		{
			if (_packetProvider == null)
			{
				throw new ObjectDisposedException("StreamDecoder");
			}
			if (!_packetProvider.CanSeek)
			{
				throw new InvalidOperationException("Seek is not supported by the Contracts.IPacketProvider instance.");
			}
			switch (seekOrigin)
			{
			case SeekOrigin.Current:
				samplePosition = SamplePosition - samplePosition;
				break;
			case SeekOrigin.End:
				samplePosition = TotalSamples - samplePosition;
				break;
			default:
				throw new ArgumentOutOfRangeException("seekOrigin");
			case SeekOrigin.Begin:
				break;
			}
			if (samplePosition < 0)
			{
				throw new ArgumentOutOfRangeException("samplePosition");
			}
			int num;
			if (samplePosition == 0L)
			{
				_packetProvider.SeekTo(0L, 0, GetPacketGranules);
				num = 0;
			}
			else
			{
				long num2 = _packetProvider.SeekTo(samplePosition, 1, GetPacketGranules);
				num = (int)(samplePosition - num2);
			}
			ResetDecoder();
			_hasPosition = true;
			if (!ReadNextPacket(0, out var samplePosition2))
			{
				_eosFound = true;
				if (_packetProvider.GetGranuleCount() != samplePosition)
				{
					throw new InvalidOperationException("Could not read pre-roll packet!  Try seeking again prior to reading more samples.");
				}
				_prevPacketStart = _prevPacketStop;
				_currentPosition = samplePosition;
				return;
			}
			if (!ReadNextPacket(0, out samplePosition2))
			{
				ResetDecoder();
				_eosFound = true;
				throw new InvalidOperationException("Could not read pre-roll packet!  Try seeking again prior to reading more samples.");
			}
			_prevPacketStart += num;
			_currentPosition = samplePosition;
		}

		private int GetPacketGranules(IPacket curPacket)
		{
			if (curPacket.IsResync)
			{
				return 0;
			}
			if (curPacket.ReadBit())
			{
				return 0;
			}
			int num = (int)curPacket.ReadBits(_modeFieldBits);
			if (num < 0 || num >= _modes.Length)
			{
				return 0;
			}
			return _modes[num].GetPacketSampleCount(curPacket);
		}

		public void Dispose()
		{
			(_packetProvider as IDisposable)?.Dispose();
			_packetProvider = null;
		}
	}
	internal class StreamStats : IStreamStats
	{
		private int _sampleRate;

		private readonly int[] _packetBits = new int[2];

		private readonly int[] _packetSamples = new int[2];

		private int _packetIndex;

		private long _totalSamples;

		private long _audioBits;

		private long _headerBits;

		private long _containerBits;

		private long _wasteBits;

		private object _lock = new object();

		private int _packetCount;

		public int EffectiveBitRate
		{
			get
			{
				long totalSamples;
				long num;
				lock (_lock)
				{
					totalSamples = _totalSamples;
					num = _audioBits + _headerBits + _containerBits + _wasteBits;
				}
				if (totalSamples > 0)
				{
					return (int)((double)num / (double)totalSamples * (double)_sampleRate);
				}
				return 0;
			}
		}

		public int InstantBitRate
		{
			get
			{
				int num;
				int num2;
				lock (_lock)
				{
					num = _packetBits[0] + _packetBits[1];
					num2 = _packetSamples[0] + _packetSamples[1];
				}
				if (num2 > 0)
				{
					return (int)((double)num / (double)num2 * (double)_sampleRate);
				}
				return 0;
			}
		}

		public long ContainerBits => _containerBits;

		public long OverheadBits => _headerBits;

		public long AudioBits => _audioBits;

		public long WasteBits => _wasteBits;

		public int PacketCount => _packetCount;

		public void ResetStats()
		{
			lock (_lock)
			{
				_packetBits[0] = (_packetBits[1] = 0);
				_packetSamples[0] = (_packetSamples[1] = 0);
				_packetIndex = 0;
				_packetCount = 0;
				_audioBits = 0L;
				_totalSamples = 0L;
				_headerBits = 0L;
				_containerBits = 0L;
				_wasteBits = 0L;
			}
		}

		internal void SetSampleRate(int sampleRate)
		{
			lock (_lock)
			{
				_sampleRate = sampleRate;
				ResetStats();
			}
		}

		internal void AddPacket(int samples, int bits, int waste, int container)
		{
			lock (_lock)
			{
				if (samples >= 0)
				{
					_audioBits += bits;
					_wasteBits += waste;
					_containerBits += container;
					_totalSamples += samples;
					_packetBits[_packetIndex] = bits + waste;
					_packetSamples[_packetIndex] = samples;
					if (++_packetIndex == 2)
					{
						_packetIndex = 0;
					}
				}
				else
				{
					_headerBits += bits;
					_wasteBits += waste;
					_containerBits += container;
				}
			}
		}
	}
	internal class TagData : ITagData
	{
		private static IReadOnlyList<string> s_emptyList = new List<string>();

		private Dictionary<string, IReadOnlyList<string>> _tags;

		public IReadOnlyDictionary<string, IReadOnlyList<string>> All => _tags;

		public string EncoderVendor { get; }

		public string Title => GetTagSingle("TITLE");

		public string Version => GetTagSingle("VERSION");

		public string Album => GetTagSingle("ALBUM");

		public string TrackNumber => GetTagSingle("TRACKNUMBER");

		public string Artist => GetTagSingle("ARTIST");

		public IReadOnlyList<string> Performers => GetTagMulti("PERFORMER");

		public string Copyright => GetTagSingle("COPYRIGHT");

		public string License => GetTagSingle("LICENSE");

		public string Organization => GetTagSingle("ORGANIZATION");

		public string Description => GetTagSingle("DESCRIPTION");

		public IReadOnlyList<string> Genres => GetTagMulti("GENRE");

		public IReadOnlyList<string> Dates => GetTagMulti("DATE");

		public IReadOnlyList<string> Locations => GetTagMulti("LOCATION");

		public string Contact => GetTagSingle("CONTACT");

		public string Isrc => GetTagSingle("ISRC");

		public TagData(string vendor, string[] comments)
		{
			EncoderVendor = vendor;
			Dictionary<string, IReadOnlyList<string>> dictionary = new Dictionary<string, IReadOnlyList<string>>();
			for (int i = 0; i < comments.Length; i++)
			{
				string[] array = comments[i].Split(new char[1] { '=' });
				if (array.Length == 1)
				{
					array = new string[2]
					{
						array[0],
						string.Empty
					};
				}
				int num = array[0].IndexOf('[');
				if (num > -1)
				{
					array[1] = array[0].Substring(num + 1, array[0].Length - num - 2).ToUpper(CultureInfo.CurrentCulture) + ": " + array[1];
					array[0] = array[0].Substring(0, num);
				}
				if (dictionary.TryGetValue(array[0].ToUpperInvariant(), out var value))
				{
					((List<string>)value).Add(array[1]);
					continue;
				}
				dictionary.Add(array[0].ToUpperInvariant(), new List<string> { array[1] });
			}
			_tags = dictionary;
		}

		public string GetTagSingle(string key, bool concatenate = false)
		{
			IReadOnlyList<string> tagMulti = GetTagMulti(key);
			if (tagMulti.Count > 0)
			{
				if (concatenate)
				{
					return string.Join(Environment.NewLine, tagMulti.ToArray());
				}
				return tagMulti[tagMulti.Count - 1];
			}
			return string.Empty;
		}

		public IReadOnlyList<string> GetTagMulti(string key)
		{
			if (_tags.TryGetValue(key.ToUpperInvariant(), out var value))
			{
				return value;
			}
			return s_emptyList;
		}
	}
	internal static class Utils
	{
		internal static int ilog(int x)
		{
			int num = 0;
			while (x > 0)
			{
				num++;
				x >>= 1;
			}
			return num;
		}

		internal static uint BitReverse(uint n)
		{
			return BitReverse(n, 32);
		}

		internal static uint BitReverse(uint n, int bits)
		{
			n = ((n & 0xAAAAAAAAu) >> 1) | ((n & 0x55555555) << 1);
			n = ((n & 0xCCCCCCCCu) >> 2) | ((n & 0x33333333) << 2);
			n = ((n & 0xF0F0F0F0u) >> 4) | ((n & 0xF0F0F0F) << 4);
			n = ((n & 0xFF00FF00u) >> 8) | ((n & 0xFF00FF) << 8);
			return ((n >> 16) | (n << 16)) >> 32 - bits;
		}

		internal static float ClipValue(float value, ref bool clipped)
		{
			if (value > (float)Math.PI * 113f / 355f)
			{
				clipped = true;
				return (float)Math.PI * 113f / 355f;
			}
			if (value < (float)Math.PI * -113f / 355f)
			{
				clipped = true;
				return (float)Math.PI * -113f / 355f;
			}
			return value;
		}

		internal static float ConvertFromVorbisFloat32(uint bits)
		{
			int num = (int)bits >> 31;
			double y = (int)(((bits & 0x7FE00000) >> 21) - 788);
			return (float)(((bits & 0x1FFFFF) ^ num) + (num & 1)) * (float)Math.Pow(2.0, y);
		}
	}
	public sealed class VorbisReader : IVorbisReader, IDisposable
	{
		private readonly List<IStreamDecoder> _decoders;

		private readonly NVorbis.Contracts.IContainerReader _containerReader;

		private readonly bool _closeOnDispose;

		private IStreamDecoder _streamDecoder;

		internal static Func<Stream, bool, NVorbis.Contracts.IContainerReader> CreateContainerReader { get; set; } = (Stream s, bool cod) => new ContainerReader(s, cod);


		internal static Func<NVorbis.Contracts.IPacketProvider, IStreamDecoder> CreateStreamDecoder { get; set; } = (NVorbis.Contracts.IPacketProvider pp) => new StreamDecoder(pp, new Factory());


		public IReadOnlyList<IStreamDecoder> Streams => _decoders;

		public int Channels => _streamDecoder.Channels;

		public int SampleRate => _streamDecoder.SampleRate;

		public int UpperBitrate => _streamDecoder.UpperBitrate;

		public int NominalBitrate => _streamDecoder.NominalBitrate;

		public int LowerBitrate => _streamDecoder.LowerBitrate;

		public ITagData Tags => _streamDecoder.Tags;

		[Obsolete("Use .Tags.EncoderVendor instead.")]
		public string Vendor => _streamDecoder.Tags.EncoderVendor;

		[Obsolete("Use .Tags.All instead.")]
		public string[] Comments => _streamDecoder.Tags.All.SelectMany((KeyValuePair<string, IReadOnlyList<string>> k) => k.Value, (KeyValuePair<string, IReadOnlyList<string>> kvp, string Item) => kvp.Key + "=" + Item).ToArray();

		[Obsolete("No longer supported.  Will receive a new stream when parameters change.", true)]
		public bool IsParameterChange
		{
			get
			{
				throw new NotSupportedException();
			}
		}

		public long ContainerOverheadBits => _containerReader?.ContainerBits ?? 0;

		public long ContainerWasteBits => _containerReader?.WasteBits ?? 0;

		public int StreamIndex => _decoders.IndexOf(_streamDecoder);

		[Obsolete("Use .Streams.Count instead.")]
		public int StreamCount => _decoders.Count;

		[Obsolete("Use VorbisReader.TimePosition instead.")]
		public TimeSpan DecodedTime
		{
			get
			{
				return _streamDecoder.TimePosition;
			}
			set
			{
				TimePosition = value;
			}
		}

		[Obsolete("Use VorbisReader.SamplePosition instead.")]
		public long DecodedPosition
		{
			get
			{
				return _streamDecoder.SamplePosition;
			}
			set
			{
				SamplePosition = value;
			}
		}

		public TimeSpan TotalTime => _streamDecoder.TotalTime;

		public long TotalSamples => _streamDecoder.TotalSamples;

		public TimeSpan TimePosition
		{
			get
			{
				return _streamDecoder.TimePosition;
			}
			set
			{
				_streamDecoder.TimePosition = value;
			}
		}

		public long SamplePosition
		{
			get
			{
				return _streamDecoder.SamplePosition;
			}
			set
			{
				_streamDecoder.SamplePosition = value;
			}
		}

		public bool IsEndOfStream => _streamDecoder.IsEndOfStream;

		public bool ClipSamples
		{
			get
			{
				return _streamDecoder.ClipSamples;
			}
			set
			{
				_streamDecoder.ClipSamples = value;
			}
		}

		public bool HasClipped => _streamDecoder.HasClipped;

		public IStreamStats StreamStats => _streamDecoder.Stats;

		[Obsolete("Use Streams[*].Stats instead.", true)]
		public IVorbisStreamStatus[] Stats
		{
			get
			{
				throw new NotSupportedException();
			}
		}

		public event EventHandler<NewStreamEventArgs> NewStream;

		public VorbisReader(string fileName)
			: this(File.OpenRead(fileName))
		{
		}

		public VorbisReader(Stream stream, bool closeOnDispose = true)
		{
			_decoders = new List<IStreamDecoder>();
			NVorbis.Contracts.IContainerReader containerReader = CreateContainerReader(stream, closeOnDispose);
			containerReader.NewStreamCallback = ProcessNewStream;
			if (!containerReader.TryInit() || _decoders.Count == 0)
			{
				containerReader.NewStreamCallback = null;
				containerReader.Dispose();
				if (closeOnDispose)
				{
					stream.Dispose();
				}
				throw new ArgumentException("Could not load the specified container!", "containerReader");
			}
			_closeOnDispose = closeOnDispose;
			_containerReader = containerReader;
			_streamDecoder = _decoders[0];
		}

		[Obsolete("Use \"new StreamDecoder(Contracts.IPacketProvider)\" and the container's NewStreamCallback or Streams property instead.", true)]
		public VorbisReader(NVorbis.Contracts.IContainerReader containerReader)
		{
			throw new NotSupportedException();
		}

		[Obsolete("Use \"new StreamDecoder(Contracts.IPacketProvider)\" instead.", true)]
		public VorbisReader(NVorbis.Contracts.IPacketProvider packetProvider)
		{
			throw new NotSupportedException();
		}

		private bool ProcessNewStream(NVorbis.Contracts.IPacketProvider packetProvider)
		{
			IStreamDecoder streamDecoder = CreateStreamDecoder(packetProvider);
			streamDecoder.ClipSamples = true;
			NewStreamEventArgs newStreamEventArgs = new NewStreamEventArgs(streamDecoder);
			this.NewStream?.Invoke(this, newStreamEventArgs);
			if (!newStreamEventArgs.IgnoreStream)
			{
				_decoders.Add(streamDecoder);
				return true;
			}
			return false;
		}

		public void Dispose()
		{
			if (_decoders != null)
			{
				foreach (IStreamDecoder decoder in _decoders)
				{
					decoder.Dispose();
				}
				_decoders.Clear();
			}
			if (_containerReader != null)
			{
				_containerReader.NewStreamCallback = null;
				if (_closeOnDispose)
				{
					_containerReader.Dispose();
				}
			}
		}

		public bool FindNextStream()
		{
			if (_containerReader == null)
			{
				return false;
			}
			return _containerReader.FindNextStream();
		}

		public bool SwitchStreams(int index)
		{
			if (index < 0 || index >= _decoders.Count)
			{
				throw new ArgumentOutOfRangeException("index");
			}
			IStreamDecoder streamDecoder = _decoders[index];
			IStreamDecoder streamDecoder2 = _streamDecoder;
			if (streamDecoder == streamDecoder2)
			{
				return false;
			}
			streamDecoder.ClipSamples = streamDecoder2.ClipSamples;
			_streamDecoder = streamDecoder;
			if (streamDecoder.Channels == streamDecoder2.Channels)
			{
				return streamDecoder.SampleRate != streamDecoder2.SampleRate;
			}
			return true;
		}

		public void SeekTo(TimeSpan timePosition, SeekOrigin seekOrigin = SeekOrigin.Begin)
		{
			_streamDecoder.SeekTo(timePosition, seekOrigin);
		}

		public void SeekTo(long samplePosition, SeekOrigin seekOrigin = SeekOrigin.Begin)
		{
			_streamDecoder.SeekTo(samplePosition, seekOrigin);
		}

		public int ReadSamples(float[] buffer, int offset, int count)
		{
			count -= count % _streamDecoder.Channels;
			if (count > 0)
			{
				return _streamDecoder.Read(buffer, offset, count);
			}
			return 0;
		}

		public int ReadSamples(Span<float> buffer)
		{
			int count = buffer.Length - buffer.Length % _streamDecoder.Channels;
			if (!buffer.IsEmpty)
			{
				return _streamDecoder.Read(buffer, 0, count);
			}
			return 0;
		}

		[Obsolete("No longer needed.", true)]
		public void ClearParameterChange()
		{
			throw new NotSupportedException();
		}
	}
}
namespace NVorbis.Ogg
{
	public sealed class ContainerReader : NVorbis.Contracts.IContainerReader, IDisposable
	{
		private IPageReader _reader;

		private List<WeakReference<NVorbis.Contracts.IPacketProvider>> _packetProviders;

		private bool _foundStream;

		internal static Func<Stream, bool, Func<NVorbis.Contracts.IPacketProvider, bool>, IPageReader> CreatePageReader { get; set; } = (Stream s, bool cod, Func<NVorbis.Contracts.IPacketProvider, bool> cb) => new PageReader(s, cod, cb);


		internal static Func<Stream, bool, Func<NVorbis.Contracts.IPacketProvider, bool>, IPageReader> CreateForwardOnlyPageReader { get; set; } = (Stream s, bool cod, Func<NVorbis.Contracts.IPacketProvider, bool> cb) => new ForwardOnlyPageReader(s, cod, cb);


		public NewStreamHandler NewStreamCallback { get; set; }

		public bool CanSeek { get; }

		public long WasteBits => _reader.WasteBits;

		public long ContainerBits => _reader.ContainerBits;

		public IReadOnlyList<NVorbis.Contracts.IPacketProvider> GetStreams()
		{
			List<NVorbis.Contracts.IPacketProvider> list = new List<NVorbis.Contracts.IPacketProvider>(_packetProviders.Count);
			for (int i = 0; i < _packetProviders.Count; i++)
			{
				if (_packetProviders[i].TryGetTarget(out var target))
				{
					list.Add(target);
					continue;
				}
				list.RemoveAt(i);
				i--;
			}
			return list;
		}

		public ContainerReader(Stream stream, bool closeOnDispose)
		{
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			_packetProviders = new List<WeakReference<NVorbis.Contracts.IPacketProvider>>();
			if (stream.CanSeek)
			{
				_reader = CreatePageReader(stream, closeOnDispose, ProcessNewStream);
				CanSeek = true;
			}
			else
			{
				_reader = CreateForwardOnlyPageReader(stream, closeOnDispose, ProcessNewStream);
			}
		}

		public bool TryInit()
		{
			return FindNextStream();
		}

		public bool FindNextStream()
		{
			_reader.Lock();
			try
			{
				_foundStream = false;
				while (_reader.ReadNextPage())
				{
					if (_foundStream)
					{
						return true;
					}
				}
				return false;
			}
			finally
			{
				_reader.Release();
			}
		}

		private bool ProcessNewStream(NVorbis.Contracts.IPacketProvider packetProvider)
		{
			bool flag = _reader.Release();
			try
			{
				NewStreamHandler newStreamCallback = NewStreamCallback;
				if (newStreamCallback == null || newStreamCallback(packetProvider))
				{
					_packetProviders.Add(new WeakReference<NVorbis.Contracts.IPacketProvider>(packetProvider));
					_foundStream = true;
					return true;
				}
				return false;
			}
			finally
			{
				if (flag)
				{
					_reader.Lock();
				}
			}
		}

		public void Dispose()
		{
			_reader?.Dispose();
			_reader = null;
		}
	}
	internal class Crc : ICrc
	{
		private const uint CRC32_POLY = 79764919u;

		private static readonly uint[] s_crcTable;

		private uint _crc;

		static Crc()
		{
			s_crcTable = new uint[256];
			for (uint num = 0u; num < 256; num++)
			{
				uint num2 = num << 24;
				for (int i = 0; i < 8; i++)
				{
					num2 = (num2 << 1) ^ ((num2 >= 2147483648u) ? 79764919u : 0u);
				}
				s_crcTable[num] = num2;
			}
		}

		public Crc()
		{
			Reset();
		}

		public void Reset()
		{
			_crc = 0u;
		}

		public void Update(int nextVal)
		{
			_crc = (_crc << 8) ^ s_crcTable[nextVal ^ (_crc >> 24)];
		}

		public bool Test(uint checkCrc)
		{
			return _crc == checkCrc;
		}
	}
	internal class ForwardOnlyPacketProvider : DataPacket, IForwardOnlyPacketProvider, NVorbis.Contracts.IPacketProvider
	{
		private int _lastSeqNo;

		private readonly Queue<(byte[] buf, bool isResync)> _pageQueue = new Queue<(byte[], bool)>();

		private readonly IPageReader _reader;

		private byte[] _pageBuf;

		private int _packetIndex;

		private bool _isEndOfStream;

		private int _dataStart;

		private bool _lastWasPeek;

		private Memory<byte> _packetBuf;

		private int _dataIndex;

		public bool CanSeek => false;

		public int StreamSerial { get; }

		protected override int TotalBits => _packetBuf.Length * 8;

		public ForwardOnlyPacketProvider(IPageReader reader, int streamSerial)
		{
			_reader = reader;
			StreamSerial = streamSerial;
			_packetIndex = int.MaxValue;
		}

		public bool AddPage(byte[] buf, bool isResync)
		{
			if ((buf[5] & 2u) != 0)
			{
				if (_isEndOfStream)
				{
					return false;
				}
				isResync = true;
				_lastSeqNo = BitConverter.ToInt32(buf, 18);
			}
			else
			{
				int num = BitConverter.ToInt32(buf, 18);
				isResync |= num != _lastSeqNo + 1;
				_lastSeqNo = num;
			}
			int num2 = 0;
			for (int i = 0; i < buf[26]; i++)
			{
				num2 += buf[27 + i];
			}
			if (num2 == 0)
			{
				return false;
			}
			_pageQueue.Enqueue((buf, isResync));
			return true;
		}

		public void SetEndOfStream()
		{
			_isEndOfStream = true;
		}

		public IPacket GetNextPacket()
		{
			if (_packetBuf.Length > 0)
			{
				if (!_lastWasPeek)
				{
					throw new InvalidOperationException("Must call Done() on previous packet first.");
				}
				_lastWasPeek = false;
				return this;
			}
			_lastWasPeek = false;
			if (GetPacket())
			{
				return this;
			}
			return null;
		}

		public IPacket PeekNextPacket()
		{
			if (_packetBuf.Length > 0)
			{
				if (!_lastWasPeek)
				{
					throw new InvalidOperationException("Must call Done() on previous packet first.");
				}
				return this;
			}
			_lastWasPeek = true;
			if (GetPacket())
			{
				return this;
			}
			return null;
		}

		private bool GetPacket()
		{
			byte[] pageBuf;
			bool isResync;
			int packetIndex;
			bool isContinuation;
			bool isContinued;
			int dataStart;
			if (_pageBuf != null && _packetIndex < 27 + _pageBuf[26])
			{
				pageBuf = _pageBuf;
				isResync = false;
				dataStart = _dataStart;
				packetIndex = _packetIndex;
				isContinuation = false;
				isContinued = pageBuf[26 + pageBuf[26]] == byte.MaxValue;
			}
			else if (!ReadNextPage(out pageBuf, out isResync, out dataStart, out packetIndex, out isContinuation, out isContinued))
			{
				return false;
			}
			int num = dataStart;
			bool flag = packetIndex == 27;
			if (isContinuation && flag)
			{
				isResync = true;
				num += GetPacketLength(pageBuf, ref packetIndex);
				if (packetIndex == 27 + pageBuf[26])
				{
					return GetPacket();
				}
			}
			if (!flag)
			{
				num = 0;
			}
			int packetLength = GetPacketLength(pageBuf, ref packetIndex);
			Memory<byte> memory = new Memory<byte>(pageBuf, dataStart, packetLength);
			dataStart += packetLength;
			bool flag2 = packetIndex == 27 + pageBuf[26];
			if (isContinued)
			{
				if (flag2)
				{
					flag2 = false;
				}
				else
				{
					int packetIndex2 = packetIndex;
					GetPacketLength(pageBuf, ref packetIndex2);
					flag2 = packetIndex2 == 27 + pageBuf[26];
				}
			}
			bool flag3 = false;
			long? granulePosition = null;
			if (flag2)
			{
				granulePosition = BitConverter.ToInt64(pageBuf, 6);
				if ((pageBuf[5] & 4u) != 0 || (_isEndOfStream && _pageQueue.Count == 0))
				{
					flag3 = true;
				}
			}
			else
			{
				while (isContinued && packetIndex == 27 + pageBuf[26] && ReadNextPage(out pageBuf, out isResync, out dataStart, out packetIndex, out isContinuation, out isContinued) && !isResync && isContinuation)
				{
					num += 27 + pageBuf[26];
					Memory<byte> memory2 = memory;
					int packetLength2 = GetPacketLength(pageBuf, ref packetIndex);
					memory = new Memory<byte>(new byte[memory2.Length + packetLength2]);
					memory2.CopyTo(memory);
					new Memory<byte>(pageBuf, dataStart, packetLength2).CopyTo(memory.Slice(memory2.Length));
					dataStart += packetLength2;
				}
			}
			base.IsResync = isResync;
			base.GranulePosition = granulePosition;
			base.IsEndOfStream = flag3;
			base.ContainerOverheadBits = num * 8;
			_pageBuf = pageBuf;
			_dataStart = dataStart;
			_packetIndex = packetIndex;
			_packetBuf = memory;
			_isEndOfStream |= flag3;
			Reset();
			return true;
		}

		private bool ReadNextPage(out byte[] pageBuf, out bool isResync, out int dataStart, out int packetIndex, out bool isContinuation, out bool isContinued)
		{
			while (_pageQueue.Count == 0)
			{
				if (_isEndOfStream || !_reader.ReadNextPage())
				{
					pageBuf = null;
					isResync = false;
					dataStart = 0;
					packetIndex = 0;
					isContinuation = false;
					isContinued = false;
					return false;
				}
			}
			(byte[], bool) tuple = _pageQueue.Dequeue();
			pageBuf = tuple.Item1;
			isResync = tuple.Item2;
			dataStart = pageBuf[26] + 27;
			packetIndex = 27;
			isContinuation = (pageBuf[5] & 1) != 0;
			isContinued = pageBuf[26 + pageBuf[26]] == byte.MaxValue;
			retu

plugins/System.Buffers.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using FxResources.System.Buffers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Buffers")]
[assembly: AssemblyDescription("System.Buffers")]
[assembly: AssemblyDefaultAlias("System.Buffers")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.25519.03")]
[assembly: AssemblyInformationalVersion("4.6.25519.03 built by: dlab-DDVSOWINAGE013. Commit Hash: 8321c729934c0f8be754953439b88e6e1c120c24")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.2.0")]
[module: UnverifiableCode]
namespace FxResources.System.Buffers
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		private const string s_resourcesName = "FxResources.System.Buffers.SR";

		private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));

		internal static string ArgumentException_BufferNotFromPool => GetResourceString("ArgumentException_BufferNotFromPool", null);

		internal static Type ResourceType => typeof(SR);

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal))
			{
				return defaultString;
			}
			return text;
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.All)]
	internal class __BlockReflectionAttribute : Attribute
	{
	}
}
namespace System.Buffers
{
	public abstract class ArrayPool<T>
	{
		private static ArrayPool<T> s_sharedInstance;

		public static ArrayPool<T> Shared
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return Volatile.Read(ref s_sharedInstance) ?? EnsureSharedCreated();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ArrayPool<T> EnsureSharedCreated()
		{
			Interlocked.CompareExchange(ref s_sharedInstance, Create(), null);
			return s_sharedInstance;
		}

		public static ArrayPool<T> Create()
		{
			return new DefaultArrayPool<T>();
		}

		public static ArrayPool<T> Create(int maxArrayLength, int maxArraysPerBucket)
		{
			return new DefaultArrayPool<T>(maxArrayLength, maxArraysPerBucket);
		}

		public abstract T[] Rent(int minimumLength);

		public abstract void Return(T[] array, bool clearArray = false);
	}
	[EventSource(Name = "System.Buffers.ArrayPoolEventSource")]
	internal sealed class ArrayPoolEventSource : EventSource
	{
		internal enum BufferAllocatedReason
		{
			Pooled,
			OverMaximumSize,
			PoolExhausted
		}

		internal static readonly System.Buffers.ArrayPoolEventSource Log = new System.Buffers.ArrayPoolEventSource();

		[Event(1, Level = EventLevel.Verbose)]
		internal unsafe void BufferRented(int bufferId, int bufferSize, int poolId, int bucketId)
		{
			EventData* ptr = stackalloc EventData[4];
			ptr->Size = 4;
			ptr->DataPointer = (IntPtr)(&bufferId);
			ptr[1].Size = 4;
			ptr[1].DataPointer = (IntPtr)(&bufferSize);
			ptr[2].Size = 4;
			ptr[2].DataPointer = (IntPtr)(&poolId);
			ptr[3].Size = 4;
			ptr[3].DataPointer = (IntPtr)(&bucketId);
			WriteEventCore(1, 4, ptr);
		}

		[Event(2, Level = EventLevel.Informational)]
		internal unsafe void BufferAllocated(int bufferId, int bufferSize, int poolId, int bucketId, BufferAllocatedReason reason)
		{
			EventData* ptr = stackalloc EventData[5];
			ptr->Size = 4;
			ptr->DataPointer = (IntPtr)(&bufferId);
			ptr[1].Size = 4;
			ptr[1].DataPointer = (IntPtr)(&bufferSize);
			ptr[2].Size = 4;
			ptr[2].DataPointer = (IntPtr)(&poolId);
			ptr[3].Size = 4;
			ptr[3].DataPointer = (IntPtr)(&bucketId);
			ptr[4].Size = 4;
			ptr[4].DataPointer = (IntPtr)(&reason);
			WriteEventCore(2, 5, ptr);
		}

		[Event(3, Level = EventLevel.Verbose)]
		internal void BufferReturned(int bufferId, int bufferSize, int poolId)
		{
			WriteEvent(3, bufferId, bufferSize, poolId);
		}
	}
	internal sealed class DefaultArrayPool<T> : ArrayPool<T>
	{
		private sealed class Bucket
		{
			internal readonly int _bufferLength;

			private readonly T[][] _buffers;

			private readonly int _poolId;

			private SpinLock _lock;

			private int _index;

			internal int Id => GetHashCode();

			internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
			{
				_lock = new SpinLock(Debugger.IsAttached);
				_buffers = new T[numberOfBuffers][];
				_bufferLength = bufferLength;
				_poolId = poolId;
			}

			internal T[] Rent()
			{
				T[][] buffers = _buffers;
				T[] array = null;
				bool lockTaken = false;
				bool flag = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index < buffers.Length)
					{
						array = buffers[_index];
						buffers[_index++] = null;
						flag = array == null;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
				if (flag)
				{
					array = new T[_bufferLength];
					System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
					if (log.IsEnabled())
					{
						log.BufferAllocated(array.GetHashCode(), _bufferLength, _poolId, Id, System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.Pooled);
					}
				}
				return array;
			}

			internal void Return(T[] array)
			{
				if (array.Length != _bufferLength)
				{
					throw new ArgumentException(System.SR.ArgumentException_BufferNotFromPool, "array");
				}
				bool lockTaken = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index != 0)
					{
						_buffers[--_index] = array;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
			}
		}

		private const int DefaultMaxArrayLength = 1048576;

		private const int DefaultMaxNumberOfArraysPerBucket = 50;

		private static T[] s_emptyArray;

		private readonly Bucket[] _buckets;

		private int Id => GetHashCode();

		internal DefaultArrayPool()
			: this(1048576, 50)
		{
		}

		internal DefaultArrayPool(int maxArrayLength, int maxArraysPerBucket)
		{
			if (maxArrayLength <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArrayLength");
			}
			if (maxArraysPerBucket <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArraysPerBucket");
			}
			if (maxArrayLength > 1073741824)
			{
				maxArrayLength = 1073741824;
			}
			else if (maxArrayLength < 16)
			{
				maxArrayLength = 16;
			}
			int id = Id;
			int num = System.Buffers.Utilities.SelectBucketIndex(maxArrayLength);
			Bucket[] array = new Bucket[num + 1];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new Bucket(System.Buffers.Utilities.GetMaxSizeForBucket(i), maxArraysPerBucket, id);
			}
			_buckets = array;
		}

		public override T[] Rent(int minimumLength)
		{
			if (minimumLength < 0)
			{
				throw new ArgumentOutOfRangeException("minimumLength");
			}
			if (minimumLength == 0)
			{
				return s_emptyArray ?? (s_emptyArray = new T[0]);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			T[] array = null;
			int num = System.Buffers.Utilities.SelectBucketIndex(minimumLength);
			if (num < _buckets.Length)
			{
				int num2 = num;
				do
				{
					array = _buckets[num2].Rent();
					if (array != null)
					{
						if (log.IsEnabled())
						{
							log.BufferRented(array.GetHashCode(), array.Length, Id, _buckets[num2].Id);
						}
						return array;
					}
				}
				while (++num2 < _buckets.Length && num2 != num + 2);
				array = new T[_buckets[num]._bufferLength];
			}
			else
			{
				array = new T[minimumLength];
			}
			if (log.IsEnabled())
			{
				int hashCode = array.GetHashCode();
				int bucketId = -1;
				log.BufferRented(hashCode, array.Length, Id, bucketId);
				log.BufferAllocated(hashCode, array.Length, Id, bucketId, (num >= _buckets.Length) ? System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.OverMaximumSize : System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.PoolExhausted);
			}
			return array;
		}

		public override void Return(T[] array, bool clearArray = false)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (array.Length == 0)
			{
				return;
			}
			int num = System.Buffers.Utilities.SelectBucketIndex(array.Length);
			if (num < _buckets.Length)
			{
				if (clearArray)
				{
					Array.Clear(array, 0, array.Length);
				}
				_buckets[num].Return(array);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			if (log.IsEnabled())
			{
				log.BufferReturned(array.GetHashCode(), array.Length, Id);
			}
		}
	}
	internal static class Utilities
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int SelectBucketIndex(int bufferSize)
		{
			uint num = (uint)(bufferSize - 1) >> 4;
			int num2 = 0;
			if (num > 65535)
			{
				num >>= 16;
				num2 = 16;
			}
			if (num > 255)
			{
				num >>= 8;
				num2 += 8;
			}
			if (num > 15)
			{
				num >>= 4;
				num2 += 4;
			}
			if (num > 3)
			{
				num >>= 2;
				num2 += 2;
			}
			if (num > 1)
			{
				num >>= 1;
				num2++;
			}
			return num2 + (int)num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int GetMaxSizeForBucket(int binIndex)
		{
			return 16 << binIndex;
		}
	}
}

plugins/System.Memory.dll

Decompiled a month ago
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Buffers.Text;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using FxResources.System.Memory;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Memory")]
[assembly: AssemblyDescription("System.Memory")]
[assembly: AssemblyDefaultAlias("System.Memory")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.27617.02")]
[assembly: AssemblyInformationalVersion("4.6.27617.02 @BuiltBy: dlab14-DDVSOWINAGE071 @Branch: release/2.1-MSRC @SrcCode: https://github.com/dotnet/corefx/tree/c6cf790234e063b855fcdb50f3fb1b3cfac73275")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.1.1")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsByRefLikeAttribute : Attribute
	{
	}
}
namespace FxResources.System.Memory
{
	internal static class SR
	{
	}
}
namespace System
{
	public readonly struct SequencePosition : IEquatable<SequencePosition>
	{
		private readonly object _object;

		private readonly int _integer;

		public SequencePosition(object @object, int integer)
		{
			_object = @object;
			_integer = integer;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public object GetObject()
		{
			return _object;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public int GetInteger()
		{
			return _integer;
		}

		public bool Equals(SequencePosition other)
		{
			if (_integer == other._integer)
			{
				return object.Equals(_object, other._object);
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is SequencePosition other)
			{
				return Equals(other);
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			return HashHelpers.Combine(_object?.GetHashCode() ?? 0, _integer);
		}
	}
	internal static class ThrowHelper
	{
		internal static void ThrowArgumentNullException(System.ExceptionArgument argument)
		{
			throw CreateArgumentNullException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentNullException(System.ExceptionArgument argument)
		{
			return new ArgumentNullException(argument.ToString());
		}

		internal static void ThrowArrayTypeMismatchException()
		{
			throw CreateArrayTypeMismatchException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArrayTypeMismatchException()
		{
			return new ArrayTypeMismatchException();
		}

		internal static void ThrowArgumentException_InvalidTypeWithPointersNotSupported(Type type)
		{
			throw CreateArgumentException_InvalidTypeWithPointersNotSupported(type);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_InvalidTypeWithPointersNotSupported(Type type)
		{
			return new ArgumentException(System.SR.Format(System.SR.Argument_InvalidTypeWithPointersNotSupported, type));
		}

		internal static void ThrowArgumentException_DestinationTooShort()
		{
			throw CreateArgumentException_DestinationTooShort();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_DestinationTooShort()
		{
			return new ArgumentException(System.SR.Argument_DestinationTooShort);
		}

		internal static void ThrowIndexOutOfRangeException()
		{
			throw CreateIndexOutOfRangeException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateIndexOutOfRangeException()
		{
			return new IndexOutOfRangeException();
		}

		internal static void ThrowArgumentOutOfRangeException()
		{
			throw CreateArgumentOutOfRangeException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException()
		{
			return new ArgumentOutOfRangeException();
		}

		internal static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument)
		{
			throw CreateArgumentOutOfRangeException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException(System.ExceptionArgument argument)
		{
			return new ArgumentOutOfRangeException(argument.ToString());
		}

		internal static void ThrowArgumentOutOfRangeException_PrecisionTooLarge()
		{
			throw CreateArgumentOutOfRangeException_PrecisionTooLarge();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_PrecisionTooLarge()
		{
			return new ArgumentOutOfRangeException("precision", System.SR.Format(System.SR.Argument_PrecisionTooLarge, (byte)99));
		}

		internal static void ThrowArgumentOutOfRangeException_SymbolDoesNotFit()
		{
			throw CreateArgumentOutOfRangeException_SymbolDoesNotFit();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_SymbolDoesNotFit()
		{
			return new ArgumentOutOfRangeException("symbol", System.SR.Argument_BadFormatSpecifier);
		}

		internal static void ThrowInvalidOperationException()
		{
			throw CreateInvalidOperationException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException()
		{
			return new InvalidOperationException();
		}

		internal static void ThrowInvalidOperationException_OutstandingReferences()
		{
			throw CreateInvalidOperationException_OutstandingReferences();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_OutstandingReferences()
		{
			return new InvalidOperationException(System.SR.OutstandingReferences);
		}

		internal static void ThrowInvalidOperationException_UnexpectedSegmentType()
		{
			throw CreateInvalidOperationException_UnexpectedSegmentType();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_UnexpectedSegmentType()
		{
			return new InvalidOperationException(System.SR.UnexpectedSegmentType);
		}

		internal static void ThrowInvalidOperationException_EndPositionNotReached()
		{
			throw CreateInvalidOperationException_EndPositionNotReached();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_EndPositionNotReached()
		{
			return new InvalidOperationException(System.SR.EndPositionNotReached);
		}

		internal static void ThrowArgumentOutOfRangeException_PositionOutOfRange()
		{
			throw CreateArgumentOutOfRangeException_PositionOutOfRange();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_PositionOutOfRange()
		{
			return new ArgumentOutOfRangeException("position");
		}

		internal static void ThrowArgumentOutOfRangeException_OffsetOutOfRange()
		{
			throw CreateArgumentOutOfRangeException_OffsetOutOfRange();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_OffsetOutOfRange()
		{
			return new ArgumentOutOfRangeException("offset");
		}

		internal static void ThrowObjectDisposedException_ArrayMemoryPoolBuffer()
		{
			throw CreateObjectDisposedException_ArrayMemoryPoolBuffer();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateObjectDisposedException_ArrayMemoryPoolBuffer()
		{
			return new ObjectDisposedException("ArrayMemoryPoolBuffer");
		}

		internal static void ThrowFormatException_BadFormatSpecifier()
		{
			throw CreateFormatException_BadFormatSpecifier();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateFormatException_BadFormatSpecifier()
		{
			return new FormatException(System.SR.Argument_BadFormatSpecifier);
		}

		internal static void ThrowArgumentException_OverlapAlignmentMismatch()
		{
			throw CreateArgumentException_OverlapAlignmentMismatch();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_OverlapAlignmentMismatch()
		{
			return new ArgumentException(System.SR.Argument_OverlapAlignmentMismatch);
		}

		internal static void ThrowNotSupportedException()
		{
			throw CreateThrowNotSupportedException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateThrowNotSupportedException()
		{
			return new NotSupportedException();
		}

		public static bool TryFormatThrowFormatException(out int bytesWritten)
		{
			bytesWritten = 0;
			ThrowFormatException_BadFormatSpecifier();
			return false;
		}

		public static bool TryParseThrowFormatException<T>(out T value, out int bytesConsumed)
		{
			value = default(T);
			bytesConsumed = 0;
			ThrowFormatException_BadFormatSpecifier();
			return false;
		}

		public static void ThrowArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment)
		{
			throw CreateArgumentValidationException(startSegment, startIndex, endSegment);
		}

		private static Exception CreateArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment)
		{
			if (startSegment == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.startSegment);
			}
			if (endSegment == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.endSegment);
			}
			if (startSegment != endSegment && startSegment.RunningIndex > endSegment.RunningIndex)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.endSegment);
			}
			if ((uint)startSegment.Memory.Length < (uint)startIndex)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.startIndex);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.endIndex);
		}

		public static void ThrowArgumentValidationException(Array array, int start)
		{
			throw CreateArgumentValidationException(array, start);
		}

		private static Exception CreateArgumentValidationException(Array array, int start)
		{
			if (array == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.array);
			}
			if ((uint)start > (uint)array.Length)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.length);
		}

		public static void ThrowStartOrEndArgumentValidationException(long start)
		{
			throw CreateStartOrEndArgumentValidationException(start);
		}

		private static Exception CreateStartOrEndArgumentValidationException(long start)
		{
			if (start < 0)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.length);
		}
	}
	internal enum ExceptionArgument
	{
		length,
		start,
		minimumBufferSize,
		elementIndex,
		comparable,
		comparer,
		destination,
		offset,
		startSegment,
		endSegment,
		startIndex,
		endIndex,
		array,
		culture,
		manager
	}
	internal static class DecimalDecCalc
	{
		private static uint D32DivMod1E9(uint hi32, ref uint lo32)
		{
			ulong num = ((ulong)hi32 << 32) | lo32;
			lo32 = (uint)(num / 1000000000);
			return (uint)(num % 1000000000);
		}

		internal static uint DecDivMod1E9(ref MutableDecimal value)
		{
			return D32DivMod1E9(D32DivMod1E9(D32DivMod1E9(0u, ref value.High), ref value.Mid), ref value.Low);
		}

		internal static void DecAddInt32(ref MutableDecimal value, uint i)
		{
			if (D32AddCarry(ref value.Low, i) && D32AddCarry(ref value.Mid, 1u))
			{
				D32AddCarry(ref value.High, 1u);
			}
		}

		private static bool D32AddCarry(ref uint value, uint i)
		{
			uint num = value;
			uint num2 = (value = num + i);
			if (num2 >= num)
			{
				return num2 < i;
			}
			return true;
		}

		internal static void DecMul10(ref MutableDecimal value)
		{
			MutableDecimal d = value;
			DecShiftLeft(ref value);
			DecShiftLeft(ref value);
			DecAdd(ref value, d);
			DecShiftLeft(ref value);
		}

		private static void DecShiftLeft(ref MutableDecimal value)
		{
			uint num = (((value.Low & 0x80000000u) != 0) ? 1u : 0u);
			uint num2 = (((value.Mid & 0x80000000u) != 0) ? 1u : 0u);
			value.Low <<= 1;
			value.Mid = (value.Mid << 1) | num;
			value.High = (value.High << 1) | num2;
		}

		private static void DecAdd(ref MutableDecimal value, MutableDecimal d)
		{
			if (D32AddCarry(ref value.Low, d.Low) && D32AddCarry(ref value.Mid, 1u))
			{
				D32AddCarry(ref value.High, 1u);
			}
			if (D32AddCarry(ref value.Mid, d.Mid))
			{
				D32AddCarry(ref value.High, 1u);
			}
			D32AddCarry(ref value.High, d.High);
		}
	}
	internal static class Number
	{
		private static class DoubleHelper
		{
			public unsafe static uint Exponent(double d)
			{
				return (*(uint*)((byte*)(&d) + 4) >> 20) & 0x7FFu;
			}

			public unsafe static ulong Mantissa(double d)
			{
				return *(uint*)(&d) | ((ulong)(uint)(*(int*)((byte*)(&d) + 4) & 0xFFFFF) << 32);
			}

			public unsafe static bool Sign(double d)
			{
				return *(uint*)((byte*)(&d) + 4) >> 31 != 0;
			}
		}

		internal const int DECIMAL_PRECISION = 29;

		private static readonly ulong[] s_rgval64Power10 = new ulong[30]
		{
			11529215046068469760uL, 14411518807585587200uL, 18014398509481984000uL, 11258999068426240000uL, 14073748835532800000uL, 17592186044416000000uL, 10995116277760000000uL, 13743895347200000000uL, 17179869184000000000uL, 10737418240000000000uL,
			13421772800000000000uL, 16777216000000000000uL, 10485760000000000000uL, 13107200000000000000uL, 16384000000000000000uL, 14757395258967641293uL, 11805916207174113035uL, 9444732965739290428uL, 15111572745182864686uL, 12089258196146291749uL,
			9671406556917033399uL, 15474250491067253438uL, 12379400392853802751uL, 9903520314283042201uL, 15845632502852867522uL, 12676506002282294018uL, 10141204801825835215uL, 16225927682921336344uL, 12980742146337069075uL, 10384593717069655260uL
		};

		private static readonly sbyte[] s_rgexp64Power10 = new sbyte[15]
		{
			4, 7, 10, 14, 17, 20, 24, 27, 30, 34,
			37, 40, 44, 47, 50
		};

		private static readonly ulong[] s_rgval64Power10By16 = new ulong[42]
		{
			10240000000000000000uL, 11368683772161602974uL, 12621774483536188886uL, 14012984643248170708uL, 15557538194652854266uL, 17272337110188889248uL, 9588073174409622172uL, 10644899600020376798uL, 11818212630765741798uL, 13120851772591970216uL,
			14567071740625403792uL, 16172698447808779622uL, 17955302187076837696uL, 9967194951097567532uL, 11065809325636130658uL, 12285516299433008778uL, 13639663065038175358uL, 15143067982934716296uL, 16812182738118149112uL, 9332636185032188787uL,
			10361307573072618722uL, 16615349947311448416uL, 14965776766268445891uL, 13479973333575319909uL, 12141680576410806707uL, 10936253623915059637uL, 9850501549098619819uL, 17745086042373215136uL, 15983352577617880260uL, 14396524142538228461uL,
			12967236152753103031uL, 11679847981112819795uL, 10520271803096747049uL, 9475818434452569218uL, 17070116948172427008uL, 15375394465392026135uL, 13848924157002783096uL, 12474001934591998882uL, 11235582092889474480uL, 10120112665365530972uL,
			18230774251475056952uL, 16420821625123739930uL
		};

		private static readonly short[] s_rgexp64Power10By16 = new short[21]
		{
			54, 107, 160, 213, 266, 319, 373, 426, 479, 532,
			585, 638, 691, 745, 798, 851, 904, 957, 1010, 1064,
			1117
		};

		public static void RoundNumber(ref NumberBuffer number, int pos)
		{
			Span<byte> digits = number.Digits;
			int i;
			for (i = 0; i < pos && digits[i] != 0; i++)
			{
			}
			if (i == pos && digits[i] >= 53)
			{
				while (i > 0 && digits[i - 1] == 57)
				{
					i--;
				}
				if (i > 0)
				{
					digits[i - 1]++;
				}
				else
				{
					number.Scale++;
					digits[0] = 49;
					i = 1;
				}
			}
			else
			{
				while (i > 0 && digits[i - 1] == 48)
				{
					i--;
				}
			}
			if (i == 0)
			{
				number.Scale = 0;
				number.IsNegative = false;
			}
			digits[i] = 0;
		}

		internal static bool NumberBufferToDouble(ref NumberBuffer number, out double value)
		{
			double num = NumberToDouble(ref number);
			uint num2 = DoubleHelper.Exponent(num);
			ulong num3 = DoubleHelper.Mantissa(num);
			switch (num2)
			{
			case 2047u:
				value = 0.0;
				return false;
			case 0u:
				if (num3 == 0L)
				{
					num = 0.0;
				}
				break;
			}
			value = num;
			return true;
		}

		public unsafe static bool NumberBufferToDecimal(ref NumberBuffer number, ref decimal value)
		{
			MutableDecimal source = default(MutableDecimal);
			byte* ptr = number.UnsafeDigits;
			int num = number.Scale;
			if (*ptr == 0)
			{
				if (num > 0)
				{
					num = 0;
				}
			}
			else
			{
				if (num > 29)
				{
					return false;
				}
				while ((num > 0 || (*ptr != 0 && num > -28)) && (source.High < 429496729 || (source.High == 429496729 && (source.Mid < 2576980377u || (source.Mid == 2576980377u && (source.Low < 2576980377u || (source.Low == 2576980377u && *ptr <= 53)))))))
				{
					DecimalDecCalc.DecMul10(ref source);
					if (*ptr != 0)
					{
						DecimalDecCalc.DecAddInt32(ref source, (uint)(*(ptr++) - 48));
					}
					num--;
				}
				if (*(ptr++) >= 53)
				{
					bool flag = true;
					if (*(ptr - 1) == 53 && *(ptr - 2) % 2 == 0)
					{
						int num2 = 20;
						while (*ptr == 48 && num2 != 0)
						{
							ptr++;
							num2--;
						}
						if (*ptr == 0 || num2 == 0)
						{
							flag = false;
						}
					}
					if (flag)
					{
						DecimalDecCalc.DecAddInt32(ref source, 1u);
						if ((source.High | source.Mid | source.Low) == 0)
						{
							source.High = 429496729u;
							source.Mid = 2576980377u;
							source.Low = 2576980378u;
							num++;
						}
					}
				}
			}
			if (num > 0)
			{
				return false;
			}
			if (num <= -29)
			{
				source.High = 0u;
				source.Low = 0u;
				source.Mid = 0u;
				source.Scale = 28;
			}
			else
			{
				source.Scale = -num;
			}
			source.IsNegative = number.IsNegative;
			value = Unsafe.As<MutableDecimal, decimal>(ref source);
			return true;
		}

		public static void DecimalToNumber(decimal value, ref NumberBuffer number)
		{
			ref MutableDecimal reference = ref Unsafe.As<decimal, MutableDecimal>(ref value);
			Span<byte> digits = number.Digits;
			number.IsNegative = reference.IsNegative;
			int num = 29;
			while ((reference.Mid != 0) | (reference.High != 0))
			{
				uint num2 = DecimalDecCalc.DecDivMod1E9(ref reference);
				for (int i = 0; i < 9; i++)
				{
					digits[--num] = (byte)(num2 % 10 + 48);
					num2 /= 10;
				}
			}
			for (uint num3 = reference.Low; num3 != 0; num3 /= 10)
			{
				digits[--num] = (byte)(num3 % 10 + 48);
			}
			int num4 = 29 - num;
			number.Scale = num4 - reference.Scale;
			Span<byte> digits2 = number.Digits;
			int index = 0;
			while (--num4 >= 0)
			{
				digits2[index++] = digits[num++];
			}
			digits2[index] = 0;
		}

		private static uint DigitsToInt(ReadOnlySpan<byte> digits, int count)
		{
			uint value;
			int bytesConsumed;
			bool flag = Utf8Parser.TryParse(digits.Slice(0, count), out value, out bytesConsumed, 'D');
			return value;
		}

		private static ulong Mul32x32To64(uint a, uint b)
		{
			return (ulong)a * (ulong)b;
		}

		private static ulong Mul64Lossy(ulong a, ulong b, ref int pexp)
		{
			ulong num = Mul32x32To64((uint)(a >> 32), (uint)(b >> 32)) + (Mul32x32To64((uint)(a >> 32), (uint)b) >> 32) + (Mul32x32To64((uint)a, (uint)(b >> 32)) >> 32);
			if ((num & 0x8000000000000000uL) == 0L)
			{
				num <<= 1;
				pexp--;
			}
			return num;
		}

		private static int abs(int value)
		{
			if (value < 0)
			{
				return -value;
			}
			return value;
		}

		private unsafe static double NumberToDouble(ref NumberBuffer number)
		{
			ReadOnlySpan<byte> digits = number.Digits;
			int i = 0;
			int numDigits = number.NumDigits;
			int num = numDigits;
			for (; digits[i] == 48; i++)
			{
				num--;
			}
			if (num == 0)
			{
				return 0.0;
			}
			int num2 = Math.Min(num, 9);
			num -= num2;
			ulong num3 = DigitsToInt(digits, num2);
			if (num > 0)
			{
				num2 = Math.Min(num, 9);
				num -= num2;
				uint b = (uint)(s_rgval64Power10[num2 - 1] >> 64 - s_rgexp64Power10[num2 - 1]);
				num3 = Mul32x32To64((uint)num3, b) + DigitsToInt(digits.Slice(9), num2);
			}
			int num4 = number.Scale - (numDigits - num);
			int num5 = abs(num4);
			if (num5 >= 352)
			{
				ulong num6 = ((num4 > 0) ? 9218868437227405312uL : 0);
				if (number.IsNegative)
				{
					num6 |= 0x8000000000000000uL;
				}
				return *(double*)(&num6);
			}
			int pexp = 64;
			if ((num3 & 0xFFFFFFFF00000000uL) == 0L)
			{
				num3 <<= 32;
				pexp -= 32;
			}
			if ((num3 & 0xFFFF000000000000uL) == 0L)
			{
				num3 <<= 16;
				pexp -= 16;
			}
			if ((num3 & 0xFF00000000000000uL) == 0L)
			{
				num3 <<= 8;
				pexp -= 8;
			}
			if ((num3 & 0xF000000000000000uL) == 0L)
			{
				num3 <<= 4;
				pexp -= 4;
			}
			if ((num3 & 0xC000000000000000uL) == 0L)
			{
				num3 <<= 2;
				pexp -= 2;
			}
			if ((num3 & 0x8000000000000000uL) == 0L)
			{
				num3 <<= 1;
				pexp--;
			}
			int num7 = num5 & 0xF;
			if (num7 != 0)
			{
				int num8 = s_rgexp64Power10[num7 - 1];
				pexp += ((num4 < 0) ? (-num8 + 1) : num8);
				ulong b2 = s_rgval64Power10[num7 + ((num4 < 0) ? 15 : 0) - 1];
				num3 = Mul64Lossy(num3, b2, ref pexp);
			}
			num7 = num5 >> 4;
			if (num7 != 0)
			{
				int num9 = s_rgexp64Power10By16[num7 - 1];
				pexp += ((num4 < 0) ? (-num9 + 1) : num9);
				ulong b3 = s_rgval64Power10By16[num7 + ((num4 < 0) ? 21 : 0) - 1];
				num3 = Mul64Lossy(num3, b3, ref pexp);
			}
			if (((uint)(int)num3 & 0x400u) != 0)
			{
				ulong num10 = num3 + 1023 + (ulong)(((int)num3 >> 11) & 1);
				if (num10 < num3)
				{
					num10 = (num10 >> 1) | 0x8000000000000000uL;
					pexp++;
				}
				num3 = num10;
			}
			pexp += 1022;
			num3 = ((pexp <= 0) ? ((pexp == -52 && num3 >= 9223372036854775896uL) ? 1 : ((pexp > -52) ? (num3 >> -pexp + 11 + 1) : 0)) : ((pexp < 2047) ? ((ulong)((long)pexp << 52) + ((num3 >> 11) & 0xFFFFFFFFFFFFFL)) : 9218868437227405312uL));
			if (number.IsNegative)
			{
				num3 |= 0x8000000000000000uL;
			}
			return *(double*)(&num3);
		}
	}
	internal ref struct NumberBuffer
	{
		public int Scale;

		public bool IsNegative;

		public const int BufferSize = 51;

		private byte _b0;

		private byte _b1;

		private byte _b2;

		private byte _b3;

		private byte _b4;

		private byte _b5;

		private byte _b6;

		private byte _b7;

		private byte _b8;

		private byte _b9;

		private byte _b10;

		private byte _b11;

		private byte _b12;

		private byte _b13;

		private byte _b14;

		private byte _b15;

		private byte _b16;

		private byte _b17;

		private byte _b18;

		private byte _b19;

		private byte _b20;

		private byte _b21;

		private byte _b22;

		private byte _b23;

		private byte _b24;

		private byte _b25;

		private byte _b26;

		private byte _b27;

		private byte _b28;

		private byte _b29;

		private byte _b30;

		private byte _b31;

		private byte _b32;

		private byte _b33;

		private byte _b34;

		private byte _b35;

		private byte _b36;

		private byte _b37;

		private byte _b38;

		private byte _b39;

		private byte _b40;

		private byte _b41;

		private byte _b42;

		private byte _b43;

		private byte _b44;

		private byte _b45;

		private byte _b46;

		private byte _b47;

		private byte _b48;

		private byte _b49;

		private byte _b50;

		public unsafe Span<byte> Digits => new Span<byte>(Unsafe.AsPointer(ref _b0), 51);

		public unsafe byte* UnsafeDigits => (byte*)Unsafe.AsPointer(ref _b0);

		public int NumDigits => Digits.IndexOf<byte>(0);

		[Conditional("DEBUG")]
		public void CheckConsistency()
		{
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append('[');
			stringBuilder.Append('"');
			Span<byte> digits = Digits;
			for (int i = 0; i < 51; i++)
			{
				byte b = digits[i];
				if (b == 0)
				{
					break;
				}
				stringBuilder.Append((char)b);
			}
			stringBuilder.Append('"');
			stringBuilder.Append(", Scale = " + Scale);
			stringBuilder.Append(", IsNegative   = " + IsNegative);
			stringBuilder.Append(']');
			return stringBuilder.ToString();
		}
	}
	[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly struct Memory<T>
	{
		private readonly object _object;

		private readonly int _index;

		private readonly int _length;

		private const int RemoveFlagsBitMask = int.MaxValue;

		public static Memory<T> Empty => default(Memory<T>);

		public int Length => _length & 0x7FFFFFFF;

		public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;

		public Span<T> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				Span<T> result;
				if (_index < 0)
				{
					result = ((MemoryManager<T>)_object).GetSpan();
					return result.Slice(_index & 0x7FFFFFFF, _length);
				}
				if (typeof(T) == typeof(char) && _object is string text)
				{
					result = new Span<T>(Unsafe.As<Pinnable<T>>(text), MemoryExtensions.StringAdjustment, text.Length);
					return result.Slice(_index, _length);
				}
				if (_object != null)
				{
					return new Span<T>((T[])_object, _index, _length & 0x7FFFFFFF);
				}
				result = default(Span<T>);
				return result;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory(T[] array)
		{
			if (array == null)
			{
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			_object = array;
			_index = 0;
			_length = array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(T[] array, int start)
		{
			if (array == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = array.Length - start;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(MemoryManager<T> manager, int length)
		{
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = manager;
			_index = int.MinValue;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(MemoryManager<T> manager, int start, int length)
		{
			if (length < 0 || start < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = manager;
			_index = start | int.MinValue;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(object obj, int start, int length)
		{
			_object = obj;
			_index = start;
			_length = length;
		}

		public static implicit operator Memory<T>(T[] array)
		{
			return new Memory<T>(array);
		}

		public static implicit operator Memory<T>(ArraySegment<T> segment)
		{
			return new Memory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public static implicit operator ReadOnlyMemory<T>(Memory<T> memory)
		{
			return Unsafe.As<Memory<T>, ReadOnlyMemory<T>>(ref memory);
		}

		public override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (!(_object is string text))
				{
					return Span.ToString();
				}
				return text.Substring(_index, _length & 0x7FFFFFFF);
			}
			return $"System.Memory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<T> Slice(int start)
		{
			int length = _length;
			int num = length & 0x7FFFFFFF;
			if ((uint)start > (uint)num)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Memory<T>(_object, _index + start, length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<T> Slice(int start, int length)
		{
			int length2 = _length;
			int num = length2 & 0x7FFFFFFF;
			if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			return new Memory<T>(_object, _index + start, length | (length2 & int.MinValue));
		}

		public void CopyTo(Memory<T> destination)
		{
			Span.CopyTo(destination.Span);
		}

		public bool TryCopyTo(Memory<T> destination)
		{
			return Span.TryCopyTo(destination.Span);
		}

		public unsafe MemoryHandle Pin()
		{
			if (_index < 0)
			{
				return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
			}
			if (typeof(T) == typeof(char) && _object is string value)
			{
				GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
				void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = Unsafe.Add<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer3, handle2);
			}
			return default(MemoryHandle);
		}

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

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is ReadOnlyMemory<T> readOnlyMemory)
			{
				return readOnlyMemory.Equals(this);
			}
			if (obj is Memory<T> other)
			{
				return Equals(other);
			}
			return false;
		}

		public bool Equals(Memory<T> other)
		{
			if (_object == other._object && _index == other._index)
			{
				return _length == other._length;
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			if (_object == null)
			{
				return 0;
			}
			int hashCode = _object.GetHashCode();
			int index = _index;
			int hashCode2 = index.GetHashCode();
			index = _length;
			return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
		}

		private static int CombineHashCodes(int left, int right)
		{
			return ((left << 5) + left) ^ right;
		}

		private static int CombineHashCodes(int h1, int h2, int h3)
		{
			return CombineHashCodes(CombineHashCodes(h1, h2), h3);
		}
	}
	internal sealed class MemoryDebugView<T>
	{
		private readonly ReadOnlyMemory<T> _memory;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items => _memory.ToArray();

		public MemoryDebugView(Memory<T> memory)
		{
			_memory = memory;
		}

		public MemoryDebugView(ReadOnlyMemory<T> memory)
		{
			_memory = memory;
		}
	}
	public static class MemoryExtensions
	{
		internal static readonly IntPtr StringAdjustment = MeasureStringAdjustment();

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span)
		{
			return span.TrimStart().TrimEnd();
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span)
		{
			int i;
			for (i = 0; i < span.Length && char.IsWhiteSpace(span[i]); i++)
			{
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span)
		{
			int num = span.Length - 1;
			while (num >= 0 && char.IsWhiteSpace(span[num]))
			{
				num--;
			}
			return span.Slice(0, num + 1);
		}

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, char trimChar)
		{
			return span.TrimStart(trimChar).TrimEnd(trimChar);
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, char trimChar)
		{
			int i;
			for (i = 0; i < span.Length && span[i] == trimChar; i++)
			{
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, char trimChar)
		{
			int num = span.Length - 1;
			while (num >= 0 && span[num] == trimChar)
			{
				num--;
			}
			return span.Slice(0, num + 1);
		}

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			return span.TrimStart(trimChars).TrimEnd(trimChars);
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			if (trimChars.IsEmpty)
			{
				return span.TrimStart();
			}
			int i;
			for (i = 0; i < span.Length; i++)
			{
				int num = 0;
				while (num < trimChars.Length)
				{
					if (span[i] != trimChars[num])
					{
						num++;
						continue;
					}
					goto IL_003c;
				}
				break;
				IL_003c:;
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			if (trimChars.IsEmpty)
			{
				return span.TrimEnd();
			}
			int num;
			for (num = span.Length - 1; num >= 0; num--)
			{
				int num2 = 0;
				while (num2 < trimChars.Length)
				{
					if (span[num] != trimChars[num2])
					{
						num2++;
						continue;
					}
					goto IL_0044;
				}
				break;
				IL_0044:;
			}
			return span.Slice(0, num + 1);
		}

		public static bool IsWhiteSpace(this ReadOnlySpan<char> span)
		{
			for (int i = 0; i < span.Length; i++)
			{
				if (!char.IsWhiteSpace(span[i]))
				{
					return false;
				}
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this Span<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this Span<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool SequenceEqual<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
		{
			int length = span.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length == other.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size);
				}
				return false;
			}
			if (length == other.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
			}
			return false;
		}

		public static int SequenceCompareTo<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IComparable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool SequenceEqual<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
		{
			int length = span.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length == other.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size);
				}
				return false;
			}
			if (length == other.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int SequenceCompareTo<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IComparable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool StartsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length <= span.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size);
				}
				return false;
			}
			if (length <= span.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool StartsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length <= span.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size);
				}
				return false;
			}
			if (length <= span.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool EndsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = span.Length;
			int length2 = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length2 <= length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool EndsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = span.Length;
			int length2 = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length2 <= length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2);
			}
			return false;
		}

		public static void Reverse<T>(this Span<T> span)
		{
			ref T reference = ref MemoryMarshal.GetReference(span);
			int num = 0;
			int num2 = span.Length - 1;
			while (num < num2)
			{
				T val = Unsafe.Add(ref reference, num);
				Unsafe.Add(ref reference, num) = Unsafe.Add(ref reference, num2);
				Unsafe.Add(ref reference, num2) = val;
				num++;
				num2--;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this T[] array)
		{
			return new Span<T>(array);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this T[] array, int start, int length)
		{
			return new Span<T>(array, start, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment)
		{
			return new Span<T>(segment.Array, segment.Offset, segment.Count);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Span<T>(segment.Array, segment.Offset + start, segment.Count - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start, int length)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			if ((uint)length > segment.Count - start)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
			}
			return new Span<T>(segment.Array, segment.Offset + start, length);
		}

		public static Memory<T> AsMemory<T>(this T[] array)
		{
			return new Memory<T>(array);
		}

		public static Memory<T> AsMemory<T>(this T[] array, int start)
		{
			return new Memory<T>(array, start);
		}

		public static Memory<T> AsMemory<T>(this T[] array, int start, int length)
		{
			return new Memory<T>(array, start, length);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment)
		{
			return new Memory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Memory<T>(segment.Array, segment.Offset + start, segment.Count - start);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start, int length)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			if ((uint)length > segment.Count - start)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
			}
			return new Memory<T>(segment.Array, segment.Offset + start, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void CopyTo<T>(this T[] source, Span<T> destination)
		{
			new ReadOnlySpan<T>(source).CopyTo(destination);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void CopyTo<T>(this T[] source, Memory<T> destination)
		{
			source.CopyTo(destination.Span);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other)
		{
			return ((ReadOnlySpan<T>)span).Overlaps(other);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other, out int elementOffset)
		{
			return ((ReadOnlySpan<T>)span).Overlaps(other, out elementOffset);
		}

		public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other)
		{
			if (span.IsEmpty || other.IsEmpty)
			{
				return false;
			}
			IntPtr intPtr = Unsafe.ByteOffset(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr >= (uint)(span.Length * Unsafe.SizeOf<T>()))
				{
					return (uint)(int)intPtr > (uint)(-(other.Length * Unsafe.SizeOf<T>()));
				}
				return true;
			}
			if ((ulong)(long)intPtr >= (ulong)((long)span.Length * (long)Unsafe.SizeOf<T>()))
			{
				return (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)Unsafe.SizeOf<T>()));
			}
			return true;
		}

		public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other, out int elementOffset)
		{
			if (span.IsEmpty || other.IsEmpty)
			{
				elementOffset = 0;
				return false;
			}
			IntPtr intPtr = Unsafe.ByteOffset(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr < (uint)(span.Length * Unsafe.SizeOf<T>()) || (uint)(int)intPtr > (uint)(-(other.Length * Unsafe.SizeOf<T>())))
				{
					if ((int)intPtr % Unsafe.SizeOf<T>() != 0)
					{
						System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
					}
					elementOffset = (int)intPtr / Unsafe.SizeOf<T>();
					return true;
				}
				elementOffset = 0;
				return false;
			}
			if ((ulong)(long)intPtr < (ulong)((long)span.Length * (long)Unsafe.SizeOf<T>()) || (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)Unsafe.SizeOf<T>())))
			{
				if ((long)intPtr % Unsafe.SizeOf<T>() != 0L)
				{
					System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
				}
				elementOffset = (int)((long)intPtr / Unsafe.SizeOf<T>());
				return true;
			}
			elementOffset = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T>(this Span<T> span, IComparable<T> comparable)
		{
			return span.BinarySearch<T, IComparable<T>>(comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this Span<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			return BinarySearch((ReadOnlySpan<T>)span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparer>(this Span<T> span, T value, TComparer comparer) where TComparer : IComparer<T>
		{
			return ((ReadOnlySpan<T>)span).BinarySearch(value, comparer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T>(this ReadOnlySpan<T> span, IComparable<T> comparable)
		{
			return MemoryExtensions.BinarySearch<T, IComparable<T>>(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			return System.SpanHelpers.BinarySearch(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparer>(this ReadOnlySpan<T> span, T value, TComparer comparer) where TComparer : IComparer<T>
		{
			if (comparer == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparer);
			}
			System.SpanHelpers.ComparerComparable<T, TComparer> comparable = new System.SpanHelpers.ComparerComparable<T, TComparer>(value, comparer);
			return BinarySearch(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool IsTypeComparableAsBytes<T>(out NUInt size)
		{
			if (typeof(T) == typeof(byte) || typeof(T) == typeof(sbyte))
			{
				size = (NUInt)1;
				return true;
			}
			if (typeof(T) == typeof(char) || typeof(T) == typeof(short) || typeof(T) == typeof(ushort))
			{
				size = (NUInt)2;
				return true;
			}
			if (typeof(T) == typeof(int) || typeof(T) == typeof(uint))
			{
				size = (NUInt)4;
				return true;
			}
			if (typeof(T) == typeof(long) || typeof(T) == typeof(ulong))
			{
				size = (NUInt)8;
				return true;
			}
			size = default(NUInt);
			return false;
		}

		public static Span<T> AsSpan<T>(this T[] array, int start)
		{
			return Span<T>.Create(array, start);
		}

		public static bool Contains(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			return span.IndexOf(value, comparisonType) >= 0;
		}

		public static bool Equals(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.SequenceEqual(other);
			case StringComparison.OrdinalIgnoreCase:
				if (span.Length != other.Length)
				{
					return false;
				}
				return EqualsOrdinalIgnoreCase(span, other);
			default:
				return span.ToString().Equals(other.ToString(), comparisonType);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool EqualsOrdinalIgnoreCase(ReadOnlySpan<char> span, ReadOnlySpan<char> other)
		{
			if (other.Length == 0)
			{
				return true;
			}
			return CompareToOrdinalIgnoreCase(span, other) == 0;
		}

		public static int CompareTo(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType)
		{
			return comparisonType switch
			{
				StringComparison.Ordinal => span.SequenceCompareTo(other), 
				StringComparison.OrdinalIgnoreCase => CompareToOrdinalIgnoreCase(span, other), 
				_ => string.Compare(span.ToString(), other.ToString(), comparisonType), 
			};
		}

		private unsafe static int CompareToOrdinalIgnoreCase(ReadOnlySpan<char> strA, ReadOnlySpan<char> strB)
		{
			int num = Math.Min(strA.Length, strB.Length);
			int num2 = num;
			fixed (char* ptr = &MemoryMarshal.GetReference(strA))
			{
				fixed (char* ptr3 = &MemoryMarshal.GetReference(strB))
				{
					char* ptr2 = ptr;
					char* ptr4 = ptr3;
					while (num != 0 && *ptr2 <= '\u007f' && *ptr4 <= '\u007f')
					{
						int num3 = *ptr2;
						int num4 = *ptr4;
						if (num3 == num4)
						{
							ptr2++;
							ptr4++;
							num--;
							continue;
						}
						if ((uint)(num3 - 97) <= 25u)
						{
							num3 -= 32;
						}
						if ((uint)(num4 - 97) <= 25u)
						{
							num4 -= 32;
						}
						if (num3 != num4)
						{
							return num3 - num4;
						}
						ptr2++;
						ptr4++;
						num--;
					}
					if (num == 0)
					{
						return strA.Length - strB.Length;
					}
					num2 -= num;
					return string.Compare(strA.Slice(num2).ToString(), strB.Slice(num2).ToString(), StringComparison.OrdinalIgnoreCase);
				}
			}
		}

		public static int IndexOf(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			if (comparisonType == StringComparison.Ordinal)
			{
				return span.IndexOf(value);
			}
			return span.ToString().IndexOf(value.ToString(), comparisonType);
		}

		public static int ToLower(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture)
		{
			if (culture == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture);
			}
			if (destination.Length < source.Length)
			{
				return -1;
			}
			string text = source.ToString();
			string text2 = text.ToLower(culture);
			AsSpan(text2).CopyTo(destination);
			return source.Length;
		}

		public static int ToLowerInvariant(this ReadOnlySpan<char> source, Span<char> destination)
		{
			return source.ToLower(destination, CultureInfo.InvariantCulture);
		}

		public static int ToUpper(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture)
		{
			if (culture == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture);
			}
			if (destination.Length < source.Length)
			{
				return -1;
			}
			string text = source.ToString();
			string text2 = text.ToUpper(culture);
			AsSpan(text2).CopyTo(destination);
			return source.Length;
		}

		public static int ToUpperInvariant(this ReadOnlySpan<char> source, Span<char> destination)
		{
			return source.ToUpper(destination, CultureInfo.InvariantCulture);
		}

		public static bool EndsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.EndsWith(value);
			case StringComparison.OrdinalIgnoreCase:
				if (value.Length <= span.Length)
				{
					return EqualsOrdinalIgnoreCase(span.Slice(span.Length - value.Length), value);
				}
				return false;
			default:
			{
				string text = span.ToString();
				string value2 = value.ToString();
				return text.EndsWith(value2, comparisonType);
			}
			}
		}

		public static bool StartsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.StartsWith(value);
			case StringComparison.OrdinalIgnoreCase:
				if (value.Length <= span.Length)
				{
					return EqualsOrdinalIgnoreCase(span.Slice(0, value.Length), value);
				}
				return false;
			default:
			{
				string text = span.ToString();
				string value2 = value.ToString();
				return text.StartsWith(value2, comparisonType);
			}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text)
		{
			if (text == null)
			{
				return default(ReadOnlySpan<char>);
			}
			return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment, text.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text, int start)
		{
			if (text == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlySpan<char>);
			}
			if ((uint)start > (uint)text.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment + start * 2, text.Length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text, int start, int length)
		{
			if (text == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlySpan<char>);
			}
			if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment + start * 2, length);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text)
		{
			if (text == null)
			{
				return default(ReadOnlyMemory<char>);
			}
			return new ReadOnlyMemory<char>(text, 0, text.Length);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text, int start)
		{
			if (text == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlyMemory<char>);
			}
			if ((uint)start > (uint)text.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<char>(text, start, text.Length - start);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text, int start, int length)
		{
			if (text == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlyMemory<char>);
			}
			if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<char>(text, start, length);
		}

		private unsafe static IntPtr MeasureStringAdjustment()
		{
			string text = "a";
			fixed (char* source = text)
			{
				return Unsafe.ByteOffset(ref Unsafe.As<Pinnable<char>>(text).Data, ref Unsafe.AsRef<char>(source));
			}
		}
	}
	[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly struct ReadOnlyMemory<T>
	{
		private readonly object _object;

		private readonly int _index;

		private readonly int _length;

		internal const int RemoveFlagsBitMask = int.MaxValue;

		public static ReadOnlyMemory<T> Empty => default(ReadOnlyMemory<T>);

		public int Length => _length & 0x7FFFFFFF;

		public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;

		public ReadOnlySpan<T> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if (_index < 0)
				{
					return ((MemoryManager<T>)_object).GetSpan().Slice(_index & 0x7FFFFFFF, _length);
				}
				ReadOnlySpan<T> result;
				if (typeof(T) == typeof(char) && _object is string text)
				{
					result = new ReadOnlySpan<T>(Unsafe.As<Pinnable<T>>(text), MemoryExtensions.StringAdjustment, text.Length);
					return result.Slice(_index, _length);
				}
				if (_object != null)
				{
					return new ReadOnlySpan<T>((T[])_object, _index, _length & 0x7FFFFFFF);
				}
				result = default(ReadOnlySpan<T>);
				return result;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory(T[] array)
		{
			if (array == null)
			{
				this = default(ReadOnlyMemory<T>);
				return;
			}
			_object = array;
			_index = 0;
			_length = array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(ReadOnlyMemory<T>);
				return;
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ReadOnlyMemory(object obj, int start, int length)
		{
			_object = obj;
			_index = start;
			_length = length;
		}

		public static implicit operator ReadOnlyMemory<T>(T[] array)
		{
			return new ReadOnlyMemory<T>(array);
		}

		public static implicit operator ReadOnlyMemory<T>(ArraySegment<T> segment)
		{
			return new ReadOnlyMemory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (!(_object is string text))
				{
					return Span.ToString();
				}
				return text.Substring(_index, _length & 0x7FFFFFFF);
			}
			return $"System.ReadOnlyMemory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory<T> Slice(int start)
		{
			int length = _length;
			int num = length & 0x7FFFFFFF;
			if ((uint)start > (uint)num)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<T>(_object, _index + start, length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory<T> Slice(int start, int length)
		{
			int length2 = _length;
			int num = _length & 0x7FFFFFFF;
			if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<T>(_object, _index + start, length | (length2 & int.MinValue));
		}

		public void CopyTo(Memory<T> destination)
		{
			Span.CopyTo(destination.Span);
		}

		public bool TryCopyTo(Memory<T> destination)
		{
			return Span.TryCopyTo(destination.Span);
		}

		public unsafe MemoryHandle Pin()
		{
			if (_index < 0)
			{
				return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
			}
			if (typeof(T) == typeof(char) && _object is string value)
			{
				GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
				void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = Unsafe.Add<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer3, handle2);
			}
			return default(MemoryHandle);
		}

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

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is ReadOnlyMemory<T> other)
			{
				return Equals(other);
			}
			if (obj is Memory<T> memory)
			{
				return Equals(memory);
			}
			return false;
		}

		public bool Equals(ReadOnlyMemory<T> other)
		{
			if (_object == other._object && _index == other._index)
			{
				return _length == other._length;
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			if (_object == null)
			{
				return 0;
			}
			int hashCode = _object.GetHashCode();
			int index = _index;
			int hashCode2 = index.GetHashCode();
			index = _length;
			return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
		}

		private static int CombineHashCodes(int left, int right)
		{
			return ((left << 5) + left) ^ right;
		}

		private static int CombineHashCodes(int h1, int h2, int h3)
		{
			return CombineHashCodes(CombineHashCodes(h1, h2), h3);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal object GetObjectStartLength(out int start, out int length)
		{
			start = _index;
			length = _length;
			return _object;
		}
	}
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly ref struct ReadOnlySpan<T>
	{
		public ref struct Enumerator
		{
			private readonly ReadOnlySpan<T> _span;

			private int _index;

			public ref readonly T Current
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return ref _span[_index];
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal Enumerator(ReadOnlySpan<T> span)
			{
				_span = span;
				_index = -1;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public bool MoveNext()
			{
				int num = _index + 1;
				if (num < _span.Length)
				{
					_index = num;
					return true;
				}
				return false;
			}
		}

		private readonly Pinnable<T> _pinnable;

		private readonly IntPtr _byteOffset;

		private readonly int _length;

		public int Length => _length;

		public bool IsEmpty => _length == 0;

		public static ReadOnlySpan<T> Empty => default(ReadOnlySpan<T>);

		public unsafe ref readonly T this[int index]
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if ((uint)index >= (uint)_length)
				{
					System.ThrowHelper.ThrowIndexOutOfRangeException();
				}
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref Unsafe.Add(ref Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref Unsafe.Add(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset), index);
			}
		}

		internal Pinnable<T> Pinnable => _pinnable;

		internal IntPtr ByteOffset => _byteOffset;

		public static bool operator !=(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
		{
			return !(left == right);
		}

		[Obsolete("Equals() on ReadOnlySpan will always throw an exception. Use == instead.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
		}

		[Obsolete("GetHashCode() on ReadOnlySpan will always throw an exception.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
		}

		public static implicit operator ReadOnlySpan<T>(T[] array)
		{
			return new ReadOnlySpan<T>(array);
		}

		public static implicit operator ReadOnlySpan<T>(ArraySegment<T> segment)
		{
			return new ReadOnlySpan<T>(segment.Array, segment.Offset, segment.Count);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan(T[] array)
		{
			if (array == null)
			{
				this = default(ReadOnlySpan<T>);
				return;
			}
			_length = array.Length;
			_pinnable = Unsafe.As<Pinnable<T>>(array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				this = default(ReadOnlySpan<T>);
				return;
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = Unsafe.As<Pinnable<T>>(array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[CLSCompliant(false)]
		public unsafe ReadOnlySpan(void* pointer, int length)
		{
			if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
			}
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = null;
			_byteOffset = new IntPtr(pointer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ReadOnlySpan(Pinnable<T> pinnable, IntPtr byteOffset, int length)
		{
			_length = length;
			_pinnable = pinnable;
			_byteOffset = byteOffset;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public unsafe ref readonly T GetPinnableReference()
		{
			if (_length != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
			}
			return ref Unsafe.AsRef<T>(null);
		}

		public void CopyTo(Span<T> destination)
		{
			if (!TryCopyTo(destination))
			{
				System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
			}
		}

		public bool TryCopyTo(Span<T> destination)
		{
			int length = _length;
			int length2 = destination.Length;
			if (length == 0)
			{
				return true;
			}
			if ((uint)length > (uint)length2)
			{
				return false;
			}
			ref T src = ref DangerousGetPinnableReference();
			System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
			return true;
		}

		public static bool operator ==(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
		{
			if (left._length == right._length)
			{
				return Unsafe.AreSame(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (_byteOffset == MemoryExtensions.StringAdjustment)
				{
					object obj = Unsafe.As<object>(_pinnable);
					if (obj is string text && _length == text.Length)
					{
						return text;
					}
				}
				fixed (char* value = &Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
				{
					return new string(value, 0, _length);
				}
			}
			return $"System.ReadOnlySpan<{typeof(T).Name}>[{_length}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan<T> Slice(int start)
		{
			if ((uint)start > (uint)_length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			int length = _length - start;
			return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan<T> Slice(int start, int length)
		{
			if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
		}

		public T[] ToArray()
		{
			if (_length == 0)
			{
				return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
			}
			T[] array = new T[_length];
			CopyTo(array);
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		internal unsafe ref T DangerousGetPinnableReference()
		{
			if (_pinnable == null)
			{
				IntPtr byteOffset = _byteOffset;
				return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
		}
	}
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly ref struct Span<T>
	{
		public ref struct Enumerator
		{
			private readonly Span<T> _span;

			private int _index;

			public ref T Current
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return ref _span[_index];
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal Enumerator(Span<T> span)
			{
				_span = span;
				_index = -1;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public bool MoveNext()
			{
				int num = _index + 1;
				if (num < _span.Length)
				{
					_index = num;
					return true;
				}
				return false;
			}
		}

		private readonly Pinnable<T> _pinnable;

		private readonly IntPtr _byteOffset;

		private readonly int _length;

		public int Length => _length;

		public bool IsEmpty => _length == 0;

		public static Span<T> Empty => default(Span<T>);

		public unsafe ref T this[int index]
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if ((uint)index >= (uint)_length)
				{
					System.ThrowHelper.ThrowIndexOutOfRangeException();
				}
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref Unsafe.Add(ref Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref Unsafe.Add(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset), index);
			}
		}

		internal Pinnable<T> Pinnable => _pinnable;

		internal IntPtr ByteOffset => _byteOffset;

		public static bool operator !=(Span<T> left, Span<T> right)
		{
			return !(left == right);
		}

		[Obsolete("Equals() on Span will always throw an exception. Use == instead.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
		}

		[Obsolete("GetHashCode() on Span will always throw an exception.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
		}

		public static implicit operator Span<T>(T[] array)
		{
			return new Span<T>(array);
		}

		public static implicit operator Span<T>(ArraySegment<T> segment)
		{
			return new Span<T>(segment.Array, segment.Offset, segment.Count);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span(T[] array)
		{
			if (array == null)
			{
				this = default(Span<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			_length = array.Length;
			_pinnable = Unsafe.As<Pinnable<T>>(array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static Span<T> Create(T[] array, int start)
		{
			if (array == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(Span<T>);
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
			int length = array.Length - start;
			return new Span<T>(Unsafe.As<Pinnable<T>>(array), byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				this = default(Span<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = Unsafe.As<Pinnable<T>>(array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[CLSCompliant(false)]
		public unsafe Span(void* pointer, int length)
		{
			if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
			}
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = null;
			_byteOffset = new IntPtr(pointer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Span(Pinnable<T> pinnable, IntPtr byteOffset, int length)
		{
			_length = length;
			_pinnable = pinnable;
			_byteOffset = byteOffset;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public unsafe ref T GetPinnableReference()
		{
			if (_length != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
			}
			return ref Unsafe.AsRef<T>(null);
		}

		public unsafe void Clear()
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			UIntPtr byteLength = (UIntPtr)(ulong)((uint)length * Unsafe.SizeOf<T>());
			if ((Unsafe.SizeOf<T>() & (sizeof(IntPtr) - 1)) != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					byte* ptr = (byte*)byteOffset.ToPointer();
					System.SpanHelpers.ClearLessThanPointerSized(ptr, byteLength);
				}
				else
				{
					System.SpanHelpers.ClearLessThanPointerSized(ref Unsafe.As<T, byte>(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset)), byteLength);
				}
			}
			else if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				UIntPtr pointerSizeLength = (UIntPtr)(ulong)(length * Unsafe.SizeOf<T>() / sizeof(IntPtr));
				System.SpanHelpers.ClearPointerSizedWithReferences(ref Unsafe.As<T, IntPtr>(ref DangerousGetPinnableReference()), pointerSizeLength);
			}
			else
			{
				System.SpanHelpers.ClearPointerSizedWithoutReferences(ref Unsafe.As<T, byte>(ref DangerousGetPinnableReference()), byteLength);
			}
		}

		public unsafe void Fill(T value)
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			if (Unsafe.SizeOf<T>() == 1)
			{
				byte value2 = Unsafe.As<T, byte>(ref value);
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					Unsafe.InitBlockUnaligned(byteOffset.ToPointer(), value2, (uint)length);
				}
				else
				{
					Unsafe.InitBlockUnaligned(ref Unsafe.As<T, byte>(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset)), value2, (uint)length);
				}
				return;
			}
			ref T source = ref DangerousGetPinnableReference();
			int i;
			for (i = 0; i < (length & -8); i += 8)
			{
				Unsafe.Add(ref source, i) = value;
				Unsafe.Add(ref source, i + 1) = value;
				Unsafe.Add(ref source, i + 2) = value;
				Unsafe.Add(ref source, i + 3) = value;
				Unsafe.Add(ref source, i + 4) = value;
				Unsafe.Add(ref source, i + 5) = value;
				Unsafe.Add(ref source, i + 6) = value;
				Unsafe.Add(ref source, i + 7) = value;
			}
			if (i < (length & -4))
			{
				Unsafe.Add(ref source, i) = value;
				Unsafe.Add(ref source, i + 1) = value;
				Unsafe.Add(ref source, i + 2) = value;
				Unsafe.Add(ref source, i + 3) = value;
				i += 4;
			}
			for (; i < length; i++)
			{
				Unsafe.Add(ref source, i) = value;
			}
		}

		public void CopyTo(Span<T> destination)
		{
			if (!TryCopyTo(destination))
			{
				System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
			}
		}

		public bool TryCopyTo(Span<T> destination)
		{
			int length = _length;
			int length2 = destination._length;
			if (length == 0)
			{
				return true;
			}
			if ((uint)length > (uint)length2)
			{
				return false;
			}
			ref T src = ref DangerousGetPinnableReference();
			System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
			return true;
		}

		public static bool operator ==(Span<T> left, Span<T> right)
		{
			if (left._length == right._length)
			{
				return Unsafe.AreSame(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public static implicit operator ReadOnlySpan<T>(Span<T> span)
		{
			return new ReadOnlySpan<T>(span._pinnable, span._byteOffset, span._length);
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				fixed (char* value = &Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
				{
					return new string(value, 0, _length);
				}
			}
			return $"System.Span<{typeof(T).Name}>[{_length}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<T> Slice(int start)
		{
			if ((uint)start > (uint)_length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			int length = _length - start;
			return new Span<T>(_pinnable, byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<T> Slice(int start, int length)
		{
			if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			return new Span<T>(_pinnable, byteOffset, length);
		}

		public T[] ToArray()
		{
			if (_length == 0)
			{
				return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
			}
			T[] array = new T[_length];
			CopyTo(array);
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		internal unsafe ref T DangerousGetPinnableReference()
		{
			if (_pinnable == null)
			{
				IntPtr byteOffset = _byteOffset;
				return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
		}
	}
	internal sealed class SpanDebugView<T>
	{
		private readonly T[] _array;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items => _array;

		public SpanDebugView(Span<T> span)
		{
			_array = span.ToArray();
		}

		public SpanDebugView(ReadOnlySpan<T> span)
		{
			_array = span.ToArray();
		}
	}
	internal static class SpanHelpers
	{
		internal struct ComparerComparable<T, TComparer> : IComparable<T> where TComparer : IComparer<T>
		{
			private readonly T _value;

			private readonly TComparer _comparer;

			public ComparerComparable(T value, TComparer comparer)
			{
				_value = value;
				_comparer = comparer;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public int CompareTo(T other)
			{
				return _comparer.Compare(_value, other);
			}
		}

		[StructLayout(LayoutKind.Sequential, Size = 64)]
		private struct Reg64
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 32)]
		private struct Reg32
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 16)]
		private struct Reg16
		{
		}

		public static class PerTypeValues<T>
		{
			public static readonly bool IsReferenceOrContainsReferences = IsReferenceOrContainsReferencesCore(typeof(T));

			public static readonly T[] EmptyArray = new T[0];

			public static readonly IntPtr ArrayAdjustment = MeasureArrayAdjustment();

			private static IntPtr MeasureArrayAdjustment()
			{
				T[] array = new T[1];
				return Unsafe.ByteOffset(ref Unsafe.As<Pinnable<T>>(array).Data, ref array[0]);
			}
		}

		private const ulong XorPowerOfTwoToHighByte = 283686952306184uL;

		private const ulong XorPowerOfTwoToHighChar = 4295098372uL;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			if (comparable == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparable);
			}
			return BinarySearch(ref MemoryMarshal.GetReference(span), span.Length, comparable);
		}

		public static int BinarySearch<T, TComparable>(ref T spanStart, int length, TComparable comparable) where TComparable : IComparable<T>
		{
			int num = 0;
			int num2 = length - 1;
			while (num <= num2)
			{
				int num3 = num2 + num >>> 1;
				int num4 = comparable.CompareTo(Unsafe.Add(ref spanStart, num3));
				if (num4 == 0)
				{
					return num3;
				}
				if (num4 > 0)
				{
					num = num3 + 1;
				}
				else
				{
					num2 = num3 - 1;
				}
			}
			return ~num;
		}

		public static int IndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			byte value2 = value;
			ref byte second = ref Unsafe.Add(ref value, 1);
			int num = valueLength - 1;
			int num2 = 0;
			while (true)
			{
				int num3 = searchSpaceLength - num2 - num;
				if (num3 <= 0)
				{
					break;
				}
				int num4 = IndexOf(ref Unsafe.Add(ref searchSpace, num2), value2, num3);
				if (num4 == -1)
				{
					break;
				}
				num2 += num4;
				if (SequenceEqual(ref Unsafe.Add(ref searchSpace, num2 + 1), ref second, num))
				{
					return num2;
				}
				num2++;
			}
			return -1;
		}

		public static int IndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			int num = -1;
			for (int i = 0; i < valueLength; i++)
			{
				int num2 = IndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength);
				if ((uint)num2 < (uint)num)
				{
					num = num2;
					searchSpaceLength = num2;
					if (num == 0)
					{
						break;
					}
				}
			}
			return num;
		}

		public static int LastIndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			int num = -1;
			for (int i = 0; i < valueLength; i++)
			{
				int num2 = LastIndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength);
				if (num2 > num)
				{
					num = num2;
				}
			}
			return num;
		}

		public unsafe static int IndexOf(ref byte searchSpace, byte value, int length)
		{
			IntPtr intPtr = (IntPtr)0;
			IntPtr intPtr2 = (IntPtr)length;
			if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2)
			{
				int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
				intPtr2 = (IntPtr)((Vector<byte>.Count - num) & (Vector<byte>.Count - 1));
			}
			while (true)
			{
				if ((nuint)(void*)intPtr2 >= (nuint)8u)
				{
					intPtr2 -= 8;
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						goto IL_0242;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
					{
						goto IL_024a;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
					{
						goto IL_0258;
					}
					if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
					{
						if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 4))
						{
							if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 5))
							{
								if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 6))
								{
									if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 7))
									{
										break;
									}
									intPtr += 8;
									continue;
								}
								return (int)(void*)(intPtr + 6);
							}
							return (int)(void*)(intPtr + 5);
						}
						return (int)(void*)(intPtr + 4);
					}
					goto IL_0266;
				}
				if ((nuint)(void*)intPtr2 >= (nuint)4u)
				{
					intPtr2 -= 4;
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						goto IL_0242;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
					{
						goto IL_024a;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
					{
						goto IL_0258;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
					{
						goto IL_0266;
					}
					intPtr += 4;
				}
				while ((void*)intPtr2 != null)
				{
					intPtr2 -= 1;
					if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						intPtr += 1;
						continue;
					}
					goto IL_0242;
				}
				if (Vector.IsHardwareAccelerated && (int)(void*)intPtr < length)
				{
					intPtr2 = (IntPtr)((length - (int)(void*)intPtr) & ~(Vector<byte>.Count - 1));
					Vector<byte> vector = GetVector(value);
					for (; (void*)intPtr2 > (void*)intPtr; intPtr += Vector<byte>.Count)
					{
						Vector<byte> vector2 = Vector.Equals(vector, Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr)));
						if (!Vector<byte>.Zero.Equals(vector2))
						{
							return (int)(void*)intPtr + LocateFirstFoundByte(vector2);
						}
					}
					if ((int)(void*)intPtr < length)
					{
						intPtr2 = (IntPtr)(length - (int)(void*)intPtr);
						continue;
					}
				}
				return -1;
				IL_0266:
				return (int)(void*)(intPtr + 3);
				IL_0242:
				return (int)(void*)intPtr;
				IL_0258:
				return (int)(void*)(intPtr + 2);
				IL_024a:
				return (int)(void*)(intPtr + 1);
			}
			return (int)(void*)(intPtr + 7);
		}

		public static int LastIndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			byte value2 = value;
			ref byte second = ref Unsafe.Add(ref value, 1);
			int num = valueLength - 1;
			int num2 = 0;
			while (true)
			{
				int num3 = searchSpaceLength - num2 - num;
				if (num3 <= 0)
				{
					break;
				}
				int num4 = LastIndexOf(ref searchSpace, value2, num3);
				if (num4 == -1)
				{
					break;
				}
				if (SequenceEqual(ref Unsafe.Add(ref searchSpace, num4 + 1), ref second, num))
				{
					return num4;
				}
				num2 += num3 - num4;
			}
			return -1;
		}

		public unsafe static int LastIndexOf(ref byte searchSpace, byte value, int length)
		{
			IntPtr intPtr = (IntPtr)length;
			IntPtr intPtr2 = (IntPtr)length;
			if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2)
			{
				int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
				intPtr2 = (IntPtr)(((length & (Vector<byte>.Count - 1)) + num) & (Vector<byte>.Count - 1));
			}
			while (true)
			{
				if ((nuint)(void*)intPtr2 >= (nuint)8u)
				{
					intPtr2 -= 8;
					intPtr -= 8;
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 7))
					{
						break;
					}
					if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 6))
					{
						if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 5))
						{
							if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 4))
							{
								if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
								{
									if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
									{
										if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
										{
											if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr))
											{
												continue;
											}
											goto IL_0254;
										}
										goto IL_025c;
									}
									goto IL_026a;
								}
								goto IL_0278;
							}
							return (int)(void*)(intPtr + 4);
						}
						return (int)(void*)(intPtr + 5);
					}
					return (int)(void*)(intPtr + 6);
				}
				if ((nuint)(void*)intPtr2 >= (nuint)4u)
				{
					intPtr2 -= 4;
					intPtr -= 4;
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
					{
						goto IL_0278;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
					{
						goto IL_026a;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
					{
						goto IL_025c;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						goto IL_0254;
					}
				}
				while ((void*)intPtr2 != null)
				{
					intPtr2 -= 1;
					intPtr -= 1;
					if (value !

plugins/System.Numerics.Vectors.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using FxResources.System.Numerics.Vectors;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Numerics.Vectors")]
[assembly: AssemblyDescription("System.Numerics.Vectors")]
[assembly: AssemblyDefaultAlias("System.Numerics.Vectors")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.25519.03")]
[assembly: AssemblyInformationalVersion("4.6.25519.03 built by: dlab-DDVSOWINAGE013. Commit Hash: 8321c729934c0f8be754953439b88e6e1c120c24")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.1.3.0")]
[assembly: TypeForwardedTo(typeof(Matrix3x2))]
[assembly: TypeForwardedTo(typeof(Matrix4x4))]
[assembly: TypeForwardedTo(typeof(Plane))]
[assembly: TypeForwardedTo(typeof(Quaternion))]
[assembly: TypeForwardedTo(typeof(Vector2))]
[assembly: TypeForwardedTo(typeof(Vector3))]
[assembly: TypeForwardedTo(typeof(Vector4))]
[module: UnverifiableCode]
namespace FxResources.System.Numerics.Vectors
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class MathF
	{
		public const float PI = 3.1415927f;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Abs(float x)
		{
			return Math.Abs(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Acos(float x)
		{
			return (float)Math.Acos(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Cos(float x)
		{
			return (float)Math.Cos(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float IEEERemainder(float x, float y)
		{
			return (float)Math.IEEERemainder(x, y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Sin(float x)
		{
			return (float)Math.Sin(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Sqrt(float x)
		{
			return (float)Math.Sqrt(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Tan(float x)
		{
			return (float)Math.Tan(x);
		}
	}
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		private const string s_resourcesName = "FxResources.System.Numerics.Vectors.SR";

		private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));

		internal static string Arg_ArgumentOutOfRangeException => GetResourceString("Arg_ArgumentOutOfRangeException", null);

		internal static string Arg_ElementsInSourceIsGreaterThanDestination => GetResourceString("Arg_ElementsInSourceIsGreaterThanDestination", null);

		internal static string Arg_NullArgumentNullRef => GetResourceString("Arg_NullArgumentNullRef", null);

		internal static string Arg_TypeNotSupported => GetResourceString("Arg_TypeNotSupported", null);

		internal static Type ResourceType => typeof(SR);

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal))
			{
				return defaultString;
			}
			return text;
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}
	}
}
namespace System.Numerics
{
	internal class ConstantHelper
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static byte GetByteWithAllBitsSet()
		{
			byte result = 0;
			result = byte.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static sbyte GetSByteWithAllBitsSet()
		{
			sbyte result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ushort GetUInt16WithAllBitsSet()
		{
			ushort result = 0;
			result = ushort.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static short GetInt16WithAllBitsSet()
		{
			short result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint GetUInt32WithAllBitsSet()
		{
			uint result = 0u;
			result = uint.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int GetInt32WithAllBitsSet()
		{
			int result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ulong GetUInt64WithAllBitsSet()
		{
			ulong result = 0uL;
			result = ulong.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static long GetInt64WithAllBitsSet()
		{
			long result = 0L;
			result = -1L;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static float GetSingleWithAllBitsSet()
		{
			float result = 0f;
			*(int*)(&result) = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static double GetDoubleWithAllBitsSet()
		{
			double result = 0.0;
			*(long*)(&result) = -1L;
			return result;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property)]
	internal class JitIntrinsicAttribute : Attribute
	{
	}
	[StructLayout(LayoutKind.Explicit)]
	internal struct Register
	{
		[FieldOffset(0)]
		internal byte byte_0;

		[FieldOffset(1)]
		internal byte byte_1;

		[FieldOffset(2)]
		internal byte byte_2;

		[FieldOffset(3)]
		internal byte byte_3;

		[FieldOffset(4)]
		internal byte byte_4;

		[FieldOffset(5)]
		internal byte byte_5;

		[FieldOffset(6)]
		internal byte byte_6;

		[FieldOffset(7)]
		internal byte byte_7;

		[FieldOffset(8)]
		internal byte byte_8;

		[FieldOffset(9)]
		internal byte byte_9;

		[FieldOffset(10)]
		internal byte byte_10;

		[FieldOffset(11)]
		internal byte byte_11;

		[FieldOffset(12)]
		internal byte byte_12;

		[FieldOffset(13)]
		internal byte byte_13;

		[FieldOffset(14)]
		internal byte byte_14;

		[FieldOffset(15)]
		internal byte byte_15;

		[FieldOffset(0)]
		internal sbyte sbyte_0;

		[FieldOffset(1)]
		internal sbyte sbyte_1;

		[FieldOffset(2)]
		internal sbyte sbyte_2;

		[FieldOffset(3)]
		internal sbyte sbyte_3;

		[FieldOffset(4)]
		internal sbyte sbyte_4;

		[FieldOffset(5)]
		internal sbyte sbyte_5;

		[FieldOffset(6)]
		internal sbyte sbyte_6;

		[FieldOffset(7)]
		internal sbyte sbyte_7;

		[FieldOffset(8)]
		internal sbyte sbyte_8;

		[FieldOffset(9)]
		internal sbyte sbyte_9;

		[FieldOffset(10)]
		internal sbyte sbyte_10;

		[FieldOffset(11)]
		internal sbyte sbyte_11;

		[FieldOffset(12)]
		internal sbyte sbyte_12;

		[FieldOffset(13)]
		internal sbyte sbyte_13;

		[FieldOffset(14)]
		internal sbyte sbyte_14;

		[FieldOffset(15)]
		internal sbyte sbyte_15;

		[FieldOffset(0)]
		internal ushort uint16_0;

		[FieldOffset(2)]
		internal ushort uint16_1;

		[FieldOffset(4)]
		internal ushort uint16_2;

		[FieldOffset(6)]
		internal ushort uint16_3;

		[FieldOffset(8)]
		internal ushort uint16_4;

		[FieldOffset(10)]
		internal ushort uint16_5;

		[FieldOffset(12)]
		internal ushort uint16_6;

		[FieldOffset(14)]
		internal ushort uint16_7;

		[FieldOffset(0)]
		internal short int16_0;

		[FieldOffset(2)]
		internal short int16_1;

		[FieldOffset(4)]
		internal short int16_2;

		[FieldOffset(6)]
		internal short int16_3;

		[FieldOffset(8)]
		internal short int16_4;

		[FieldOffset(10)]
		internal short int16_5;

		[FieldOffset(12)]
		internal short int16_6;

		[FieldOffset(14)]
		internal short int16_7;

		[FieldOffset(0)]
		internal uint uint32_0;

		[FieldOffset(4)]
		internal uint uint32_1;

		[FieldOffset(8)]
		internal uint uint32_2;

		[FieldOffset(12)]
		internal uint uint32_3;

		[FieldOffset(0)]
		internal int int32_0;

		[FieldOffset(4)]
		internal int int32_1;

		[FieldOffset(8)]
		internal int int32_2;

		[FieldOffset(12)]
		internal int int32_3;

		[FieldOffset(0)]
		internal ulong uint64_0;

		[FieldOffset(8)]
		internal ulong uint64_1;

		[FieldOffset(0)]
		internal long int64_0;

		[FieldOffset(8)]
		internal long int64_1;

		[FieldOffset(0)]
		internal float single_0;

		[FieldOffset(4)]
		internal float single_1;

		[FieldOffset(8)]
		internal float single_2;

		[FieldOffset(12)]
		internal float single_3;

		[FieldOffset(0)]
		internal double double_0;

		[FieldOffset(8)]
		internal double double_1;
	}
	public struct Vector<T> : IEquatable<Vector<T>>, IFormattable where T : struct
	{
		private struct VectorSizeHelper
		{
			internal Vector<T> _placeholder;

			internal byte _byte;
		}

		private System.Numerics.Register register;

		private static readonly int s_count = InitializeCount();

		private static readonly Vector<T> zero = new Vector<T>(GetZeroValue());

		private static readonly Vector<T> one = new Vector<T>(GetOneValue());

		private static readonly Vector<T> allOnes = new Vector<T>(GetAllBitsSetValue());

		[JitIntrinsic]
		public static int Count => s_count;

		[JitIntrinsic]
		public static Vector<T> Zero => zero;

		[JitIntrinsic]
		public static Vector<T> One => one;

		internal static Vector<T> AllOnes => allOnes;

		[JitIntrinsic]
		public unsafe T this[int index]
		{
			get
			{
				if (index >= Count || index < 0)
				{
					throw new IndexOutOfRangeException(System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, index));
				}
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						return (T)(object)ptr[index];
					}
				}
				if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						return (T)(object)ptr2[index];
					}
				}
				if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						return (T)(object)ptr3[index];
					}
				}
				if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						return (T)(object)ptr4[index];
					}
				}
				if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						return (T)(object)ptr5[index];
					}
				}
				if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						return (T)(object)ptr6[index];
					}
				}
				if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						return (T)(object)ptr7[index];
					}
				}
				if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						return (T)(object)ptr8[index];
					}
				}
				if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						return (T)(object)ptr9[index];
					}
				}
				if (typeof(T) == typeof(double))
				{
					fixed (double* ptr10 = &register.double_0)
					{
						return (T)(object)ptr10[index];
					}
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
		}

		private unsafe static int InitializeCount()
		{
			VectorSizeHelper vectorSizeHelper = default(VectorSizeHelper);
			byte* ptr = &vectorSizeHelper._placeholder.register.byte_0;
			byte* ptr2 = &vectorSizeHelper._byte;
			int num = (int)(ptr2 - ptr);
			int num2 = -1;
			if (typeof(T) == typeof(byte))
			{
				num2 = 1;
			}
			else if (typeof(T) == typeof(sbyte))
			{
				num2 = 1;
			}
			else if (typeof(T) == typeof(ushort))
			{
				num2 = 2;
			}
			else if (typeof(T) == typeof(short))
			{
				num2 = 2;
			}
			else if (typeof(T) == typeof(uint))
			{
				num2 = 4;
			}
			else if (typeof(T) == typeof(int))
			{
				num2 = 4;
			}
			else if (typeof(T) == typeof(ulong))
			{
				num2 = 8;
			}
			else if (typeof(T) == typeof(long))
			{
				num2 = 8;
			}
			else if (typeof(T) == typeof(float))
			{
				num2 = 4;
			}
			else
			{
				if (!(typeof(T) == typeof(double)))
				{
					throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
				}
				num2 = 8;
			}
			return num / num2;
		}

		[JitIntrinsic]
		public unsafe Vector(T value)
		{
			this = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[i] = (byte)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[j] = (sbyte)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[k] = (ushort)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[l] = (short)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[m] = (uint)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[n] = (int)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[num] = (ulong)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[num2] = (long)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[num3] = (float)(object)value;
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = &register.double_0)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[num4] = (double)(object)value;
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				register.byte_0 = (byte)(object)value;
				register.byte_1 = (byte)(object)value;
				register.byte_2 = (byte)(object)value;
				register.byte_3 = (byte)(object)value;
				register.byte_4 = (byte)(object)value;
				register.byte_5 = (byte)(object)value;
				register.byte_6 = (byte)(object)value;
				register.byte_7 = (byte)(object)value;
				register.byte_8 = (byte)(object)value;
				register.byte_9 = (byte)(object)value;
				register.byte_10 = (byte)(object)value;
				register.byte_11 = (byte)(object)value;
				register.byte_12 = (byte)(object)value;
				register.byte_13 = (byte)(object)value;
				register.byte_14 = (byte)(object)value;
				register.byte_15 = (byte)(object)value;
			}
			else if (typeof(T) == typeof(sbyte))
			{
				register.sbyte_0 = (sbyte)(object)value;
				register.sbyte_1 = (sbyte)(object)value;
				register.sbyte_2 = (sbyte)(object)value;
				register.sbyte_3 = (sbyte)(object)value;
				register.sbyte_4 = (sbyte)(object)value;
				register.sbyte_5 = (sbyte)(object)value;
				register.sbyte_6 = (sbyte)(object)value;
				register.sbyte_7 = (sbyte)(object)value;
				register.sbyte_8 = (sbyte)(object)value;
				register.sbyte_9 = (sbyte)(object)value;
				register.sbyte_10 = (sbyte)(object)value;
				register.sbyte_11 = (sbyte)(object)value;
				register.sbyte_12 = (sbyte)(object)value;
				register.sbyte_13 = (sbyte)(object)value;
				register.sbyte_14 = (sbyte)(object)value;
				register.sbyte_15 = (sbyte)(object)value;
			}
			else if (typeof(T) == typeof(ushort))
			{
				register.uint16_0 = (ushort)(object)value;
				register.uint16_1 = (ushort)(object)value;
				register.uint16_2 = (ushort)(object)value;
				register.uint16_3 = (ushort)(object)value;
				register.uint16_4 = (ushort)(object)value;
				register.uint16_5 = (ushort)(object)value;
				register.uint16_6 = (ushort)(object)value;
				register.uint16_7 = (ushort)(object)value;
			}
			else if (typeof(T) == typeof(short))
			{
				register.int16_0 = (short)(object)value;
				register.int16_1 = (short)(object)value;
				register.int16_2 = (short)(object)value;
				register.int16_3 = (short)(object)value;
				register.int16_4 = (short)(object)value;
				register.int16_5 = (short)(object)value;
				register.int16_6 = (short)(object)value;
				register.int16_7 = (short)(object)value;
			}
			else if (typeof(T) == typeof(uint))
			{
				register.uint32_0 = (uint)(object)value;
				register.uint32_1 = (uint)(object)value;
				register.uint32_2 = (uint)(object)value;
				register.uint32_3 = (uint)(object)value;
			}
			else if (typeof(T) == typeof(int))
			{
				register.int32_0 = (int)(object)value;
				register.int32_1 = (int)(object)value;
				register.int32_2 = (int)(object)value;
				register.int32_3 = (int)(object)value;
			}
			else if (typeof(T) == typeof(ulong))
			{
				register.uint64_0 = (ulong)(object)value;
				register.uint64_1 = (ulong)(object)value;
			}
			else if (typeof(T) == typeof(long))
			{
				register.int64_0 = (long)(object)value;
				register.int64_1 = (long)(object)value;
			}
			else if (typeof(T) == typeof(float))
			{
				register.single_0 = (float)(object)value;
				register.single_1 = (float)(object)value;
				register.single_2 = (float)(object)value;
				register.single_3 = (float)(object)value;
			}
			else if (typeof(T) == typeof(double))
			{
				register.double_0 = (double)(object)value;
				register.double_1 = (double)(object)value;
			}
		}

		[JitIntrinsic]
		public Vector(T[] values)
			: this(values, 0)
		{
		}

		public unsafe Vector(T[] values, int index)
		{
			this = default(Vector<T>);
			if (values == null)
			{
				throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef);
			}
			if (index < 0 || values.Length - index < Count)
			{
				throw new IndexOutOfRangeException();
			}
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[i] = (byte)(object)values[i + index];
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[j] = (sbyte)(object)values[j + index];
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[k] = (ushort)(object)values[k + index];
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[l] = (short)(object)values[l + index];
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[m] = (uint)(object)values[m + index];
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[n] = (int)(object)values[n + index];
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[num] = (ulong)(object)values[num + index];
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[num2] = (long)(object)values[num2 + index];
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[num3] = (float)(object)values[num3 + index];
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = &register.double_0)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[num4] = (double)(object)values[num4 + index];
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				fixed (byte* ptr11 = &register.byte_0)
				{
					*ptr11 = (byte)(object)values[index];
					ptr11[1] = (byte)(object)values[1 + index];
					ptr11[2] = (byte)(object)values[2 + index];
					ptr11[3] = (byte)(object)values[3 + index];
					ptr11[4] = (byte)(object)values[4 + index];
					ptr11[5] = (byte)(object)values[5 + index];
					ptr11[6] = (byte)(object)values[6 + index];
					ptr11[7] = (byte)(object)values[7 + index];
					ptr11[8] = (byte)(object)values[8 + index];
					ptr11[9] = (byte)(object)values[9 + index];
					ptr11[10] = (byte)(object)values[10 + index];
					ptr11[11] = (byte)(object)values[11 + index];
					ptr11[12] = (byte)(object)values[12 + index];
					ptr11[13] = (byte)(object)values[13 + index];
					ptr11[14] = (byte)(object)values[14 + index];
					ptr11[15] = (byte)(object)values[15 + index];
				}
			}
			else if (typeof(T) == typeof(sbyte))
			{
				fixed (sbyte* ptr12 = &register.sbyte_0)
				{
					*ptr12 = (sbyte)(object)values[index];
					ptr12[1] = (sbyte)(object)values[1 + index];
					ptr12[2] = (sbyte)(object)values[2 + index];
					ptr12[3] = (sbyte)(object)values[3 + index];
					ptr12[4] = (sbyte)(object)values[4 + index];
					ptr12[5] = (sbyte)(object)values[5 + index];
					ptr12[6] = (sbyte)(object)values[6 + index];
					ptr12[7] = (sbyte)(object)values[7 + index];
					ptr12[8] = (sbyte)(object)values[8 + index];
					ptr12[9] = (sbyte)(object)values[9 + index];
					ptr12[10] = (sbyte)(object)values[10 + index];
					ptr12[11] = (sbyte)(object)values[11 + index];
					ptr12[12] = (sbyte)(object)values[12 + index];
					ptr12[13] = (sbyte)(object)values[13 + index];
					ptr12[14] = (sbyte)(object)values[14 + index];
					ptr12[15] = (sbyte)(object)values[15 + index];
				}
			}
			else if (typeof(T) == typeof(ushort))
			{
				fixed (ushort* ptr13 = &register.uint16_0)
				{
					*ptr13 = (ushort)(object)values[index];
					ptr13[1] = (ushort)(object)values[1 + index];
					ptr13[2] = (ushort)(object)values[2 + index];
					ptr13[3] = (ushort)(object)values[3 + index];
					ptr13[4] = (ushort)(object)values[4 + index];
					ptr13[5] = (ushort)(object)values[5 + index];
					ptr13[6] = (ushort)(object)values[6 + index];
					ptr13[7] = (ushort)(object)values[7 + index];
				}
			}
			else if (typeof(T) == typeof(short))
			{
				fixed (short* ptr14 = &register.int16_0)
				{
					*ptr14 = (short)(object)values[index];
					ptr14[1] = (short)(object)values[1 + index];
					ptr14[2] = (short)(object)values[2 + index];
					ptr14[3] = (short)(object)values[3 + index];
					ptr14[4] = (short)(object)values[4 + index];
					ptr14[5] = (short)(object)values[5 + index];
					ptr14[6] = (short)(object)values[6 + index];
					ptr14[7] = (short)(object)values[7 + index];
				}
			}
			else if (typeof(T) == typeof(uint))
			{
				fixed (uint* ptr15 = &register.uint32_0)
				{
					*ptr15 = (uint)(object)values[index];
					ptr15[1] = (uint)(object)values[1 + index];
					ptr15[2] = (uint)(object)values[2 + index];
					ptr15[3] = (uint)(object)values[3 + index];
				}
			}
			else if (typeof(T) == typeof(int))
			{
				fixed (int* ptr16 = &register.int32_0)
				{
					*ptr16 = (int)(object)values[index];
					ptr16[1] = (int)(object)values[1 + index];
					ptr16[2] = (int)(object)values[2 + index];
					ptr16[3] = (int)(object)values[3 + index];
				}
			}
			else if (typeof(T) == typeof(ulong))
			{
				fixed (ulong* ptr17 = &register.uint64_0)
				{
					*ptr17 = (ulong)(object)values[index];
					ptr17[1] = (ulong)(object)values[1 + index];
				}
			}
			else if (typeof(T) == typeof(long))
			{
				fixed (long* ptr18 = &register.int64_0)
				{
					*ptr18 = (long)(object)values[index];
					ptr18[1] = (long)(object)values[1 + index];
				}
			}
			else if (typeof(T) == typeof(float))
			{
				fixed (float* ptr19 = &register.single_0)
				{
					*ptr19 = (float)(object)values[index];
					ptr19[1] = (float)(object)values[1 + index];
					ptr19[2] = (float)(object)values[2 + index];
					ptr19[3] = (float)(object)values[3 + index];
				}
			}
			else if (typeof(T) == typeof(double))
			{
				fixed (double* ptr20 = &register.double_0)
				{
					*ptr20 = (double)(object)values[index];
					ptr20[1] = (double)(object)values[1 + index];
				}
			}
		}

		internal unsafe Vector(void* dataPointer)
			: this(dataPointer, 0)
		{
		}

		internal unsafe Vector(void* dataPointer, int offset)
		{
			this = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				byte* ptr = (byte*)dataPointer;
				ptr += offset;
				fixed (byte* ptr2 = &register.byte_0)
				{
					for (int i = 0; i < Count; i++)
					{
						ptr2[i] = ptr[i];
					}
				}
				return;
			}
			if (typeof(T) == typeof(sbyte))
			{
				sbyte* ptr3 = (sbyte*)dataPointer;
				ptr3 += offset;
				fixed (sbyte* ptr4 = &register.sbyte_0)
				{
					for (int j = 0; j < Count; j++)
					{
						ptr4[j] = ptr3[j];
					}
				}
				return;
			}
			if (typeof(T) == typeof(ushort))
			{
				ushort* ptr5 = (ushort*)dataPointer;
				ptr5 += offset;
				fixed (ushort* ptr6 = &register.uint16_0)
				{
					for (int k = 0; k < Count; k++)
					{
						ptr6[k] = ptr5[k];
					}
				}
				return;
			}
			if (typeof(T) == typeof(short))
			{
				short* ptr7 = (short*)dataPointer;
				ptr7 += offset;
				fixed (short* ptr8 = &register.int16_0)
				{
					for (int l = 0; l < Count; l++)
					{
						ptr8[l] = ptr7[l];
					}
				}
				return;
			}
			if (typeof(T) == typeof(uint))
			{
				uint* ptr9 = (uint*)dataPointer;
				ptr9 += offset;
				fixed (uint* ptr10 = &register.uint32_0)
				{
					for (int m = 0; m < Count; m++)
					{
						ptr10[m] = ptr9[m];
					}
				}
				return;
			}
			if (typeof(T) == typeof(int))
			{
				int* ptr11 = (int*)dataPointer;
				ptr11 += offset;
				fixed (int* ptr12 = &register.int32_0)
				{
					for (int n = 0; n < Count; n++)
					{
						ptr12[n] = ptr11[n];
					}
				}
				return;
			}
			if (typeof(T) == typeof(ulong))
			{
				ulong* ptr13 = (ulong*)dataPointer;
				ptr13 += offset;
				fixed (ulong* ptr14 = &register.uint64_0)
				{
					for (int num = 0; num < Count; num++)
					{
						ptr14[num] = ptr13[num];
					}
				}
				return;
			}
			if (typeof(T) == typeof(long))
			{
				long* ptr15 = (long*)dataPointer;
				ptr15 += offset;
				fixed (long* ptr16 = &register.int64_0)
				{
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr16[num2] = ptr15[num2];
					}
				}
				return;
			}
			if (typeof(T) == typeof(float))
			{
				float* ptr17 = (float*)dataPointer;
				ptr17 += offset;
				fixed (float* ptr18 = &register.single_0)
				{
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr18[num3] = ptr17[num3];
					}
				}
				return;
			}
			if (typeof(T) == typeof(double))
			{
				double* ptr19 = (double*)dataPointer;
				ptr19 += offset;
				fixed (double* ptr20 = &register.double_0)
				{
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr20[num4] = ptr19[num4];
					}
				}
				return;
			}
			throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
		}

		private Vector(ref System.Numerics.Register existingRegister)
		{
			register = existingRegister;
		}

		[JitIntrinsic]
		public void CopyTo(T[] destination)
		{
			CopyTo(destination, 0);
		}

		[JitIntrinsic]
		public unsafe void CopyTo(T[] destination, int startIndex)
		{
			if (destination == null)
			{
				throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef);
			}
			if (startIndex < 0 || startIndex >= destination.Length)
			{
				throw new ArgumentOutOfRangeException("startIndex", System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, startIndex));
			}
			if (destination.Length - startIndex < Count)
			{
				throw new ArgumentException(System.SR.Format(System.SR.Arg_ElementsInSourceIsGreaterThanDestination, startIndex));
			}
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = (byte[])(object)destination)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[startIndex + i] = (byte)(object)this[i];
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = (sbyte[])(object)destination)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[startIndex + j] = (sbyte)(object)this[j];
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = (ushort[])(object)destination)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[startIndex + k] = (ushort)(object)this[k];
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = (short[])(object)destination)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[startIndex + l] = (short)(object)this[l];
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = (uint[])(object)destination)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[startIndex + m] = (uint)(object)this[m];
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = (int[])(object)destination)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[startIndex + n] = (int)(object)this[n];
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = (ulong[])(object)destination)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[startIndex + num] = (ulong)(object)this[num];
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = (long[])(object)destination)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[startIndex + num2] = (long)(object)this[num2];
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = (float[])(object)destination)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[startIndex + num3] = (float)(object)this[num3];
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = (double[])(object)destination)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[startIndex + num4] = (double)(object)this[num4];
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				fixed (byte* ptr11 = (byte[])(object)destination)
				{
					ptr11[startIndex] = register.byte_0;
					ptr11[startIndex + 1] = register.byte_1;
					ptr11[startIndex + 2] = register.byte_2;
					ptr11[startIndex + 3] = register.byte_3;
					ptr11[startIndex + 4] = register.byte_4;
					ptr11[startIndex + 5] = register.byte_5;
					ptr11[startIndex + 6] = register.byte_6;
					ptr11[startIndex + 7] = register.byte_7;
					ptr11[startIndex + 8] = register.byte_8;
					ptr11[startIndex + 9] = register.byte_9;
					ptr11[startIndex + 10] = register.byte_10;
					ptr11[startIndex + 11] = register.byte_11;
					ptr11[startIndex + 12] = register.byte_12;
					ptr11[startIndex + 13] = register.byte_13;
					ptr11[startIndex + 14] = register.byte_14;
					ptr11[startIndex + 15] = register.byte_15;
				}
			}
			else if (typeof(T) == typeof(sbyte))
			{
				fixed (sbyte* ptr12 = (sbyte[])(object)destination)
				{
					ptr12[startIndex] = register.sbyte_0;
					ptr12[startIndex + 1] = register.sbyte_1;
					ptr12[startIndex + 2] = register.sbyte_2;
					ptr12[startIndex + 3] = register.sbyte_3;
					ptr12[startIndex + 4] = register.sbyte_4;
					ptr12[startIndex + 5] = register.sbyte_5;
					ptr12[startIndex + 6] = register.sbyte_6;
					ptr12[startIndex + 7] = register.sbyte_7;
					ptr12[startIndex + 8] = register.sbyte_8;
					ptr12[startIndex + 9] = register.sbyte_9;
					ptr12[startIndex + 10] = register.sbyte_10;
					ptr12[startIndex + 11] = register.sbyte_11;
					ptr12[startIndex + 12] = register.sbyte_12;
					ptr12[startIndex + 13] = register.sbyte_13;
					ptr12[startIndex + 14] = register.sbyte_14;
					ptr12[startIndex + 15] = register.sbyte_15;
				}
			}
			else if (typeof(T) == typeof(ushort))
			{
				fixed (ushort* ptr13 = (ushort[])(object)destination)
				{
					ptr13[startIndex] = register.uint16_0;
					ptr13[startIndex + 1] = register.uint16_1;
					ptr13[startIndex + 2] = register.uint16_2;
					ptr13[startIndex + 3] = register.uint16_3;
					ptr13[startIndex + 4] = register.uint16_4;
					ptr13[startIndex + 5] = register.uint16_5;
					ptr13[startIndex + 6] = register.uint16_6;
					ptr13[startIndex + 7] = register.uint16_7;
				}
			}
			else if (typeof(T) == typeof(short))
			{
				fixed (short* ptr14 = (short[])(object)destination)
				{
					ptr14[startIndex] = register.int16_0;
					ptr14[startIndex + 1] = register.int16_1;
					ptr14[startIndex + 2] = register.int16_2;
					ptr14[startIndex + 3] = register.int16_3;
					ptr14[startIndex + 4] = register.int16_4;
					ptr14[startIndex + 5] = register.int16_5;
					ptr14[startIndex + 6] = register.int16_6;
					ptr14[startIndex + 7] = register.int16_7;
				}
			}
			else if (typeof(T) == typeof(uint))
			{
				fixed (uint* ptr15 = (uint[])(object)destination)
				{
					ptr15[startIndex] = register.uint32_0;
					ptr15[startIndex + 1] = register.uint32_1;
					ptr15[startIndex + 2] = register.uint32_2;
					ptr15[startIndex + 3] = register.uint32_3;
				}
			}
			else if (typeof(T) == typeof(int))
			{
				fixed (int* ptr16 = (int[])(object)destination)
				{
					ptr16[startIndex] = register.int32_0;
					ptr16[startIndex + 1] = register.int32_1;
					ptr16[startIndex + 2] = register.int32_2;
					ptr16[startIndex + 3] = register.int32_3;
				}
			}
			else if (typeof(T) == typeof(ulong))
			{
				fixed (ulong* ptr17 = (ulong[])(object)destination)
				{
					ptr17[startIndex] = register.uint64_0;
					ptr17[startIndex + 1] = register.uint64_1;
				}
			}
			else if (typeof(T) == typeof(long))
			{
				fixed (long* ptr18 = (long[])(object)destination)
				{
					ptr18[startIndex] = register.int64_0;
					ptr18[startIndex + 1] = register.int64_1;
				}
			}
			else if (typeof(T) == typeof(float))
			{
				fixed (float* ptr19 = (float[])(object)destination)
				{
					ptr19[startIndex] = register.single_0;
					ptr19[startIndex + 1] = register.single_1;
					ptr19[startIndex + 2] = register.single_2;
					ptr19[startIndex + 3] = register.single_3;
				}
			}
			else if (typeof(T) == typeof(double))
			{
				fixed (double* ptr20 = (double[])(object)destination)
				{
					ptr20[startIndex] = register.double_0;
					ptr20[startIndex + 1] = register.double_1;
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public override bool Equals(object obj)
		{
			if (!(obj is Vector<T>))
			{
				return false;
			}
			return Equals((Vector<T>)obj);
		}

		[JitIntrinsic]
		public bool Equals(Vector<T> other)
		{
			if (Vector.IsHardwareAccelerated)
			{
				for (int i = 0; i < Count; i++)
				{
					if (!ScalarEquals(this[i], other[i]))
					{
						return false;
					}
				}
				return true;
			}
			if (typeof(T) == typeof(byte))
			{
				if (register.byte_0 == other.register.byte_0 && register.byte_1 == other.register.byte_1 && register.byte_2 == other.register.byte_2 && register.byte_3 == other.register.byte_3 && register.byte_4 == other.register.byte_4 && register.byte_5 == other.register.byte_5 && register.byte_6 == other.register.byte_6 && register.byte_7 == other.register.byte_7 && register.byte_8 == other.register.byte_8 && register.byte_9 == other.register.byte_9 && register.byte_10 == other.register.byte_10 && register.byte_11 == other.register.byte_11 && register.byte_12 == other.register.byte_12 && register.byte_13 == other.register.byte_13 && register.byte_14 == other.register.byte_14)
				{
					return register.byte_15 == other.register.byte_15;
				}
				return false;
			}
			if (typeof(T) == typeof(sbyte))
			{
				if (register.sbyte_0 == other.register.sbyte_0 && register.sbyte_1 == other.register.sbyte_1 && register.sbyte_2 == other.register.sbyte_2 && register.sbyte_3 == other.register.sbyte_3 && register.sbyte_4 == other.register.sbyte_4 && register.sbyte_5 == other.register.sbyte_5 && register.sbyte_6 == other.register.sbyte_6 && register.sbyte_7 == other.register.sbyte_7 && register.sbyte_8 == other.register.sbyte_8 && register.sbyte_9 == other.register.sbyte_9 && register.sbyte_10 == other.register.sbyte_10 && register.sbyte_11 == other.register.sbyte_11 && register.sbyte_12 == other.register.sbyte_12 && register.sbyte_13 == other.register.sbyte_13 && register.sbyte_14 == other.register.sbyte_14)
				{
					return register.sbyte_15 == other.register.sbyte_15;
				}
				return false;
			}
			if (typeof(T) == typeof(ushort))
			{
				if (register.uint16_0 == other.register.uint16_0 && register.uint16_1 == other.register.uint16_1 && register.uint16_2 == other.register.uint16_2 && register.uint16_3 == other.register.uint16_3 && register.uint16_4 == other.register.uint16_4 && register.uint16_5 == other.register.uint16_5 && register.uint16_6 == other.register.uint16_6)
				{
					return register.uint16_7 == other.register.uint16_7;
				}
				return false;
			}
			if (typeof(T) == typeof(short))
			{
				if (register.int16_0 == other.register.int16_0 && register.int16_1 == other.register.int16_1 && register.int16_2 == other.register.int16_2 && register.int16_3 == other.register.int16_3 && register.int16_4 == other.register.int16_4 && register.int16_5 == other.register.int16_5 && register.int16_6 == other.register.int16_6)
				{
					return register.int16_7 == other.register.int16_7;
				}
				return false;
			}
			if (typeof(T) == typeof(uint))
			{
				if (register.uint32_0 == other.register.uint32_0 && register.uint32_1 == other.register.uint32_1 && register.uint32_2 == other.register.uint32_2)
				{
					return register.uint32_3 == other.register.uint32_3;
				}
				return false;
			}
			if (typeof(T) == typeof(int))
			{
				if (register.int32_0 == other.register.int32_0 && register.int32_1 == other.register.int32_1 && register.int32_2 == other.register.int32_2)
				{
					return register.int32_3 == other.register.int32_3;
				}
				return false;
			}
			if (typeof(T) == typeof(ulong))
			{
				if (register.uint64_0 == other.register.uint64_0)
				{
					return register.uint64_1 == other.register.uint64_1;
				}
				return false;
			}
			if (typeof(T) == typeof(long))
			{
				if (register.int64_0 == other.register.int64_0)
				{
					return register.int64_1 == other.register.int64_1;
				}
				return false;
			}
			if (typeof(T) == typeof(float))
			{
				if (register.single_0 == other.register.single_0 && register.single_1 == other.register.single_1 && register.single_2 == other.register.single_2)
				{
					return register.single_3 == other.register.single_3;
				}
				return false;
			}
			if (typeof(T) == typeof(double))
			{
				if (register.double_0 == other.register.double_0)
				{
					return register.double_1 == other.register.double_1;
				}
				return false;
			}
			throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
		}

		public override int GetHashCode()
		{
			int num = 0;
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					for (int i = 0; i < Count; i++)
					{
						num = HashHelpers.Combine(num, ((byte)(object)this[i]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(sbyte))
				{
					for (int j = 0; j < Count; j++)
					{
						num = HashHelpers.Combine(num, ((sbyte)(object)this[j]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(ushort))
				{
					for (int k = 0; k < Count; k++)
					{
						num = HashHelpers.Combine(num, ((ushort)(object)this[k]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(short))
				{
					for (int l = 0; l < Count; l++)
					{
						num = HashHelpers.Combine(num, ((short)(object)this[l]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(uint))
				{
					for (int m = 0; m < Count; m++)
					{
						num = HashHelpers.Combine(num, ((uint)(object)this[m]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(int))
				{
					for (int n = 0; n < Count; n++)
					{
						num = HashHelpers.Combine(num, ((int)(object)this[n]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(ulong))
				{
					for (int num2 = 0; num2 < Count; num2++)
					{
						num = HashHelpers.Combine(num, ((ulong)(object)this[num2]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(long))
				{
					for (int num3 = 0; num3 < Count; num3++)
					{
						num = HashHelpers.Combine(num, ((long)(object)this[num3]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(float))
				{
					for (int num4 = 0; num4 < Count; num4++)
					{
						num = HashHelpers.Combine(num, ((float)(object)this[num4]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(double))
				{
					for (int num5 = 0; num5 < Count; num5++)
					{
						num = HashHelpers.Combine(num, ((double)(object)this[num5]).GetHashCode());
					}
					return num;
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			if (typeof(T) == typeof(byte))
			{
				num = HashHelpers.Combine(num, register.byte_0.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_1.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_2.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_3.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_4.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_5.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_6.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_7.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_8.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_9.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_10.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_11.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_12.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_13.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_14.GetHashCode());
				return HashHelpers.Combine(num, register.byte_15.GetHashCode());
			}
			if (typeof(T) == typeof(sbyte))
			{
				num = HashHelpers.Combine(num, register.sbyte_0.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_1.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_2.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_3.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_4.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_5.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_6.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_7.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_8.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_9.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_10.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_11.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_12.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_13.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_14.GetHashCode());
				return HashHelpers.Combine(num, register.sbyte_15.GetHashCode());
			}
			if (typeof(T) == typeof(ushort))
			{
				num = HashHelpers.Combine(num, register.uint16_0.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_1.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_2.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_3.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_4.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_5.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_6.GetHashCode());
				return HashHelpers.Combine(num, register.uint16_7.GetHashCode());
			}
			if (typeof(T) == typeof(short))
			{
				num = HashHelpers.Combine(num, register.int16_0.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_1.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_2.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_3.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_4.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_5.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_6.GetHashCode());
				return HashHelpers.Combine(num, register.int16_7.GetHashCode());
			}
			if (typeof(T) == typeof(uint))
			{
				num = HashHelpers.Combine(num, register.uint32_0.GetHashCode());
				num = HashHelpers.Combine(num, register.uint32_1.GetHashCode());
				num = HashHelpers.Combine(num, register.uint32_2.GetHashCode());
				return HashHelpers.Combine(num, register.uint32_3.GetHashCode());
			}
			if (typeof(T) == typeof(int))
			{
				num = HashHelpers.Combine(num, register.int32_0.GetHashCode());
				num = HashHelpers.Combine(num, register.int32_1.GetHashCode());
				num = HashHelpers.Combine(num, register.int32_2.GetHashCode());
				return HashHelpers.Combine(num, register.int32_3.GetHashCode());
			}
			if (typeof(T) == typeof(ulong))
			{
				num = HashHelpers.Combine(num, register.uint64_0.GetHashCode());
				return HashHelpers.Combine(num, register.uint64_1.GetHashCode());
			}
			if (typeof(T) == typeof(long))
			{
				num = HashHelpers.Combine(num, register.int64_0.GetHashCode());
				return HashHelpers.Combine(num, register.int64_1.GetHashCode());
			}
			if (typeof(T) == typeof(float))
			{
				num = HashHelpers.Combine(num, register.single_0.GetHashCode());
				num = HashHelpers.Combine(num, register.single_1.GetHashCode());
				num = HashHelpers.Combine(num, register.single_2.GetHashCode());
				return HashHelpers.Combine(num, register.single_3.GetHashCode());
			}
			if (typeof(T) == typeof(double))
			{
				num = HashHelpers.Combine(num, register.double_0.GetHashCode());
				return HashHelpers.Combine(num, register.double_1.GetHashCode());
			}
			throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
		}

		public override string ToString()
		{
			return ToString("G", CultureInfo.CurrentCulture);
		}

		public string ToString(string format)
		{
			return ToString(format, CultureInfo.CurrentCulture);
		}

		public string ToString(string format, IFormatProvider formatProvider)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string numberGroupSeparator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator;
			stringBuilder.Append('<');
			for (int i = 0; i < Count - 1; i++)
			{
				stringBuilder.Append(((IFormattable)(object)this[i]).ToString(format, formatProvider));
				stringBuilder.Append(numberGroupSeparator);
				stringBuilder.Append(' ');
			}
			stringBuilder.Append(((IFormattable)(object)this[Count - 1]).ToString(format, formatProvider));
			stringBuilder.Append('>');
			return stringBuilder.ToString();
		}

		public unsafe static Vector<T>operator +(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarAdd(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarAdd(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarAdd(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarAdd(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarAdd(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarAdd(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarAdd(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarAdd(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarAdd(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarAdd(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 + right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 + right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 + right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 + right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 + right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 + right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 + right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 + right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 + right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 + right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 + right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 + right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 + right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 + right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 + right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 + right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 + right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 + right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 + right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 + right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 + right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 + right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 + right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 + right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 + right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 + right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 + right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 + right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 + right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 + right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 + right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 + right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 + right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 + right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 + right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 + right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 + right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 + right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 + right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 + right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 + right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 + right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 + right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 + right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 + right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 + right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 + right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 + right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 + right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 + right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 + right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 + right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 + right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 + right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 + right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 + right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 + right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 + right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 + right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 + right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 + right.register.single_0;
				result.register.single_1 = left.register.single_1 + right.register.single_1;
				result.register.single_2 = left.register.single_2 + right.register.single_2;
				result.register.single_3 = left.register.single_3 + right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 + right.register.double_0;
				result.register.double_1 = left.register.double_1 + right.register.double_1;
			}
			return result;
		}

		public unsafe static Vector<T>operator -(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarSubtract(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarSubtract(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarSubtract(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarSubtract(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarSubtract(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarSubtract(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarSubtract(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarSubtract(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarSubtract(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarSubtract(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 - right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 - right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 - right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 - right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 - right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 - right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 - right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 - right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 - right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 - right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 - right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 - right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 - right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 - right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 - right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 - right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 - right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 - right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 - right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 - right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 - right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 - right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 - right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 - right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 - right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 - right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 - right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 - right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 - right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 - right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 - right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 - right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 - right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 - right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 - right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 - right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 - right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 - right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 - right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 - right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 - right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 - right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 - right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 - right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 - right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 - right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 - right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 - right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 - right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 - right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 - right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 - right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 - right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 - right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 - right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 - right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 - right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 - right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 - right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 - right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 - right.register.single_0;
				result.register.single_1 = left.register.single_1 - right.register.single_1;
				result.register.single_2 = left.register.single_2 - right.register.single_2;
				result.register.single_3 = left.register.single_3 - right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 - right.register.double_0;
				result.register.double_1 = left.register.double_1 - right.register.double_1;
			}
			return result;
		}

		public unsafe static Vector<T>operator *(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarMultiply(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarMultiply(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarMultiply(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarMultiply(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarMultiply(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarMultiply(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarMultiply(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarMultiply(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarMultiply(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarMultiply(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 * right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 * right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 * right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 * right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 * right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 * right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 * right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 * right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 * right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 * right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 * right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 * right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 * right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 * right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 * right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 * right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 * right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 * right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 * right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 * right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 * right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 * right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 * right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 * right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 * right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 * right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 * right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 * right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 * right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 * right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 * right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 * right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 * right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 * right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 * right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 * right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 * right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 * right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 * right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 * right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 * right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 * right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 * right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 * right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 * right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 * right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 * right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 * right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 * right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 * right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 * right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 * right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 * right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 * right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 * right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 * right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 * right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 * right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 * right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 * right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 * right.register.single_0;
				result.register.single_1 = left.register.single_1 * right.register.single_1;
				result.register.single_2 = left.register.single_2 * right.register.single_2;
				result.register.single_3 = left.register.single_3 * right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 * right.register.double_0;
				result.register.double_1 = left.register.double_1 * right.register.double_1;
			}
			return result;
		}

		public static Vector<T>operator *(Vector<T> value, T factor)
		{
			if (Vector.IsHardwareAccelerated)
			{
				return new Vector<T>(factor) * value;
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(value.register.byte_0 * (byte)(object)factor);
				result.register.byte_1 = (byte)(value.register.byte_1 * (byte)(object)factor);
				result.register.byte_2 = (byte)(value.register.byte_2 * (byte)(object)factor);
				result.register.byte_3 = (byte)(value.register.byte_3 * (byte)(object)factor);
				result.register.byte_4 = (byte)(value.register.byte_4 * (byte)(object)factor);
				result.register.byte_5 = (byte)(value.register.byte_5 * (byte)(object)factor);
				result.register.byte_6 = (byte)(value.register.byte_6 * (byte)(object)factor);
				result.register.byte_7 = (byte)(value.register.byte_7 * (byte)(object)factor);
				result.register.byte_8 = (byte)(value.register.byte_8 * (byte)(object)factor);
				result.register.byte_9 = (byte)(value.register.byte_9 * (byte)(object)factor);
				result.register.byte_10 = (byte)(value.register.byte_10 * (byte)(object)factor);
				result.register.byte_11 = (byte)(value.register.byte_11 * (byte)(object)factor);
				result.register.byte_12 = (byte)(value.register.byte_12 * (byte)(object)factor);
				result.register.byte_13 = (byte)(value.register.byte_13 * (byte)(object)factor);
				result.register.byte_14 = (byte)(value.register.byte_14 * (byte)(object)factor);
				result.register.byte_15 = (byte)(value.register.byte_15 * (byte)(object)factor);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(value.register.sbyte_0 * (sbyte)(object)factor);
				result.register.sbyte_1 = (sbyte)(value.register.sbyte_1 * (sbyte)(object)factor);
				result.register.sbyte_2 = (sbyte)(value.register.sbyte_2 * (sbyte)(object)factor);
				result.register.sbyte_3 = (sbyte)(value.register.sbyte_3 * (sbyte)(object)factor);
				result.register.sbyte_4 = (sbyte)(value.register.sbyte_4 * (sbyte)(object)factor);
				result.register.sbyte_5 = (sbyte)(value.register.sbyte_5 * (sbyte)(object)factor);
				result.register.sbyte_6 = (sbyte)(value.register.sbyte_6 * (sbyte)(object)factor);
				result.register.sbyte_7 = (sbyte)(value.register.sbyte_7 * (sbyte)(object)factor);
				result.register.sbyte_8 = (sbyte)(value.register.sbyte_8 * (sbyte)(object)factor);
				result.register.sbyte_9 = (sbyte)(value.register.sbyte_9 * (sbyte)(object)factor);
				result.register.sbyte_10 = (sbyte)(value.register.sbyte_10 * (sbyte)(object)factor);
				result.register.sbyte_11 = (sbyte)(value.register.sbyte_11 * (sbyte)(object)factor);
				result.register.sbyte_12 = (sbyte)(value.register.sbyte_12 * (sbyte)(object)factor);
				result.register.sbyte_13 = (sbyte)(value.register.sbyte_13 * (sbyte)(object)factor);
				result.register.sbyte_14 = (sbyte)(value.register.sbyte_14 * (sbyte)(object)factor);
				result.register.sbyte_15 = (sbyte)(value.register.sbyte_15 * (sbyte)(object)factor);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(value.register.uint16_0 * (ushort)(object)factor);
				result.register.uint16_1 = (ushort)(value.register.uint16_1 * (ushort)(object)factor);
				result.register.uint16_2 = (ushort)(value.register.uint16_2 * (ushort)(object)factor);
				result.register.uint16_3 = (ushort)(value.register.uint16_3 * (ushort)(object)factor);
				result.register.uint16_4 = (ushort)(value.register.uint16_4 * (ushort)(object)factor);
				result.register.uint16_5 = (ushort)(value.register.uint16_5 * (ushort)(object)factor);
				result.register.uint16_6 = (ushort)(value.register.uint16_6 * (ushort)(object)factor);
				result.register.uint16_7 = (ushort)(value.register.uint16_7 * (ushort)(object)factor);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(value.register.int16_0 * (short)(object)factor);
				result.register.int16_1 = (short)(value.register.int16_1 * (short)(object)factor);
				result.register.int16_2 = (short)(value.register.int16_2 * (short)(object)factor);
				result.register.int16_3 = (short)(value.register.int16_3 * (short)(object)factor);
				result.register.int16_4 = (short)(value.register.int16_4 * (short)(object)factor);
				result.register.int16_5 = (short)(value.register.int16_5 * (short)(object)factor);
				result.register.int16_6 = (short)(value.register.int16_6 * (short)(object)factor);
				result.register.int16_7 = (short)(value.register.int16_7 * (short)(object)factor);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = value.register.uint32_0 * (uint)(object)factor;
				result.register.uint32_1 = value.register.uint32_1 * (uint)(object)factor;
				result.register.uint32_2 = value.register.uint32_2 * (uint)(object)factor;
				result.register.uint32_3 = value.register.uint32_3 * (uint)(object)factor;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = value.register.int32_0 * (int)(object)factor;
				result.register.int32_1 = value.register.int32_1 * (int)(object)factor;
				result.register.int32_2 = value.register.int32_2 * (int)(object)factor;
				result.register.int32_3 = value.register.int32_3 * (int)(object)factor;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = value.register.uint64_0 * (ulong)(object)factor;
				result.register.uint64_1 = value.register.uint64_1 * (ulong)(object)factor;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = value.register.int64_0 * (long)(object)factor;
				result.register.int64_1 = value.register.int64_1 * (long)(object)factor;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = value.register.single_0 * (float)(object)factor;
				result.register.single_1 = value.register.single_1 * (float)(object)factor;
				result.register.single_2 = value.register.single_2 * (float)(object)factor;
				result.register.single_3 = value.register.single_3 * (float)(object)factor;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = value.register.double_0 * (double)(object)factor;
				result.register.double_1 = value.register.double_1 * (double)(object)factor;
			}
			return result;
		}

		public static Vector<T>operator *(T factor, Vector<T> value)
		{
			if (Vector.IsHardwareAccelerated)
			{
				return new Vector<T>(factor) * value;
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(value.register.byte_0 * (byte)(object)factor);
				result.register.byte_1 = (byte)(value.register.byte_1 * (byte)(object)factor);
				result.register.byte_2 = (byte)(value.register.byte_2 * (byte)(object)factor);
				result.register.byte_3 = (byte)(value.register.byte_3 * (byte)(object)factor);
				result.register.byte_4 = (byte)(value.register.byte_4 * (byte)(object)factor);
				result.register.byte_5 = (byte)(value.register.byte_5 * (byte)(object)factor);
				result.register.byte_6 = (byte)(value.register.byte_6 * (byte)(object)factor);
				result.register.byte_7 = (byte)(value.register.byte_7 * (byte)(object)factor);
				result.register.byte_8 = (byte)(value.register.byte_8 * (byte)(object)factor);
				result.register.byte_9 = (byte)(value.register.byte_9 * (byte)(object)factor);
				result.register.byte_10 = (byte)(value.register.byte_10 * (byte)(object)factor);
				result.register.byte_11 = (byte)(value.register.byte_11 * (byte)(object)factor);
				result.register.byte_12 = (byte)(value.register.byte_12 * (byte)(object)factor);
				result.register.byte_13 = (byte)(value.register.byte_13 * (byte)(object)factor);
				result.register.byte_14 = (byte)(value.register.byte_14 * (byte)(object)factor);
				result.register.byte_15 = (byte)(value.register.byte_15 * (byte)(object)factor);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(value.register.sbyte_0 * (sbyte)(object)factor);
				result.register.sbyte_1 = (sbyte)(value.register.sbyte_1 * (sbyte)(object)factor);
				result.register.sbyte_2 = (sbyte)(value.register.sbyte_2 * (sbyte)(object)factor);
				result.register.sbyte_3 = (sbyte)(value.register.sbyte_3 * (sbyte)(object)factor);
				result.register.sbyte_4 = (sbyte)(value.register.sbyte_4 * (sbyte)(object)factor);
				result.register.sbyte_5 = (sbyte)(value.register.sbyte_5 * (sbyte)(object)factor);
				result.register.sbyte_6 = (sbyte)(value.register.sbyte_6 * (sbyte)(object)factor);
				result.register.sbyte_7 = (sbyte)(value.register.sbyte_7 * (sbyte)(object)factor);
				result.register.sbyte_8 = (sbyte)(value.register.sbyte_8 * (sbyte)(object)factor);
				result.register.sbyte_9 = (sbyte)(value.register.sbyte_9 * (sbyte)(object)factor);
				result.register.sbyte_10 = (sbyte)(value.register.sbyte_10 * (sbyte)(object)factor);
				result.register.sbyte_11 = (sbyte)(value.register.sbyte_11 * (sbyte)(object)factor);
				result.register.sbyte_12 = (sbyte)(value.register.sbyte_12 * (sbyte)(object)factor);
				result.register.sbyte_13 = (sbyte)(value.register.sbyte_13 * (sbyte)(object)factor);
				result.register.sbyte_14 = (sbyte)(value.register.sbyte_14 * (sbyte)(object)factor);
				result.register.sbyte_15 = (sbyte)(value.register.sbyte_15 * (sbyte)(object)factor);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(value.register.uint16_0 * (ushort)(object)factor);
				result.register.uint16_1 = (ushort)(value.register.uint16_1 * (ushort)(object)factor);
				result.register.uint16_2 = (ushort)(value.register.uint16_2 * (ushort)(object)factor);
				result.register.uint16_3 = (ushort)(value.register.uint16_3 * (ushort)(object)factor);
				result.register.uint16_4 = (ushort)(value.register.uint16_4 * (ushort)(object)factor);
				result.register.uint16_5 = (ushort)(value.register.uint16_5 * (ushort)(object)factor);
				result.register.uint16_6 = (ushort)(value.register.uint16_6 * (ushort)(object)factor);
				result.register.uint16_7 = (ushort)(value.register.uint16_7 * (ushort)(object)factor);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(value.register.int16_0 * (short)(object)factor);
				result.register.int16_1 = (short)(value.register.int16_1 * (short)(object)factor);
				result.register.int16_2 = (short)(value.register.int16_2 * (short)(object)factor);
				result.register.int16_3 = (short)(value.register.int16_3 * (short)(object)factor);
				result.register.int16_4 = (short)(value.register.int16_4 * (short)(object)factor);
				result.register.int16_5 = (short)(value.register.int16_5 * (short)(object)factor);
				result.register.int16_6 = (short)(value.register.int16_6 * (short)(object)factor);
				result.register.int16_7 = (short)(value.register.int16_7 * (short)(object)factor);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = value.register.uint32_0 * (uint)(object)factor;
				result.register.uint32_1 = value.register.uint32_1 * (uint)(object)factor;
				result.register.uint32_2 = value.register.uint32_2 * (uint)(object)factor;
				result.register.uint32_3 = value.register.uint32_3 * (uint)(object)factor;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = value.register.int32_0 * (int)(object)factor;
				result.register.int32_1 = value.register.int32_1 * (int)(object)factor;
				result.register.int32_2 = value.register.int32_2 * (int)(object)factor;
				result.register.int32_3 = value.register.int32_3 * (int)(object)factor;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = value.register.uint64_0 * (ulong)(object)factor;
				result.register.uint64_1 = value.register.uint64_1 * (ulong)(object)factor;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = value.register.int64_0 * (long)(object)factor;
				result.register.int64_1 = value.register.int64_1 * (long)(object)factor;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = value.register.single_0 * (float)(object)factor;
				result.register.single_1 = value.register.single_1 * (float)(object)factor;
				result.register.single_2 = value.register.single_2 * (float)(object)factor;
				result.register.single_3 = value.register.single_3 * (float)(object)factor;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = value.register.double_0 * (double)(object)factor;
				result.register.double_1 = value.register.double_1 * (double)(object)factor;
			}
			return result;
		}

		public unsafe static Vector<T>operator /(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarDivide(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarDivide(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarDivide(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarDivide(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarDivide(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarDivide(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarDivide(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarDivide(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarDivide(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarDivide(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 / right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 / right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 / right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 / right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 / right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 / right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 / right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 / right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 / right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 / right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 / right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 / right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 / right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 / right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 / right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 / right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 / right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 / right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 / right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 / right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 / right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 / right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 / right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 / right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 / right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 / right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 / right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 / right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 / right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 / right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 / right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 / right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 / right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 / right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 / right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 / right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 / right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 / right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 / right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 / right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 / right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 / right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 / right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 / right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 / right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 / right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 / right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 / right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 / right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 / right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 / right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 / right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 / right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 / right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 / right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 / right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 / right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 / right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 / right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 / right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 / right.register.single_0;
				result.register.single_1 = left.register.single_1 / right.register.single_1;
				result.register.single_2 = left.register.single_2 / right.register.single_2;
				result.register.single_3 = left.register.single_3 / right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 / right.register.double_0;
				result.register.double_1 = left.register.double_1 / right.register.double_1;
			}
			return result;
		}

		public static Vector<T>operator -(Vector<T> value)
		{
			return Zero - value;
		}

		[JitIntrinsic]
		public unsafe static Vector<T>operator &(Vector<T> left, Vector<T> right)
		{
			Vector<T> result = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				long* ptr = &result.register.int64_0;
				long* ptr2 = &left.register.int64_0;
				long* ptr3 = &right.register.int64_0;
				for (int i = 0; i < Vector<long>.Count; i++)
				{
					ptr[i] = ptr2[i] & ptr3[i];
				}
			}
			else
			{
				result.register.int64_0 = left.register.int64_0 & right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 & right.register.int64_1;
			}
			return result;
		}

		[JitIntrinsic]
		public unsafe static Vector<T>operator |(Vector<T> left, Vector<T> right)
		{
			Vector<T> result = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				long* ptr = &result.register.int64_0;
				long* ptr2 = &left.register.int64_0;
				long* ptr3 = &right.register.int64_0;
				for (int i = 0; i < Vector<long>.Count; i++)
				{
					ptr[i] = ptr2[i] | ptr3[i];
				}
			}
			else
			{
				result.register.int64_0 = left.register.int64_0 | right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 | right.register.int64_1;
			}
			return result;
		}

		[JitIntrinsic]
		public unsafe static Vector<T>operator ^(Vector<T> left, Vector<T> right)
		{
			Vector<T> result = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				long* ptr = &result.register.int64_0;
				long* ptr2 = &left.register.int64_0;
				long* ptr3 = &right.register.int64_0;
				for (int i = 0; i < Vector<long>.Count; i++)
				{
					ptr[i] = ptr2[i] ^ ptr3[i];
				}
			}
			else
			{
				result.register.int64_0 = left.register.int64_0 ^ right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 ^ right.register.int64_1;
			}
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector<T>operator ~(Vector<T> value)
		{
			return allOnes ^ value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator ==(Vector<T> left, Vector<T> right)
		{
			return left.Equals(right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator !=(Vector<T> left, Vector<T> right)
		{
			return !(left == right);
		}

		[JitIntrinsic]
		public static explicit operator Vector<byte>(Vector<T> value)
		{
			return new Vector<byte>(ref value.register);
		}

		[CLSCompliant(false)]
		[JitIntrinsic]
		public static explicit operator Vector<sbyte>(Vector<T> value)
		{
			return new Vector<sbyte>(ref value.register);
		}

		[CLSCompliant(false)]
		[JitIntrinsic]
		public static explicit operator Vector<ushort>(Vector<T> value)
		{
			return new Vector<ushort>(ref value.register);
		}

		[JitIntrinsic]
		public static explicit operator Vector<short>(Vector<T> value)
		{
			return new Vector<short>(ref value.register);
		}

		[CLSCompliant(false)]
		[JitIntrinsic]
		public static explicit operator Vector<uint>(Vector<T> value)
		{
			return new Vector<uint>(ref value.register);
		}

		[JitIntrinsic]
		public static explicit operator Vector<int>(Vector<T> value)
		{
			return new Vector<int>(ref value.register);
		}

		[CLSCompliant(false)]
		[JitIntrinsic]
		public static explicit operator Vector<ulong>(Vector<T> value)
		{
			return new Vector<ulong>(ref value.register);
		}

		[JitIntrinsic]
		public static explicit operator Vector<long>(Vector<T> value)
		{
			return new Vector<long>(ref value.register);
		}

		[JitIntrinsic]
		public static explicit operator Vector<float>(Vector<T> value)
		{
			return new Vector<float>(ref value.register);
		}

		[JitIntrinsic]
		public static explicit operator Vector<double>(Vector<T> value)
		{
			return new Vector<double>(ref value.register);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[JitIntrinsic]
		internal unsafe static Vector<T> Equals(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(ScalarEquals(left[i], right[i]) ? ConstantHelper.GetByteWithAllBitsSet() : 0);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(ScalarEquals(left[j], right[j]) ? ConstantHelper.GetSByteWithAllBitsSet() : 0);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] =

plugins/System.Runtime.CompilerServices.Unsafe.dll

Decompiled a month ago
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;

[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyFileVersion("4.0.0.0")]
[assembly: AssemblyInformationalVersion("4.0.0.0")]
[assembly: AssemblyTitle("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyDescription("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: CLSCompliant(false)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("4.0.4.1")]
namespace System.Runtime.CompilerServices
{
	public static class Unsafe : Object
	{
		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static T Read<T>(void* source)
		{
			return Unsafe.Read<T>(source);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static T ReadUnaligned<T>(void* source)
		{
			return Unsafe.ReadUnaligned<T>(source);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static T ReadUnaligned<T>(ref byte source)
		{
			return Unsafe.ReadUnaligned<T>(ref source);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void Write<T>(void* destination, T value)
		{
			Unsafe.Write(destination, value);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void WriteUnaligned<T>(void* destination, T value)
		{
			Unsafe.WriteUnaligned(destination, value);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static void WriteUnaligned<T>(ref byte destination, T value)
		{
			Unsafe.WriteUnaligned(ref destination, value);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void Copy<T>(void* destination, ref T source)
		{
			Unsafe.Write(destination, source);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void Copy<T>(ref T destination, void* source)
		{
			destination = Unsafe.Read<T>(source);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void* AsPointer<T>(ref T value)
		{
			return Unsafe.AsPointer(ref value);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static int SizeOf<T>()
		{
			return Unsafe.SizeOf<T>();
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void CopyBlock(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(destination, source, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static void CopyBlock(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(ref destination, ref source, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(destination, source, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(ref destination, ref source, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(startAddress, value, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static void InitBlock(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(ref startAddress, value, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(startAddress, value, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(ref startAddress, value, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static T As<T>(object o) where T : class
		{
			return (T)o;
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static ref T AsRef<T>(void* source)
		{
			return ref *(T*)source;
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T AsRef<T>(in T source)
		{
			return ref source;
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref TTo As<TFrom, TTo>(ref TFrom source)
		{
			return ref Unsafe.As<TFrom, TTo>(ref source);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T Add<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void* Add<T>(void* source, int elementOffset)
		{
			return (byte*)source + (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T Add<T>(ref T source, System.IntPtr elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T AddByteOffset<T>(ref T source, System.IntPtr byteOffset)
		{
			return ref Unsafe.AddByteOffset(ref source, byteOffset);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T Subtract<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void* Subtract<T>(void* source, int elementOffset)
		{
			return (byte*)source - (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T Subtract<T>(ref T source, System.IntPtr elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T SubtractByteOffset<T>(ref T source, System.IntPtr byteOffset)
		{
			return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static System.IntPtr ByteOffset<T>(ref T origin, ref T target)
		{
			return Unsafe.ByteOffset(target: ref target, origin: ref origin);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static bool AreSame<T>(ref T left, ref T right)
		{
			return Unsafe.AreSame(ref left, ref right);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static bool IsAddressGreaterThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressGreaterThan(ref left, ref right);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static bool IsAddressLessThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressLessThan(ref left, ref right);
		}
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	internal sealed class NonVersionableAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}

plugins/System.Security.AccessControl.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.AccessControl;
using System.Security.Permissions;
using FxResources.System.Security.AccessControl;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyDefaultAlias("System.Security.AccessControl")]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("System.Security.AccessControl")]
[assembly: AssemblyFileVersion("4.700.19.56404")]
[assembly: AssemblyInformationalVersion("3.1.0+0f7f38c4fd323b26da10cce95f857f77f0f09b48")]
[assembly: AssemblyProduct("Microsoft® .NET Core")]
[assembly: AssemblyTitle("System.Security.AccessControl")]
[assembly: CLSCompliant(true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.1.3.0")]
[assembly: TypeForwardedTo(typeof(AccessControlActions))]
[assembly: TypeForwardedTo(typeof(AccessControlModification))]
[assembly: TypeForwardedTo(typeof(AccessControlSections))]
[assembly: TypeForwardedTo(typeof(AccessControlType))]
[assembly: TypeForwardedTo(typeof(AccessRule))]
[assembly: TypeForwardedTo(typeof(AccessRule<>))]
[assembly: TypeForwardedTo(typeof(AceEnumerator))]
[assembly: TypeForwardedTo(typeof(AceFlags))]
[assembly: TypeForwardedTo(typeof(AceQualifier))]
[assembly: TypeForwardedTo(typeof(AceType))]
[assembly: TypeForwardedTo(typeof(AuditFlags))]
[assembly: TypeForwardedTo(typeof(AuditRule))]
[assembly: TypeForwardedTo(typeof(AuditRule<>))]
[assembly: TypeForwardedTo(typeof(AuthorizationRule))]
[assembly: TypeForwardedTo(typeof(AuthorizationRuleCollection))]
[assembly: TypeForwardedTo(typeof(CommonAce))]
[assembly: TypeForwardedTo(typeof(CommonAcl))]
[assembly: TypeForwardedTo(typeof(CommonObjectSecurity))]
[assembly: TypeForwardedTo(typeof(CommonSecurityDescriptor))]
[assembly: TypeForwardedTo(typeof(CompoundAce))]
[assembly: TypeForwardedTo(typeof(CompoundAceType))]
[assembly: TypeForwardedTo(typeof(ControlFlags))]
[assembly: TypeForwardedTo(typeof(CustomAce))]
[assembly: TypeForwardedTo(typeof(DiscretionaryAcl))]
[assembly: TypeForwardedTo(typeof(GenericAce))]
[assembly: TypeForwardedTo(typeof(GenericAcl))]
[assembly: TypeForwardedTo(typeof(GenericSecurityDescriptor))]
[assembly: TypeForwardedTo(typeof(InheritanceFlags))]
[assembly: TypeForwardedTo(typeof(KnownAce))]
[assembly: TypeForwardedTo(typeof(NativeObjectSecurity))]
[assembly: TypeForwardedTo(typeof(ObjectAccessRule))]
[assembly: TypeForwardedTo(typeof(ObjectAce))]
[assembly: TypeForwardedTo(typeof(ObjectAceFlags))]
[assembly: TypeForwardedTo(typeof(ObjectAuditRule))]
[assembly: TypeForwardedTo(typeof(ObjectSecurity))]
[assembly: TypeForwardedTo(typeof(ObjectSecurity<>))]
[assembly: TypeForwardedTo(typeof(PrivilegeNotHeldException))]
[assembly: TypeForwardedTo(typeof(PropagationFlags))]
[assembly: TypeForwardedTo(typeof(QualifiedAce))]
[assembly: TypeForwardedTo(typeof(RawAcl))]
[assembly: TypeForwardedTo(typeof(RawSecurityDescriptor))]
[assembly: TypeForwardedTo(typeof(ResourceType))]
[assembly: TypeForwardedTo(typeof(SecurityInfos))]
[assembly: TypeForwardedTo(typeof(SystemAcl))]
[module: UnverifiableCode]
namespace FxResources.System.Security.AccessControl
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(FxResources.System.Security.AccessControl.SR)));

		internal static string AccessControl_AclTooLong => GetResourceString("AccessControl_AclTooLong");

		internal static string AccessControl_InvalidAccessRuleType => GetResourceString("AccessControl_InvalidAccessRuleType");

		internal static string AccessControl_InvalidAuditRuleType => GetResourceString("AccessControl_InvalidAuditRuleType");

		internal static string AccessControl_InvalidOwner => GetResourceString("AccessControl_InvalidOwner");

		internal static string AccessControl_InvalidGroup => GetResourceString("AccessControl_InvalidGroup");

		internal static string AccessControl_InvalidHandle => GetResourceString("AccessControl_InvalidHandle");

		internal static string AccessControl_InvalidSecurityDescriptorRevision => GetResourceString("AccessControl_InvalidSecurityDescriptorRevision");

		internal static string AccessControl_InvalidSecurityDescriptorSelfRelativeForm => GetResourceString("AccessControl_InvalidSecurityDescriptorSelfRelativeForm");

		internal static string AccessControl_InvalidSidInSDDLString => GetResourceString("AccessControl_InvalidSidInSDDLString");

		internal static string AccessControl_MustSpecifyContainerAcl => GetResourceString("AccessControl_MustSpecifyContainerAcl");

		internal static string AccessControl_MustSpecifyDirectoryObjectAcl => GetResourceString("AccessControl_MustSpecifyDirectoryObjectAcl");

		internal static string AccessControl_MustSpecifyLeafObjectAcl => GetResourceString("AccessControl_MustSpecifyLeafObjectAcl");

		internal static string AccessControl_MustSpecifyNonDirectoryObjectAcl => GetResourceString("AccessControl_MustSpecifyNonDirectoryObjectAcl");

		internal static string AccessControl_NoAssociatedSecurity => GetResourceString("AccessControl_NoAssociatedSecurity");

		internal static string AccessControl_UnexpectedError => GetResourceString("AccessControl_UnexpectedError");

		internal static string Arg_EnumAtLeastOneFlag => GetResourceString("Arg_EnumAtLeastOneFlag");

		internal static string Arg_EnumIllegalVal => GetResourceString("Arg_EnumIllegalVal");

		internal static string Arg_InvalidOperationException => GetResourceString("Arg_InvalidOperationException");

		internal static string Arg_MustBeIdentityReferenceType => GetResourceString("Arg_MustBeIdentityReferenceType");

		internal static string Argument_ArgumentZero => GetResourceString("Argument_ArgumentZero");

		internal static string Argument_InvalidAnyFlag => GetResourceString("Argument_InvalidAnyFlag");

		internal static string Argument_InvalidEnumValue => GetResourceString("Argument_InvalidEnumValue");

		internal static string Argument_InvalidName => GetResourceString("Argument_InvalidName");

		internal static string Argument_InvalidPrivilegeName => GetResourceString("Argument_InvalidPrivilegeName");

		internal static string Argument_InvalidSafeHandle => GetResourceString("Argument_InvalidSafeHandle");

		internal static string ArgumentException_InvalidAceBinaryForm => GetResourceString("ArgumentException_InvalidAceBinaryForm");

		internal static string ArgumentException_InvalidAclBinaryForm => GetResourceString("ArgumentException_InvalidAclBinaryForm");

		internal static string ArgumentException_InvalidSDSddlForm => GetResourceString("ArgumentException_InvalidSDSddlForm");

		internal static string ArgumentOutOfRange_ArrayLength => GetResourceString("ArgumentOutOfRange_ArrayLength");

		internal static string ArgumentOutOfRange_ArrayLengthMultiple => GetResourceString("ArgumentOutOfRange_ArrayLengthMultiple");

		internal static string ArgumentOutOfRange_ArrayTooSmall => GetResourceString("ArgumentOutOfRange_ArrayTooSmall");

		internal static string ArgumentOutOfRange_Enum => GetResourceString("ArgumentOutOfRange_Enum");

		internal static string ArgumentOutOfRange_InvalidUserDefinedAceType => GetResourceString("ArgumentOutOfRange_InvalidUserDefinedAceType");

		internal static string ArgumentOutOfRange_NeedNonNegNum => GetResourceString("ArgumentOutOfRange_NeedNonNegNum");

		internal static string InvalidOperation_ModificationOfNonCanonicalAcl => GetResourceString("InvalidOperation_ModificationOfNonCanonicalAcl");

		internal static string InvalidOperation_MustBeSameThread => GetResourceString("InvalidOperation_MustBeSameThread");

		internal static string InvalidOperation_MustLockForReadOrWrite => GetResourceString("InvalidOperation_MustLockForReadOrWrite");

		internal static string InvalidOperation_MustLockForWrite => GetResourceString("InvalidOperation_MustLockForWrite");

		internal static string InvalidOperation_MustRevertPrivilege => GetResourceString("InvalidOperation_MustRevertPrivilege");

		internal static string InvalidOperation_NoSecurityDescriptor => GetResourceString("InvalidOperation_NoSecurityDescriptor");

		internal static string InvalidOperation_OnlyValidForDS => GetResourceString("InvalidOperation_OnlyValidForDS");

		internal static string InvalidOperation_DisconnectedPipe => GetResourceString("InvalidOperation_DisconnectedPipe");

		internal static string NotSupported_SetMethod => GetResourceString("NotSupported_SetMethod");

		internal static string PrivilegeNotHeld_Default => GetResourceString("PrivilegeNotHeld_Default");

		internal static string PrivilegeNotHeld_Named => GetResourceString("PrivilegeNotHeld_Named");

		internal static string Rank_MultiDimNotSupported => GetResourceString("Rank_MultiDimNotSupported");

		internal static string PlatformNotSupported_AccessControl => GetResourceString("PlatformNotSupported_AccessControl");

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString = null)
		{
			if (UsingResourceKeys())
			{
				return defaultString ?? resourceKey;
			}
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text))
			{
				return defaultString;
			}
			return text;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(provider, resourceFormat, p1);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(provider, resourceFormat, p1, p2);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(provider, resourceFormat, p1, p2, p3);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
}

plugins/System.Security.Principal.Windows.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using Microsoft.Win32.SafeHandles;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyDefaultAlias("System.Security.Principal.Windows")]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("System.Security.Principal.Windows")]
[assembly: AssemblyFileVersion("4.700.19.56404")]
[assembly: AssemblyInformationalVersion("3.1.0+0f7f38c4fd323b26da10cce95f857f77f0f09b48")]
[assembly: AssemblyProduct("Microsoft® .NET Core")]
[assembly: AssemblyTitle("System.Security.Principal.Windows")]
[assembly: CLSCompliant(true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.1.3.0")]
[assembly: TypeForwardedTo(typeof(SafeAccessTokenHandle))]
[assembly: TypeForwardedTo(typeof(IdentityNotMappedException))]
[assembly: TypeForwardedTo(typeof(IdentityReference))]
[assembly: TypeForwardedTo(typeof(IdentityReferenceCollection))]
[assembly: TypeForwardedTo(typeof(NTAccount))]
[assembly: TypeForwardedTo(typeof(SecurityIdentifier))]
[assembly: TypeForwardedTo(typeof(TokenAccessLevels))]
[assembly: TypeForwardedTo(typeof(WellKnownSidType))]
[assembly: TypeForwardedTo(typeof(WindowsAccountType))]
[assembly: TypeForwardedTo(typeof(WindowsBuiltInRole))]
[assembly: TypeForwardedTo(typeof(WindowsIdentity))]
[assembly: TypeForwardedTo(typeof(WindowsPrincipal))]
[module: UnverifiableCode]

plugins/System.ValueTuple.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using FxResources.System.ValueTuple;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.ValueTuple")]
[assembly: AssemblyDescription("System.ValueTuple")]
[assembly: AssemblyDefaultAlias("System.ValueTuple")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.26515.06")]
[assembly: AssemblyInformationalVersion("4.6.26515.06 @BuiltBy: dlab-DDVSOWINAGE059 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/corefx/tree/30ab651fcb4354552bd4891619a0bdd81e0ebdbf")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyVersion("4.0.3.0")]
[assembly: TypeForwardedTo(typeof(TupleElementNamesAttribute))]
[assembly: TypeForwardedTo(typeof(TupleExtensions))]
[assembly: TypeForwardedTo(typeof(ValueTuple))]
[assembly: TypeForwardedTo(typeof(ValueTuple<>))]
[assembly: TypeForwardedTo(typeof(ValueTuple<, >))]
[assembly: TypeForwardedTo(typeof(ValueTuple<, , >))]
[assembly: TypeForwardedTo(typeof(ValueTuple<, , , >))]
[assembly: TypeForwardedTo(typeof(ValueTuple<, , , , >))]
[assembly: TypeForwardedTo(typeof(ValueTuple<, , , , , >))]
[assembly: TypeForwardedTo(typeof(ValueTuple<, , , , , , >))]
[assembly: TypeForwardedTo(typeof(ValueTuple<, , , , , , , >))]
namespace FxResources.System.ValueTuple
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));

		internal static Type ResourceType { get; } = typeof(SR);


		internal static string ArgumentException_ValueTupleIncorrectType => GetResourceString("ArgumentException_ValueTupleIncorrectType", null);

		internal static string ArgumentException_ValueTupleLastArgumentNotAValueTuple => GetResourceString("ArgumentException_ValueTupleLastArgumentNotAValueTuple", null);

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal))
			{
				return defaultString;
			}
			return text;
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}
	}
}