Decompiled source of ProximityVoice v0.1.0

Concentus.dll

Decompiled 16 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Numerics;
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 Concentus.Celt;
using Concentus.Celt.Structs;
using Concentus.Common;
using Concentus.Common.CPlusPlus;
using Concentus.Enums;
using Concentus.Native;
using Concentus.Silk;
using Concentus.Silk.Enums;
using Concentus.Silk.Structs;
using Concentus.Structs;
using Microsoft.CodeAnalysis;
using Microsoft.Win32.SafeHandles;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("ParityTest, PublicKey=002400000480000094000000060200000024000052534131000400000100010071a2f675c04c87e64b9be6d37f5833c5285fb4ed883780cf6d61e80aee5d77950b2f06dd45bc634f53405f2a2b7b2332f4dfdcb0554ffc97b935e7343e76e733eea44346e56ac1098c12a66de71e324f2f503f9f2e32560910e2082d6943df50db42679a330e52979bd1eefbb59485d2c7420d158f6ab6d41bdf42d2172675e1")]
[assembly: InternalsVisibleTo("TestOpusEncode, PublicKey=002400000480000094000000060200000024000052534131000400000100010071a2f675c04c87e64b9be6d37f5833c5285fb4ed883780cf6d61e80aee5d77950b2f06dd45bc634f53405f2a2b7b2332f4dfdcb0554ffc97b935e7343e76e733eea44346e56ac1098c12a66de71e324f2f503f9f2e32560910e2082d6943df50db42679a330e52979bd1eefbb59485d2c7420d158f6ab6d41bdf42d2172675e1")]
[assembly: TargetFramework(".NETFramework,Version=v4.5.2", FrameworkDisplayName = ".NET Framework 4.5.2")]
[assembly: AssemblyCompany("Logan Stromberg")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Xiph.Org Foundation, Skype Limited, CSIRO, Microsoft Corp.")]
[assembly: AssemblyDescription("This package is a portable C# implementation of the Opus audio compression codec (see https://opus-codec.org/ for more details). This package contains the Opus encoder, decoder, multistream codecs, repacketizer, as well as a port of the libspeexdsp resampler. It does NOT contain code to parse .ogg or .opus container files or to manage RTP packet streams. For better performance depending on your platform, see also the Concentus.Native package.")]
[assembly: AssemblyFileVersion("2.2.2.0")]
[assembly: AssemblyInformationalVersion("2.2.2+6c2328dc19044601e33a9c11628b8d60e1f3011c")]
[assembly: AssemblyProduct("Concentus")]
[assembly: AssemblyTitle("Concentus")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/lostromb/concentus")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.2.2.0")]
[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
	{
	}
}
namespace Concentus
{
	public interface IOpusDecoder : IDisposable
	{
		OpusBandwidth Bandwidth { get; }

		uint FinalRange { get; }

		int Gain { get; set; }

		int LastPacketDuration { get; }

		int NumChannels { get; }

		int Pitch { get; }

		int SampleRate { get; }

		int Decode(ReadOnlySpan<byte> in_data, Span<float> out_pcm, int frame_size, bool decode_fec = false);

		int Decode(ReadOnlySpan<byte> in_data, Span<short> out_pcm, int frame_size, bool decode_fec = false);

		void ResetState();

		string GetVersionString();
	}
	public interface IOpusEncoder : IDisposable
	{
		OpusApplication Application { get; set; }

		int Bitrate { get; set; }

		int ForceChannels { get; set; }

		OpusBandwidth MaxBandwidth { get; set; }

		OpusBandwidth Bandwidth { get; set; }

		bool UseDTX { get; set; }

		int Complexity { get; set; }

		bool UseInbandFEC { get; set; }

		int PacketLossPercent { get; set; }

		bool UseVBR { get; set; }

		bool UseConstrainedVBR { get; set; }

		OpusSignal SignalType { get; set; }

		int Lookahead { get; }

		int SampleRate { get; }

		int NumChannels { get; }

		uint FinalRange { get; }

		int LSBDepth { get; set; }

		OpusFramesize ExpertFrameDuration { get; set; }

		OpusMode ForceMode { set; }

		bool PredictionDisabled { get; set; }

		int Encode(ReadOnlySpan<short> in_pcm, int frame_size, Span<byte> out_data, int max_data_bytes);

		int Encode(ReadOnlySpan<float> in_pcm, int frame_size, Span<byte> out_data, int max_data_bytes);

		void ResetState();

		string GetVersionString();
	}
	public interface IOpusMultiStreamDecoder : IDisposable
	{
		OpusBandwidth Bandwidth { get; }

		uint FinalRange { get; }

		int Gain { get; set; }

		int LastPacketDuration { get; }

		int SampleRate { get; }

		int NumChannels { get; }

		int DecodeMultistream(ReadOnlySpan<byte> data, Span<float> out_pcm, int frame_size, bool decode_fec);

		int DecodeMultistream(ReadOnlySpan<byte> data, Span<short> out_pcm, int frame_size, bool decode_fec);

		void ResetState();

		string GetVersionString();
	}
	public interface IOpusMultiStreamEncoder : IDisposable
	{
		OpusApplication Application { get; set; }

		OpusBandwidth Bandwidth { get; set; }

		int Bitrate { get; set; }

		int Complexity { get; set; }

		int NumChannels { get; }

		OpusFramesize ExpertFrameDuration { get; set; }

		uint FinalRange { get; }

		OpusMode ForceMode { set; }

		int Lookahead { get; }

		int LSBDepth { get; set; }

		OpusBandwidth MaxBandwidth { get; set; }

		int PacketLossPercent { get; set; }

		bool PredictionDisabled { get; set; }

		int SampleRate { get; }

		OpusSignal SignalType { get; set; }

		bool UseConstrainedVBR { get; set; }

		bool UseDTX { get; set; }

		bool UseInbandFEC { get; set; }

		bool UseVBR { get; set; }

		int EncodeMultistream(ReadOnlySpan<float> in_pcm, int frame_size, Span<byte> out_data, int max_data_bytes);

		int EncodeMultistream(ReadOnlySpan<short> in_pcm, int frame_size, Span<byte> out_data, int max_data_bytes);

		void ResetState();

		string GetVersionString();
	}
	public interface IResampler : IDisposable
	{
		int InputLatency { get; }

		int InputStride { get; set; }

		int OutputLatencySamples { get; }

		TimeSpan OutputLatency { get; }

		int OutputStride { get; set; }

		int Quality { get; set; }

		void GetRateFraction(out int ratio_num, out int ratio_den);

		void GetRates(out int in_rate, out int out_rate);

		void ResetMem();

		void SkipZeroes();

		void Process(int channel_index, Span<float> input, ref int in_len, Span<float> output, ref int out_len);

		void Process(int channel_index, Span<short> input, ref int in_len, Span<short> output, ref int out_len);

		void ProcessInterleaved(Span<float> input, ref int in_len, Span<float> output, ref int out_len);

		void ProcessInterleaved(Span<short> input, ref int in_len, Span<short> output, ref int out_len);

		void SetRateFraction(int ratio_num, int ratio_den, int in_rate, int out_rate);

		void SetRates(int in_rate, int out_rate);
	}
	public static class OpusCodecFactory
	{
		private static readonly object _mutex = new object();

		private static bool _nativeLibInitialized = false;

		private static bool _isNativeLibAvailable = false;

		private static bool _userAllowNativeLib = true;

		public static bool AttemptToUseNativeLibrary
		{
			get
			{
				return _userAllowNativeLib;
			}
			set
			{
				_userAllowNativeLib = value;
			}
		}

		public static IOpusEncoder CreateEncoder(int sampleRate, int numChannels, OpusApplication application = OpusApplication.OPUS_APPLICATION_AUDIO, TextWriter messageLogger = null)
		{
			if (_userAllowNativeLib && NativeLibraryAvailable(messageLogger))
			{
				return NativeOpusEncoder.Create(sampleRate, numChannels, application);
			}
			return new OpusEncoder(sampleRate, numChannels, application);
		}

		public static IOpusDecoder CreateDecoder(int sampleRate, int numChannels, TextWriter messageLogger = null)
		{
			if (_userAllowNativeLib && NativeLibraryAvailable(messageLogger))
			{
				return NativeOpusDecoder.Create(sampleRate, numChannels);
			}
			return new OpusDecoder(sampleRate, numChannels);
		}

		public static IOpusMultiStreamEncoder CreateMultiStreamEncoder(int sampleRate, int numChannels, int mappingFamily, out int streams, out int coupledStreams, byte[] mapping, OpusApplication application, TextWriter messageLogger = null)
		{
			if (_userAllowNativeLib && NativeLibraryAvailable(messageLogger))
			{
				return NativeOpusMultistreamEncoder.Create(sampleRate, numChannels, mappingFamily, out streams, out coupledStreams, mapping, application);
			}
			return OpusMSEncoder.CreateSurround(sampleRate, numChannels, mappingFamily, out streams, out coupledStreams, mapping, application);
		}

		public static IOpusMultiStreamDecoder CreateMultiStreamDecoder(int sampleRate, int numChannels, int streams, int coupledStreams, byte[] mapping, TextWriter messageLogger = null)
		{
			if (_userAllowNativeLib && NativeLibraryAvailable(messageLogger))
			{
				return NativeOpusMultistreamDecoder.Create(sampleRate, numChannels, streams, coupledStreams, mapping);
			}
			return new OpusMSDecoder(sampleRate, numChannels, streams, coupledStreams, mapping);
		}

		private static bool NativeLibraryAvailable(TextWriter messageLogger)
		{
			lock (_mutex)
			{
				if (!_nativeLibInitialized)
				{
					try
					{
						_isNativeLibAvailable = NativeOpus.Initialize(messageLogger);
						messageLogger?.WriteLine($"Is native opus available? {_isNativeLibAvailable}");
					}
					catch (Exception ex)
					{
						messageLogger?.WriteLine(ex.ToString());
					}
					_nativeLibInitialized = true;
				}
				return _isNativeLibAvailable;
			}
		}
	}
	internal static class Analysis
	{
		private const double M_PI = 3.141592653;

		private const float cA = 0.43157974f;

		private const float cB = 0.678484f;

		private const float cC = 0.08595542f;

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

		private const int NB_TONAL_SKIP_BANDS = 9;

		internal static float fast_atan2f(float y, float x)
		{
			if (Inlines.ABS16(x) + Inlines.ABS16(y) < 1E-09f)
			{
				x *= 1E+12f;
				y *= 1E+12f;
			}
			float num = x * x;
			float num2 = y * y;
			if (num < num2)
			{
				float num3 = (num2 + 0.678484f * num) * (num2 + 0.08595542f * num);
				if (num3 != 0f)
				{
					return (0f - x) * y * (num2 + 0.43157974f * num) / num3 + ((y < 0f) ? (-(float)Math.PI / 2f) : ((float)Math.PI / 2f));
				}
				if (!(y < 0f))
				{
					return (float)Math.PI / 2f;
				}
				return -(float)Math.PI / 2f;
			}
			float num4 = (num + 0.678484f * num2) * (num + 0.08595542f * num2);
			if (num4 != 0f)
			{
				return x * y * (num + 0.43157974f * num2) / num4 + ((y < 0f) ? (-(float)Math.PI / 2f) : ((float)Math.PI / 2f)) - ((x * y < 0f) ? (-(float)Math.PI / 2f) : ((float)Math.PI / 2f));
			}
			return ((y < 0f) ? (-(float)Math.PI / 2f) : ((float)Math.PI / 2f)) - ((x * y < 0f) ? (-(float)Math.PI / 2f) : ((float)Math.PI / 2f));
		}

		internal static void tonality_analysis_init(TonalityAnalysisState tonal)
		{
			tonal.Reset();
		}

		internal static void tonality_get_info(TonalityAnalysisState tonal, AnalysisInfo info_out, int len)
		{
			int num = tonal.read_pos;
			int num2 = tonal.write_pos - tonal.read_pos;
			if (num2 < 0)
			{
				num2 += 200;
			}
			if (len > 480 && num != tonal.write_pos)
			{
				num++;
				if (num == 200)
				{
					num = 0;
				}
			}
			if (num == tonal.write_pos)
			{
				num--;
			}
			if (num < 0)
			{
				num = 199;
			}
			info_out.Assign(tonal.info[num]);
			tonal.read_subframe += len / 120;
			while (tonal.read_subframe >= 4)
			{
				tonal.read_subframe -= 4;
				tonal.read_pos++;
			}
			if (tonal.read_pos >= 200)
			{
				tonal.read_pos -= 200;
			}
			num2 = Inlines.IMAX(num2 - 10, 0);
			float num3 = 0f;
			int i;
			for (i = 0; i < 200 - num2; i++)
			{
				num3 += tonal.pmusic[i];
			}
			for (; i < 200; i++)
			{
				num3 += tonal.pspeech[i];
			}
			num3 = num3 * tonal.music_confidence + (1f - num3) * tonal.speech_confidence;
			info_out.music_prob = num3;
		}

		internal static void tonality_analysis<T>(TonalityAnalysisState tonal, CeltMode celt_mode, ReadOnlySpan<T> x, int len, int offset, int c1, int c2, int C, int lsb_depth, Downmix.downmix_func<T> downmix)
		{
			int num = 480;
			int num2 = 240;
			float[] angle = tonal.angle;
			float[] d_angle = tonal.d_angle;
			float[] d2_angle = tonal.d2_angle;
			float[] array = new float[18];
			float[] array2 = new float[18];
			float[] array3 = new float[8];
			float[] array4 = new float[25];
			float num3 = 97.40909f;
			float num4 = 0f;
			float[] array5 = new float[2];
			int num5 = 0;
			float num6 = 0f;
			tonal.last_transition++;
			float num7 = 1f / (float)Inlines.IMIN(20, 1 + tonal.count);
			float num8 = 1f / (float)Inlines.IMIN(50, 1 + tonal.count);
			float num9 = 1f / (float)Inlines.IMIN(1000, 1 + tonal.count);
			if (tonal.count < 4)
			{
				tonal.music_prob = 0.5f;
			}
			FFTState st = celt_mode.mdct.kfft[0];
			if (tonal.count == 0)
			{
				tonal.mem_fill = 240;
			}
			downmix(x, tonal.inmem, tonal.mem_fill, Inlines.IMIN(len, 720 - tonal.mem_fill), offset, c1, c2, C);
			if (tonal.mem_fill + len < 720)
			{
				tonal.mem_fill += len;
				return;
			}
			AnalysisInfo analysisInfo = tonal.info[tonal.write_pos++];
			if (tonal.write_pos >= 200)
			{
				tonal.write_pos -= 200;
			}
			int[] array6 = new int[960];
			int[] array7 = new int[960];
			float[] array8 = new float[240];
			float[] array9 = new float[240];
			for (int i = 0; i < num2; i++)
			{
				float num10 = Tables.analysis_window[i];
				array6[2 * i] = (int)(num10 * (float)tonal.inmem[i]);
				array6[2 * i + 1] = (int)(num10 * (float)tonal.inmem[num2 + i]);
				array6[2 * (num - i - 1)] = (int)(num10 * (float)tonal.inmem[num - i - 1]);
				array6[2 * (num - i - 1) + 1] = (int)(num10 * (float)tonal.inmem[num + num2 - i - 1]);
			}
			Arrays.MemMoveInt(tonal.inmem, 480, 0, 240);
			int num11 = len - (720 - tonal.mem_fill);
			downmix(x, tonal.inmem, 240, num11, offset + 720 - tonal.mem_fill, c1, c2, C);
			tonal.mem_fill = 240 + num11;
			KissFFT.opus_fft(st, array6, array7);
			for (int i = 1; i < num2; i++)
			{
				float x2 = (float)array7[2 * i] + (float)array7[2 * (num - i)];
				float y = (float)array7[2 * i + 1] - (float)array7[2 * (num - i) + 1];
				float x3 = (float)array7[2 * i + 1] + (float)array7[2 * (num - i) + 1];
				float y2 = (float)array7[2 * (num - i)] - (float)array7[2 * i];
				float num12 = 1f / (2f * (float)Math.PI) * fast_atan2f(y, x2);
				float num13 = num12 - angle[i];
				float num14 = num13 - d_angle[i];
				float num15 = 1f / (2f * (float)Math.PI) * fast_atan2f(y2, x3);
				float num16 = num15 - num12;
				float num17 = num16 - num13;
				float num18 = num14 - (float)Math.Floor(0.5f + num14);
				array9[i] = Inlines.ABS16(num18);
				num18 *= num18;
				num18 *= num18;
				float num19 = num17 - (float)Math.Floor(0.5f + num17);
				array9[i] += Inlines.ABS16(num19);
				num19 *= num19;
				num19 *= num19;
				float num20 = 0.25f * (d2_angle[i] + 2f * num18 + num19);
				array8[i] = 1f / (1f + 640f * num3 * num20) - 0.015f;
				angle[i] = num15;
				d_angle[i] = num16;
				d2_angle[i] = num19;
			}
			float num21 = 0f;
			float num22 = 0f;
			analysisInfo.activity = 0f;
			float num23 = 0f;
			float num24 = 0f;
			if (tonal.count == 0)
			{
				for (int j = 0; j < 18; j++)
				{
					tonal.lowE[j] = 1E+10f;
					tonal.highE[j] = -1E+10f;
				}
			}
			float num25 = 0f;
			float num26 = 0f;
			for (int j = 0; j < 18; j++)
			{
				float num27 = 0f;
				float num28 = 0f;
				float num29 = 0f;
				for (int i = Tables.tbands[j]; i < Tables.tbands[j + 1]; i++)
				{
					float num30 = (float)array7[2 * i] * (float)array7[2 * i] + (float)array7[2 * (num - i)] * (float)array7[2 * (num - i)] + (float)array7[2 * i + 1] * (float)array7[2 * i + 1] + (float)array7[2 * (num - i) + 1] * (float)array7[2 * (num - i) + 1];
					num30 *= 5.55E-17f;
					num27 += num30;
					num28 += num30 * array8[i];
					num29 += num30 * 2f * (0.5f - array9[i]);
				}
				tonal.E[tonal.E_count][j] = num27;
				num23 += num29 / (1E-15f + num27);
				num26 += (float)Math.Sqrt(num27 + 1E-10f);
				array2[j] = (float)Math.Log(num27 + 1E-10f);
				tonal.lowE[j] = Inlines.MIN32(array2[j], tonal.lowE[j] + 0.01f);
				tonal.highE[j] = Inlines.MAX32(array2[j], tonal.highE[j] - 0.1f);
				if (tonal.highE[j] < tonal.lowE[j] + 1f)
				{
					tonal.highE[j] += 0.5f;
					tonal.lowE[j] -= 0.5f;
				}
				num25 += (array2[j] - tonal.lowE[j]) / (1E-15f + tonal.highE[j] - tonal.lowE[j]);
				float num31;
				float num32 = (num31 = 0f);
				for (int i = 0; i < 8; i++)
				{
					num32 += (float)Math.Sqrt(tonal.E[i][j]);
					num31 += tonal.E[i][j];
				}
				float num33 = Inlines.MIN16(0.99f, num32 / (float)Math.Sqrt(1E-15 + (double)(8f * num31)));
				num33 *= num33;
				num33 *= num33;
				num24 += num33;
				array[j] = Inlines.MAX16(num28 / (1E-15f + num27), num33 * tonal.prev_band_tonality[j]);
				num21 += array[j];
				if (j >= 9)
				{
					num21 -= array[j - 18 + 9];
				}
				num22 = Inlines.MAX16(num22, (1f + 0.03f * (float)(j - 18)) * num21);
				num4 += array[j] * (float)(j - 8);
				tonal.prev_band_tonality[j] = array[j];
			}
			float num34 = 0f;
			num5 = 0;
			num6 = 0f;
			float num35 = 0.00057f / (float)(1 << Inlines.IMAX(0, lsb_depth - 8));
			num35 *= 134217730f;
			num35 *= num35;
			for (int j = 0; j < 21; j++)
			{
				float num36 = 0f;
				int num37 = Tables.extra_bands[j];
				int num38 = Tables.extra_bands[j + 1];
				for (int i = num37; i < num38; i++)
				{
					float num39 = (float)array7[2 * i] * (float)array7[2 * i] + (float)array7[2 * (num - i)] * (float)array7[2 * (num - i)] + (float)array7[2 * i + 1] * (float)array7[2 * i + 1] + (float)array7[2 * (num - i) + 1] * (float)array7[2 * (num - i) + 1];
					num36 += num39;
				}
				num6 = Inlines.MAX32(num6, num36);
				tonal.meanE[j] = Inlines.MAX32((1f - num9) * tonal.meanE[j], num36);
				num36 = Inlines.MAX32(num36, tonal.meanE[j]);
				num34 = Inlines.MAX32(0.05f * num34, num36);
				if ((double)num36 > 0.1 * (double)num34 && num36 * 1E+09f > num6 && num36 > num35 * (float)(num38 - num37))
				{
					num5 = j;
				}
			}
			if (tonal.count <= 2)
			{
				num5 = 20;
			}
			num26 = 20f * (float)Math.Log10(num26);
			tonal.Etracker = Inlines.MAX32(tonal.Etracker - 0.03f, num26);
			tonal.lowECount *= 1f - num8;
			if (num26 < tonal.Etracker - 30f)
			{
				tonal.lowECount += num8;
			}
			for (int i = 0; i < 8; i++)
			{
				float num40 = 0f;
				for (int j = 0; j < 16; j++)
				{
					num40 += Tables.dct_table[i * 16 + j] * array2[j];
				}
				array3[i] = num40;
			}
			num24 /= 18f;
			num25 /= 18f;
			if (tonal.count < 10)
			{
				num25 = 0.5f;
			}
			num23 /= 18f;
			analysisInfo.activity = num23 + (1f - num23) * num25;
			num21 = num22 / 9f;
			num21 = (tonal.prev_tonality = Inlines.MAX16(num21, tonal.prev_tonality * 0.8f));
			num4 /= 64f;
			analysisInfo.tonality_slope = num4;
			tonal.E_count = (tonal.E_count + 1) % 8;
			tonal.count++;
			analysisInfo.tonality = num21;
			for (int i = 0; i < 4; i++)
			{
				array4[i] = -0.12299f * (array3[i] + tonal.mem[i + 24]) + 0.49195f * (tonal.mem[i] + tonal.mem[i + 16]) + 0.69693f * tonal.mem[i + 8] - 1.4349f * tonal.cmean[i];
			}
			for (int i = 0; i < 4; i++)
			{
				tonal.cmean[i] = (1f - num7) * tonal.cmean[i] + num7 * array3[i];
			}
			for (int i = 0; i < 4; i++)
			{
				array4[4 + i] = 0.63246f * (array3[i] - tonal.mem[i + 24]) + 0.31623f * (tonal.mem[i] - tonal.mem[i + 16]);
			}
			for (int i = 0; i < 3; i++)
			{
				array4[8 + i] = 0.53452f * (array3[i] + tonal.mem[i + 24]) - 0.26726f * (tonal.mem[i] + tonal.mem[i + 16]) - 0.53452f * tonal.mem[i + 8];
			}
			if (tonal.count > 5)
			{
				for (int i = 0; i < 9; i++)
				{
					tonal.std[i] = (1f - num7) * tonal.std[i] + num7 * array4[i] * array4[i];
				}
			}
			for (int i = 0; i < 8; i++)
			{
				tonal.mem[i + 24] = tonal.mem[i + 16];
				tonal.mem[i + 16] = tonal.mem[i + 8];
				tonal.mem[i + 8] = tonal.mem[i];
				tonal.mem[i] = array3[i];
			}
			for (int i = 0; i < 9; i++)
			{
				array4[11 + i] = (float)Math.Sqrt(tonal.std[i]);
			}
			array4[20] = analysisInfo.tonality;
			array4[21] = analysisInfo.activity;
			array4[22] = num24;
			array4[23] = analysisInfo.tonality_slope;
			array4[24] = tonal.lowECount;
			MultiLayerPerceptron.mlp_process(Tables.net, array4, array5);
			array5[0] = 0.5f * (array5[0] + 1f);
			array5[0] = 0.01f + 1.21f * array5[0] * array5[0] - 0.23f * (float)Math.Pow(array5[0], 10.0);
			array5[1] = 0.5f * array5[1] + 0.5f;
			array5[0] = array5[1] * array5[0] + (1f - array5[1]) * 0.5f;
			float num41 = 5E-05f * array5[1];
			float num42 = 0.05f;
			float num43 = Inlines.MAX16(0.05f, Inlines.MIN16(0.95f, array5[0]));
			float num44 = Inlines.MAX16(0.05f, Inlines.MIN16(0.95f, tonal.music_prob));
			num42 = 0.01f + 0.05f * Inlines.ABS16(num43 - num44) / (num43 * (1f - num44) + num44 * (1f - num43));
			float num45 = (1f - tonal.music_prob) * (1f - num41) + tonal.music_prob * num41;
			float num46 = tonal.music_prob * (1f - num41) + (1f - tonal.music_prob) * num41;
			num45 *= (float)Math.Pow(1f - array5[0], num42);
			num46 *= (float)Math.Pow(array5[0], num42);
			tonal.music_prob = num46 / (num45 + num46);
			analysisInfo.music_prob = tonal.music_prob;
			float num47 = 1E-20f;
			float num48 = (float)Math.Pow(1f - array5[0], num42);
			float num49 = (float)Math.Pow(array5[0], num42);
			if (tonal.count == 1)
			{
				tonal.pspeech[0] = 0.5f;
				tonal.pmusic[0] = 0.5f;
			}
			float num50 = tonal.pspeech[0] + tonal.pspeech[1];
			float num51 = tonal.pmusic[0] + tonal.pmusic[1];
			tonal.pspeech[0] = num50 * (1f - num41) * num48;
			tonal.pmusic[0] = num51 * (1f - num41) * num49;
			for (int i = 1; i < 199; i++)
			{
				tonal.pspeech[i] = tonal.pspeech[i + 1] * num48;
				tonal.pmusic[i] = tonal.pmusic[i + 1] * num49;
			}
			tonal.pspeech[199] = num51 * num41 * num48;
			tonal.pmusic[199] = num50 * num41 * num49;
			for (int i = 0; i < 200; i++)
			{
				num47 += tonal.pspeech[i] + tonal.pmusic[i];
			}
			num47 = 1f / num47;
			for (int i = 0; i < 200; i++)
			{
				tonal.pspeech[i] *= num47;
				tonal.pmusic[i] *= num47;
			}
			num47 = tonal.pmusic[0];
			for (int i = 1; i < 200; i++)
			{
				num47 += tonal.pspeech[i];
			}
			if ((double)array5[1] > 0.75)
			{
				if ((double)tonal.music_prob > 0.9)
				{
					float num52 = 1f / (float)(++tonal.music_confidence_count);
					tonal.music_confidence_count = Inlines.IMIN(tonal.music_confidence_count, 500);
					tonal.music_confidence += num52 * Inlines.MAX16(-0.2f, array5[0] - tonal.music_confidence);
				}
				if ((double)tonal.music_prob < 0.1)
				{
					float num53 = 1f / (float)(++tonal.speech_confidence_count);
					tonal.speech_confidence_count = Inlines.IMIN(tonal.speech_confidence_count, 500);
					tonal.speech_confidence += num53 * Inlines.MIN16(0.2f, array5[0] - tonal.speech_confidence);
				}
			}
			else
			{
				if (tonal.music_confidence_count == 0)
				{
					tonal.music_confidence = 0.9f;
				}
				if (tonal.speech_confidence_count == 0)
				{
					tonal.speech_confidence = 0.1f;
				}
			}
			if (tonal.last_music != ((tonal.music_prob > 0.5f) ? 1 : 0))
			{
				tonal.last_transition = 0;
			}
			tonal.last_music = ((tonal.music_prob > 0.5f) ? 1 : 0);
			analysisInfo.bandwidth = num5;
			analysisInfo.noisiness = num23;
			analysisInfo.valid = 1;
		}

		internal static void run_analysis<T>(TonalityAnalysisState analysis, CeltMode celt_mode, ReadOnlySpan<T> analysis_pcm, int analysis_frame_size, int frame_size, int c1, int c2, int C, int Fs, int lsb_depth, Downmix.downmix_func<T> downmix, AnalysisInfo analysis_info)
		{
			if (!analysis_pcm.IsEmpty)
			{
				analysis_frame_size = Inlines.IMIN(195 * Fs / 100, analysis_frame_size);
				int num = analysis_frame_size - analysis.analysis_offset;
				int num2 = analysis.analysis_offset;
				do
				{
					tonality_analysis(analysis, celt_mode, analysis_pcm, Inlines.IMIN(480, num), num2, c1, c2, C, lsb_depth, downmix);
					num2 += 480;
					num -= 480;
				}
				while (num > 0);
				analysis.analysis_offset = analysis_frame_size;
				analysis.analysis_offset -= frame_size;
			}
			analysis_info.valid = 0;
			tonality_get_info(analysis, analysis_info, frame_size);
		}
	}
	internal static class CodecHelpers
	{
		private const int MAX_DYNAMIC_FRAMESIZE = 24;

		internal static byte gen_toc(OpusMode mode, int framerate, OpusBandwidth bandwidth, int channels)
		{
			int num = 0;
			while (framerate < 400)
			{
				framerate <<= 1;
				num++;
			}
			byte b;
			switch (mode)
			{
			case OpusMode.MODE_SILK_ONLY:
				b = (byte)((int)(bandwidth - 1101) << 5);
				b |= (byte)(num - 2 << 3);
				break;
			case OpusMode.MODE_CELT_ONLY:
			{
				int num2 = (int)(bandwidth - 1102);
				if (num2 < 0)
				{
					num2 = 0;
				}
				b = 128;
				b |= (byte)(num2 << 5);
				b |= (byte)(num << 3);
				break;
			}
			default:
				b = 96;
				b |= (byte)((int)(bandwidth - 1104) << 4);
				b |= (byte)(num - 2 << 3);
				break;
			}
			return (byte)(b | (byte)(((channels == 2) ? 1u : 0u) << 2));
		}

		internal static void hp_cutoff(ReadOnlySpan<short> input, int input_ptr, int cutoff_Hz, Span<short> output, int output_ptr, int[] hp_mem, int len, int channels, int Fs)
		{
			int[] array = new int[3];
			int[] array2 = new int[2];
			int num = Inlines.silk_DIV32_16(Inlines.silk_SMULBB(2471, cutoff_Hz), Fs / 1000);
			int num2 = (array[0] = 268435456 - Inlines.silk_MUL(471, num));
			array[1] = Inlines.silk_LSHIFT(-num2, 1);
			array[2] = num2;
			int num3 = Inlines.silk_RSHIFT(num2, 6);
			array2[0] = Inlines.silk_SMULWW(num3, Inlines.silk_SMULWW(num, num) - 8388608);
			array2[1] = Inlines.silk_SMULWW(num3, num3);
			Filters.silk_biquad_alt(input, input_ptr, array, array2, hp_mem, 0, output, output_ptr, len, channels);
			if (channels == 2)
			{
				Filters.silk_biquad_alt(input, input_ptr + 1, array, array2, hp_mem, 2, output, output_ptr + 1, len, channels);
			}
		}

		internal static void dc_reject(ReadOnlySpan<short> input, int input_ptr, int cutoff_Hz, Span<short> output, int output_ptr, int[] hp_mem, int len, int channels, int Fs)
		{
			int shift = Inlines.celt_ilog2(Fs / (cutoff_Hz * 3));
			for (int i = 0; i < channels; i++)
			{
				for (int j = 0; j < len; j++)
				{
					int num = Inlines.SHL32(Inlines.EXTEND32(input[channels * j + i + input_ptr]), 15);
					int num2 = num - hp_mem[2 * i];
					hp_mem[2 * i] += Inlines.PSHR32(num - hp_mem[2 * i], shift);
					int a = num2 - hp_mem[2 * i + 1];
					hp_mem[2 * i + 1] += Inlines.PSHR32(num2 - hp_mem[2 * i + 1], shift);
					output[channels * j + i + output_ptr] = Inlines.EXTRACT16(Inlines.SATURATE(Inlines.PSHR32(a, 15), 32767));
				}
			}
		}

		internal static void stereo_fade(short[] pcm_buf, int g1, int g2, int overlap48, int frame_size, int channels, int[] window, int Fs)
		{
			int num = 48000 / Fs;
			int num2 = overlap48 / num;
			g1 = 32767 - g1;
			g2 = 32767 - g2;
			int i;
			for (i = 0; i < num2; i++)
			{
				int num3 = Inlines.MULT16_16_Q15(window[i * num], window[i * num]);
				int a = Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(num3, g2), 32767 - num3, g1), 15);
				int b = Inlines.EXTRACT16(Inlines.HALF32(pcm_buf[i * channels] - pcm_buf[i * channels + 1]));
				b = Inlines.MULT16_16_Q15(a, b);
				pcm_buf[i * channels] = (short)(pcm_buf[i * channels] - b);
				pcm_buf[i * channels + 1] = (short)(pcm_buf[i * channels + 1] + b);
			}
			for (; i < frame_size; i++)
			{
				int b2 = Inlines.EXTRACT16(Inlines.HALF32(pcm_buf[i * channels] - pcm_buf[i * channels + 1]));
				b2 = Inlines.MULT16_16_Q15(g2, b2);
				pcm_buf[i * channels] = (short)(pcm_buf[i * channels] - b2);
				pcm_buf[i * channels + 1] = (short)(pcm_buf[i * channels + 1] + b2);
			}
		}

		internal static void gain_fade(short[] buffer, int buf_ptr, int g1, int g2, int overlap48, int frame_size, int channels, int[] window, int Fs)
		{
			int num = 48000 / Fs;
			int num2 = overlap48 / num;
			if (channels == 1)
			{
				for (int i = 0; i < num2; i++)
				{
					int num3 = Inlines.MULT16_16_Q15(window[i * num], window[i * num]);
					int a = Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(num3, g2), 32767 - num3, g1), 15);
					buffer[buf_ptr + i] = (short)Inlines.MULT16_16_Q15(a, buffer[buf_ptr + i]);
				}
			}
			else
			{
				for (int i = 0; i < num2; i++)
				{
					int num4 = Inlines.MULT16_16_Q15(window[i * num], window[i * num]);
					int a2 = Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(num4, g2), 32767 - num4, g1), 15);
					buffer[buf_ptr + i * 2] = (short)Inlines.MULT16_16_Q15(a2, buffer[buf_ptr + i * 2]);
					buffer[buf_ptr + i * 2 + 1] = (short)Inlines.MULT16_16_Q15(a2, buffer[buf_ptr + i * 2 + 1]);
				}
			}
			int num5 = 0;
			do
			{
				for (int i = num2; i < frame_size; i++)
				{
					buffer[buf_ptr + i * channels + num5] = (short)Inlines.MULT16_16_Q15(g2, buffer[buf_ptr + i * channels + num5]);
				}
			}
			while (++num5 < channels);
		}

		internal static float transient_boost(Span<float> E, int E_ptr, float[] E_1, int LM, int maxM)
		{
			float num = 0f;
			float num2 = 0f;
			int num3 = Inlines.IMIN(maxM, (1 << LM) + 1);
			for (int i = E_ptr; i < num3 + E_ptr; i++)
			{
				num += E[i];
				num2 += E_1[i];
			}
			float num4 = num * num2 / (float)(num3 * num3);
			return Inlines.MIN16(1f, (float)Math.Sqrt(Inlines.MAX16(0f, 0.05f * (num4 - 2f))));
		}

		internal static int transient_viterbi(float[] E, float[] E_1, int N, int frame_cost, int rate)
		{
			float[][] array = Arrays.InitTwoDimensionalArray<float>(24, 16);
			int[][] array2 = Arrays.InitTwoDimensionalArray<int>(24, 16);
			float num = ((rate < 80) ? 0f : ((rate <= 160) ? (((float)rate - 80f) / 80f) : 1f));
			for (int i = 0; i < 16; i++)
			{
				array2[0][i] = -1;
				array[0][i] = 1E+10f;
			}
			for (int i = 0; i < 4; i++)
			{
				array[0][1 << i] = (float)(frame_cost + rate * (1 << i)) * (1f + num * transient_boost(E, 0, E_1, i, N + 1));
				array2[0][1 << i] = i;
			}
			for (int i = 1; i < N; i++)
			{
				for (int j = 2; j < 16; j++)
				{
					array[i][j] = array[i - 1][j - 1];
					array2[i][j] = j - 1;
				}
				for (int j = 0; j < 4; j++)
				{
					array2[i][1 << j] = 1;
					float num2 = array[i - 1][1];
					for (int k = 1; k < 4; k++)
					{
						float num3 = array[i - 1][(1 << k + 1) - 1];
						if (num3 < num2)
						{
							array2[i][1 << j] = (1 << k + 1) - 1;
							num2 = num3;
						}
					}
					float num4 = (float)(frame_cost + rate * (1 << j)) * (1f + num * transient_boost(E, i, E_1, j, N - i + 1));
					array[i][1 << j] = num2;
					if (N - i < 1 << j)
					{
						array[i][1 << j] += num4 * (float)(N - i) / (float)(1 << j);
					}
					else
					{
						array[i][1 << j] += num4;
					}
				}
			}
			int num5 = 1;
			float num6 = array[N - 1][1];
			for (int i = 2; i < 16; i++)
			{
				if (array[N - 1][i] < num6)
				{
					num6 = array[N - 1][i];
					num5 = i;
				}
			}
			for (int i = N - 1; i >= 0; i--)
			{
				num5 = array2[i][num5];
			}
			return num5;
		}

		internal static int optimize_framesize<T>(ReadOnlySpan<T> x, int len, int C, int Fs, int bitrate, int tonality, float[] mem, int buffering, Downmix.downmix_func<T> downmix)
		{
			float[] array = new float[28];
			float[] array2 = new float[27];
			int num = 0;
			int num2 = Fs / 400;
			int[] array3 = new int[num2];
			array[0] = mem[0];
			array2[0] = 1f / (1f + mem[0]);
			int num3;
			int num4;
			if (buffering != 0)
			{
				num3 = 2 * num2 - buffering;
				len -= num3;
				array[1] = mem[1];
				array2[1] = 1f / (1f + mem[1]);
				array[2] = mem[2];
				array2[2] = 1f / (1f + mem[2]);
				num4 = 3;
			}
			else
			{
				num4 = 1;
				num3 = 0;
			}
			int num5 = Inlines.IMIN(len / num2, 24);
			int num6 = 0;
			int i;
			for (i = 0; i < num5; i++)
			{
				float num7 = 1f;
				downmix(x, array3, 0, num2, i * num2 + num3, 0, -2, C);
				if (i == 0)
				{
					num6 = array3[0];
				}
				for (int j = 0; j < num2; j++)
				{
					int num8 = array3[j];
					num7 += (float)(num8 - num6) * (float)(num8 - num6);
					num6 = num8;
				}
				array[i + num4] = num7;
				array2[i + num4] = 1f / num7;
			}
			array[i + num4] = array[i + num4 - 1];
			if (buffering != 0)
			{
				num5 = Inlines.IMIN(24, num5 + 2);
			}
			num = transient_viterbi(array, array2, num5, (int)((1f + 0.5f * (float)tonality) * (float)(60 * C + 40)), bitrate / 400);
			mem[0] = array[1 << num];
			if (buffering != 0)
			{
				mem[1] = array[(1 << num) + 1];
				mem[2] = array[(1 << num) + 2];
			}
			return num;
		}

		internal static int frame_size_select(int frame_size, OpusFramesize variable_duration, int Fs)
		{
			if (frame_size < Fs / 400)
			{
				return -1;
			}
			int num;
			switch (variable_duration)
			{
			case OpusFramesize.OPUS_FRAMESIZE_ARG:
				num = frame_size;
				break;
			case OpusFramesize.OPUS_FRAMESIZE_VARIABLE:
				num = Fs / 50;
				break;
			case OpusFramesize.OPUS_FRAMESIZE_2_5_MS:
			case OpusFramesize.OPUS_FRAMESIZE_5_MS:
			case OpusFramesize.OPUS_FRAMESIZE_10_MS:
			case OpusFramesize.OPUS_FRAMESIZE_20_MS:
			case OpusFramesize.OPUS_FRAMESIZE_40_MS:
			case OpusFramesize.OPUS_FRAMESIZE_60_MS:
				num = Inlines.IMIN(3 * Fs / 50, Fs / 400 << (int)(variable_duration - 5001));
				break;
			default:
				return -1;
			}
			if (num > frame_size)
			{
				return -1;
			}
			if (400 * num != Fs && 200 * num != Fs && 100 * num != Fs && 50 * num != Fs && 25 * num != Fs && 50 * num != 3 * Fs)
			{
				return -1;
			}
			return num;
		}

		internal static int compute_frame_size<T>(ReadOnlySpan<T> analysis_pcm, int frame_size, OpusFramesize variable_duration, int C, int Fs, int bitrate_bps, int delay_compensation, Downmix.downmix_func<T> downmix, float[] subframe_mem, bool analysis_enabled)
		{
			if (analysis_enabled && variable_duration == OpusFramesize.OPUS_FRAMESIZE_VARIABLE && frame_size >= Fs / 200)
			{
				int num = 3;
				num = optimize_framesize(analysis_pcm, frame_size, C, Fs, bitrate_bps, 0, subframe_mem, delay_compensation, downmix);
				while (Fs / 400 << num > frame_size)
				{
					num--;
				}
				frame_size = Fs / 400 << num;
			}
			else
			{
				frame_size = frame_size_select(frame_size, variable_duration, Fs);
			}
			if (frame_size < 0)
			{
				return -1;
			}
			return frame_size;
		}

		internal static int compute_stereo_width(ReadOnlySpan<short> pcm, int pcm_ptr, int frame_size, int Fs, StereoWidthState mem)
		{
			int num = Fs / frame_size;
			int a = 32767 - 819175 / Inlines.IMAX(50, num);
			int num3;
			int num2;
			int num4 = (num3 = (num2 = 0));
			for (int i = 0; i < frame_size - 3; i += 4)
			{
				int num5 = 0;
				int num6 = 0;
				int num7 = 0;
				int num8 = pcm_ptr + 2 * i;
				int num9 = pcm[num8];
				int num10 = pcm[num8 + 1];
				num5 = Inlines.SHR32(Inlines.MULT16_16(num9, num9), 2);
				num6 = Inlines.SHR32(Inlines.MULT16_16(num9, num10), 2);
				num7 = Inlines.SHR32(Inlines.MULT16_16(num10, num10), 2);
				num9 = pcm[num8 + 2];
				num10 = pcm[num8 + 3];
				num5 += Inlines.SHR32(Inlines.MULT16_16(num9, num9), 2);
				num6 += Inlines.SHR32(Inlines.MULT16_16(num9, num10), 2);
				num7 += Inlines.SHR32(Inlines.MULT16_16(num10, num10), 2);
				num9 = pcm[num8 + 4];
				num10 = pcm[num8 + 5];
				num5 += Inlines.SHR32(Inlines.MULT16_16(num9, num9), 2);
				num6 += Inlines.SHR32(Inlines.MULT16_16(num9, num10), 2);
				num7 += Inlines.SHR32(Inlines.MULT16_16(num10, num10), 2);
				num9 = pcm[num8 + 6];
				num10 = pcm[num8 + 7];
				num5 += Inlines.SHR32(Inlines.MULT16_16(num9, num9), 2);
				num6 += Inlines.SHR32(Inlines.MULT16_16(num9, num10), 2);
				num7 += Inlines.SHR32(Inlines.MULT16_16(num10, num10), 2);
				num4 += Inlines.SHR32(num5, 10);
				num3 += Inlines.SHR32(num6, 10);
				num2 += Inlines.SHR32(num7, 10);
			}
			mem.XX += Inlines.MULT16_32_Q15(a, num4 - mem.XX);
			mem.XY += Inlines.MULT16_32_Q15(a, num3 - mem.XY);
			mem.YY += Inlines.MULT16_32_Q15(a, num2 - mem.YY);
			mem.XX = Inlines.MAX32(0, mem.XX);
			mem.XY = Inlines.MAX32(0, mem.XY);
			mem.YY = Inlines.MAX32(0, mem.YY);
			if (Inlines.MAX32(mem.XX, mem.YY) > 210)
			{
				int num11 = Inlines.celt_sqrt(mem.XX);
				int num12 = Inlines.celt_sqrt(mem.YY);
				int num13 = Inlines.celt_sqrt(num11);
				int num14 = Inlines.celt_sqrt(num12);
				mem.XY = Inlines.MIN32(mem.XY, num11 * num12);
				int num15 = Inlines.SHR32(Inlines.frac_div32(mem.XY, 1 + Inlines.MULT16_16(num11, num12)), 16);
				int b = 32767 * Inlines.ABS16(num13 - num14) / (1 + num13 + num14);
				int num16 = Inlines.MULT16_16_Q15(Inlines.celt_sqrt(1073741824 - Inlines.MULT16_16(num15, num15)), b);
				mem.smoothed_width += (num16 - mem.smoothed_width) / num;
				mem.max_follower = Inlines.MAX16(mem.max_follower - 655 / num, mem.smoothed_width);
			}
			else
			{
				int num16 = 0;
				int num15 = 32767;
				int b = 0;
			}
			return Inlines.EXTRACT16(Inlines.MIN32(32767, 20 * mem.max_follower));
		}

		internal static void smooth_fade(Span<short> in1, int in1_ptr, Span<short> in2, int in2_ptr, Span<short> output, int output_ptr, int overlap, int channels, int[] window, int Fs)
		{
			int num = 48000 / Fs;
			for (int i = 0; i < channels; i++)
			{
				for (int j = 0; j < overlap; j++)
				{
					int num2 = Inlines.MULT16_16_Q15(window[j * num], window[j * num]);
					output[output_ptr + j * channels + i] = (short)Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(num2, in2[in2_ptr + j * channels + i]), 32767 - num2, in1[in1_ptr + j * channels + i]), 15);
				}
			}
		}

		internal static string opus_strerror(int error)
		{
			string[] array = new string[8] { "success", "invalid argument", "buffer too small", "internal error", "corrupted stream", "request not implemented", "invalid state", "memory allocation failed" };
			if (error > 0 || error < -7)
			{
				return "unknown error";
			}
			return array[-error];
		}

		internal static string GetVersionString()
		{
			return "Concentus 2.1.2";
		}
	}
	internal static class Downmix
	{
		internal delegate void downmix_func<T>(ReadOnlySpan<T> _x, Span<int> sub, int sub_ptr, int subframe, int offset, int c1, int c2, int C);

		internal static void downmix_float(ReadOnlySpan<float> x, Span<int> sub, int sub_ptr, int subframe, int offset, int c1, int c2, int C)
		{
			for (int i = 0; i < subframe; i++)
			{
				sub[sub_ptr + i] = Inlines.FLOAT2INT16(x[(i + offset) * C + c1]);
			}
			if (c2 > -1)
			{
				for (int i = 0; i < subframe; i++)
				{
					sub[sub_ptr + i] += Inlines.FLOAT2INT16(x[(i + offset) * C + c2]);
				}
			}
			else if (c2 == -2)
			{
				for (int j = 1; j < C; j++)
				{
					int num = j;
					for (int i = 0; i < subframe; i++)
					{
						sub[sub_ptr + i] += Inlines.FLOAT2INT16(x[(i + offset) * C + num]);
					}
				}
			}
			int num2 = 4096;
			num2 = ((C != -2) ? (num2 / 2) : (num2 / C));
			for (int i = 0; i < subframe; i++)
			{
				sub[sub_ptr + i] *= num2;
			}
		}

		internal static void downmix_int(ReadOnlySpan<short> x, Span<int> sub, int sub_ptr, int subframe, int offset, int c1, int c2, int C)
		{
			for (int i = 0; i < subframe; i++)
			{
				sub[i + sub_ptr] = x[(i + offset) * C + c1];
			}
			if (c2 > -1)
			{
				for (int i = 0; i < subframe; i++)
				{
					sub[i + sub_ptr] += x[(i + offset) * C + c2];
				}
			}
			else if (c2 == -2)
			{
				for (int j = 1; j < C; j++)
				{
					for (int i = 0; i < subframe; i++)
					{
						sub[i + sub_ptr] += x[(i + offset) * C + j];
					}
				}
			}
			int num = 4096;
			num = ((C != -2) ? (num / 2) : (num / C));
			for (int i = 0; i < subframe; i++)
			{
				sub[i + sub_ptr] *= num;
			}
		}
	}
	internal static class MultiLayerPerceptron
	{
		private const int MAX_NEURONS = 100;

		internal static float tansig_approx(float x)
		{
			float num = 1f;
			if (!(x < 8f))
			{
				return 1f;
			}
			if (!(x > -8f))
			{
				return -1f;
			}
			if (x < 0f)
			{
				x = 0f - x;
				num = -1f;
			}
			int num2 = (int)Math.Floor(0.5f + 25f * x);
			x -= 0.04f * (float)num2;
			float num3 = Tables.tansig_table[num2];
			float num4 = 1f - num3 * num3;
			num3 += x * num4 * (1f - num3 * x);
			return num * num3;
		}

		internal static void mlp_process(MLP m, float[] input, float[] output)
		{
			float[] array = new float[100];
			float[] weights = m.weights;
			int num = 0;
			for (int i = 0; i < m.topo[1]; i++)
			{
				float num2 = weights[num];
				num++;
				for (int j = 0; j < m.topo[0]; j++)
				{
					num2 += input[j] * weights[num];
					num++;
				}
				array[i] = tansig_approx(num2);
			}
			for (int i = 0; i < m.topo[2]; i++)
			{
				float num3 = weights[num];
				num++;
				for (int k = 0; k < m.topo[1]; k++)
				{
					num3 += array[k] * weights[num];
					num++;
				}
				output[i] = tansig_approx(num3);
			}
		}
	}
	internal static class OpusCompare
	{
		private const int NBANDS = 21;

		private const int NFREQS = 240;

		private const int TEST_WIN_SIZE = 480;

		private const int TEST_WIN_STEP = 120;

		private static readonly int[] BANDS = new int[22]
		{
			0, 2, 4, 6, 8, 10, 12, 14, 16, 20,
			24, 28, 32, 40, 48, 56, 68, 80, 96, 120,
			156, 200
		};

		private static void band_energy(Pointer<float> _out, Pointer<float> _ps, Pointer<int> _bands, int _nbands, Pointer<float> _in, int _nchannels, int _nframes, int _window_sz, int _step, int _downsample)
		{
			Pointer<float> pointer = Concentus.Common.CPlusPlus.Pointer.Malloc<float>((3 + _nchannels) * _window_sz);
			Pointer<float> pointer2 = pointer.Point(_window_sz);
			Pointer<float> pointer3 = pointer2.Point(_window_sz);
			Pointer<float> pointer4 = pointer3.Point(_window_sz);
			int num = _window_sz / 2;
			for (int i = 0; i < _window_sz; i++)
			{
				pointer[i] = (float)(0.5 - 0.5 * Math.Cos(Math.PI * 2.0 / (double)(_window_sz - 1) * (double)i));
			}
			for (int i = 0; i < _window_sz; i++)
			{
				pointer2[i] = (float)Math.Cos(Math.PI * 2.0 / (double)_window_sz * (double)i);
			}
			for (int i = 0; i < _window_sz; i++)
			{
				pointer3[i] = (float)Math.Sin(Math.PI * 2.0 / (double)_window_sz * (double)i);
			}
			for (int j = 0; j < _nframes; j++)
			{
				for (int k = 0; k < _nchannels; k++)
				{
					for (int l = 0; l < _window_sz; l++)
					{
						pointer4[k * _window_sz + l] = pointer[l] * _in[(j * _step + l) * _nchannels + k];
					}
				}
				int i;
				for (int m = (i = 0); m < _nbands; m++)
				{
					float[] array = new float[2];
					for (; i < _bands[m + 1]; i++)
					{
						for (int k = 0; k < _nchannels; k++)
						{
							int num2 = 0;
							float num3;
							float num4 = (num3 = 0f);
							for (int l = 0; l < _window_sz; l++)
							{
								num4 += pointer2[num2] * pointer4[k * _window_sz + l];
								num3 -= pointer3[num2] * pointer4[k * _window_sz + l];
								num2 += i;
								if (num2 >= _window_sz)
								{
									num2 -= _window_sz;
								}
							}
							num4 *= (float)_downsample;
							num3 *= (float)_downsample;
							_ps[(j * num + i) * _nchannels + k] = num4 * num4 + num3 * num3 + 100000f;
							array[k] += _ps[(j * num + i) * _nchannels + k];
						}
					}
					if (_out != null)
					{
						_out[(j * _nbands + m) * _nchannels] = array[0] / (float)(_bands[m + 1] - _bands[m]);
						if (_nchannels == 2)
						{
							_out[(j * _nbands + m) * _nchannels + 1] = array[1] / (float)(_bands[m + 1] - _bands[m]);
						}
					}
				}
			}
		}

		internal static float compare(float[] x, float[] y, int nchannels, int rate = 48000)
		{
			int num = x.Length;
			int num2 = y.Length;
			int num3 = 21;
			int num4 = 240;
			if (rate != 8000 && rate != 12000 && rate != 16000 && rate != 24000 && rate != 48000)
			{
				throw new ArgumentException("Sampling rate must be 8000, 12000, 16000, 24000, or 48000\n");
			}
			int num5;
			if (rate != 48000)
			{
				num5 = 48000 / rate;
				switch (rate)
				{
				case 8000:
					num3 = 13;
					break;
				case 12000:
					num3 = 15;
					break;
				case 16000:
					num3 = 17;
					break;
				case 24000:
					num3 = 19;
					break;
				}
				num4 = 240 / num5;
			}
			else
			{
				num5 = 1;
			}
			if (num != num2 * num5)
			{
				throw new ArgumentException("Sample counts do not match");
			}
			if (num < 480)
			{
				throw new ArgumentException("Insufficient sample data");
			}
			int num6 = (num - 480 + 120) / 120;
			Pointer<float> pointer = Concentus.Common.CPlusPlus.Pointer.Malloc<float>(num6 * 21 * nchannels);
			Pointer<float> pointer2 = Concentus.Common.CPlusPlus.Pointer.Malloc<float>(num6 * 240 * nchannels);
			Pointer<float> pointer3 = Concentus.Common.CPlusPlus.Pointer.Malloc<float>(num6 * num4 * nchannels);
			band_energy(pointer, pointer2, BANDS.GetPointer(), 21, x.GetPointer(), nchannels, num6, 480, 120, 1);
			band_energy(null, pointer3, BANDS.GetPointer(), num3, y.GetPointer(), nchannels, num6, 480 / num5, 120 / num5, num5);
			for (int i = 0; i < num6; i++)
			{
				int j;
				for (j = 1; j < 21; j++)
				{
					for (int k = 0; k < nchannels; k++)
					{
						pointer[(i * 21 + j) * nchannels + k] += 0.1f * pointer[(i * 21 + j - 1) * nchannels + k];
					}
				}
				j = 20;
				while (j-- > 0)
				{
					for (int k = 0; k < nchannels; k++)
					{
						pointer[(i * 21 + j) * nchannels + k] += 0.03f * pointer[(i * 21 + j + 1) * nchannels + k];
					}
				}
				if (i > 0)
				{
					for (j = 0; j < 21; j++)
					{
						for (int k = 0; k < nchannels; k++)
						{
							pointer[(i * 21 + j) * nchannels + k] += 0.5f * pointer[((i - 1) * 21 + j) * nchannels + k];
						}
					}
				}
				if (nchannels == 2)
				{
					for (j = 0; j < 21; j++)
					{
						float num7 = pointer[(i * 21 + j) * nchannels];
						float num8 = pointer[(i * 21 + j) * nchannels + 1];
						pointer[(i * 21 + j) * nchannels] += 0.01f * num8;
						pointer[(i * 21 + j) * nchannels + 1] += 0.01f * num7;
					}
				}
				for (j = 0; j < num3; j++)
				{
					for (int l = BANDS[j]; l < BANDS[j + 1]; l++)
					{
						for (int k = 0; k < nchannels; k++)
						{
							pointer2[(i * 240 + l) * nchannels + k] += 0.1f * pointer[(i * 21 + j) * nchannels + k];
							pointer3[(i * num4 + l) * nchannels + k] += 0.1f * pointer[(i * 21 + j) * nchannels + k];
						}
					}
				}
			}
			for (int j = 0; j < num3; j++)
			{
				for (int l = BANDS[j]; l < BANDS[j + 1]; l++)
				{
					for (int k = 0; k < nchannels; k++)
					{
						float num9 = pointer2[l * nchannels + k];
						float num10 = pointer3[l * nchannels + k];
						for (int i = 1; i < num6; i++)
						{
							float num11 = pointer2[(i * 240 + l) * nchannels + k];
							float num12 = pointer3[(i * num4 + l) * nchannels + k];
							pointer2[(i * 240 + l) * nchannels + k] += num9;
							pointer3[(i * num4 + l) * nchannels + k] += num10;
							num9 = num11;
							num10 = num12;
						}
					}
				}
			}
			int num13 = rate switch
			{
				48000 => BANDS[21], 
				12000 => BANDS[num3], 
				_ => BANDS[num3] - 3, 
			};
			double num14 = 0.0;
			for (int i = 0; i < num6; i++)
			{
				double num15 = 0.0;
				for (int j = 0; j < num3; j++)
				{
					double num16 = 0.0;
					for (int l = BANDS[j]; l < BANDS[j + 1] && l < num13; l++)
					{
						for (int k = 0; k < nchannels; k++)
						{
							float num17 = pointer3[(i * num4 + l) * nchannels + k] / pointer2[(i * 240 + l) * nchannels + k];
							float num18 = num17 - (float)Math.Log(num17) - 1f;
							if (l >= 79 && l <= 81)
							{
								num18 *= 0.1f;
							}
							if (l == 80)
							{
								num18 *= 0.1f;
							}
							num16 += (double)num18;
						}
					}
					num16 /= (double)((BANDS[j + 1] - BANDS[j]) * nchannels);
					num15 += num16 * num16;
				}
				num15 /= 21.0;
				num15 *= num15;
				num14 += num15 * num15;
			}
			num14 = Math.Pow(num14 / (double)num6, 0.0625);
			float result = (float)(100.0 * (1.0 - 0.5 * Math.Log(1.0 + num14) / Math.Log(1.13)));
			_ = 0f;
			return result;
		}
	}
	internal static class OpusConstants
	{
		internal const int OPUS_AUTO = -1000;

		internal const int OPUS_BITRATE_MAX = -1;

		internal const int NB_FRAMES = 8;

		internal const int NB_TBANDS = 18;

		internal const int NB_TOT_BANDS = 21;

		internal const int NB_TONAL_SKIP_BANDS = 9;

		internal const int ANALYSIS_BUF_SIZE = 720;

		internal const int DETECT_SIZE = 200;

		internal const int MAX_ENCODER_BUFFER = 480;
	}
	public class OpusException : Exception
	{
		public int OpusErrorCode { get; private set; }

		internal OpusException()
			: base("Unknown error")
		{
			OpusErrorCode = -100;
		}

		internal OpusException(string message)
			: base(message)
		{
			OpusErrorCode = -100;
		}

		internal OpusException(int opusError)
			: base(CodecHelpers.opus_strerror(opusError))
		{
			OpusErrorCode = opusError;
		}

		internal OpusException(string message, int opusError)
			: base(message)
		{
			OpusErrorCode = opusError;
		}
	}
	internal static class OpusMultistream
	{
		internal static int validate_layout(ChannelLayout layout)
		{
			int num = layout.nb_streams + layout.nb_coupled_streams;
			if (num > 255)
			{
				return 0;
			}
			for (int i = 0; i < layout.nb_channels; i++)
			{
				if (layout.mapping[i] >= num && layout.mapping[i] != byte.MaxValue)
				{
					return 0;
				}
			}
			return 1;
		}

		internal static int get_left_channel(ChannelLayout layout, int stream_id, int prev)
		{
			for (int i = ((prev >= 0) ? (prev + 1) : 0); i < layout.nb_channels; i++)
			{
				if (layout.mapping[i] == stream_id * 2)
				{
					return i;
				}
			}
			return -1;
		}

		internal static int get_right_channel(ChannelLayout layout, int stream_id, int prev)
		{
			for (int i = ((prev >= 0) ? (prev + 1) : 0); i < layout.nb_channels; i++)
			{
				if (layout.mapping[i] == stream_id * 2 + 1)
				{
					return i;
				}
			}
			return -1;
		}

		internal static int get_mono_channel(ChannelLayout layout, int stream_id, int prev)
		{
			for (int i = ((prev >= 0) ? (prev + 1) : 0); i < layout.nb_channels; i++)
			{
				if (layout.mapping[i] == stream_id + layout.nb_coupled_streams)
				{
					return i;
				}
			}
			return -1;
		}
	}
	internal static class Tables
	{
		internal static readonly float[] dct_table = new float[128]
		{
			0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f,
			0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.351851f, 0.33833f, 0.311806f, 0.2733f,
			0.224292f, 0.166664f, 0.102631f, 0.034654f, -0.034654f, -0.102631f, -0.166664f, -0.224292f, -0.2733f, -0.311806f,
			-0.33833f, -0.351851f, 0.34676f, 0.293969f, 0.196424f, 0.068975f, -0.068975f, -0.196424f, -0.293969f, -0.34676f,
			-0.34676f, -0.293969f, -0.196424f, -0.068975f, 0.068975f, 0.196424f, 0.293969f, 0.34676f, 0.33833f, 0.224292f,
			0.034654f, -0.166664f, -0.311806f, -0.351851f, -0.2733f, -0.102631f, 0.102631f, 0.2733f, 0.351851f, 0.311806f,
			0.166664f, -0.034654f, -0.224292f, -0.33833f, 0.326641f, 0.135299f, -0.135299f, -0.326641f, -0.326641f, -0.135299f,
			0.135299f, 0.326641f, 0.326641f, 0.135299f, -0.135299f, -0.326641f, -0.326641f, -0.135299f, 0.135299f, 0.326641f,
			0.311806f, 0.034654f, -0.2733f, -0.33833f, -0.102631f, 0.224292f, 0.351851f, 0.166664f, -0.166664f, -0.351851f,
			-0.224292f, 0.102631f, 0.33833f, 0.2733f, -0.034654f, -0.311806f, 0.293969f, -0.068975f, -0.34676f, -0.196424f,
			0.196424f, 0.34676f, 0.068975f, -0.293969f, -0.293969f, 0.068975f, 0.34676f, 0.196424f, -0.196424f, -0.34676f,
			-0.068975f, 0.293969f, 0.2733f, -0.166664f, -0.33833f, 0.034654f, 0.351851f, 0.102631f, -0.311806f, -0.224292f,
			0.224292f, 0.311806f, -0.102631f, -0.351851f, -0.034654f, 0.33833f, 0.166664f, -0.2733f
		};

		internal static readonly float[] analysis_window = new float[240]
		{
			4.3E-05f, 0.000171f, 0.000385f, 0.000685f, 0.001071f, 0.001541f, 0.002098f, 0.002739f, 0.003466f, 0.004278f,
			0.005174f, 0.006156f, 0.007222f, 0.008373f, 0.009607f, 0.010926f, 0.012329f, 0.013815f, 0.015385f, 0.017037f,
			0.018772f, 0.02059f, 0.02249f, 0.024472f, 0.026535f, 0.028679f, 0.030904f, 0.03321f, 0.035595f, 0.03806f,
			0.040604f, 0.043227f, 0.045928f, 0.048707f, 0.051564f, 0.054497f, 0.057506f, 0.060591f, 0.063752f, 0.066987f,
			0.070297f, 0.07368f, 0.077136f, 0.080665f, 0.084265f, 0.087937f, 0.091679f, 0.095492f, 0.099373f, 0.103323f,
			0.107342f, 0.111427f, 0.115579f, 0.119797f, 0.12408f, 0.128428f, 0.132839f, 0.137313f, 0.141849f, 0.146447f,
			0.151105f, 0.155823f, 0.1606f, 0.165435f, 0.170327f, 0.175276f, 0.18028f, 0.18534f, 0.190453f, 0.195619f,
			0.200838f, 0.206107f, 0.211427f, 0.216797f, 0.222215f, 0.22768f, 0.233193f, 0.238751f, 0.244353f, 0.25f,
			0.255689f, 0.261421f, 0.267193f, 0.273005f, 0.278856f, 0.284744f, 0.29067f, 0.296632f, 0.302628f, 0.308658f,
			0.314721f, 0.320816f, 0.326941f, 0.333097f, 0.33928f, 0.345492f, 0.351729f, 0.357992f, 0.36428f, 0.37059f,
			0.376923f, 0.383277f, 0.389651f, 0.396044f, 0.402455f, 0.408882f, 0.415325f, 0.421783f, 0.428254f, 0.434737f,
			0.441231f, 0.447736f, 0.454249f, 0.46077f, 0.467298f, 0.473832f, 0.48037f, 0.486912f, 0.493455f, 0.5f,
			0.506545f, 0.513088f, 0.51963f, 0.526168f, 0.532702f, 0.53923f, 0.545751f, 0.552264f, 0.558769f, 0.565263f,
			0.571746f, 0.578217f, 0.584675f, 0.591118f, 0.597545f, 0.603956f, 0.610349f, 0.616723f, 0.623077f, 0.62941f,
			0.63572f, 0.642008f, 0.648271f, 0.654508f, 0.66072f, 0.666903f, 0.673059f, 0.679184f, 0.685279f, 0.691342f,
			0.697372f, 0.703368f, 0.70933f, 0.715256f, 0.721144f, 0.726995f, 0.732807f, 0.738579f, 0.744311f, 0.75f,
			0.755647f, 0.761249f, 0.766807f, 0.77232f, 0.777785f, 0.783203f, 0.788573f, 0.793893f, 0.799162f, 0.804381f,
			0.809547f, 0.81466f, 0.81972f, 0.824724f, 0.829673f, 0.834565f, 0.8394f, 0.844177f, 0.848895f, 0.853553f,
			0.858151f, 0.862687f, 0.867161f, 0.871572f, 0.87592f, 0.880203f, 0.884421f, 0.888573f, 0.892658f, 0.896677f,
			0.900627f, 0.904508f, 0.908321f, 0.912063f, 0.915735f, 0.919335f, 0.922864f, 0.92632f, 0.929703f, 0.933013f,
			0.936248f, 0.939409f, 0.942494f, 0.945503f, 0.948436f, 0.951293f, 0.954072f, 0.956773f, 0.959396f, 0.96194f,
			0.964405f, 0.96679f, 0.969096f, 0.971321f, 0.973465f, 0.975528f, 0.97751f, 0.97941f, 0.981228f, 0.982963f,
			0.984615f, 0.986185f, 0.987671f, 0.989074f, 0.990393f, 0.991627f, 0.992778f, 0.993844f, 0.994826f, 0.995722f,
			0.996534f, 0.997261f, 0.997902f, 0.998459f, 0.998929f, 0.999315f, 0.999615f, 0.999829f, 0.999957f, 1f
		};

		internal static readonly int[] tbands = new int[19]
		{
			2, 4, 6, 8, 10, 12, 14, 16, 20, 24,
			28, 32, 40, 48, 56, 68, 80, 96, 120
		};

		internal static readonly int[] extra_bands = new int[22]
		{
			1, 2, 4, 6, 8, 10, 12, 14, 16, 20,
			24, 28, 32, 40, 48, 56, 68, 80, 96, 120,
			160, 200
		};

		internal static readonly float[] weights = new float[422]
		{
			-0.0941125f,
			-0.302976f,
			-0.603555f,
			-0.19393f,
			-0.185983f,
			-0.601617f,
			-0.0465317f,
			-0.114563f,
			-0.103599f,
			-0.618938f,
			-0.317859f,
			-0.169949f,
			-0.0702885f,
			0.148065f,
			0.409524f,
			0.548432f,
			0.367649f,
			-0.494393f,
			0.764306f,
			-1.83957f,
			0.170849f,
			12.786f,
			-1.08848f,
			-1.27284f,
			-16.2606f,
			24.1773f,
			-5.57454f,
			-0.17276f,
			-0.163388f,
			-0.224421f,
			-0.0948944f,
			-0.0728695f,
			-0.26557f,
			-0.100283f,
			-0.0515459f,
			-0.146142f,
			-0.120674f,
			-0.180655f,
			0.12857f,
			0.442138f,
			-0.493735f,
			0.167767f,
			0.206699f,
			-0.197567f,
			0.417999f,
			1.50364f,
			-0.773341f,
			-10.0401f,
			0.401872f,
			2.97966f,
			15.2165f,
			-1.88905f,
			-1.19254f,
			0.0285397f,
			-0.00405139f,
			0.0707565f,
			0.00825699f,
			-0.0927269f,
			-0.010393f,
			-0.00428882f,
			-0.00489743f,
			-0.0709731f,
			-0.00255992f,
			0.0395619f,
			0.226424f,
			0.0325231f,
			0.162175f,
			-0.100118f,
			0.485789f,
			0.12697f,
			0.285937f,
			0.0155637f,
			0.10546f,
			3.05558f,
			1.15059f,
			-1.00904f,
			-1.83088f,
			3.31766f,
			-3.42516f,
			-0.119135f,
			-0.0405654f,
			0.00690068f,
			0.0179877f,
			-0.0382487f,
			0.00597941f,
			-0.0183611f,
			0.00190395f,
			-0.144322f,
			-0.0435671f,
			0.000990594f,
			0.221087f,
			0.142405f,
			0.484066f,
			0.404395f,
			0.511955f,
			-0.237255f,
			0.241742f,
			0.35045f,
			-0.699428f,
			10.3993f,
			2.6507f,
			-2.43459f,
			-4.18838f,
			1.05928f,
			1.71067f,
			0.00667811f,
			-0.0721335f,
			-0.0397346f,
			0.0362704f,
			-0.11496f,
			-0.0235776f,
			0.0082161f,
			-0.0141741f,
			-0.0329699f,
			-0.0354253f,
			0.00277404f,
			-0.290654f,
			-1.14767f,
			-0.319157f,
			-0.686544f,
			0.36897f,
			0.478899f,
			0.182579f,
			-0.411069f,
			0.881104f,
			-4.60683f,
			1.4697f,
			325f / (356f * (float)Math.E),
			-1.81905f,
			-30.1699f,
			5.55225f,
			0.0019508f,
			-0.123576f,
			-0.0727332f,
			-0.0641597f,
			-0.0534458f,
			-0.108166f,
			-0.0937368f,
			-0.0697883f,
			-0.0275475f,
			-0.192309f,
			-0.110074f,
			0.285375f,
			-0.405597f,
			0.0926724f,
			-0.287881f,
			-0.851193f,
			-0.099493f,
			-0.233764f,
			-1.2852f,
			1.13611f,
			3.12168f,
			-0.0699f,
			-1.86216f,
			2.65292f,
			-7.31036f,
			2.44776f,
			-0.00111802f,
			-0.0632786f,
			-0.0376296f,
			-0.149851f,
			0.142963f,
			0.184368f,
			0.123433f,
			0.0756158f,
			0.117312f,
			0.0933395f,
			0.0692163f,
			0.0842592f,
			0.0704683f,
			0.0589963f,
			0.0942205f,
			-0.448862f,
			0.0262677f,
			0.270352f,
			-0.262317f,
			0.172586f,
			2.00227f,
			-0.159216f,
			0.038422f,
			10.2073f,
			4.15536f,
			-2.3407f,
			-0.0550265f,
			0.00964792f,
			-0.141336f,
			0.0274501f,
			0.0343921f,
			-0.0487428f,
			0.0950172f,
			-0.00775017f,
			-0.0372492f,
			-0.00548121f,
			-0.0663695f,
			0.0960506f,
			-0.200008f,
			-0.0412827f,
			0.58728f,
			0.0515787f,
			0.337254f,
			0.855024f,
			0.668371f,
			-0.114904f,
			-3.62962f,
			-0.467477f,
			-0.215472f,
			2.61537f,
			0.406117f,
			-1.36373f,
			0.0425394f,
			0.12208f,
			0.0934502f,
			0.123055f,
			0.0340935f,
			-0.142466f,
			0.035037f,
			-0.0490666f,
			0.0733208f,
			0.0576672f,
			0.123984f,
			-0.0517194f,
			-0.253018f,
			0.590565f,
			0.145849f,
			0.315185f,
			0.221534f,
			-0.149081f,
			0.216161f,
			-0.349575f,
			24.5664f,
			-0.994196f,
			0.614289f,
			-18.7905f,
			-2.83277f,
			-0.716801f,
			-0.347201f,
			0.479515f,
			-0.246027f,
			0.0758683f,
			0.137293f,
			-0.17781f,
			0.118751f,
			-0.00108329f,
			-0.237334f,
			0.355732f,
			-0.12991f,
			-0.0547627f,
			-0.318576f,
			-0.325524f,
			0.180494f,
			-0.0625604f,
			0.141219f,
			0.344064f,
			0.37658f,
			-0.591772f,
			5.8427f,
			-0.38075f,
			0.221894f,
			-1.41934f,
			-1879430f,
			1.34114f,
			0.0283355f,
			-0.0447856f,
			-0.0211466f,
			-0.0256927f,
			0.0139618f,
			0.0207934f,
			-0.0107666f,
			0.0110969f,
			0.0586069f,
			-0.0253545f,
			-0.0328433f,
			0.11872f,
			-0.216943f,
			0.145748f,
			0.119808f,
			-0.0915211f,
			-0.120647f,
			-0.0787719f,
			-0.143644f,
			-0.595116f,
			-1.152f,
			-1.25335f,
			-1.17092f,
			4.34023f,
			-975268f,
			-1.37033f,
			-0.0401123f,
			0.210602f,
			-0.136656f,
			0.135962f,
			-0.0523293f,
			0.0444604f,
			0.0143928f,
			0.00412666f,
			-0.0193003f,
			0.218452f,
			-0.110204f,
			-2.02563f,
			0.918238f,
			-2.45362f,
			1.19542f,
			-0.061362f,
			-1.92243f,
			0.308111f,
			0.49764f,
			0.912356f,
			0.209272f,
			-2.34525f,
			2.19326f,
			-6.47121f,
			1.69771f,
			-0.725123f,
			0.0118929f,
			0.0377944f,
			0.0554003f,
			0.0226452f,
			-0.0704421f,
			-0.0300309f,
			0.0122978f,
			-0.0041782f,
			-0.0686612f,
			0.0313115f,
			0.039111f,
			0.364111f,
			-0.0945548f,
			0.0229876f,
			-0.17414f,
			0.329795f,
			0.114714f,
			0.30022f,
			0.106997f,
			0.132355f,
			5.79932f,
			0.908058f,
			-0.905324f,
			-3.3561f,
			0.190647f,
			0.184211f,
			-0.673648f,
			0.231807f,
			-0.0586222f,
			0.230752f,
			-0.438277f,
			0.245857f,
			-0.17215f,
			0.0876383f,
			-0.720512f,
			0.162515f,
			0.0170571f,
			0.101781f,
			0.388477f,
			1.32931f,
			1.08548f,
			-0.936301f,
			-2.36958f,
			-6.71988f,
			-3.44376f,
			2.13818f,
			14.2318f,
			4.91459f,
			-3.09052f,
			-9.69191f,
			-0.768234f,
			1.79604f,
			0.0549653f,
			0.163399f,
			0.0797025f,
			0.0343933f,
			-0.0555876f,
			-0.00505673f,
			0.0187258f,
			0.0326628f,
			0.0231486f,
			0.15573f,
			0.0476223f,
			-0.254824f,
			1.60155f,
			-0.801221f,
			2.55496f,
			0.737629f,
			-1.36249f,
			-0.695463f,
			-2.44301f,
			-1.73188f,
			3.95279f,
			1.89068f,
			0.486087f,
			-11.3343f,
			3941600f,
			-0.381439f,
			0.12115f,
			-0.906927f,
			2.93878f,
			1.6388f,
			0.882811f,
			0.874344f,
			1.21726f,
			-0.874545f,
			0.321706f,
			0.785055f,
			0.946558f,
			-0.575066f,
			-3.46553f,
			0.884905f,
			0.0924047f,
			-9.90712f,
			0.391338f,
			0.160103f,
			-2.04954f,
			4.1455f,
			0.0684029f,
			-0.144761f,
			-0.285282f,
			0.379244f,
			-1.1584f,
			-0.0277241f,
			-9.85f,
			-4.82386f,
			3.71333f,
			3.87308f,
			3.52558f
		};

		internal static readonly int[] topo = new int[3] { 25, 15, 2 };

		internal static readonly MLP net = new MLP
		{
			layers = 3,
			topo = topo,
			weights = weights
		};

		internal static readonly float[] tansig_table = new float[201]
		{
			0f, 0.039979f, 0.07983f, 0.119427f, 0.158649f, 0.197375f, 0.235496f, 0.272905f, 0.309507f, 0.345214f,
			0.379949f, 0.413644f, 0.446244f, 0.4777f, 0.507977f, 0.53705f, 0.5649f, 0.591519f, 0.616909f, 0.641077f,
			0.664037f, 0.685809f, 0.706419f, 0.725897f, 0.744277f, 0.761594f, 0.777888f, 0.793199f, 0.807569f, 0.82104f,
			0.833655f, 0.845456f, 0.856485f, 0.866784f, 0.876393f, 0.885352f, 0.893698f, 0.901468f, 0.908698f, 0.91542f,
			0.921669f, 0.927473f, 0.932862f, 0.937863f, 0.942503f, 0.946806f, 0.950795f, 0.954492f, 0.957917f, 0.96109f,
			0.964028f, 0.966747f, 0.969265f, 0.971594f, 0.973749f, 0.975743f, 0.977587f, 0.979293f, 0.980869f, 0.982327f,
			0.983675f, 0.984921f, 0.986072f, 0.987136f, 0.988119f, 0.989027f, 0.989867f, 0.990642f, 0.991359f, 0.99202f,
			0.992631f, 0.993196f, 0.993718f, 0.994199f, 0.994644f, 0.995055f, 0.995434f, 0.995784f, 0.996108f, 0.996407f,
			0.996682f, 0.996937f, 0.997172f, 0.997389f, 0.99759f, 0.997775f, 0.997946f, 0.998104f, 0.998249f, 0.998384f,
			0.998508f, 0.998623f, 0.998728f, 0.998826f, 0.998916f, 0.999f, 0.999076f, 0.999147f, 0.999213f, 0.999273f,
			0.999329f, 0.999381f, 0.999428f, 0.999472f, 0.999513f, 0.99955f, 0.999585f, 0.999617f, 0.999646f, 0.999673f,
			0.999699f, 0.999722f, 0.999743f, 0.999763f, 0.999781f, 0.999798f, 0.999813f, 0.999828f, 0.999841f, 0.999853f,
			0.999865f, 0.999875f, 0.999885f, 0.999893f, 0.999902f, 0.999909f, 0.999916f, 0.999923f, 0.999929f, 0.999934f,
			0.999939f, 0.999944f, 0.999948f, 0.999952f, 0.999956f, 0.999959f, 0.999962f, 0.999965f, 0.999968f, 0.99997f,
			0.999973f, 0.999975f, 0.999977f, 0.999978f, 0.99998f, 0.999982f, 0.999983f, 0.999984f, 0.999986f, 0.999987f,
			0.999988f, 0.999989f, 0.99999f, 0.99999f, 0.999991f, 0.999992f, 0.999992f, 0.999993f, 0.999994f, 0.999994f,
			0.999994f, 0.999995f, 0.999995f, 0.999996f, 0.999996f, 0.999996f, 0.999997f, 0.999997f, 0.999997f, 0.999997f,
			0.999997f, 0.999998f, 0.999998f, 0.999998f, 0.999998f, 0.999998f, 0.999998f, 0.999999f, 0.999999f, 0.999999f,
			0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f,
			1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f,
			1f
		};

		internal static readonly int[] mono_voice_bandwidth_thresholds = new int[8] { 11000, 1000, 14000, 1000, 17000, 1000, 21000, 2000 };

		internal static readonly int[] mono_music_bandwidth_thresholds = new int[8] { 12000, 1000, 15000, 1000, 18000, 2000, 22000, 2000 };

		internal static readonly int[] stereo_voice_bandwidth_thresholds = new int[8] { 11000, 1000, 14000, 1000, 21000, 2000, 28000, 2000 };

		internal static readonly int[] stereo_music_bandwidth_thresholds = new int[8] { 12000, 1000, 18000, 2000, 21000, 2000, 30000, 2000 };

		internal const int stereo_voice_threshold = 30000;

		internal const int stereo_music_threshold = 30000;

		internal static readonly int[][] mode_thresholds = new int[2][]
		{
			new int[2] { 64000, 16000 },
			new int[2] { 36000, 16000 }
		};
	}
	public static class ResamplerFactory
	{
		public static IResampler CreateResampler(int numChannels, int inRate, int outRate, int quality, TextWriter logger = null)
		{
			return CreateResampler(numChannels, inRate, outRate, inRate, outRate, quality, logger);
		}

		public static IResampler CreateResampler(int numChannels, int ratioNum, int ratioDen, int inRate, int outRate, int quality, TextWriter logger = null)
		{
			if (numChannels <= 0)
			{
				throw new ArgumentOutOfRangeException("numChannels");
			}
			if (ratioNum <= 0)
			{
				throw new ArgumentOutOfRangeException("ratioNum");
			}
			if (ratioDen <= 0)
			{
				throw new ArgumentOutOfRangeException("ratioDen");
			}
			if (inRate <= 0)
			{
				throw new ArgumentOutOfRangeException("inRate");
			}
			if (outRate <= 0)
			{
				throw new ArgumentOutOfRangeException("outRate");
			}
			if (quality < 0 || quality > 10)
			{
				throw new ArgumentOutOfRangeException("quality", "Quality must be between 0 and 10");
			}
			return new SpeexResampler(numChannels, ratioNum, ratioDen, inRate, outRate, quality);
		}
	}
}
namespace Concentus.Silk
{
	internal static class ApplySineWindow
	{
		private static readonly short[] freq_table_Q16 = new short[27]
		{
			12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202, 3885,
			3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422, 2313, 2214,
			2123, 2038, 1961, 1889, 1822, 1760, 1702
		};

		internal static void silk_apply_sine_window(short[] px_win, int px_win_ptr, short[] px, int px_ptr, int win_type, int length)
		{
			int num = (length >> 2) - 4;
			int num2 = freq_table_Q16[num];
			int num3 = Inlines.silk_SMULWB(num2, -num2);
			int num4;
			int num5;
			if (win_type == 1)
			{
				num4 = 0;
				num5 = num2 + Inlines.silk_RSHIFT(length, 3);
			}
			else
			{
				num4 = 65536;
				num5 = 65536 + Inlines.silk_RSHIFT(num3, 1) + Inlines.silk_RSHIFT(length, 4);
			}
			for (num = 0; num < length; num += 4)
			{
				int num6 = px_win_ptr + num;
				int num7 = px_ptr + num;
				px_win[num6] = (short)Inlines.silk_SMULWB(Inlines.silk_RSHIFT(num4 + num5, 1), px[num7]);
				px_win[num6 + 1] = (short)Inlines.silk_SMULWB(num5, px[num7 + 1]);
				num4 = Inlines.silk_SMULWB(num5, num3) + Inlines.silk_LSHIFT(num5, 1) - num4 + 1;
				num4 = Inlines.silk_min(num4, 65536);
				px_win[num6 + 2] = (short)Inlines.silk_SMULWB(Inlines.silk_RSHIFT(num4 + num5, 1), px[num7 + 2]);
				px_win[num6 + 3] = (short)Inlines.silk_SMULWB(num4, px[num7 + 3]);
				num5 = Inlines.silk_SMULWB(num4, num3) + Inlines.silk_LSHIFT(num4, 1) - num5;
				num5 = Inlines.silk_min(num5, 65536);
			}
		}
	}
	internal static class BurgModified
	{
		private const int MAX_FRAME_SIZE = 384;

		private const int QA = 25;

		private const int N_BITS_HEAD_ROOM = 2;

		private const int MIN_RSHIFTS = -16;

		private const int MAX_RSHIFTS = 7;

		internal static void silk_burg_modified(BoxedValueInt res_nrg, BoxedValueInt res_nrg_Q, int[] A_Q16, short[] x, int x_ptr, int minInvGain_Q30, int subfr_length, int nb_subfr, int D)
		{
			int[] array = new int[16];
			int[] array2 = new int[16];
			int[] array3 = new int[16];
			int[] array4 = new int[17];
			int[] array5 = new int[17];
			int[] array6 = new int[16];
			long num = Inlines.silk_inner_prod16_aligned_64(x, x_ptr, x, x_ptr, subfr_length * nb_subfr);
			int num2 = Inlines.silk_CLZ64(num);
			int num3 = 35 - num2;
			if (num3 > 7)
			{
				num3 = 7;
			}
			if (num3 < -16)
			{
				num3 = -16;
			}
			int num4 = (int)((num3 <= 0) ? Inlines.silk_LSHIFT32((int)num, -num3) : Inlines.silk_RSHIFT64(num, num3));
			array5[0] = (array4[0] = num4 + Inlines.silk_SMMUL(42950, num4) + 1);
			Arrays.MemSetInt(array, 0, 16);
			if (num3 > 0)
			{
				for (int i = 0; i < nb_subfr; i++)
				{
					int num5 = x_ptr + i * subfr_length;
					for (int j = 1; j < D + 1; j++)
					{
						array[j - 1] += (int)Inlines.silk_RSHIFT64(Inlines.silk_inner_prod16_aligned_64(x, num5, x, num5 + j, subfr_length - j), num3);
					}
				}
			}
			else
			{
				for (int i = 0; i < nb_subfr; i++)
				{
					int num5 = x_ptr + i * subfr_length;
					CeltPitchXCorr.pitch_xcorr(x, num5, x, num5 + 1, array6, subfr_length - D, D);
					for (int j = 1; j < D + 1; j++)
					{
						int k = j + subfr_length - D;
						int num6 = 0;
						for (; k < subfr_length; k++)
						{
							num6 = Inlines.MAC16_16(num6, x[num5 + k], x[num5 + k - j]);
						}
						array6[j - 1] += num6;
					}
					for (int j = 1; j < D + 1; j++)
					{
						array[j - 1] += Inlines.silk_LSHIFT32(array6[j - 1], -num3);
					}
				}
			}
			Arrays.MemCopy(array, 0, array2, 0, 16);
			array5[0] = (array4[0] = num4 + Inlines.silk_SMMUL(42950, num4) + 1);
			int num7 = 1073741824;
			int num8 = 0;
			for (int j = 0; j < D; j++)
			{
				int num9;
				int num10;
				if (num3 > -2)
				{
					for (int i = 0; i < nb_subfr; i++)
					{
						int num5 = x_ptr + i * subfr_length;
						int b = -Inlines.silk_LSHIFT32(x[num5 + j], 16 - num3);
						int b2 = -Inlines.silk_LSHIFT32(x[num5 + subfr_length - j - 1], 16 - num3);
						num9 = Inlines.silk_LSHIFT32(x[num5 + j], 9);
						num10 = Inlines.silk_LSHIFT32(x[num5 + subfr_length - j - 1], 9);
						for (int l = 0; l < j; l++)
						{
							array[l] = Inlines.silk_SMLAWB(array[l], b, x[num5 + j - l - 1]);
							array2[l] = Inlines.silk_SMLAWB(array2[l], b2, x[num5 + subfr_length - j + l]);
							int b3 = array3[l];
							num9 = Inlines.silk_SMLAWB(num9, b3, x[num5 + j - l - 1]);
							num10 = Inlines.silk_SMLAWB(num10, b3, x[num5 + subfr_length - j + l]);
						}
						num9 = Inlines.silk_LSHIFT32(-num9, 7 - num3);
						num10 = Inlines.silk_LSHIFT32(-num10, 7 - num3);
						for (int l = 0; l <= j; l++)
						{
							array4[l] = Inlines.silk_SMLAWB(array4[l], num9, x[num5 + j - l]);
							array5[l] = Inlines.silk_SMLAWB(array5[l], num10, x[num5 + subfr_length - j + l - 1]);
						}
					}
				}
				else
				{
					for (int i = 0; i < nb_subfr; i++)
					{
						int num5 = x_ptr + i * subfr_length;
						int b = -Inlines.silk_LSHIFT32(x[num5 + j], -num3);
						int b2 = -Inlines.silk_LSHIFT32(x[num5 + subfr_length - j - 1], -num3);
						num9 = Inlines.silk_LSHIFT32(x[num5 + j], 17);
						num10 = Inlines.silk_LSHIFT32(x[num5 + subfr_length - j - 1], 17);
						for (int l = 0; l < j; l++)
						{
							array[l] = Inlines.silk_MLA(array[l], b, x[num5 + j - l - 1]);
							array2[l] = Inlines.silk_MLA(array2[l], b2, x[num5 + subfr_length - j + l]);
							int c = Inlines.silk_RSHIFT_ROUND(array3[l], 8);
							num9 = Inlines.silk_MLA(num9, x[num5 + j - l - 1], c);
							num10 = Inlines.silk_MLA(num10, x[num5 + subfr_length - j + l], c);
						}
						num9 = -num9;
						num10 = -num10;
						for (int l = 0; l <= j; l++)
						{
							array4[l] = Inlines.silk_SMLAWW(array4[l], num9, Inlines.silk_LSHIFT32(x[num5 + j - l], -num3 - 1));
							array5[l] = Inlines.silk_SMLAWW(array5[l], num10, Inlines.silk_LSHIFT32(x[num5 + subfr_length - j + l - 1], -num3 - 1));
						}
					}
				}
				num9 = array[j];
				num10 = array2[j];
				int a = 0;
				int num11 = Inlines.silk_ADD32(array5[0], array4[0]);
				for (int l = 0; l < j; l++)
				{
					int b3 = array3[l];
					num2 = Inlines.silk_CLZ32(Inlines.silk_abs(b3)) - 1;
					num2 = Inlines.silk_min(7, num2);
					int c = Inlines.silk_LSHIFT32(b3, num2);
					num9 = Inlines.silk_ADD_LSHIFT32(num9, Inlines.silk_SMMUL(array2[j - l - 1], c), 7 - num2);
					num10 = Inlines.silk_ADD_LSHIFT32(num10, Inlines.silk_SMMUL(array[j - l - 1], c), 7 - num2);
					a = Inlines.silk_ADD_LSHIFT32(a, Inlines.silk_SMMUL(array5[j - l], c), 7 - num2);
					num11 = Inlines.silk_ADD_LSHIFT32(num11, Inlines.silk_SMMUL(Inlines.silk_ADD32(array5[l + 1], array4[l + 1]), c), 7 - num2);
				}
				array4[j + 1] = num9;
				array5[j + 1] = num10;
				a = Inlines.silk_ADD32(a, num10);
				a = Inlines.silk_LSHIFT32(-a, 1);
				int num12 = ((Inlines.silk_abs(a) >= num11) ? ((a > 0) ? int.MaxValue : int.MinValue) : Inlines.silk_DIV32_varQ(a, num11, 31));
				num9 = 1073741824 - Inlines.silk_SMMUL(num12, num12);
				num9 = Inlines.silk_LSHIFT(Inlines.silk_SMMUL(num7, num9), 2);
				if (num9 <= minInvGain_Q30)
				{
					num10 = 1073741824 - Inlines.silk_DIV32_varQ(minInvGain_Q30, num7, 30);
					num12 = Inlines.silk_SQRT_APPROX(num10);
					num12 = Inlines.silk_RSHIFT32(num12 + Inlines.silk_DIV32(num10, num12), 1);
					num12 = Inlines.silk_LSHIFT32(num12, 16);
					if (a < 0)
					{
						num12 = -num12;
					}
					num7 = minInvGain_Q30;
					num8 = 1;
				}
				else
				{
					num7 = num9;
				}
				for (int l = 0; l < j + 1 >> 1; l++)
				{
					num9 = array3[l];
					num10 = array3[j - l - 1];
					array3[l] = Inlines.silk_ADD_LSHIFT32(num9, Inlines.silk_SMMUL(num10, num12), 1);
					array3[j - l - 1] = Inlines.silk_ADD_LSHIFT32(num10, Inlines.silk_SMMUL(num9, num12), 1);
				}
				array3[j] = Inlines.silk_RSHIFT32(num12, 6);
				if (num8 != 0)
				{
					for (int l = j + 1; l < D; l++)
					{
						array3[l] = 0;
					}
					break;
				}
				for (int l = 0; l <= j + 1; l++)
				{
					num9 = array4[l];
					num10 = array5[j - l + 1];
					array4[l] = Inlines.silk_ADD_LSHIFT32(num9, Inlines.silk_SMMUL(num10, num12), 1);
					array5[j - l + 1] = Inlines.silk_ADD_LSHIFT32(num10, Inlines.silk_SMMUL(num9, num12), 1);
				}
			}
			if (num8 != 0)
			{
				for (int l = 0; l < D; l++)
				{
					A_Q16[l] = -Inlines.silk_RSHIFT_ROUND(array3[l], 9);
				}
				if (num3 > 0)
				{
					for (int i = 0; i < nb_subfr; i++)
					{
						int num5 = x_ptr + i * subfr_length;
						num4 -= (int)Inlines.silk_RSHIFT64(Inlines.silk_inner_prod16_aligned_64(x, num5, x, num5, D), num3);
					}
				}
				else
				{
					for (int i = 0; i < nb_subfr; i++)
					{
						int num5 = x_ptr + i * subfr_length;
						num4 -= Inlines.silk_LSHIFT32(Inlines.silk_inner_prod_self(x, num5, D), -num3);
					}
				}
				res_nrg.Val = Inlines.silk_LSHIFT(Inlines.silk_SMMUL(num7, num4), 2);
				res_nrg_Q.Val = -num3;
			}
			else
			{
				int num11 = array4[0];
				int num9 = 65536;
				for (int l = 0; l < D; l++)
				{
					int c = Inlines.silk_RSHIFT_ROUND(array3[l], 9);
					num11 = Inlines.silk_SMLAWW(num11, array4[l + 1], c);
					num9 = Inlines.silk_SMLAWW(num9, c, c);
					A_Q16[l] = -c;
				}
				res_nrg.Val = Inlines.silk_SMLAWW(num11, Inlines.silk_SMMUL(42950, num4), -num9);
				res_nrg_Q.Val = -num3;
			}
		}
	}
	internal static class BWExpander
	{
		internal static void silk_bwexpander_32(int[] ar, int d, int chirp_Q16)
		{
			int b = chirp_Q16 - 65536;
			for (int i = 0; i < d - 1; i++)
			{
				ar[i] = Inlines.silk_SMULWW(chirp_Q16, ar[i]);
				chirp_Q16 += Inlines.silk_RSHIFT_ROUND(Inlines.silk_MUL(chirp_Q16, b), 16);
			}
			ar[d - 1] = Inlines.silk_SMULWW(chirp_Q16, ar[d - 1]);
		}

		internal static void silk_bwexpander(short[] ar, int d, int chirp_Q16)
		{
			int b = chirp_Q16 - 65536;
			for (int i = 0; i < d - 1; i++)
			{
				ar[i] = (short)Inlines.silk_RSHIFT_ROUND(Inlines.silk_MUL(chirp_Q16, ar[i]), 16);
				chirp_Q16 += Inlines.silk_RSHIFT_ROUND(Inlines.silk_MUL(chirp_Q16, b), 16);
			}
			ar[d - 1] = (short)Inlines.silk_RSHIFT_ROUND(Inlines.silk_MUL(chirp_Q16, ar[d - 1]), 16);
		}
	}
	internal static class CNG
	{
		internal static void silk_CNG_exc(Span<int> exc_Q10, int exc_Q10_ptr, int[] exc_buf_Q14, int Gain_Q16, int length, ref int rand_seed)
		{
			int num;
			for (num = 255; num > length; num = Inlines.silk_RSHIFT(num, 1))
			{
			}
			int num2 = rand_seed;
			for (int i = exc_Q10_ptr; i < exc_Q10_ptr + length; i++)
			{
				num2 = Inlines.silk_RAND(num2);
				int num3 = Inlines.silk_RSHIFT(num2, 24) & num;
				exc_Q10[i] = (short)Inlines.silk_SAT16(Inlines.silk_SMULWW(exc_buf_Q14[num3], Gain_Q16 >> 4));
			}
			rand_seed = num2;
		}

		internal static void silk_CNG_Reset(SilkChannelDecoder psDec)
		{
			int num = Inlines.silk_DIV32_16(32767, (short)(psDec.LPC_order + 1));
			int num2 = 0;
			for (int i = 0; i < psDec.LPC_order; i++)
			{
				num2 += num;
				psDec.sCNG.CNG_smth_NLSF_Q15[i] = (short)num2;
			}
			psDec.sCNG.CNG_smth_Gain_Q16 = 0;
			psDec.sCNG.rand_seed = 3176576;
		}

		internal static void silk_CNG(SilkChannelDecoder psDec, SilkDecoderControl psDecCtrl, Span<short> frame, int frame_ptr, int length)
		{
			short[] array = new short[psDec.LPC_order];
			CNGState sCNG = psDec.sCNG;
			if (psDec.fs_kHz != sCNG.fs_kHz)
			{
				silk_CNG_Reset(psDec);
				sCNG.fs_kHz = psDec.fs_kHz;
			}
			if (psDec.lossCnt == 0 && psDec.prevSignalType == 0)
			{
				for (int i = 0; i < psDec.LPC_order; i++)
				{
					sCNG.CNG_smth_NLSF_Q15[i] += (short)Inlines.silk_SMULWB(psDec.prevNLSF_Q15[i] - sCNG.CNG_smth_NLSF_Q15[i], 16348);
				}
				int num = 0;
				for (int i = 0; i < psDec.nb_subfr; i++)
				{
					if (psDecCtrl.Gains_Q16[i] > num)
					{
						num = psDecCtrl.Gains_Q16[i];
					}
				}
				Arrays.MemMoveInt(sCNG.CNG_exc_buf_Q14, 0, psDec.subfr_length, (psDec.nb_subfr - 1) * psDec.subfr_length);
				for (int i = 0; i < psDec.nb_subfr; i++)
				{
					sCNG.CNG_smth_Gain_Q16 += Inlines.silk_SMULWB(psDecCtrl.Gains_Q16[i] - sCNG.CNG_smth_Gain_Q16, 4634);
				}
			}
			if (psDec.lossCnt != 0)
			{
				int[] array2 = new int[length + 16];
				int num2 = Inlines.silk_SMULWW(psDec.sPLC.randScale_Q14, psDec.sPLC.prevGain_Q16[1]);
				if (num2 >= 2097152 || sCNG.CNG_smth_Gain_Q16 > 8388608)
				{
					num2 = Inlines.silk_SMULTT(num2, num2);
					num2 = Inlines.silk_SUB_LSHIFT32(Inlines.silk_SMULTT(sCNG.CNG_smth_Gain_Q16, sCNG.CNG_smth_Gain_Q16), num2, 5);
					num2 = Inlines.silk_LSHIFT32(Inlines.silk_SQRT_APPROX(num2), 16);
				}
				else
				{
					num2 = Inlines.silk_SMULWW(num2, num2);
					num2 = Inlines.silk_SUB_LSHIFT32(Inlines.silk_SMULWW(sCNG.CNG_smth_Gain_Q16, sCNG.CNG_smth_Gain_Q16), num2, 5);
					num2 = Inlines.silk_LSHIFT32(Inlines.silk_SQRT_APPROX(num2), 8);
				}
				silk_CNG_exc(array2, 16, sCNG.CNG_exc_buf_Q14, num2, length, ref sCNG.rand_seed);
				NLSF.silk_NLSF2A(array, sCNG.CNG_smth_NLSF_Q15, psDec.LPC_order);
				Arrays.MemCopy(sCNG.CNG_synth_state, 0, array2, 0, 16);
				for (int i = 0; i < length; i++)
				{
					int num3 = 16 + i;
					int a = Inlines.silk_RSHIFT(psDec.LPC_order, 1);
					a = Inlines.silk_SMLAWB(a, array2[num3 - 1], array[0]);
					a = Inlines.silk_SMLAWB(a, array2[num3 - 2], array[1]);
					a = Inlines.silk_SMLAWB(a, array2[num3 - 3], array[2]);
					a = Inlines.silk_SMLAWB(a, array2[num3 - 4], array[3]);
					a = Inlines.silk_SMLAWB(a, array2[num3 - 5], array[4]);
					a = Inlines.silk_SMLAWB(a, array2[num3 - 6], array[5]);
					a = Inlines.silk_SMLAWB(a, array2[num3 - 7], array[6]);
					a = Inlines.silk_SMLAWB(a, array2[num3 - 8], array[7]);
					a = Inlines.silk_SMLAWB(a, array2[num3 - 9], array[8]);
					a = Inlines.silk_SMLAWB(a, array2[num3 - 10], array[9]);
					if (psDec.LPC_order == 16)
					{
						a = Inlines.silk_SMLAWB(a, array2[num3 - 11], array[10]);
						a = Inlines.silk_SMLAWB(a, array2[num3 - 12], array[11]);
						a = Inlines.silk_SMLAWB(a, array2[num3 - 13], array[12]);
						a = Inlines.silk_SMLAWB(a, array2[num3 - 14], array[13]);
						a = Inlines.silk_SMLAWB(a, array2[num3 - 15], array[14]);
						a = Inlines.silk_SMLAWB(a, array2[num3 - 16], array[15]);
					}
					array2[num3] = Inlines.silk_ADD_LSHIFT(array2[num3], a, 4);
					frame[frame_ptr + i] = Inlines.silk_ADD_SAT16(frame[frame_ptr + i], (short)Inlines.silk_RSHIFT_ROUND(array2[num3], 10));
				}
				Arrays.MemCopy(array2, length, sCNG.CNG_synth_state, 0, 16);
			}
			else
			{
				Arrays.MemSetInt(sCNG.CNG_synth_state, 0, psDec.LPC_order);
			}
		}
	}
	internal static class CodeSigns
	{
		private static int silk_enc_map(int a)
		{
			return Inlines.silk_RSHIFT(a, 15) + 1;
		}

		private static int silk_dec_map(int a)
		{
			return Inlines.silk_LSHIFT(a, 1) - 1;
		}

		internal static void silk_encode_signs(EntropyCoder psRangeEnc, Span<byte> encodedData, Span<sbyte> pulses, int length, int signalType, int quantOffsetType, int[] sum_pulses)
		{
			byte[] array = new byte[2];
			byte[] silk_sign_iCDF = Tables.silk_sign_iCDF;
			array[1] = 0;
			int num = 0;
			int num2 = Inlines.silk_SMULBB(7, Inlines.silk_ADD_LSHIFT(quantOffsetType, signalType, 1));
			int num3 = num2;
			length = Inlines.silk_RSHIFT(length + 8, 4);
			for (num2 = 0; num2 < length; num2++)
			{
				int num4 = sum_pulses[num2];
				if (num4 > 0)
				{
					array[0] = silk_sign_iCDF[num3 + Inlines.silk_min(num4 & 0x1F, 6)];
					for (int i = num; i < num + 16; i++)
					{
						if (pulses[i] != 0)
						{
							psRangeEnc.enc_icdf(encodedData, silk_enc_map(pulses[i]), array, 8u);
						}
					}
				}
				num += 16;
			}
		}

		internal static void silk_decode_signs(EntropyCoder psRangeDec, ReadOnlySpan<byte> encodedData, short[] pulses, int length, int signalType, int quantOffsetType, int[] sum_pulses)
		{
			byte[] array = new byte[2];
			byte[] silk_sign_iCDF = Tables.silk_sign_iCDF;
			array[1] = 0;
			int num = 0;
			int num2 = Inlines.silk_SMULBB(7, Inlines.silk_ADD_LSHIFT(quantOffsetType, signalType, 1));
			int num3 = num2;
			length = Inlines.silk_RSHIFT(length + 8, 4);
			for (num2 = 0; num2 < length; num2++)
			{
				int num4 = sum_pulses[num2];
				if (num4 > 0)
				{
					array[0] = silk_sign_iCDF[num3 + Inlines.silk_min(num4 & 0x1F, 6)];
					for (int i = 0; i < 16; i++)
					{
						if (pulses[num + i] > 0)
						{
							pulses[num + i] *= (short)silk_dec_map(psRangeDec.dec_icdf(encodedData, array, 8u));
						}
					}
				}
				num += 16;
			}
		}
	}
	internal static class CorrelateMatrix
	{
		internal static void silk_corrVector(short[] x, int x_ptr, short[] t, int t_ptr, int L, int order, int[] Xt, int rshifts)
		{
			int num = x_ptr + order - 1;
			if (rshifts > 0)
			{
				for (int i = 0; i < order; i++)
				{
					int num2 = 0;
					for (int j = 0; j < L; j++)
					{
						num2 += Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[num + j], t[t_ptr + j]), rshifts);
					}
					Xt[i] = num2;
					num--;
				}
			}
			else
			{
				for (int i = 0; i < order; i++)
				{
					Xt[i] = Inlines.silk_inner_prod(x, num, t, t_ptr, L);
					num--;
				}
			}
		}

		internal static void silk_corrMatrix(short[] x, int x_ptr, int L, int order, int head_room, int[] XX, int XX_ptr, BoxedValueInt rshifts)
		{
			SumSqrShift.silk_sum_sqr_shift(out var energy, out var shift, x, x_ptr, L + order - 1);
			int num = Inlines.silk_max(head_room - Inlines.silk_CLZ32(energy), 0);
			energy = Inlines.silk_RSHIFT32(energy, num);
			shift += num;
			for (int i = x_ptr; i < x_ptr + order - 1; i++)
			{
				energy -= Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[i], x[i]), shift);
			}
			if (shift < rshifts.Val)
			{
				energy = Inlines.silk_RSHIFT32(energy, rshifts.Val - shift);
				shift = rshifts.Val;
			}
			Inlines.MatrixSet(XX, XX_ptr, 0, 0, order, energy);
			int num2 = x_ptr + order - 1;
			for (int j = 1; j < order; j++)
			{
				energy = Inlines.silk_SUB32(energy, Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[num2 + L - j], x[num2 + L - j]), shift));
				energy = Inlines.silk_ADD32(energy, Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[num2 - j], x[num2 - j]), shift));
				Inlines.MatrixSet(XX, XX_ptr, j, j, order, energy);
			}
			int num3 = x_ptr + order - 2;
			if (shift > 0)
			{
				for (int k = 1; k < order; k++)
				{
					energy = 0;
					for (int i = 0; i < L; i++)
					{
						energy += Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[num2 + i], x[num3 + i]), shift);
					}
					Inlines.MatrixSet(XX, XX_ptr, k, 0, order, energy);
					Inlines.MatrixSet(XX, XX_ptr, 0, k, order, energy);
					for (int j = 1; j < order - k; j++)
					{
						energy = Inlines.silk_SUB32(energy, Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[num2 + L - j], x[num3 + L - j]), shift));
						energy = Inlines.silk_ADD32(energy, Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[num2 - j], x[num3 - j]), shift));
						Inlines.MatrixSet(XX, XX_ptr, k + j, j, order, energy);
						Inlines.MatrixSet(XX, XX_ptr, j, k + j, order, energy);
					}
					num3--;
				}
			}
			else
			{
				for (int k = 1; k < order; k++)
				{
					energy = Inlines.silk_inner_prod(x, num2, x, num3, L);
					Inlines.MatrixSet(XX, XX_ptr, k, 0, order, energy);
					Inlines.MatrixSet(XX, XX_ptr, 0, k, order, energy);
					for (int j = 1; j < order - k; j++)
					{
						energy = Inlines.silk_SUB32(energy, Inlines.silk_SMULBB(x[num2 + L - j], x[num3 + L - j]));
						energy = Inlines.silk_SMLABB(energy, x[num2 - j], x[num3 - j]);
						Inlines.MatrixSet(XX, XX_ptr, k + j, j, order, energy);
						Inlines.MatrixSet(XX, XX_ptr, j, k + j, order, energy);
					}
					num3--;
				}
			}
			rshifts.Val = shift;
		}
	}
	internal static class DecodeAPI
	{
		internal static int silk_InitDecoder(SilkDecoder decState)
		{
			decState.Reset();
			int result = SilkError.SILK_NO_ERROR;
			SilkChannelDecoder[] channel_state = decState.channel_state;
			for (int i = 0; i < 2; i++)
			{
				result = channel_state[i].silk_init_decoder();
			}
			decState.sStereo.Reset();
			decState.prev_decode_only_middle = 0;
			return result;
		}

		internal static int silk_Decode(SilkDecoder psDec, DecControlState decControl, ReadOnlySpan<byte> frameData, int lostFlag, int newPacketFlag, EntropyCoder psRangeDec, Span<short> samplesOut, int samplesOut_ptr, out int nSamplesOut)
		{
			int num = 0;
			int num2 = SilkError.SILK_NO_ERROR;
			BoxedValueInt boxedValueInt = new BoxedValueInt();
			int[] array = new int[2];
			int[] array2 = new int[2];
			SilkChannelDecoder[] channel_state = psDec.channel_state;
			nSamplesOut = 0;
			if (newPacketFlag != 0)
			{
				for (int i = 0; i < decControl.nChannelsInternal; i++)
				{
					channel_state[i].nFramesDecoded = 0;
				}
			}
			if (decControl.nChannelsInternal > psDec.nChannelsInternal)
			{
				num2 += channel_state[1].silk_init_decoder();
			}
			int num3 = ((decControl.nChannelsInternal == 1 && psDec.nChannelsInternal == 2 && decControl.internalSampleRate == 1000 * channel_state[0].fs_kHz) ? 1 : 0);
			if (channel_state[0].nFramesDecoded == 0)
			{
				for (int i = 0; i < decControl.nChannelsInternal; i++)
				{
					if (decControl.payloadSize_ms == 0)
					{
						channel_state[i].nFramesPerPacket = 1;
						channel_state[i].nb_subfr = 2;
					}
					else if (decControl.payloadSize_ms == 10)
					{
						channel_state[i].nFramesPerPacket = 1;
						channel_state[i].nb_subfr = 2;
					}
					else if (decControl.payloadSize_ms == 20)
					{
						channel_state[i].nFramesPerPacket = 1;
						channel_state[i].nb_subfr = 4;
					}
					else if (decControl.payloadSize_ms == 40)
					{
						channel_state[i].nFramesPerPacket = 2;
						channel_state[i].nb_subfr = 4;
					}
					else
					{
						if (decControl.payloadSize_ms != 60)
						{
							return SilkError.SILK_DEC_INVALID_FRAME_SIZE;
						}
						channel_state[i].nFramesPerPacket = 3;
						channel_state[i].nb_subfr = 4;
					}
					int num4 = (decControl.internalSampleRate >> 10) + 1;
					if (num4 != 8 && num4 != 12 && num4 != 16)
					{
						return SilkError.SILK_DEC_INVALID_SAMPLING_FREQUENCY;
					}
					num2 += channel_state[i].silk_decoder_set_fs(num4, decControl.API_sampleRate);
				}
			}
			if (decControl.nChannelsAPI == 2 && decControl.nChannelsInternal == 2 && (psDec.nChannelsAPI == 1 || psDec.nChannelsInternal == 1))
			{
				Arrays.MemSetShort(psDec.sStereo.pred_prev_Q13, 0, 2);
				Arrays.MemSetShort(psDec.sStereo.sSide, 0, 2);
				channel_state[1].resampler_state.Assign(channel_state[0].resampler_state);
			}
			psDec.nChannelsAPI = decControl.nChannelsAPI;
			psDec.nChannelsInternal = decControl.nChannelsInternal;
			if (decControl.API_sampleRate > 48000 || decControl.API_sampleRate < 8000)
			{
				return SilkError.SILK_DEC_INVALID_SAMPLING_FREQUENCY;
			}
			if (lostFlag != 1 && channel_state[0].nFramesDecoded == 0)
			{
				for (int i = 0; i < decControl.nChannelsInternal; i++)
				{
					for (int j = 0; j < channel_state[i].nFramesPerPacket; j++)
					{
						channel_state[i].VAD_flags[j] = psRangeDec.dec_bit_logp(frameData, 1u);
					}
					channel_state[i].LBRR_flag = psRangeDec.dec_bit_logp(frameData, 1u);
				}
				for (int i = 0; i < decControl.nChannelsInternal; i++)
				{
					Arrays.MemSetInt(channel_state[i].LBRR_flags, 0, 3);
					if (channel_state[i].LBRR_flag == 0)
					{
						continue;
					}
					if (channel_state[i].nFramesPerPacket == 1)
					{
						channel_state[i].LBRR_flags[0] = 1;
						continue;
					}
					int a = psRangeDec.dec_icdf(frameData, Tables.silk_LBRR_flags_iCDF_ptr[channel_state[i].nFramesPerPacket - 2], 8u) + 1;
					for (int j = 0; j < channel_state[i].nFramesPerPacket; j++)
					{
						channel_state[i].LBRR_flags[j] = Inlines.silk_RSHIFT(a, j) & 1;
					}
				}
				if (lostFlag == 0)
				{
					for (int j = 0; j < channel_state[0].nFramesPerPacket; j++)
					{
						for (int i = 0; i < decControl.nChannelsInternal; i++)
						{
							if (channel_state[i].LBRR_flags[j] == 0)
							{
								continue;
							}
							short[] pulses = new short[320];
							if (decControl.nChannelsInternal == 2 && i == 0)
							{
								Stereo.silk_stereo_decode_pred(psRangeDec, frameData, array2);
								if (channel_state[1].LBRR_flags[j] == 0)
								{
									BoxedValueInt boxedValueInt2 = new BoxedValueInt(num);
									Stereo.silk_stereo_decode_mid_only(psRangeDec, frameData, boxedValueInt2);
									num = boxedValueInt2.Val;
								}
							}
							DecodeIndices.silk_decode_indices(condCoding: (j > 0 && channel_state[i].LBRR_flags[j - 1] != 0) ? 2 : 0, psDec: channel_state[i], psRangeDec: psRangeDec, frameData: frameData, FrameIndex: j, decode_LBRR: 1);
							DecodePulses.silk_decode_pulses(psRangeDec, frameData, pulses, channel_state[i].indices.signalType, channel_state[i].indices.quantOffsetType, channel_state[i].frame_length);
						}
					}
				}
			}
			if (decControl.nChannelsInternal == 2)
			{
				if (lostFlag == 0 || (lostFlag == 2 && channel_state[0].LBRR_flags[channel_state[0].nFramesDecoded] == 1))
				{
					Stereo.silk_stereo_decode_pred(psRangeDec, frameData, array2);
					if ((lostFlag == 0 && channel_state[1].VAD_flags[channel_state[0].nFramesDecoded] == 0) || (lostFlag == 2 && channel_state[1].LBRR_flags[channel_state[0].nFramesDecoded] == 0))
					{
						BoxedValueInt boxedValueInt3 = new BoxedValueInt(num);
						Stereo.silk_stereo_decode_mid_only(psRangeDec, frameData, boxedValueInt3);
						num = boxedValueInt3.Val;
					}
					else
					{
						num = 0;
					}
				}
				else
				{
					for (int i = 0; i < 2; i++)
					{
						array2[i] = psDec.sStereo.pred_prev_Q13[i];
					}
				}
			}
			if (decControl.nChannelsInternal == 2 && num == 0 && psDec.prev_decode_only_middle == 1)
			{
				Arrays.MemSetShort(psDec.channel_state[1].outBuf, 0, 480);
				Arrays.MemSetInt(psDec.channel_state[1].sLPC_Q14_buf, 0, 16);
				psDec.channel_state[1].lagPrev = 100;
				psDec.channel_state[1].LastGainIndex = 10;
				psDec.channel_state[1].prevSignalType = 0;
				psDec.channel_state[1].first_frame_after_reset = 1;
			}
			int num5 = ((decControl.internalSampleRate * decControl.nChannelsInternal < decControl.API_sampleRate * decControl.nChannelsAPI) ? 1 : 0);
			Span<short> span;
			if (num5 != 0)
			{
				span = samplesOut;
				array[0] = samplesOut_ptr;
				array[1] = samplesOut_ptr + channel_state[0].frame_length + 2;
			}
			else
			{
				span = new short[decControl.nChannelsInternal * (channel_state[0].frame_length + 2)];
				array[0] = 0;
				array[1] = channel_state[0].frame_length + 2;
			}
			int num6 = ((lostFlag != 0) ? ((psDec.prev_decode_only_middle == 0 || (decControl.nChannelsInternal == 2 && lostFlag == 2 && channel_state[1].LBRR_flags[channel_state[1].nFramesDecoded] == 1)) ? 1 : 0) : ((num == 0) ? 1 : 0));
			for (int i = 0; i < decControl.nChannelsInternal; i++)
			{
				if (i == 0 || num6 != 0)
				{
					int num7 = channel_state[0].nFramesDecoded - i;
					int condCoding2 = ((num7 > 0) ? ((lostFlag == 2) ? ((channel_state[i].LBRR_flags[num7 - 1] != 0) ? 2 : 0) : ((i > 0 && psDec.prev_decode_only_middle != 0) ? 1 : 2)) : 0);
					num2 += channel_state[i].silk_decode_frame(psRangeDec, frameData, span, array[i] + 2, boxedValueInt, lostFlag, condCoding2);
				}
				else
				{
					Arrays.MemSetWithOffset<short>(span, 0, array[i] + 2, boxedValueInt.Val);
				}
				channel_state[i].nFramesDecoded++;
			}
			if (decControl.nChannelsAPI == 2 && decControl.nChannelsInternal == 2)
			{
				Stereo.silk_stereo_MS_to_LR(psDec.sStereo, span, array[0], span, array[1], array2, channel_state[0].fs_kHz, boxedValueInt.Val);
			}
			else
			{
				psDec.sStereo.sMid.AsSpan(0, 2).CopyTo(span.Slice(array[0]));
				span.Slice(array[0] + boxedValueInt.Val, 2).CopyTo(psDec.sStereo.sMid);
			}
			nSamplesOut = Inlines.silk_DIV32(boxedValueInt.Val * decControl.API_sampleRate, Inlines.silk_SMULBB(channel_state[0].fs_kHz, 1000));
			Span<short> output;
			int num8;
			if (decControl.nChannelsAPI == 2)
			{
				output = new short[nSamplesOut];
				num8 = 0;
			}
			else
			{
				output = samplesOut;
				num8 = samplesOut_ptr;
			}
			if (num5 != 0)
			{
				short[] array3 = new short[decControl.nChannelsInternal * (channel_state[0].frame_length + 2)];
				samplesOut.Slice(samplesOut_ptr, decControl.nChannelsInternal * (channel_state[0].frame_length + 2)).CopyTo(array3);
				span = array3;
				array[0] = 0;
				array[1] = channel_state[0].frame_length + 2;
			}
			for (int i = 0; i < Inlines.silk_min(decControl.nChannelsAPI, decControl.nChannelsInternal); i++)
			{
				num2 += Resampler.silk_resampler(channel_state[i].resampler_state, output, num8, span, array[i] + 1, boxedValueInt.Val);
				if (decControl.nChannelsAPI == 2)
				{
					int num9 = samplesOut_ptr + i;
					for (int j = 0; j < nSamplesOut; j++)
					{
						samplesOut[num9 + 2 * j] = output[num8 + j];
					}
				}
			}
			if (decControl.nChannelsAPI == 2 && decControl.nChannelsInternal == 1)
			{
				if (num3 != 0)
				{
					num2 += Resampler.silk_resampler(channel_state[1].resampler_state, output, num8, span, array[0] + 1, boxedValueInt.Val);
					for (int j = 0; j < nSamplesOut; j++)
					{
						samplesOut[samplesOut_ptr + 1 + 2 * j] = output[num8 + j];
					}
				}
				else
				{
					for (int j = 0; j < nSamplesOut; j++)
					{
						samplesOut[samplesOut_ptr + 1 + 2 * j] = samplesOut[samplesOut_ptr + 2 * j];
					}
				}
			}
			if (channel_state[0].prevSignalType == 2)
			{
				int[] array4 = new int[3] { 6, 4, 3 };
				decControl.prevPitchLag = channel_state[0].lagPrev * array4[channel_state[0].fs_kHz - 8 >> 2];
			}
			else
			{
				decControl.prevPitchLag = 0;
			}
			if (lostFlag == 1)
			{
				for (int j = 0; j < psDec.nChannelsInternal; j++)
				{
					psDec.channel_state[j].LastGainIndex = 10;
				}
			}
			else
			{
				psDec.prev_decode_only_middle = num;
			}
			return num2;
		}
	}
	internal static class DecodeCore
	{
		internal static void silk_decode_core(SilkChannelDecoder psDec, SilkDecoderControl psDecCtrl, Span<short> xq, int xq_ptr, short[] pulses)
		{
			int num = 0;
			short[] lTPCoef_Q = psDecCtrl.LTPCoef_Q14;
			short[] array = new short[psDec.ltp_mem_length];
			int[] array2 = new int[psDec.ltp_mem_length + psDec.frame_length];
			int[] array3 = new int[psDec.subfr_length];
			int[] array4 = new int[psDec.subfr_length + 16];
			int num2 = Tables.silk_Quantization_Offsets_Q10[psDec.indices.signalType >> 1][psDec.indices.quantOffsetType];
			int num3 = ((psDec.indices.NLSFInterpCoef_Q2 < 4) ? 1 : 0);
			int seed = psDec.indices.Seed;
			for (int i = 0; i < psDec.frame_length; i++)
			{
				seed = Inlines.silk_RAND(seed);
				psDec.exc_Q14[i] = Inlines.silk_LSHIFT(pulses[i], 14);
				if (psDec.exc_Q14[i] > 0)
				{
					psDec.exc_Q14[i] -= 1280;
				}
				else if (psDec.exc_Q14[i] < 0)
				{
					psDec.exc_Q14[i] += 1280;
				}
				psDec.exc_Q14[i] += num2 << 4;
				if (seed < 0)
				{
					psDec.exc_Q14[i] = -psDec.exc_Q14[i];
				}
				seed = Inlines.silk_ADD32_ovflw(seed, pulses[i]);
			}
			Arrays.MemCopy(psDec.sLPC_Q14_buf, 0, array4, 0, 16);
			int num4 = 0;
			int num5 = xq_ptr;
			int num6 = psDec.ltp_mem_length;
			for (int j = 0; j < psDec.nb_subfr; j++)
			{
				int[] array5 = array3;
				int num7 = 0;
				short[] array6 = psDecCtrl.PredCoef_Q12[j >> 1];
				int num8 = j * 5;
				int num9 = psDec.indices.signalType;
				int b = Inlines.silk_RSHIFT(psDecCtrl.Gains_Q16[j], 6);
				int a = Inlines.silk_INVERSE32_varQ(psDecCtrl.Gains_Q16[j], 47);
				int num10;
				if (psDecCtrl.Gains_Q16[j] != psDec.prev_gain_Q16)
				{
					num10 = Inlines.silk_DIV32_varQ(psDec.prev_gain_Q16, psDecCtrl.Gains_Q16[j], 16);
					for (int i = 0; i < 16; i++)
					{
						array4[i] = Inlines.silk_SMULWW(num10, array4[i]);
					}
				}
				else
				{
					num10 = 65536;
				}
				psDec.prev_gain_Q16 = psDecCtrl.Gains_Q16[j];
				if (psDec.lossCnt != 0 && psDec.prevSignalType == 2 && psDec.indices.signalType != 2 && j < 2)
				{
					Arrays.MemSetWithOffset(lTPCoef_Q, (short)0, num8, 5);
					lTPCoef_Q[num8 + 2] = 4096;
					num9 = 2;
					psDecCtrl.pitchL[j] = psDec.lagPrev;
				}
				if (num9 == 2)
				{
					num = psDecCtrl.pitchL[j];
					if (j == 0 || (j == 2 && num3 != 0))
					{
						int num11 = psDec.ltp_mem_length - num - psDec.LPC_order - 2;
						if (j == 2)
						{
							xq.Slice(xq_ptr, 2 * psDec.subfr_length).CopyTo(psDec.outBuf.AsSpan(psDec.ltp_mem_length));
						}
						Filters.silk_LPC_analysis_filter(array, num11, psDec.outBuf, num11 + j * psDec.subfr_length, array6, 0, psDec.ltp_mem_length - num11, psDec.LPC_order);
						if (j == 0)
						{
							a = Inlines.silk_LSHIFT(Inlines.silk_SMULWB(a, psDecCtrl.LTP_scale_Q14), 2);
						}
						for (int i = 0; i < num + 2; i++)
						{
							array2[num6 - i - 1] = Inlines.silk_SMULWB(a, array[psDec.ltp_mem_length - i - 1]);
						}
					}
					else if (num10 != 65536)
					{
						for (int i = 0; i < num + 2; i++)
						{
							array2[num6 - i - 1] = Inlines.silk_SMULWW(num10, array2[num6 - i - 1]);
						}
					}
				}
				if (num9 == 2)
				{
					int num12 = num6 - num + 2;
					for (int i = 0; i < psDec.subfr_length; i++)
					{
						int a2 = 2;
						a2 = Inlines.silk_SMLAWB(a2, array2[num12], lTPCoef_Q[num8]);
						a2 = Inlines.silk_SMLAWB(a2, array2[num12 - 1], lTPCoef_Q[num8 + 1]);
						a2 = Inlines.silk_SMLAWB(a2, array2[num12 - 2], lTPCoef_Q[num8 + 2]);
						a2 = Inlines.silk_SMLAWB(a2, array2[num12 - 3], lTPCoef_Q[num8 + 3]);
						a2 = Inlines.silk_SMLAWB(a2, array2[num12 - 4], lTPCoef_Q[num8 + 4]);
						num12++;
						array5[num7 + i] = Inlines.silk_ADD_LSHIFT32(psDec.exc_Q14[num4 + i], a2, 1);
						array2[num6] = Inlines.silk_LSHIFT(array5[num7 + i], 1);
						num6++;
					}
				}
				else
				{
					array5 = psDec.exc_Q14;
					num7 = num4;
				}
				for (int i = 0; i < psDec.subfr_length; i++)
				{
					int a3 = Inlines.silk_RSHIFT(psDec.LPC_order, 1);
					a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 1], array6[0]);
					a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 2], array6[1]);
					a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 3], array6[2]);
					a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 4], array6[3]);
					a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 5], array6[4]);
					a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 6], array6[5]);
					a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 7], array6[6]);
					a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 8], array6[7]);
					a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 9], array6[8]);
					a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 10], array6[9]);
					if (psDec.LPC_order == 16)
					{
						a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 11], array6[10]);
						a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 12], array6[11]);
						a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 13], array6[12]);
						a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 14], array6[13]);
						a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 15], array6[14]);
						a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 16], array6[15]);
					}
					array4[16 + i] = Inlines.silk_ADD_LSHIFT32(array5[num7 + i], a3, 4);
					xq[num5 + i] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULWW(array4[16 + i], b), 8));
				}
				Arrays.MemCopy(array4, psDec.subfr_length, array4, 0, 16);
				num4 += psDec.subfr_length;
				num5 += psDec.subfr_length;
			}
			Arrays.MemCopy(array4, 0, psDec.sLPC_Q14_buf, 0, 16);
		}
	}
	internal static class DecodeIndices
	{
		internal static void silk_decode_indices(SilkChannelDecoder psDec, EntropyCoder psRangeDec, ReadOnlySpan<byte> frameData, int FrameIndex, int decode_LBRR, int condCoding)
		{
			short[] array = new short[psDec.LPC_order];
			byte[] array2 = new byte[psDec.LPC_order];
			int num = ((decode_LBRR == 0 && psDec.VAD_flags[FrameIndex] == 0) ? psRangeDec.dec_icdf(frameData, Tables.silk_type_offset_no_VAD_iCDF, 8u) : (psRangeDec.dec_icdf(frameData, Tables.silk_type_offset_VAD_iCDF, 8u) + 2));
			psDec.indices.signalType = (sbyte)Inlines.silk_RSHIFT(num, 1);
			psDec.indices.quantOffsetType = (sbyte)(num & 1);
			if (condCoding == 2)
			{
				psDec.indices.GainsIndices[0] = (sbyte)psRangeDec.dec_icdf(frameData, Tables.silk_delta_gain_iCDF, 8u);
			}
			else
			{
				psDec.indices.GainsIndices[0] = (sbyte)Inlines.silk_LSHIFT(psRangeDec.dec_icdf(frameData, Tables.silk_gain_iCDF[psDec.indices.signalType], 8u), 3);
				psDec.indices.GainsIndices[0] += (sbyte)psRangeDec.dec_icdf(frameData, Tables.silk_uniform8_iCDF, 8u);
			}
			for (int i = 1; i < psDec.nb_subfr; i++)
			{
				psDec.indices.GainsIndices[i] = (sbyte)psRangeDec.dec_icdf(frameData, Tables.silk_delta_gain_iCDF, 8u);
			}
			psDec.indices.NLSFIndices[0] = (sbyte)psRangeDec.dec_icdf(frameData, psDec.psNLSF_CB.CB1_iCDF, (psDec.indices.signalType >> 1) * psDec.psNLSF_CB.nVectors, 8u);
			NLSF.silk_NLSF_unpack(array, array2, psDec.psNLSF_CB, psDec.indices.NLSFIndices[0]);
			for (int i = 0; i < psDec.psNLSF_CB.order; i++)
			{
				num = psRangeDec.dec_icdf(frameData, psDec.psNLSF_CB.ec_iCDF, array[i], 8u);
				switch (num)
				{
				case 0:
					num -= psRangeDec.dec_icdf(frameData, Tables.silk_NLSF_EXT_iCDF, 8u);
					break;
				case 8:
					num += psRangeDec.dec_icdf(frameData, Tables.silk_NLSF_EXT_iCDF, 8u);
					break;
				}
				psDec.indices.NLSFIndices[i + 1] = (sbyte)(num - 4);
			}
			if (psDec.nb_subfr =

Microsoft.Win32.Registry.dll

Decompiled 16 hours 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.Microsoft.Win32.Registry;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyDefaultAlias("Microsoft.Win32.Registry")]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("Microsoft.Win32.Registry")]
[assembly: AssemblyFileVersion("4.700.19.56404")]
[assembly: AssemblyInformationalVersion("3.1.0+0f7f38c4fd323b26da10cce95f857f77f0f09b48")]
[assembly: AssemblyProduct("Microsoft® .NET Core")]
[assembly: AssemblyTitle("Microsoft.Win32.Registry")]
[assembly: CLSCompliant(true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.1.3.0")]
[assembly: TypeForwardedTo(typeof(Registry))]
[assembly: TypeForwardedTo(typeof(RegistryHive))]
[assembly: TypeForwardedTo(typeof(RegistryKey))]
[assembly: TypeForwardedTo(typeof(RegistryKeyPermissionCheck))]
[assembly: TypeForwardedTo(typeof(RegistryOptions))]
[assembly: TypeForwardedTo(typeof(RegistryValueKind))]
[assembly: TypeForwardedTo(typeof(RegistryValueOptions))]
[assembly: TypeForwardedTo(typeof(RegistryView))]
[assembly: TypeForwardedTo(typeof(SafeRegistryHandle))]
[assembly: TypeForwardedTo(typeof(RegistryAccessRule))]
[assembly: TypeForwardedTo(typeof(RegistryAuditRule))]
[assembly: TypeForwardedTo(typeof(RegistryRights))]
[assembly: TypeForwardedTo(typeof(RegistrySecurity))]
[module: UnverifiableCode]
namespace FxResources.Microsoft.Win32.Registry
{
	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.Microsoft.Win32.Registry.SR)));

		internal static string AccessControl_InvalidHandle => GetResourceString("AccessControl_InvalidHandle");

		internal static string Arg_RegSubKeyAbsent => GetResourceString("Arg_RegSubKeyAbsent");

		internal static string Arg_RegKeyDelHive => GetResourceString("Arg_RegKeyDelHive");

		internal static string Arg_RegKeyNoRemoteConnect => GetResourceString("Arg_RegKeyNoRemoteConnect");

		internal static string Arg_RegKeyOutOfRange => GetResourceString("Arg_RegKeyOutOfRange");

		internal static string Arg_RegKeyNotFound => GetResourceString("Arg_RegKeyNotFound");

		internal static string Arg_RegKeyStrLenBug => GetResourceString("Arg_RegKeyStrLenBug");

		internal static string Arg_RegValStrLenBug => GetResourceString("Arg_RegValStrLenBug");

		internal static string Arg_RegBadKeyKind => GetResourceString("Arg_RegBadKeyKind");

		internal static string Arg_RegGetOverflowBug => GetResourceString("Arg_RegGetOverflowBug");

		internal static string Arg_RegSetMismatchedKind => GetResourceString("Arg_RegSetMismatchedKind");

		internal static string Arg_RegSetBadArrType => GetResourceString("Arg_RegSetBadArrType");

		internal static string Arg_RegSetStrArrNull => GetResourceString("Arg_RegSetStrArrNull");

		internal static string Arg_RegInvalidKeyName => GetResourceString("Arg_RegInvalidKeyName");

		internal static string Arg_DllInitFailure => GetResourceString("Arg_DllInitFailure");

		internal static string Arg_EnumIllegalVal => GetResourceString("Arg_EnumIllegalVal");

		internal static string Arg_RegSubKeyValueAbsent => GetResourceString("Arg_RegSubKeyValueAbsent");

		internal static string Argument_InvalidRegistryOptionsCheck => GetResourceString("Argument_InvalidRegistryOptionsCheck");

		internal static string Argument_InvalidRegistryViewCheck => GetResourceString("Argument_InvalidRegistryViewCheck");

		internal static string Argument_InvalidRegistryKeyPermissionCheck => GetResourceString("Argument_InvalidRegistryKeyPermissionCheck");

		internal static string InvalidOperation_RegRemoveSubKey => GetResourceString("InvalidOperation_RegRemoveSubKey");

		internal static string ObjectDisposed_RegKeyClosed => GetResourceString("ObjectDisposed_RegKeyClosed");

		internal static string PlatformNotSupported_Registry => GetResourceString("PlatformNotSupported_Registry");

		internal static string Security_RegistryPermission => GetResourceString("Security_RegistryPermission");

		internal static string UnauthorizedAccess_RegistryKeyGeneric_Key => GetResourceString("UnauthorizedAccess_RegistryKeyGeneric_Key");

		internal static string UnauthorizedAccess_RegistryNoWrite => GetResourceString("UnauthorizedAccess_RegistryNoWrite");

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

NAudio.Core.dll

Decompiled 16 hours 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 2026")]
[assembly: AssemblyFileVersion("2.3.0.0")]
[assembly: AssemblyInformationalVersion("2.3.0+c89fee940ee6f8d7374d18714a6b85d8b7a18ab0")]
[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.3.0.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 += dataChunkLength;
				}
				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, int channelMask = 0)
			: base(rate, bits, channels)
		{
			waveFormatTag = WaveFormatEncoding.Extensible;
			extraSize = 22;
			wValidBitsPerSample = (short)bits;
			if (channelMask != 0)
			{
				dwChannelMask = channelMask;
			}
			else
			{
				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[] sam

NAudio.WinMM.dll

Decompiled 16 hours ago
using System;
using System.Collections;
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.3.0.0")]
[assembly: AssemblyInformationalVersion("2.3.0+c89fee940ee6f8d7374d18714a6b85d8b7a18ab0")]
[assembly: AssemblyProduct("NAudio.WinMM")]
[assembly: AssemblyTitle("NAudio.WinMM")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")]
[assembly: AssemblyVersion("2.3.0.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
	{
		[CompilerGenerated]
		private sealed class <get_Destinations>d__16 : IEnumerable<MixerLine>, IEnumerable, IEnumerator<MixerLine>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MixerLine <>2__current;

			private int <>l__initialThreadId;

			public Mixer <>4__this;

			private int <destination>5__2;

			MixerLine IEnumerator<MixerLine>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <get_Destinations>d__16(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				Mixer mixer = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<destination>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<destination>5__2++;
					break;
				}
				if (<destination>5__2 < mixer.DestinationCount)
				{
					<>2__current = mixer.GetDestination(<destination>5__2);
					<>1__state = 1;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<MixerLine> IEnumerable<MixerLine>.GetEnumerator()
			{
				<get_Destinations>d__16 result;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					result = this;
				}
				else
				{
					result = new <get_Destinations>d__16(0)
					{
						<>4__this = <>4__this
					};
				}
				return result;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MixerLine>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <get_Mixers>d__18 : IEnumerable<Mixer>, IEnumerable, IEnumerator<Mixer>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private Mixer <>2__current;

			private int <>l__initialThreadId;

			private int <device>5__2;

			Mixer IEnumerator<Mixer>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <get_Mixers>d__18(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<device>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<device>5__2++;
					break;
				}
				if (<device>5__2 < NumberOfDevices)
				{
					<>2__current = new Mixer(<device>5__2);
					<>1__state = 1;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Mixer> IEnumerable<Mixer>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <get_Mixers>d__18(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Mixer>)this).GetEnumerator();
			}
		}

		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
		{
			[IteratorStateMachine(typeof(<get_Destinations>d__16))]
			get
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <get_Destinations>d__16(-2)
				{
					<>4__this = this
				};
			}
		}

		public static IEnumerable<Mixer> Mixers
		{
			[IteratorStateMachine(typeof(<get_Mixers>d__18))]
			get
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <get_Mixers>d__18(-2);
			}
		}

		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
	{
		[CompilerGenerated]
		private sealed class <get_Sources>d__32 : IEnumerable<MixerLine>, IEnumerable, IEnumerator<MixerLine>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MixerLine <>2__current;

			private int <>l__initialThreadId;

			public MixerLine <>4__this;

			private int <source>5__2;

			MixerLine IEnumerator<MixerLine>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <get_Sources>d__32(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				MixerLine mixerLine = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<source>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<source>5__2++;
					break;
				}
				if (<source>5__2 < mixerLine.SourceCount)
				{
					<>2__current = mixerLine.GetSource(<source>5__2);
					<>1__state = 1;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<MixerLine> IEnumerable<MixerLine>.GetEnumerator()
			{
				<get_Sources>d__32 result;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					result = this;
				}
				else
				{
					result = new <get_Sources>d__32(0)
					{
						<>4__this = <>4__this
					};
				}
				return result;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MixerLine>)this).GetEnumerator();
			}
		}

		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
		{
			[IteratorStateMachine(typeof(<get_Sources>d__32))]
			get
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <get_Sources>d__32(-2)
				{
					<>4__this = this
				};
			}
		}

		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;
			}
			if (streamHeader == null)
			{
				throw new ObjectDisposedException("AcmStream has already been disposed");
			}
			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

ProximityVoice.dll

Decompiled 16 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Concentus;
using Concentus.Enums;
using Microsoft.CodeAnalysis;
using NAudio.Wave;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("ProximityVoice")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ProximityVoice")]
[assembly: AssemblyTitle("ProximityVoice")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ProximityVoice
{
	public interface IMicCapture
	{
		bool Running { get; }

		void Start();

		void Stop();

		void PollFrames(List<short[]> frames);
	}
	public static class MicCapture
	{
		public static IMicCapture Create()
		{
			try
			{
				if (NAudioMicCapture.IsAvailable())
				{
					Plugin.Log.LogInfo((object)"Mic capture backend: NAudio (WaveIn).");
					return new NAudioMicCapture();
				}
				Plugin.Log.LogWarning((object)"NAudio reports no capture devices; using Unity Microphone.");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("NAudio capture unavailable (" + ex.GetType().Name + "); using Unity Microphone."));
			}
			return new UnityMicCapture();
		}
	}
	public sealed class NAudioMicCapture : IMicCapture
	{
		private const int BytesPerSample = 2;

		private static readonly int BytesPerFrame = 1920;

		private const int MaxQueuedFrames = 50;

		private WaveInEvent _wave;

		private readonly object _lock = new object();

		private readonly Queue<short[]> _frames = new Queue<short[]>();

		private byte[] _accum = new byte[BytesPerFrame * 4];

		private int _accumLen;

		public bool Running { get; private set; }

		public static bool IsAvailable()
		{
			try
			{
				return WaveInEvent.DeviceCount > 0;
			}
			catch
			{
				return false;
			}
		}

		public void Start()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			if (!Running)
			{
				_wave = new WaveInEvent
				{
					DeviceNumber = ResolveDevice(VoiceConfig.MicDevice.Value),
					WaveFormat = new WaveFormat(48000, 16, 1),
					BufferMilliseconds = 40
				};
				_wave.DataAvailable += OnData;
				_accumLen = 0;
				lock (_lock)
				{
					_frames.Clear();
				}
				_wave.StartRecording();
				Running = true;
			}
		}

		public void Stop()
		{
			if (!Running)
			{
				return;
			}
			Running = false;
			try
			{
				_wave.StopRecording();
			}
			catch
			{
			}
			if (_wave != null)
			{
				_wave.DataAvailable -= OnData;
				_wave.Dispose();
				_wave = null;
			}
			lock (_lock)
			{
				_frames.Clear();
			}
		}

		public void PollFrames(List<short[]> frames)
		{
			lock (_lock)
			{
				while (_frames.Count > 0)
				{
					frames.Add(_frames.Dequeue());
				}
			}
		}

		private void OnData(object sender, WaveInEventArgs e)
		{
			EnsureCapacity(_accumLen + e.BytesRecorded);
			Buffer.BlockCopy(e.Buffer, 0, _accum, _accumLen, e.BytesRecorded);
			_accumLen += e.BytesRecorded;
			int num = 0;
			while (_accumLen - num >= BytesPerFrame)
			{
				short[] array = new short[960];
				for (int i = 0; i < 960; i++)
				{
					int num2 = num + i * 2;
					array[i] = (short)(_accum[num2] | (_accum[num2 + 1] << 8));
				}
				num += BytesPerFrame;
				lock (_lock)
				{
					if (_frames.Count >= 50)
					{
						_frames.Dequeue();
					}
					_frames.Enqueue(array);
				}
			}
			int num3 = _accumLen - num;
			if (num3 > 0 && num > 0)
			{
				Buffer.BlockCopy(_accum, num, _accum, 0, num3);
			}
			_accumLen = num3;
		}

		private void EnsureCapacity(int needed)
		{
			if (_accum.Length < needed)
			{
				int num = Math.Max(needed, _accum.Length * 2);
				byte[] array = new byte[num];
				Buffer.BlockCopy(_accum, 0, array, 0, _accumLen);
				_accum = array;
			}
		}

		private static int ResolveDevice(string name)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(name))
			{
				return -1;
			}
			for (int i = 0; i < WaveInEvent.DeviceCount; i++)
			{
				WaveInCapabilities capabilities = WaveInEvent.GetCapabilities(i);
				if (((WaveInCapabilities)(ref capabilities)).ProductName == name)
				{
					return i;
				}
			}
			Plugin.Log.LogWarning((object)("Mic device \"" + name + "\" not found; using system default."));
			return -1;
		}
	}
	public sealed class SpeakerVoice
	{
		private const int RingSeconds = 2;

		private readonly int _ringSize = 96000;

		private readonly GameObject _go;

		private readonly AudioSource _source;

		private readonly VoiceDecoder _decoder = new VoiceDecoder();

		private readonly float[] _ring;

		private readonly object _lock = new object();

		private int _writeIdx;

		private int _readIdx;

		private int _count;

		public float LastActiveTime;

		public SpeakerVoice(long speakerId)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			_ring = new float[_ringSize];
			_go = new GameObject("PV_Speaker_" + speakerId);
			Object.DontDestroyOnLoad((Object)(object)_go);
			_source = _go.AddComponent<AudioSource>();
			_source.spatialBlend = 1f;
			_source.rolloffMode = (AudioRolloffMode)1;
			_source.minDistance = VoiceConfig.FullVolumeRange.Value;
			_source.maxDistance = VoiceConfig.HearingRange.Value;
			_source.bypassReverbZones = true;
			_source.bypassListenerEffects = true;
			_source.dopplerLevel = 0f;
			_source.loop = true;
			_source.clip = AudioClip.Create("PV_Stream_" + speakerId, _ringSize, 1, 48000, true, new PCMReaderCallback(OnPcmRead));
			_source.Play();
		}

		public void SetPosition(Vector3 pos)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			_go.transform.position = pos;
		}

		public void PushPacket(byte[] packet)
		{
			short[] pcmOut;
			int num = _decoder.Decode(packet, out pcmOut);
			if (num <= 0)
			{
				return;
			}
			float value = VoiceConfig.Volume.Value;
			lock (_lock)
			{
				for (int i = 0; i < num; i++)
				{
					if (_count >= _ringSize)
					{
						break;
					}
					_ring[_writeIdx] = (float)pcmOut[i] / 32767f * value;
					_writeIdx = (_writeIdx + 1) % _ringSize;
					_count++;
				}
			}
			LastActiveTime = Time.realtimeSinceStartup;
		}

		private void OnPcmRead(float[] data)
		{
			lock (_lock)
			{
				for (int i = 0; i < data.Length; i++)
				{
					if (_count > 0)
					{
						data[i] = _ring[_readIdx];
						_readIdx = (_readIdx + 1) % _ringSize;
						_count--;
					}
					else
					{
						data[i] = 0f;
					}
				}
			}
		}

		public void Destroy()
		{
			_decoder.Dispose();
			if ((Object)(object)_go != (Object)null)
			{
				Object.Destroy((Object)(object)_go);
			}
		}
	}
	public sealed class UnityMicCapture : IMicCapture
	{
		private const int ClipSeconds = 1;

		private AudioClip _clip;

		private string _device;

		private int _readPos;

		private readonly float[] _scratch = new float[960];

		private readonly List<float> _accum = new List<float>(1920);

		public bool Running => (Object)(object)_clip != (Object)null;

		public void Start()
		{
			if (!Running)
			{
				_device = (string.IsNullOrEmpty(VoiceConfig.MicDevice.Value) ? null : VoiceConfig.MicDevice.Value);
				if (Microphone.devices == null || Microphone.devices.Length == 0)
				{
					Plugin.Log.LogWarning((object)"No microphone devices found; capture disabled.");
					return;
				}
				_clip = Microphone.Start(_device, true, 1, 48000);
				_readPos = 0;
				_accum.Clear();
			}
		}

		public void Stop()
		{
			if (Running)
			{
				Microphone.End(_device);
				_clip = null;
				_accum.Clear();
			}
		}

		public void PollFrames(List<short[]> frames)
		{
			if (!Running)
			{
				return;
			}
			int position = Microphone.GetPosition(_device);
			if (position < 0)
			{
				return;
			}
			int samples = _clip.samples;
			int num = position - _readPos;
			if (num < 0)
			{
				num += samples;
			}
			if (num <= 0)
			{
				return;
			}
			int num2 = Mathf.Min(num, samples - _readPos);
			AppendFromClip(_readPos, num2);
			if (num > num2)
			{
				AppendFromClip(0, num - num2);
			}
			_readPos = position;
			while (_accum.Count >= 960)
			{
				short[] array = new short[960];
				for (int i = 0; i < 960; i++)
				{
					array[i] = FloatToPcm(_accum[i]);
				}
				_accum.RemoveRange(0, 960);
				frames.Add(array);
			}
		}

		private void AppendFromClip(int offset, int count)
		{
			int num = count;
			int num2 = offset;
			while (num > 0)
			{
				int num3 = Mathf.Min(num, _scratch.Length);
				_clip.GetData(_scratch, num2);
				for (int i = 0; i < num3; i++)
				{
					_accum.Add(_scratch[i]);
				}
				num2 += num3;
				if (num2 >= _clip.samples)
				{
					num2 -= _clip.samples;
				}
				num -= num3;
			}
		}

		private static short FloatToPcm(float f)
		{
			f = Mathf.Clamp(f, -1f, 1f);
			return (short)Mathf.RoundToInt(f * 32767f);
		}
	}
	public static class VoiceHud
	{
		private const int W = 26;

		private const int H = 18;

		private const float DbFloor = -60f;

		private static Texture2D _body;

		private static Texture2D[] _waves;

		private static GUIStyle _label;

		private static readonly float[] WaveRadius = new float[3] { 11f, 14f, 17f };

		private static readonly float[] WaveHalf = new float[3] { 2.5f, 4.5f, 7f };

		private static readonly float[] WaveThreshold = new float[3] { 0.06f, 0.33f, 0.62f };

		public static void Draw(float level, bool gateOpen)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			EnsureTextures();
			float num = (gateOpen ? Mathf.Clamp01(level * 4f) : 0f);
			float value = VoiceConfig.HudScale.Value;
			float num2 = 26f * value;
			float num3 = 18f * value;
			float value2 = VoiceConfig.HudX.Value;
			float num4 = (float)Screen.height - VoiceConfig.HudBottom.Value;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(value2, num4, num2, num3);
			Color color = GUI.color;
			GUI.color = new Color(1f, 1f, 1f, 0.95f);
			GUI.DrawTexture(val, (Texture)(object)_body);
			for (int i = 0; i < _waves.Length; i++)
			{
				float num5 = Mathf.Clamp01((num - WaveThreshold[i]) / 0.15f);
				if (!(num5 <= 0f))
				{
					GUI.color = new Color(1f, 1f, 1f, num5);
					GUI.DrawTexture(val, (Texture)(object)_waves[i]);
				}
			}
			GUI.color = color;
		}

		public static void DrawCalibration(float db, float thresholdDb, bool gateOpen)
		{
			//IL_0007: 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_0051: 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)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			EnsureLabel();
			Color color = GUI.color;
			float num = 380f;
			float num2 = 104f;
			float num3 = ((float)Screen.width - num) * 0.5f;
			float num4 = (float)Screen.height * 0.16f;
			Texture2D whiteTexture = Texture2D.whiteTexture;
			GUI.color = new Color(0f, 0f, 0f, 0.72f);
			GUI.DrawTexture(new Rect(num3, num4, num, num2), (Texture)(object)whiteTexture);
			GUI.color = Color.white;
			GUI.Label(new Rect(num3 + 14f, num4 + 8f, num - 28f, 22f), "Mic Calibration", _label);
			float num5 = num3 + 14f;
			float num6 = num4 + 40f;
			float num7 = num - 28f;
			float num8 = 18f;
			GUI.color = new Color(1f, 1f, 1f, 0.14f);
			GUI.DrawTexture(new Rect(num5, num6, num7, num8), (Texture)(object)whiteTexture);
			float num9 = Mathf.Clamp01(Mathf.InverseLerp(-60f, 0f, db));
			GUI.color = (gateOpen ? new Color(0.3f, 0.95f, 0.4f, 0.95f) : new Color(0.6f, 0.6f, 0.6f, 0.85f));
			GUI.DrawTexture(new Rect(num5, num6, num7 * num9, num8), (Texture)(object)whiteTexture);
			float num10 = Mathf.Clamp01(Mathf.InverseLerp(-60f, 0f, thresholdDb));
			GUI.color = new Color(1f, 0.32f, 0.32f, 1f);
			GUI.DrawTexture(new Rect(num5 + num7 * num10 - 1f, num6 - 4f, 2f, num8 + 8f), (Texture)(object)whiteTexture);
			GUI.color = Color.white;
			KeyCode value = VoiceConfig.CalibrateKey.Value;
			string arg = ((object)(KeyCode)(ref value)).ToString();
			GUI.Label(new Rect(num3 + 14f, num4 + 64f, num - 28f, 22f), $"Level {db:0.0} dB   ·   Gate {thresholdDb:0} dB   ·   [ ] / scroll   ·   {arg} exit", _label);
			GUI.color = color;
		}

		public static void DrawGainAdjust(float db, float micGain, bool gateOpen)
		{
			//IL_0007: 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_0051: 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)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			EnsureLabel();
			Color color = GUI.color;
			float num = 380f;
			float num2 = 104f;
			float num3 = ((float)Screen.width - num) * 0.5f;
			float num4 = (float)Screen.height * 0.16f;
			Texture2D whiteTexture = Texture2D.whiteTexture;
			GUI.color = new Color(0f, 0f, 0f, 0.72f);
			GUI.DrawTexture(new Rect(num3, num4, num, num2), (Texture)(object)whiteTexture);
			GUI.color = Color.white;
			GUI.Label(new Rect(num3 + 14f, num4 + 8f, num - 28f, 22f), "Mic Gain", _label);
			float num5 = num3 + 14f;
			float num6 = num4 + 40f;
			float num7 = num - 28f;
			float num8 = 18f;
			GUI.color = new Color(1f, 1f, 1f, 0.14f);
			GUI.DrawTexture(new Rect(num5, num6, num7, num8), (Texture)(object)whiteTexture);
			float num9 = Mathf.Clamp01(Mathf.InverseLerp(1f, 12f, micGain));
			GUI.color = new Color(0.4f, 0.7f, 1f, 0.95f);
			GUI.DrawTexture(new Rect(num5, num6, num7 * num9, num8), (Texture)(object)whiteTexture);
			float num10 = Mathf.Clamp01(Mathf.InverseLerp(-60f, 0f, db));
			GUI.color = (gateOpen ? new Color(0.3f, 0.95f, 0.4f, 0.95f) : new Color(0.6f, 0.6f, 0.6f, 0.85f));
			GUI.DrawTexture(new Rect(num5 + num7 * num10 - 1f, num6 - 4f, 2f, num8 + 8f), (Texture)(object)whiteTexture);
			GUI.color = Color.white;
			KeyCode value = VoiceConfig.MicGainKey.Value;
			string arg = ((object)(KeyCode)(ref value)).ToString();
			GUI.Label(new Rect(num3 + 14f, num4 + 64f, num - 28f, 22f), $"Gain {micGain:0.0}x   ·   Level {db:0.0} dB   ·   scroll / Up Down   ·   {arg} exit", _label);
			GUI.color = color;
		}

		public static void DrawRebindPrompt()
		{
			//IL_0007: 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_0051: 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)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			EnsureLabel();
			Color color = GUI.color;
			float num = 460f;
			float num2 = 74f;
			float num3 = ((float)Screen.width - num) * 0.5f;
			float num4 = (float)Screen.height * 0.16f;
			Texture2D whiteTexture = Texture2D.whiteTexture;
			GUI.color = new Color(0f, 0f, 0f, 0.78f);
			GUI.DrawTexture(new Rect(num3, num4, num, num2), (Texture)(object)whiteTexture);
			GUIStyle val = new GUIStyle(_label)
			{
				alignment = (TextAnchor)4
			};
			val.normal.textColor = Color.white;
			GUI.Label(new Rect(num3, num4 + 12f, num, 24f), "Press a key or mouse button for Push-to-Talk", val);
			GUIStyle val2 = new GUIStyle(val)
			{
				fontSize = 12,
				fontStyle = (FontStyle)0
			};
			val2.normal.textColor = new Color(1f, 1f, 1f, 0.7f);
			GUI.Label(new Rect(num3, num4 + 42f, num, 20f), "Esc to cancel", val2);
			GUI.color = color;
		}

		private static void EnsureLabel()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if (_label == null)
			{
				_label = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					fontStyle = (FontStyle)1
				};
				_label.normal.textColor = Color.white;
			}
		}

		private static void EnsureTextures()
		{
			if ((Object)(object)_body != (Object)null)
			{
				return;
			}
			_body = Build((int x, int y) => IsBody(x, y));
			_waves = (Texture2D[])(object)new Texture2D[WaveRadius.Length];
			for (int i = 0; i < _waves.Length; i++)
			{
				int wave = i;
				_waves[i] = Build((int x, int y) => IsWave(x, y, wave));
			}
		}

		private static bool IsBody(int x, int y)
		{
			if (x >= 2 && x <= 4 && Mathf.Abs((float)y - 8.5f) <= 3f)
			{
				return true;
			}
			if (x >= 4 && x <= 9)
			{
				float num = 2.5f + (float)(x - 4) * 1.1f;
				if (Mathf.Abs((float)y - 8.5f) <= num)
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsWave(int x, int y, int k)
		{
			if (x < 10)
			{
				return false;
			}
			float num = (float)x - 2f;
			float num2 = (float)y - 8.5f;
			if (num <= 0f || Mathf.Abs(num2) > WaveHalf[k])
			{
				return false;
			}
			float num3 = Mathf.Sqrt(num * num + num2 * num2);
			return Mathf.Abs(num3 - WaveRadius[k]) <= 0.9f;
		}

		private static Texture2D Build(Func<int, int, bool> on)
		{
			//IL_0007: 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_0015: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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)
			Texture2D val = new Texture2D(26, 18, (TextureFormat)5, false)
			{
				filterMode = (FilterMode)0
			};
			Color[] array = (Color[])(object)new Color[468];
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(1f, 1f, 1f, 0f);
			for (int i = 0; i < 18; i++)
			{
				for (int j = 0; j < 26; j++)
				{
					array[i * 26 + j] = (on(j, i) ? Color.white : val2);
				}
			}
			val.SetPixels(array);
			val.Apply();
			return val;
		}
	}
	public sealed class VoiceEncoder : IDisposable
	{
		private readonly IOpusEncoder _enc;

		private readonly byte[] _out = new byte[4000];

		public VoiceEncoder()
		{
			_enc = OpusCodecFactory.CreateEncoder(48000, 1, (OpusApplication)2048, (TextWriter)null);
			_enc.Bitrate = 24000;
		}

		public byte[] Encode(short[] pcmFrame)
		{
			try
			{
				int num = _enc.Encode((ReadOnlySpan<short>)pcmFrame, 960, (Span<byte>)_out, _out.Length);
				if (num <= 0)
				{
					return null;
				}
				byte[] array = new byte[num];
				Buffer.BlockCopy(_out, 0, array, 0, num);
				return array;
			}
			catch
			{
				return null;
			}
		}

		public void Dispose()
		{
			((IDisposable)_enc)?.Dispose();
		}
	}
	public sealed class VoiceDecoder : IDisposable
	{
		private readonly IOpusDecoder _dec;

		private readonly short[] _pcm = new short[960];

		public VoiceDecoder()
		{
			_dec = OpusCodecFactory.CreateDecoder(48000, 1, (TextWriter)null);
		}

		public int Decode(byte[] packet, out short[] pcmOut)
		{
			pcmOut = _pcm;
			try
			{
				return _dec.Decode((ReadOnlySpan<byte>)packet, (Span<short>)_pcm, 960, false);
			}
			catch
			{
				return 0;
			}
		}

		public void Dispose()
		{
			((IDisposable)_dec)?.Dispose();
		}
	}
	public enum MicMode
	{
		Toggle,
		PushToTalk
	}
	public static class VoiceConfig
	{
		public const int SampleRate = 48000;

		public const int Channels = 1;

		public const int FrameMs = 20;

		public const int FrameSamples = 960;

		public const int Bitrate = 24000;

		public static ConfigEntry<MicMode> Mode;

		public static ConfigEntry<float> PttReleaseTail;

		public static ConfigEntry<KeyCode> PushToTalkKey;

		public static ConfigEntry<KeyCode> CalibrateKey;

		public static ConfigEntry<KeyCode> MicGainKey;

		public static ConfigEntry<KeyCode> RebindKey;

		public static ConfigEntry<float> FullVolumeRange;

		public static ConfigEntry<float> HearingRange;

		public static ConfigEntry<float> Volume;

		public static ConfigEntry<float> MicGain;

		public static ConfigEntry<string> MicDevice;

		public static ConfigEntry<float> NoiseGateDb;

		public static ConfigEntry<float> HudX;

		public static ConfigEntry<float> HudBottom;

		public static ConfigEntry<float> HudScale;

		public static ConfigEntry<bool> SelfTest;

		public static void Init(ConfigFile cfg)
		{
			Mode = cfg.Bind<MicMode>("General", "MicMode", MicMode.PushToTalk, "Toggle = press the talk key to turn the mic on/off. PushToTalk = hold the talk key to talk.");
			PttReleaseTail = cfg.Bind<float>("General", "PushToTalkReleaseTail", 0.5f, "Push-to-talk only: keep transmitting this many seconds after releasing the key, so the end of your sentence isn't cut off by capture latency.");
			PushToTalkKey = cfg.Bind<KeyCode>("General", "PushToTalkKey", (KeyCode)117, "Talk key (used by both modes). Mouse buttons work too: Mouse3/Mouse4 are the side buttons, Mouse2 = middle. Any Unity KeyCode is accepted.");
			CalibrateKey = cfg.Bind<KeyCode>("General", "CalibrateKey", (KeyCode)287, "Toggles the in-game mic calibration overlay (live dB + adjustable noise-gate threshold).");
			MicGainKey = cfg.Bind<KeyCode>("General", "MicGainKey", (KeyCode)285, "Toggles the mic gain overlay. While open, scroll the mouse wheel (or Up/Down arrows) to raise/lower how loud your own microphone is sent to others.");
			RebindKey = cfg.Bind<KeyCode>("General", "RebindKey", (KeyCode)288, "Press this, then press any key or mouse button to set it as the talk key (Esc cancels).");
			FullVolumeRange = cfg.Bind<float>("General", "FullVolumeRange", 20f, "Distance (metres) within which a speaker is heard at full volume, with no falloff. Beyond this, volume fades linearly to silence at HearingRange.");
			HearingRange = cfg.Bind<float>("General", "HearingRange", 80f, "Max distance (metres) at which other players can hear you. Voice plays at full volume within FullVolumeRange, then fades linearly to silence at this distance. Used for server-side culling too.");
			Volume = cfg.Bind<float>("Audio", "Volume", 1f, "Playback volume multiplier for incoming voices.");
			MicGain = cfg.Bind<float>("Audio", "MicGain", 4f, "Amplification applied to your OWN microphone before sending (1 = no change). Raise this if others can barely hear you. Adjust live in the calibration overlay (CalibrateKey) with the Up/Down arrow keys.");
			MicDevice = cfg.Bind<string>("Audio", "MicDevice", "", "Microphone device name. Leave empty to use the system default.");
			NoiseGateDb = cfg.Bind<float>("Audio", "NoiseGateDb", -50f, "Noise gate threshold in dBFS: audio quieter than this is not transmitted. Use the in-game calibration overlay (CalibrateKey) to set it visually. -80 = off.");
			HudX = cfg.Bind<float>("HUD", "MicIndicatorX", 60f, "Horizontal pixel position of the mic level indicator (from the left).");
			HudBottom = cfg.Bind<float>("HUD", "MicIndicatorBottom", 300f, "Vertical position of the mic level indicator, as pixels up from the screen bottom.");
			HudScale = cfg.Bind<float>("HUD", "MicIndicatorScale", 2f, "Size multiplier for the mic level indicator.");
			SelfTest = cfg.Bind<bool>("Debug", "SelfTest", false, "Loopback test: also play your OWN voice back locally (through the full Opus pipeline) so you can judge audio quality solo. Leave OFF for normal play.");
		}
	}
	public static class VoiceRouter
	{
		private sealed class RateLimiter
		{
			private sealed class Bucket
			{
				public float Tokens;

				public float LastSeen;
			}

			private const float BurstSeconds = 1.5f;

			private const float ResetAfterSilence = 10f;

			private readonly Dictionary<long, Bucket> _buckets = new Dictionary<long, Bucket>();

			public bool Allow(long senderPeerId)
			{
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				float num = Mathf.Max(0.02f, 0.02f);
				float num2 = 1f / num;
				float num3 = Mathf.Max(3f, num2 * 1.5f);
				if (!_buckets.TryGetValue(senderPeerId, out var value))
				{
					value = new Bucket
					{
						Tokens = num3,
						LastSeen = realtimeSinceStartup
					};
					_buckets[senderPeerId] = value;
				}
				if (realtimeSinceStartup - value.LastSeen > 10f)
				{
					value.Tokens = num3;
				}
				else
				{
					value.Tokens = Mathf.Min(num3, value.Tokens + (realtimeSinceStartup - value.LastSeen) * num2);
				}
				value.LastSeen = realtimeSinceStartup;
				if (value.Tokens < 1f)
				{
					return false;
				}
				value.Tokens -= 1f;
				return true;
			}
		}

		private const string RpcUp = "PV_Up";

		private const string RpcDown = "PV_Down";

		private const int MaxOpusPayloadBytes = 1275;

		private const long LoopbackId = long.MinValue;

		private static bool _registered;

		private static readonly Dictionary<long, SpeakerVoice> Speakers = new Dictionary<long, SpeakerVoice>();

		private static readonly RateLimiter Limiter = new RateLimiter();

		public static bool Ready => _registered && ZRoutedRpc.instance != null;

		public static void EnsureRegistered()
		{
			if (!_registered && ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.Register<ZPackage>("PV_Up", (Action<long, ZPackage>)OnUpstream);
				ZRoutedRpc.instance.Register<ZPackage>("PV_Down", (Action<long, ZPackage>)OnDownstream);
				_registered = true;
				Plugin.Log.LogInfo((object)"VoiceRouter registered RPCs.");
			}
		}

		public static void Reset()
		{
			_registered = false;
			foreach (SpeakerVoice value in Speakers.Values)
			{
				value.Destroy();
			}
			Speakers.Clear();
		}

		public static void SendFrame(byte[] opus, Vector3 pos)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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)
			if (!Ready || opus == null)
			{
				return;
			}
			if (VoiceConfig.SelfTest.Value)
			{
				PlayLocal(long.MinValue, pos, opus);
			}
			ZPackage val = new ZPackage();
			val.Write(pos.x);
			val.Write(pos.y);
			val.Write(pos.z);
			val.Write(opus);
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				val.SetPos(0);
				OnUpstream(ZDOMan.GetSessionID(), val);
				return;
			}
			ZNetPeer val2 = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetServerPeer() : null);
			if (val2 != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(val2.m_uid, "PV_Up", new object[1] { val });
			}
		}

		private static void OnUpstream(long sender, ZPackage pkg)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || !Limiter.Allow(sender) || !TryReadFrame(pkg, out var pos, out var opus))
			{
				return;
			}
			float value = VoiceConfig.HearingRange.Value;
			float num = value * value;
			Vector3 val;
			foreach (ZNetPeer peer in ZNet.instance.GetPeers())
			{
				if (peer != null && peer.m_uid != sender)
				{
					val = peer.m_refPos - pos;
					if (!(((Vector3)(ref val)).sqrMagnitude > num))
					{
						ZPackage val2 = BuildDown(sender, pos, opus);
						ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_uid, "PV_Down", new object[1] { val2 });
					}
				}
			}
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer != (Object)null))
			{
				return;
			}
			long sessionID = ZDOMan.GetSessionID();
			if (sessionID != sender)
			{
				val = ((Component)localPlayer).transform.position - pos;
				if (((Vector3)(ref val)).sqrMagnitude <= num)
				{
					PlayLocal(sender, pos, opus);
				}
			}
		}

		private static void OnDownstream(long sender, ZPackage pkg)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			long speakerId;
			Vector3 pos;
			byte[] opus;
			try
			{
				speakerId = pkg.ReadLong();
				pos = new Vector3(pkg.ReadSingle(), pkg.ReadSingle(), pkg.ReadSingle());
				opus = pkg.ReadByteArray();
			}
			catch
			{
				return;
			}
			if (IsValidFrame(pos, opus))
			{
				PlayLocal(speakerId, pos, opus);
			}
		}

		private static bool TryReadFrame(ZPackage pkg, out Vector3 pos, out byte[] opus)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//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_003b: Unknown result type (might be due to invalid IL or missing references)
			pos = default(Vector3);
			opus = null;
			try
			{
				pos = new Vector3(pkg.ReadSingle(), pkg.ReadSingle(), pkg.ReadSingle());
				opus = pkg.ReadByteArray();
			}
			catch
			{
				return false;
			}
			return IsValidFrame(pos, opus);
		}

		private static bool IsValidFrame(Vector3 pos, byte[] opus)
		{
			//IL_001d: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			if (opus == null || opus.Length == 0 || opus.Length > 1275)
			{
				return false;
			}
			if (!IsFinite(pos.x) || !IsFinite(pos.y) || !IsFinite(pos.z))
			{
				return false;
			}
			return true;
		}

		private static bool IsFinite(float f)
		{
			return !float.IsNaN(f) && !float.IsInfinity(f);
		}

		private static void PlayLocal(long speakerId, Vector3 pos, byte[] opus)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (!Speakers.TryGetValue(speakerId, out var value))
			{
				value = new SpeakerVoice(speakerId);
				Speakers[speakerId] = value;
			}
			value.SetPosition(pos);
			value.PushPacket(opus);
		}

		private static ZPackage BuildDown(long speakerId, Vector3 pos, byte[] opus)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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)
			ZPackage val = new ZPackage();
			val.Write(speakerId);
			val.Write(pos.x);
			val.Write(pos.y);
			val.Write(pos.z);
			val.Write(opus);
			return val;
		}

		public static void PruneIdle(float idleSeconds)
		{
			if (Speakers.Count == 0)
			{
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			List<long> list = null;
			foreach (KeyValuePair<long, SpeakerVoice> speaker in Speakers)
			{
				if (realtimeSinceStartup - speaker.Value.LastActiveTime > idleSeconds)
				{
					(list ?? (list = new List<long>())).Add(speaker.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (long item in list)
			{
				Speakers[item].Destroy();
				Speakers.Remove(item);
			}
		}
	}
	[BepInPlugin("Nubedeu.proximityvoice", "ProximityVoice", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "Nubedeu.proximityvoice";

		public const string PluginName = "ProximityVoice";

		public const string PluginVersion = "0.1.0";

		public static ManualLogSource Log;

		private IMicCapture _mic;

		private readonly List<short[]> _frameBuf = new List<short[]>();

		private VoiceEncoder _encoder;

		private bool _wasCapturing;

		private bool _micOn;

		private bool _calibrating;

		private bool _gainAdjust;

		private bool _rebinding;

		private static KeyCode[] _rebindCandidates;

		private float _micLevel;

		private float _curDb;

		private bool _gateOpen;

		private float _gateOpenUntil;

		private float _pttHeldUntil;

		private const float GateHold = 0.25f;

		private static KeyCode[] RebindCandidates
		{
			get
			{
				//IL_0032: 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_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Invalid comparison between Unknown and I4
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				if (_rebindCandidates == null)
				{
					List<KeyCode> list = new List<KeyCode>();
					foreach (KeyCode value in Enum.GetValues(typeof(KeyCode)))
					{
						if ((int)value > 0)
						{
							list.Add(value);
						}
					}
					_rebindCandidates = list.ToArray();
				}
				return _rebindCandidates;
			}
		}

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			VoiceConfig.Init(((BaseUnityPlugin)this).Config);
			_mic = MicCapture.Create();
			_encoder = new VoiceEncoder();
			Log.LogInfo((object)"ProximityVoice loaded.");
		}

		private void Update()
		{
			//IL_003e: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0432: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			VoiceRouter.EnsureRegistered();
			if (!VoiceRouter.Ready)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (_rebinding)
			{
				HandleRebind();
				return;
			}
			if (Input.GetKeyDown(VoiceConfig.RebindKey.Value))
			{
				_rebinding = true;
				return;
			}
			KeyCode value = VoiceConfig.PushToTalkKey.Value;
			if (VoiceConfig.Mode.Value == MicMode.PushToTalk)
			{
				if (Input.GetKey(value))
				{
					_pttHeldUntil = Time.time + VoiceConfig.PttReleaseTail.Value;
				}
				_micOn = Time.time <= _pttHeldUntil;
			}
			else if (Input.GetKeyDown(value))
			{
				_micOn = !_micOn;
				if ((Object)(object)MessageHud.instance != (Object)null)
				{
					MessageHud.instance.ShowMessage((MessageType)1, _micOn ? "VOIP Ligado" : "VOIP Desligado", 0, (Sprite)null, false);
				}
			}
			if (Input.GetKeyDown(VoiceConfig.MicGainKey.Value))
			{
				_gainAdjust = !_gainAdjust;
			}
			if (_gainAdjust)
			{
				float num = 0f;
				if (Input.GetKeyDown((KeyCode)273))
				{
					num += 0.5f;
				}
				if (Input.GetKeyDown((KeyCode)274))
				{
					num -= 0.5f;
				}
				float y = Input.mouseScrollDelta.y;
				if (y > 0f)
				{
					num += 0.5f;
				}
				else if (y < 0f)
				{
					num -= 0.5f;
				}
				if (num != 0f)
				{
					VoiceConfig.MicGain.Value = Mathf.Clamp(VoiceConfig.MicGain.Value + num, 1f, 20f);
				}
			}
			if (Input.GetKeyDown(VoiceConfig.CalibrateKey.Value))
			{
				_calibrating = !_calibrating;
			}
			if (_calibrating)
			{
				float num2 = 0f;
				if (Input.GetKeyDown((KeyCode)91))
				{
					num2 -= 1f;
				}
				if (Input.GetKeyDown((KeyCode)93))
				{
					num2 += 1f;
				}
				float y2 = Input.mouseScrollDelta.y;
				if (y2 > 0f)
				{
					num2 += 1f;
				}
				else if (y2 < 0f)
				{
					num2 -= 1f;
				}
				if (num2 != 0f)
				{
					VoiceConfig.NoiseGateDb.Value = Mathf.Clamp(VoiceConfig.NoiseGateDb.Value + num2, -80f, 0f);
				}
			}
			bool flag = (_micOn || _calibrating || _gainAdjust) && (Object)(object)localPlayer != (Object)null;
			float num3 = 0f;
			if (flag)
			{
				if (!_mic.Running)
				{
					_mic.Start();
				}
				_frameBuf.Clear();
				_mic.PollFrames(_frameBuf);
				ApplyMicGain(_frameBuf, VoiceConfig.MicGain.Value);
				foreach (short[] item in _frameBuf)
				{
					for (int i = 0; i < item.Length; i++)
					{
						float num4 = (float)Mathf.Abs((int)item[i]) * 3.0517578E-05f;
						if (num4 > num3)
						{
							num3 = num4;
						}
					}
				}
				if (Dbfs(num3) >= VoiceConfig.NoiseGateDb.Value)
				{
					_gateOpenUntil = Time.time + 0.25f;
				}
				_gateOpen = Time.time <= _gateOpenUntil;
				if (_micOn && _gateOpen && (Object)(object)localPlayer != (Object)null)
				{
					Vector3 position = ((Component)localPlayer).transform.position;
					foreach (short[] item2 in _frameBuf)
					{
						byte[] array = _encoder.Encode(item2);
						if (array != null)
						{
							VoiceRouter.SendFrame(array, position);
						}
					}
				}
			}
			else if (_wasCapturing)
			{
				_mic.Stop();
				_gateOpen = false;
			}
			float num5 = (flag ? num3 : 0f);
			if (num5 > _micLevel)
			{
				_micLevel = num5;
			}
			else
			{
				_micLevel = Mathf.MoveTowards(_micLevel, num5, Time.deltaTime * 1.5f);
			}
			_curDb = Dbfs(_micLevel);
			_wasCapturing = flag;
			VoiceRouter.PruneIdle(2f);
		}

		private static void ApplyMicGain(List<short[]> frames, float gain)
		{
			if (gain == 1f)
			{
				return;
			}
			foreach (short[] frame in frames)
			{
				for (int i = 0; i < frame.Length; i++)
				{
					int num = (int)((float)frame[i] * gain);
					if (num > 32767)
					{
						num = 32767;
					}
					else if (num < -32768)
					{
						num = -32768;
					}
					frame[i] = (short)num;
				}
			}
		}

		private static float Dbfs(float amp)
		{
			return (amp <= 0.0001f) ? (-80f) : Mathf.Max(-80f, 20f * Mathf.Log10(amp));
		}

		private void HandleRebind()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			if (Input.GetKeyDown((KeyCode)27))
			{
				_rebinding = false;
			}
			else
			{
				if (!Input.anyKeyDown)
				{
					return;
				}
				KeyCode[] rebindCandidates = RebindCandidates;
				for (int i = 0; i < rebindCandidates.Length; i++)
				{
					KeyCode val = rebindCandidates[i];
					if ((int)val != 27 && val != VoiceConfig.RebindKey.Value && Input.GetKeyDown(val))
					{
						VoiceConfig.PushToTalkKey.Value = val;
						_rebinding = false;
						if ((Object)(object)MessageHud.instance != (Object)null)
						{
							MessageHud.instance.ShowMessage((MessageType)1, "Talk key: " + ((object)(KeyCode)(ref val)).ToString(), 0, (Sprite)null, false);
						}
						break;
					}
				}
			}
		}

		private void OnGUI()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			if (_rebinding)
			{
				VoiceHud.DrawRebindPrompt();
				return;
			}
			if (_micOn)
			{
				VoiceHud.Draw(_micLevel, _gateOpen);
			}
			if (_calibrating)
			{
				VoiceHud.DrawCalibration(_curDb, VoiceConfig.NoiseGateDb.Value, _gateOpen);
			}
			if (_gainAdjust)
			{
				VoiceHud.DrawGainAdjust(_curDb, VoiceConfig.MicGain.Value, _gateOpen);
			}
		}

		private void OnDestroy()
		{
			_mic.Stop();
			_encoder?.Dispose();
			VoiceRouter.Reset();
		}
	}
}

System.Buffers.dll

Decompiled 16 hours 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.28619.01")]
[assembly: AssemblyInformationalVersion("4.6.28619.01 @BuiltBy: dlab14-DDVSOWINAGE069 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/corefx/tree/7601f4f6225089ffb291dc7d58293c7bbf5c5d4f")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.3.0")]
[module: UnverifiableCode]
namespace FxResources.System.Buffers
{
	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_BufferNotFromPool => GetResourceString("ArgumentException_BufferNotFromPool", 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);
		}
	}
}
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 = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				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 = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			ptr[4] = new EventData
			{
				Size = 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;
		}
	}
}

System.Memory.dll

Decompiled 16 hours 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.28619.01")]
[assembly: AssemblyInformationalVersion("4.6.28619.01 @BuiltBy: dlab14-DDVSOWINAGE069 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/corefx/tree/7601f4f6225089ffb291dc7d58293c7bbf5c5d4f")]
[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 value2 = 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)) && (value2.High < 429496729 || (value2.High == 429496729 && (value2.Mid < 2576980377u || (value2.Mid == 2576980377u && (value2.Low < 2576980377u || (value2.Low == 2576980377u && *ptr <= 53)))))))
				{
					DecimalDecCalc.DecMul10(ref value2);
					if (*ptr != 0)
					{
						DecimalDecCalc.DecAddInt32(ref value2, (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 value2, 1u);
						if ((value2.High | value2.Mid | value2.Low) == 0)
						{
							value2.High = 429496729u;
							value2.Mid = 2576980377u;
							value2.Low = 2576980378u;
							num++;
						}
					}
				}
			}
			if (num > 0)
			{
				return false;
			}
			if (num <= -29)
			{
				value2.High = 0u;
				value2.Low = 0u;
				value2.Mid = 0u;
				value2.Scale = 28;
			}
			else
			{
				value2.Scale = -num;
			}
			value2.IsNegative = number.IsNegative;
			value = System.Runtime.CompilerServices.Unsafe.As<MutableDecimal, decimal>(ref value2);
			return true;
		}

		public static void DecimalToNumber(decimal value, ref NumberBuffer number)
		{
			ref MutableDecimal reference = ref System.Runtime.CompilerServices.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>(System.Runtime.CompilerServices.Unsafe.AsPointer<byte>(ref _b0), 51);

		public unsafe byte* UnsafeDigits => (byte*)System.Runtime.CompilerServices.Unsafe.AsPointer<byte>(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>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)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 System.Runtime.CompilerServices.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 = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = System.Runtime.CompilerServices.Unsafe.Add<T>(System.Runtime.CompilerServices.Unsafe.AsPointer<T>(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.Add<T>(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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.Add<T>(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 = System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num);
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num) = System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num2);
				System.Runtime.CompilerServices.Unsafe.Add<T>(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 = System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (System.Runtime.CompilerServices.Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr >= (uint)(span.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>()))
				{
					return (uint)(int)intPtr > (uint)(-(other.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>()));
				}
				return true;
			}
			if ((ulong)(long)intPtr >= (ulong)((long)span.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>()))
			{
				return (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)System.Runtime.CompilerServices.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 = System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (System.Runtime.CompilerServices.Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr < (uint)(span.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>()) || (uint)(int)intPtr > (uint)(-(other.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>())))
				{
					if ((int)intPtr % System.Runtime.CompilerServices.Unsafe.SizeOf<T>() != 0)
					{
						System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
					}
					elementOffset = (int)intPtr / System.Runtime.CompilerServices.Unsafe.SizeOf<T>();
					return true;
				}
				elementOffset = 0;
				return false;
			}
			if ((ulong)(long)intPtr < (ulong)((long)span.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>()) || (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>())))
			{
				if ((long)intPtr % System.Runtime.CompilerServices.Unsafe.SizeOf<T>() != 0L)
				{
					System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
				}
				elementOffset = (int)((long)intPtr / System.Runtime.CompilerServices.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>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)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>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)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>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)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* ptr = text)
			{
				return System.Runtime.CompilerServices.Unsafe.ByteOffset<char>(ref System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text).Data, ref System.Runtime.CompilerServices.Unsafe.AsRef<char>((void*)ptr));
			}
		}
	}
	[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>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)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 = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = System.Runtime.CompilerServices.Unsafe.Add<T>(System.Runtime.CompilerServices.Unsafe.AsPointer<T>(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(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 = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)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 = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)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 System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
			}
			return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>((void*)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 System.Runtime.CompilerServices.Unsafe.AreSame<T>(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (_byteOffset == MemoryExtensions.StringAdjustment)
				{
					object obj = System.Runtime.CompilerServices.Unsafe.As<object>((object)_pinnable);
					if (obj is string text && _length == text.Length)
					{
						return text;
					}
				}
				fixed (char* value = &System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(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 System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(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 = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)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>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)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 = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)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 System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
			}
			return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>((void*)null);
		}

		public unsafe void Clear()
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			UIntPtr byteLength = (UIntPtr)(ulong)((uint)length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>());
			if ((System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset)), byteLength);
				}
			}
			else if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				UIntPtr pointerSizeLength = (UIntPtr)(ulong)(length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>() / sizeof(IntPtr));
				System.SpanHelpers.ClearPointerSizedWithReferences(ref System.Runtime.CompilerServices.Unsafe.As<T, IntPtr>(ref DangerousGetPinnableReference()), pointerSizeLength);
			}
			else
			{
				System.SpanHelpers.ClearPointerSizedWithoutReferences(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref DangerousGetPinnableReference()), byteLength);
			}
		}

		public unsafe void Fill(T value)
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			if (System.Runtime.CompilerServices.Unsafe.SizeOf<T>() == 1)
			{
				byte b = System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value);
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(byteOffset.ToPointer(), b, (uint)length);
				}
				else
				{
					System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset)), b, (uint)length);
				}
				return;
			}
			ref T reference = ref DangerousGetPinnableReference();
			int i;
			for (i = 0; i < (length & -8); i += 8)
			{
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 1) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 2) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 3) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 4) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 5) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 6) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 7) = value;
			}
			if (i < (length & -4))
			{
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 1) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 2) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 3) = value;
				i += 4;
			}
			for (; i < length; i++)
			{
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, 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 System.Runtime.CompilerServices.Unsafe.AreSame<T>(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 = &System.Runtime.CompilerServices.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 System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(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 System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)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(System.Runtime.CompilerServices.Unsafe.Add<T>(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 System.Runtime.CompilerServices.Unsafe.Add<byte>(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 System.Runtime.CompilerServices.Unsafe.Add<byte>(ref searchSpace, num2), value2, num3);
				if (num4 == -1)
				{
					break;
				}
				num2 += num4;
				if (SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.Add<byte>(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, System.Runtime.CompilerServices.Unsafe.Add<byte>(ref value, i), searchSpaceLength);
				if ((uint)num2 < (uint)num)
				{
					num = num2;
					searchSpaceLength = num2;
					if (num == 0)
					{
						break;
					}
				}

System.Numerics.Vectors.dll

Decompiled 16 hours 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.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: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.1.4.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 Pow(float x, float y)
		{
			return (float)Math.Pow(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 static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));

		internal static Type ResourceType { get; } = typeof(SR);


		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 string Arg_InsufficientNumberOfElements => GetResourceString("Arg_InsufficientNumberOfElements", 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);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Field, Inherited = false)]
	internal sealed class IntrinsicAttribute : Attribute
	{
	}
}
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;
		}
	}
	[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;
	}
	[System.Runtime.CompilerServices.Intrinsic]
	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> s_zero = default(Vector<T>);

		private static readonly Vector<T> s_one = new Vector<T>(GetOneValue());

		private static readonly Vector<T> s_allOnes = new Vector<T>(GetAllBitsSetValue());

		public static int Count
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				return s_count;
			}
		}

		public static Vector<T> Zero
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				return s_zero;
			}
		}

		public static Vector<T> One
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				return s_one;
			}
		}

		internal static Vector<T> AllOnes => s_allOnes;

		public unsafe T this[int index]
		{
			[System.Runtime.CompilerServices.Intrinsic]
			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;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		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;
			}
		}

		[System.Runtime.CompilerServices.Intrinsic]
		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(System.SR.Format(System.SR.Arg_InsufficientNumberOfElements, Count, "values"));
			}
			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;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public void CopyTo(T[] destination)
		{
			CopyTo(destination, 0);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		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);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		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)(uint)Count];
					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)(uint)Count];
					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)(uint)Count];
					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)(uint)Count];
					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)(uint)Count];
					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)(uint)Count];
					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)(uint)Count];
					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)(uint)Count];
					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;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		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;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		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;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		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 s_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);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<byte>(Vector<T> value)
		{
			return new Vector<byte>(ref value.register);
		}

		[CLSCompliant(false)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<sbyte>(Vector<T> value)
		{
			return new Vector<sbyte>(ref value.register);
		}

		[CLSCompliant(false)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<ushort>(Vector<T> value)
		{
			return new Vector<ushort>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<short>(Vector<T> value)
		{
			return new Vector<short>(ref value.register);
		}

		[CLSCompliant(false)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<uint>(Vector<T> value)
		{
			return new Vector<uint>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<int>(Vector<T> value)
		{
			return new Vector<int>(ref value.register);
		}

		[CLSCompliant(false)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<ulong>(Vector<T> value)
		{
			return new Vector<ulong>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<long>(Vector<T> value)
		{
			return new Vector<long>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<float>(Vector<T> value)
		{
			return new Vector<float>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<double>(Vector<T> value)
		{
			return new Vector<double>(ref value.register);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Compile

System.Runtime.CompilerServices.Unsafe.dll

Decompiled 16 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;

[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: CompilationRelaxations(8)]
[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: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: CLSCompliant(false)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("4.0.4.1")]
namespace System.Runtime.CompilerServices
{
	public static class Unsafe
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static T Read<T>(void* source)
		{
			return Unsafe.Read<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static T ReadUnaligned<T>(void* source)
		{
			return Unsafe.ReadUnaligned<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static T ReadUnaligned<T>(ref byte source)
		{
			return Unsafe.ReadUnaligned<T>(ref source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Write<T>(void* destination, T value)
		{
			Unsafe.Write(destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void WriteUnaligned<T>(void* destination, T value)
		{
			Unsafe.WriteUnaligned(destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void WriteUnaligned<T>(ref byte destination, T value)
		{
			Unsafe.WriteUnaligned(ref destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Copy<T>(void* destination, ref T source)
		{
			Unsafe.Write(destination, source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Copy<T>(ref T destination, void* source)
		{
			destination = Unsafe.Read<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* AsPointer<T>(ref T value)
		{
			return Unsafe.AsPointer(ref value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static int SizeOf<T>()
		{
			return Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void CopyBlock(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(destination, source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void CopyBlock(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(ref destination, ref source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(destination, source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(ref destination, ref source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void InitBlock(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(ref startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(ref startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static T As<T>(object o) where T : class
		{
			return (T)o;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static ref T AsRef<T>(void* source)
		{
			return ref *(T*)source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T AsRef<T>(in T source)
		{
			return ref source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref TTo As<TFrom, TTo>(ref TFrom source)
		{
			return ref Unsafe.As<TFrom, TTo>(ref source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Add<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* Add<T>(void* source, int elementOffset)
		{
			return (byte*)source + (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Add<T>(ref T source, IntPtr elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T AddByteOffset<T>(ref T source, IntPtr byteOffset)
		{
			return ref Unsafe.AddByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Subtract<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* Subtract<T>(void* source, int elementOffset)
		{
			return (byte*)source - (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Subtract<T>(ref T source, IntPtr elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T SubtractByteOffset<T>(ref T source, IntPtr byteOffset)
		{
			return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static IntPtr ByteOffset<T>(ref T origin, ref T target)
		{
			return Unsafe.ByteOffset(target: ref target, origin: ref origin);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool AreSame<T>(ref T left, ref T right)
		{
			return Unsafe.AreSame(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool IsAddressGreaterThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressGreaterThan(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool IsAddressLessThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressLessThan(ref left, ref right);
		}
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class NonVersionableAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}

System.Security.AccessControl.dll

Decompiled 16 hours 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;
		}
	}
}

System.Security.Principal.Windows.dll

Decompiled 16 hours 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]