Decompiled source of mszguns v2.0.1

Mods/mszguns.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Il2Cpp;
using Il2CppDG.Tweening;
using Il2CppDG.Tweening.Core;
using Il2CppDG.Tweening.Plugins.Options;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using InventoryFramework;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using MultiSide.shared;
using NAudio.Wave;
using Newtonsoft.Json;
using UnityEngine;
using VGltf;
using VGltf.Types;
using mszguns;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "Miside Zero AK47", "2.0.0", "gameknight963", null)]
[assembly: MelonOptionalDependencies(new string[] { "Multiside.shared" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("mszguns")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ea64eccaf8e04528403e11d3d55c582edd51a6b1")]
[assembly: AssemblyProduct("mszguns")]
[assembly: AssemblyTitle("mszguns")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 mszguns
{
	public static class AudioImporter
	{
		public static AudioClip Load(string filePath)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if (!File.Exists(filePath))
			{
				throw new FileNotFoundException(filePath);
			}
			AudioFileReader val = new AudioFileReader(filePath);
			try
			{
				int channels = ((WaveStream)val).WaveFormat.Channels;
				int sampleRate = ((WaveStream)val).WaveFormat.SampleRate;
				float[] array = ReadAllSamples(val);
				AudioClip val2 = AudioClip.Create(Path.GetFileNameWithoutExtension(filePath), array.Length / channels, channels, sampleRate, false);
				val2.SetData(Il2CppStructArray<float>.op_Implicit(array), 0);
				return val2;
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}

		private static float[] ReadAllSamples(AudioFileReader reader)
		{
			List<float> list = new List<float>((int)(((Stream)(object)reader).Length / 4));
			float[] array = new float[4096];
			int num;
			while ((num = reader.Read(array, 0, array.Length)) > 0)
			{
				for (int i = 0; i < num; i++)
				{
					list.Add(array[i]);
				}
			}
			return list.ToArray();
		}
	}
	public class Core : MelonMod
	{
		private List<Gun> guns = new List<Gun>();

		private List<GameObject> gunObjects = new List<GameObject>();

		private List<AudioClip> gunShots = new List<AudioClip>();

		private List<AudioSource> gunSources = new List<AudioSource>();

		private static Gun? activeGun;

		private GameObject? activeGunObject;

		private AudioSource? activeSource;

		private SettingsManager? settingsManager;

		private float fireTimer = 0f;

		private const string MoveTweenId = "gun_move";

		private const string RotateTweenId = "gun_rotate";

		public static string ModResources { get; set; } = Path.Combine(MelonEnvironment.ModsDirectory, "mszguns");


		public static string? ActiveGunId => activeGun?.Id;

		public static Texture2D? BulletHoleTexture { get; private set; }

		public override void OnInitializeMelon()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			guns = GunLoader.LoadAll(ModResources);
			foreach (Gun gun in guns)
			{
				InventoryManager.Instance.RegisterItem(new ItemDefinition(gun.Id, gun.DisplayName, LoadSprite(GunLoader.GetIconPath(ModResources, gun))));
			}
			InventoryManager.Instance.OnItemSelected += Instance_OnItemSelected;
			BulletHoleTexture = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(BulletHoleTexture, Il2CppStructArray<byte>.op_Implicit(File.ReadAllBytes(GunLoader.GetDefaultHolePath(ModResources))));
			((Object)BulletHoleTexture).hideFlags = (HideFlags)32;
			GunNetworking.Init(ModResources, guns, ((MelonBase)this).LoggerInstance);
		}

		public override void OnLateInitializeMelon()
		{
			settingsManager = Void.instance.settings;
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			if (sceneName != "Version 1.9 POST")
			{
				return;
			}
			Transform transform = ((Component)Camera.main).transform;
			gunObjects.Clear();
			gunShots.Clear();
			gunSources.Clear();
			foreach (Gun gun in guns)
			{
				GameObject val = GunLoader.LoadGun(GunLoader.GetModelPath(ModResources, gun));
				val.transform.parent = transform;
				val.transform.eulerAngles = transform.eulerAngles;
				val.transform.position = transform.position;
				Transform transform2 = val.transform;
				transform2.localPosition += gun.NormalPosition.ToVector3();
				val.active = false;
				AudioClip val2 = AudioImporter.Load(GunLoader.GetAudioPath(ModResources, gun));
				AudioSource val3 = val.AddComponent<AudioSource>();
				val3.clip = val2;
				val3.volume = gun.AudioVolume;
				val3.playOnAwake = false;
				gunObjects.Add(val);
				gunShots.Add(val2);
				gunSources.Add(val3);
			}
		}

		public override void OnUpdate()
		{
			//IL_0084: 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)
			if (activeGun == null || (Object)(object)activeGunObject == (Object)null)
			{
				return;
			}
			InventoryItem selectedItem = InventoryManager.Instance.SelectedItem;
			if (!(((selectedItem != null) ? selectedItem.Definition.Id : null) != activeGun.Id))
			{
				if (Input.GetMouseButtonDown(1))
				{
					DOTween.Kill(Object.op_Implicit("gun_move"), false);
					TweenSettingsExtensions.SetId<TweenerCore<Vector3, Vector3, VectorOptions>>(TweenSettingsExtensions.SetEase<TweenerCore<Vector3, Vector3, VectorOptions>>(ShortcutExtensions.DOLocalMove(activeGunObject.transform, activeGun.AdsPosition.ToVector3(), activeGun.AdsSpeed, false), (Ease)6), "gun_move");
					TweenSettingsExtensions.SetId<TweenerCore<float, float, FloatOptions>>(TweenSettingsExtensions.SetEase<TweenerCore<float, float, FloatOptions>>(ShortcutExtensions.DOFieldOfView(Camera.main, activeGun.AdsFov, activeGun.AdsSpeed), (Ease)6), "gun_move");
				}
				if (Input.GetMouseButtonUp(1))
				{
					DOTween.Kill(Object.op_Implicit("gun_move"), false);
					TweenSettingsExtensions.SetId<TweenerCore<Vector3, Vector3, VectorOptions>>(TweenSettingsExtensions.SetEase<TweenerCore<Vector3, Vector3, VectorOptions>>(ShortcutExtensions.DOLocalMove(activeGunObject.transform, activeGun.NormalPosition.ToVector3(), activeGun.AdsSpeed, false), (Ease)6), "gun_move");
					TweenSettingsExtensions.SetId<TweenerCore<float, float, FloatOptions>>(TweenSettingsExtensions.SetEase<TweenerCore<float, float, FloatOptions>>(ShortcutExtensions.DOFieldOfView(Camera.main, settingsManager.fov, activeGun.AdsSpeed), (Ease)6), "gun_move");
				}
				if (Input.GetMouseButton(0) && fireTimer <= 0f)
				{
					fireTimer = activeGun.FireRate;
					Shoot(activeGun, activeGunObject, activeSource, BulletHoleTexture);
				}
				fireTimer -= Time.deltaTime;
			}
		}

		private void Shoot(Gun gun, GameObject gunObject, AudioSource source, Texture2D holeTexture)
		{
			//IL_005d: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			Gun gun2 = gun;
			Texture2D holeTexture2 = holeTexture;
			GameObject gunObject2 = gunObject;
			source.PlayOneShot(source.clip);
			switch (gun2.Effect)
			{
			case ShotEffect.Normal:
			{
				RaycastHit hit = default(RaycastHit);
				if (Physics.Raycast(((Component)Camera.main).transform.position, ((Component)Camera.main).transform.forward, ref hit, gun2.Range))
				{
					SpawnBulletHole(hit, holeTexture2, gun2.BulletHoleDuration);
					GunNetworking.Instance?.SendShot(ShotEffect.Normal, ((RaycastHit)(ref hit)).point, ((RaycastHit)(ref hit)).normal, gun2.BulletHoleDuration);
				}
				GunNetworking.Instance?.SendFireAudioMessage();
				break;
			}
			case ShotEffect.Shotgun:
				Enumerable.Range(0, 8).ToList().ForEach(delegate
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0033: 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_003d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0048: Unknown result type (might be due to invalid IL or missing references)
					//IL_004d: 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_008b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0092: Unknown result type (might be due to invalid IL or missing references)
					Vector3 val3 = ((Component)Camera.main).transform.forward + new Vector3(Random.Range(-0.1f, 0.1f), Random.Range(-0.1f, 0.1f), 0f);
					RaycastHit hit2 = default(RaycastHit);
					if (Physics.Raycast(((Component)Camera.main).transform.position, val3, ref hit2, gun2.Range))
					{
						SpawnBulletHole(hit2, holeTexture2, gun2.BulletHoleDuration);
						GunNetworking.Instance?.SendShot(ShotEffect.Shotgun, ((RaycastHit)(ref hit2)).point, ((RaycastHit)(ref hit2)).normal, gun2.BulletHoleDuration);
					}
				});
				GunNetworking.Instance?.SendFireAudioMessage();
				break;
			case ShotEffect.Cube:
			{
				GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
				val.transform.position = ((Component)Camera.main).transform.position + ((Component)Camera.main).transform.forward;
				val.transform.localScale = Vector3.one * 0.2f;
				Rigidbody val2 = val.AddComponent<Rigidbody>();
				val2.velocity = ((Component)Camera.main).transform.forward * 20f;
				Object.Destroy((Object)(object)val, 5f);
				GunNetworking.Instance?.SendShot(ShotEffect.Cube, ((Component)Camera.main).transform.position + ((Component)Camera.main).transform.forward, ((Component)Camera.main).transform.forward, 0f);
				GunNetworking.Instance?.SendFireAudioMessage();
				break;
			}
			}
			DOTween.Kill(Object.op_Implicit("gun_rotate"), false);
			TweenSettingsExtensions.OnComplete<TweenerCore<Quaternion, Vector3, QuaternionOptions>>(TweenSettingsExtensions.SetId<TweenerCore<Quaternion, Vector3, QuaternionOptions>>(TweenSettingsExtensions.SetEase<TweenerCore<Quaternion, Vector3, QuaternionOptions>>(ShortcutExtensions.DOLocalRotate(gunObject2.transform, gun2.RecoilAngle.ToVector3(), gun2.RecoilKickDuration, (RotateMode)0), (Ease)6), "gun_rotate"), TweenCallback.op_Implicit((Action)delegate
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				TweenSettingsExtensions.SetId<TweenerCore<Quaternion, Vector3, QuaternionOptions>>(TweenSettingsExtensions.SetEase<TweenerCore<Quaternion, Vector3, QuaternionOptions>>(ShortcutExtensions.DOLocalRotate(gunObject2.transform, gun2.NormalAngle.ToVector3(), gun2.RecoilRecoverDuration, (RotateMode)0), (Ease)6), "gun_rotate");
			}));
		}

		private void Instance_OnItemSelected(InventoryItem? item)
		{
			InventoryItem item2 = item;
			if ((Object)(object)Camera.main == (Object)null)
			{
				return;
			}
			foreach (GameObject gunObject in gunObjects)
			{
				gunObject.active = false;
			}
			if (item2 == null)
			{
				activeGun = null;
				activeGunObject = null;
				activeSource = null;
				Camera.main.fieldOfView = settingsManager.fov;
				GunNetworking.Instance?.SendEquip(null);
				return;
			}
			int num = guns.FindIndex((Gun g) => g.Id == item2.Definition.Id);
			if (num != -1)
			{
				activeGun = guns[num];
				activeGunObject = gunObjects[num];
				activeSource = gunSources[num];
				activeGunObject.active = true;
				fireTimer = 0f;
				GunNetworking.Instance?.SendEquip(activeGun.Id);
			}
		}

		internal static void SpawnBulletHole(Vector3 point, Vector3 normal, Texture2D texture, float duration)
		{
			//IL_002f: 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_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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0097: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			GameObject hole = GameObject.CreatePrimitive((PrimitiveType)5);
			((Object)hole).name = "bullet hole";
			hole.transform.position = point + normal * 0.01f;
			hole.transform.rotation = Quaternion.LookRotation(-normal);
			hole.transform.Rotate(0f, 0f, Random.Range(0f, 360f));
			hole.transform.localScale = Vector3.one * Random.Range(0.1f, 0.3f);
			Object.Destroy((Object)(object)hole.GetComponent<MeshCollider>());
			MeshRenderer component = hole.GetComponent<MeshRenderer>();
			Material val = new Material(Shader.Find("Unlit/Transparent"));
			val.SetTexture("_MainTex", (Texture)(object)texture);
			((Renderer)component).material = val;
			TweenSettingsExtensions.OnComplete<TweenerCore<Color, Color, ColorOptions>>(TweenSettingsExtensions.SetDelay<TweenerCore<Color, Color, ColorOptions>>(ShortcutExtensions.DOColor(((Renderer)component).material, new Color(1f, 1f, 1f, 0f), 1f), duration), TweenCallback.op_Implicit((Action)delegate
			{
				Object.Destroy((Object)(object)hole);
			}));
		}

		private static void SpawnBulletHole(RaycastHit hit, Texture2D texture, float duration)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			SpawnBulletHole(((RaycastHit)(ref hit)).point, ((RaycastHit)(ref hit)).normal, texture, duration);
		}

		public Sprite LoadSprite(string path)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0038: 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)
			byte[] array = File.ReadAllBytes(path);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array));
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}
	}
	public static class Extensions
	{
		public static Vector3 ToVector3(this float[] arr)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(arr[0], arr[1], arr[2]);
		}

		public static Transform? FindRecursive(this Transform parent, string name)
		{
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				if (((Object)child).name == name)
				{
					return child;
				}
				Transform val = child.FindRecursive(name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
	internal static class GltfHelpers
	{
		public static void BuildNode(GltfContainer container, int nodeIndex, Transform parent)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			Node val = container.Gltf.Nodes[nodeIndex];
			GameObject val2 = new GameObject(((GltfChildOfRootProperty)val).Name ?? "Node");
			val2.transform.SetParent(parent, false);
			if (val.Mesh.HasValue)
			{
				var (sharedMesh, num) = BuildMesh(container, val.Mesh.Value);
				val2.AddComponent<MeshFilter>().sharedMesh = sharedMesh;
				MeshRenderer val3 = val2.AddComponent<MeshRenderer>();
				Material val4 = new Material(Shader.Find("Standard"));
				if (num.HasValue)
				{
					Texture2D val5 = LoadTexture(container, num.Value);
					if ((Object)(object)val5 != (Object)null)
					{
						val4.mainTexture = (Texture)(object)val5;
					}
				}
				((Renderer)val3).material = val4;
			}
			if (val.Children != null)
			{
				int[] children = val.Children;
				foreach (int nodeIndex2 in children)
				{
					BuildNode(container, nodeIndex2, val2.transform);
				}
			}
		}

		public static (Mesh, int?) BuildMesh(GltfContainer container, int meshIndex)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			Mesh val = container.Gltf.Meshes[meshIndex];
			Mesh val2 = new Mesh();
			PrimitiveType val3 = val.Primitives[0];
			int accessorIndex = val3.Attributes["POSITION"];
			Vector3[] array = ReadVec3Array(container, accessorIndex);
			val2.vertices = Il2CppStructArray<Vector3>.op_Implicit(array);
			if (val3.Attributes.ContainsKey("TEXCOORD_0"))
			{
				int accessorIndex2 = val3.Attributes["TEXCOORD_0"];
				Vector2[] array2 = ReadVec2Array(container, accessorIndex2);
				val2.uv = Il2CppStructArray<Vector2>.op_Implicit(array2);
			}
			if (val3.Indices.HasValue)
			{
				int[] array3 = ReadIntArray(container, val3.Indices.Value);
				for (int i = 0; i < array3.Length; i += 3)
				{
					ref int reference = ref array3[i + 2];
					ref int reference2 = ref array3[i];
					int num = array3[i];
					int num2 = array3[i + 2];
					reference = num;
					reference2 = num2;
				}
				val2.triangles = Il2CppStructArray<int>.op_Implicit(array3);
			}
			val2.RecalculateNormals();
			val2.RecalculateBounds();
			return (val2, val3.Material);
		}

		public static Texture2D? LoadTexture(GltfContainer container, int materialIndex)
		{
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			Material val = container.Gltf.Materials[materialIndex];
			if (val.PbrMetallicRoughness?.BaseColorTexture == null)
			{
				return null;
			}
			int index = ((TextureInfo)val.PbrMetallicRoughness.BaseColorTexture).Index;
			Texture val2 = container.Gltf.Textures[index];
			if (!val2.Source.HasValue)
			{
				return null;
			}
			Image val3 = container.Gltf.Images[val2.Source.Value];
			if (!val3.BufferView.HasValue)
			{
				return null;
			}
			BufferView val4 = container.Gltf.BufferViews[val3.BufferView.Value];
			byte[] sourceArray = container.Buffer.Payload.ToArray();
			byte[] array = new byte[val4.ByteLength];
			Array.Copy(sourceArray, val4.ByteOffset, array, 0, val4.ByteLength);
			Texture2D val5 = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(val5, Il2CppStructArray<byte>.op_Implicit(array));
			return val5;
		}

		public static Vector2[] ReadVec2Array(GltfContainer container, int accessorIndex)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			Accessor val = container.Gltf.Accessors[accessorIndex];
			BufferView val2 = container.Gltf.BufferViews[val.BufferView.Value];
			byte[] value = container.Buffer.Payload.ToArray();
			int num = val2.ByteOffset + val.ByteOffset;
			Vector2[] array = (Vector2[])(object)new Vector2[val.Count];
			for (int i = 0; i < val.Count; i++)
			{
				float num2 = BitConverter.ToSingle(value, num + i * 8);
				float num3 = BitConverter.ToSingle(value, num + i * 8 + 4);
				array[i] = new Vector2(num2, 1f - num3);
			}
			return array;
		}

		public static Vector3[] ReadVec3Array(GltfContainer container, int accessorIndex)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			Accessor val = container.Gltf.Accessors[accessorIndex];
			BufferView val2 = container.Gltf.BufferViews[val.BufferView.Value];
			byte[] value = container.Buffer.Payload.ToArray();
			int num = val2.ByteOffset + val.ByteOffset;
			Vector3[] array = (Vector3[])(object)new Vector3[val.Count];
			for (int i = 0; i < val.Count; i++)
			{
				float num2 = BitConverter.ToSingle(value, num + i * 12);
				float num3 = BitConverter.ToSingle(value, num + i * 12 + 4);
				float num4 = BitConverter.ToSingle(value, num + i * 12 + 8);
				array[i] = new Vector3(0f - num2, num3, num4);
			}
			return array;
		}

		public static int[] ReadIntArray(GltfContainer container, int accessorIndex)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Invalid comparison between Unknown and I4
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Invalid comparison between Unknown and I4
			Accessor val = container.Gltf.Accessors[accessorIndex];
			BufferView val2 = container.Gltf.BufferViews[val.BufferView.Value];
			byte[] value = container.Buffer.Payload.ToArray();
			int num = val2.ByteOffset + val.ByteOffset;
			int[] array = new int[val.Count];
			for (int i = 0; i < val.Count; i++)
			{
				if ((int)val.ComponentType == 5123)
				{
					array[i] = BitConverter.ToUInt16(value, num + i * 2);
				}
				else if ((int)val.ComponentType == 5125)
				{
					array[i] = (int)BitConverter.ToUInt32(value, num + i * 4);
				}
			}
			return array;
		}
	}
	public class Grip
	{
		public string BoneName { get; set; } = "";


		public float PositionWeight { get; set; } = 1f;


		public float RotationWeight { get; set; } = 1f;

	}
	public class Gun
	{
		public int[] Version { get; set; } = new int[3] { 1, 0, 0 };


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


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


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


		public string? AudioFile { get; set; }

		public string? IconFile { get; set; }

		public string? HoleFile { get; set; }

		public float FireRate { get; set; } = 0.1f;


		public float AudioVolume { get; set; } = 0.5f;


		public float Damage { get; set; } = 10f;


		public float Range { get; set; } = 100f;


		public float AdsSpeed { get; set; } = 0.2f;


		public float AdsFov { get; set; } = 50f;


		public float RecoilKickDuration { get; set; } = 0.05f;


		public float RecoilRecoverDuration { get; set; } = 0.15f;


		public float BulletHoleDuration { get; set; } = 10f;


		public float[] NormalPosition { get; set; } = new float[3];


		public float[] AdsPosition { get; set; } = new float[3];


		public float[] NormalAngle { get; set; } = new float[3];


		public float[] RecoilAngle { get; set; } = new float[3];


		public ShotEffect Effect { get; set; } = ShotEffect.Normal;

	}
	internal static class GunLoader
	{
		public static List<Gun> LoadAll(string modResources)
		{
			List<Gun> list = new List<Gun>();
			string[] directories = Directory.GetDirectories(modResources);
			foreach (string text in directories)
			{
				string path = Path.Combine(text, "gun.json");
				if (File.Exists(path))
				{
					Gun gun = JsonConvert.DeserializeObject<Gun>(File.ReadAllText(path));
					if (string.IsNullOrEmpty(gun.Id))
					{
						gun.Id = Path.GetFileName(text);
					}
					Gun gun2 = gun;
					if (gun2.ModelFile == null)
					{
						Gun gun3 = gun2;
						string? obj = Directory.GetFiles(text, "*.glb").FirstOrDefault() ?? "";
						string text2 = obj;
						gun3.ModelFile = obj;
					}
					gun2 = gun;
					if (gun2.AudioFile == null)
					{
						Gun gun4 = gun2;
						string? obj2 = Directory.GetFiles(text, "*.wav").FirstOrDefault() ?? Directory.GetFiles(text, "*.mp3").FirstOrDefault();
						string text2 = obj2;
						gun4.AudioFile = obj2;
					}
					gun2 = gun;
					if (gun2.IconFile == null)
					{
						Gun gun5 = gun2;
						string? obj3 = Directory.GetFiles(text, "icon.*").FirstOrDefault() ?? Directory.GetFiles(text, "*.png").FirstOrDefault();
						string text2 = obj3;
						gun5.IconFile = obj3;
					}
					gun2 = gun;
					if (gun2.HoleFile == null)
					{
						string text2 = (gun2.HoleFile = Directory.GetFiles(text, "hole.*").FirstOrDefault());
					}
					list.Add(gun);
				}
			}
			return list;
		}

		public static GameObject LoadGun(string path)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			GltfContainer val;
			using (FileStream fileStream = new FileStream(path, FileMode.Open))
			{
				val = GltfContainer.FromGlb((Stream)fileStream);
			}
			GameObject val2 = new GameObject("Gun");
			if (val.Gltf.Scene.HasValue)
			{
				int[] nodes = val.Gltf.Scenes[val.Gltf.Scene.Value].Nodes;
				foreach (int nodeIndex in nodes)
				{
					GltfHelpers.BuildNode(val, nodeIndex, val2.transform);
				}
			}
			val2.transform.localScale = Vector3.one * 0.075f;
			return val2;
		}

		public static string GetModelPath(string modResources, Gun gun)
		{
			return Path.IsPathRooted(gun.ModelFile) ? gun.ModelFile : Path.Combine(modResources, gun.Id, gun.ModelFile);
		}

		public static string GetAudioPath(string modResources, Gun gun)
		{
			return (gun.AudioFile != null && Path.IsPathRooted(gun.AudioFile)) ? gun.AudioFile : Fallback(modResources, gun.Id, gun.AudioFile ?? "shot.wav", "shot.wav");
		}

		public static string GetIconPath(string modResources, Gun gun)
		{
			return (gun.IconFile != null && Path.IsPathRooted(gun.IconFile)) ? gun.IconFile : Fallback(modResources, gun.Id, gun.IconFile ?? "icon.png", "icon.png");
		}

		public static string GetHolePath(string modResources, Gun gun)
		{
			return (gun.HoleFile != null && Path.IsPathRooted(gun.HoleFile)) ? gun.HoleFile : Fallback(modResources, gun.Id, gun.HoleFile ?? "hole.png", "hole.png");
		}

		public static string GetDefaultHolePath(string modResources)
		{
			return Path.Combine(modResources, "hole.png");
		}

		private static string Fallback(string modResources, string gunId, string file, string fallback)
		{
			string text = Path.Combine(modResources, gunId, file);
			return File.Exists(text) ? text : Path.Combine(modResources, fallback);
		}
	}
	public class GunNetworking
	{
		private class GunNetworkLogger
		{
			[CompilerGenerated]
			[DebuggerBrowsable(DebuggerBrowsableState.Never)]
			private Instance <logger>P;

			public bool _loggingEnabled;

			public GunNetworkLogger(Instance logger)
			{
				<logger>P = logger;
				_loggingEnabled = false;
				base..ctor();
			}

			public void SetLoggingEnabled(bool enabled)
			{
				_loggingEnabled = enabled;
			}

			public void Msg(object obj)
			{
				if (_loggingEnabled)
				{
					<logger>P.Msg(obj);
				}
			}

			public void Warning(object obj)
			{
				if (_loggingEnabled)
				{
					<logger>P.Warning(obj);
				}
			}

			public void Error(object obj)
			{
				if (_loggingEnabled)
				{
					<logger>P.Warning(obj);
				}
			}
		}

		private readonly Dictionary<int, string> _remoteGuns = new Dictionary<int, string>();

		private readonly Dictionary<int, Dictionary<string, GameObject>> _remoteGunObjects = new Dictionary<int, Dictionary<string, GameObject>>();

		private readonly string _modResources;

		private readonly List<Gun> _guns;

		private GunNetworkLogger? _logger;

		private bool _loggingEnabled = false;

		public static GunNetworking? Instance { get; private set; }

		public bool LoggingEnabled
		{
			get
			{
				return _loggingEnabled;
			}
			set
			{
				_loggingEnabled = value;
				_logger?.SetLoggingEnabled(value);
			}
		}

		private GunNetworking(string modResources, List<Gun> guns)
		{
			_modResources = modResources;
			_guns = guns;
		}

		public static void Init(string modResources, List<Gun> guns, Instance logger)
		{
			if (AppDomain.CurrentDomain.GetAssemblies().Any((Assembly a) => a.GetName().Name == "Multiside.shared"))
			{
				Instance = new GunNetworking(modResources, guns);
				Instance._logger = new GunNetworkLogger(logger);
				Instance._logger.SetLoggingEnabled(Instance.LoggingEnabled);
				Instance._logger.Msg("Starting in Online mode");
				Instance.InitNetwork();
			}
		}

		private void InitNetwork()
		{
			if (NetworkRegistry.Provider != null)
			{
				Subscribe(NetworkRegistry.Provider);
			}
			else
			{
				NetworkRegistry.OnProviderRegistered += Subscribe;
			}
		}

		private void Subscribe(INetworkProvider provider)
		{
			INetworkProvider provider2 = provider;
			_logger?.Msg("GunNetworking: subscribing to network events");
			provider2.OnReceived += delegate(int actor, string channel, object data)
			{
				//IL_0197: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01de: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
				if (channel == "mszguns.equip")
				{
					string text = (string)data;
					_logger?.Msg($"GunNetworking: equip received from {actor}: '{text}'");
					if (string.IsNullOrEmpty(text))
					{
						_remoteGuns.Remove(actor);
					}
					else
					{
						_remoteGuns[actor] = text;
					}
					GameObject playerObject = provider2.GetPlayerObject(actor);
					if ((Object)(object)playerObject == (Object)null)
					{
						_logger?.Warning($"GunNetworking: no player object for actor {actor}");
					}
					else
					{
						SetRemoteGun(actor, playerObject, text);
					}
				}
				else if (channel == "mszguns.audio")
				{
					GameObject playerObject2 = provider2.GetPlayerObject(actor);
					if ((Object)(object)playerObject2 != (Object)null)
					{
						PlayRemoteShot(playerObject2);
					}
				}
				else if (!(channel != "mszguns.shot"))
				{
					float[] array = (float[])data;
					ShotEffect shotEffect = (ShotEffect)array[7];
					if (shotEffect == ShotEffect.Cube)
					{
						SpawnRemoteCube(new Vector3(array[0], array[1], array[2]), new Vector3(array[3], array[4], array[5]));
					}
					else if (array.Length >= 7 && !((Object)(object)Core.BulletHoleTexture == (Object)null))
					{
						Core.SpawnBulletHole(new Vector3(array[0], array[1], array[2]), new Vector3(array[3], array[4], array[5]), Core.BulletHoleTexture, array[6]);
					}
				}
			};
			provider2.OnPlayerLeft += delegate(int actor)
			{
				_logger?.Msg($"GunNetworking: player {actor} left, cleaning up");
				_remoteGuns.Remove(actor);
				_remoteGunObjects.Remove(actor);
			};
			provider2.OnRoomJoined += delegate
			{
				_logger?.Msg("GunNetworking: room joined, broadcasting equip: '" + Core.ActiveGunId + "'");
				SendEquip(Core.ActiveGunId);
			};
			provider2.OnPlayerJoined += delegate(int actor)
			{
				_logger?.Msg($"GunNetworking: player {actor} joined, sending equip: '{Core.ActiveGunId}'");
				if (!string.IsNullOrEmpty(Core.ActiveGunId))
				{
					provider2.SendTo(actor, "mszguns.equip", (object)Core.ActiveGunId, true);
				}
			};
		}

		public void SendFireAudioMessage()
		{
			INetworkProvider provider = NetworkRegistry.Provider;
			if (provider != null)
			{
				provider.Send("mszguns.audio", (object)(-1), true);
			}
		}

		private void SetRemoteGun(int actor, GameObject playerObj, string gunId)
		{
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			string gunId2 = gunId;
			_logger?.Msg($"GunNetworking: setting remote gun for actor {actor}: '{gunId2}'");
			if (_remoteGunObjects.TryGetValue(actor, out Dictionary<string, GameObject> value))
			{
				foreach (GameObject value3 in value.Values)
				{
					value3.SetActive(false);
				}
				if (!string.IsNullOrEmpty(gunId2) && value.TryGetValue(gunId2, out var value2))
				{
					_logger?.Msg("GunNetworking: using cached model for '" + gunId2 + "'");
					value2.SetActive(true);
					UpdateAudioClip(playerObj, gunId2);
					return;
				}
			}
			if (string.IsNullOrEmpty(gunId2))
			{
				return;
			}
			Gun gun = _guns.FirstOrDefault((Gun g) => g.Id == gunId2);
			if (gun == null)
			{
				_logger?.Warning("GunNetworking: gun '" + gunId2 + "' not found in registry");
				return;
			}
			_logger?.Msg("GunNetworking: loading model for '" + gunId2 + "'");
			GameObject val = GunLoader.LoadGun(GunLoader.GetModelPath(_modResources, gun));
			((Object)val).name = "RemoteGun";
			Transform val2 = playerObj.transform.Find("Zero/PLAYER Armature/Rig Root/Hips/Spine/Chest/Neck2/Neck1/Head/CameraHoldHead/playerCamera");
			if ((Object)(object)val2 == (Object)null)
			{
				_logger?.Warning($"GunNetworking: could not find camera transform on actor {actor}, parenting to root");
			}
			val.transform.SetParent(val2 ?? playerObj.transform, false);
			val.transform.localPosition = gun.NormalPosition.ToVector3();
			val.transform.localEulerAngles = gun.NormalAngle.ToVector3();
			if (!_remoteGunObjects.ContainsKey(actor))
			{
				_remoteGunObjects[actor] = new Dictionary<string, GameObject>();
			}
			_remoteGunObjects[actor][gunId2] = val;
			UpdateAudioClip(playerObj, gunId2);
		}

		private void UpdateAudioClip(GameObject playerObj, string gunId)
		{
			string gunId2 = gunId;
			Gun gun = _guns.FirstOrDefault((Gun g) => g.Id == gunId2);
			if (gun == null)
			{
				_logger?.Warning("HandleGunAudio: gun '" + gunId2 + "' not found");
				return;
			}
			AudioSource val = playerObj.GetComponent<AudioSource>();
			if ((Object)(object)val == (Object)null)
			{
				_logger?.Msg("GunNetworking: adding AudioSource to player object for '" + gunId2 + "'");
				val = playerObj.AddComponent<AudioSource>();
				val.spatialBlend = 1f;
				val.maxDistance = 50f;
				val.rolloffMode = (AudioRolloffMode)1;
			}
			if ((Object)(object)val.clip == (Object)null || ((Object)val.clip).name != gun.Id)
			{
				val.clip = AudioImporter.Load(GunLoader.GetAudioPath(_modResources, gun));
			}
		}

		private void PlayRemoteShot(GameObject playerObj)
		{
			AudioSource component = playerObj.GetComponent<AudioSource>();
			component.PlayOneShot(component.clip);
		}

		private static void SpawnRemoteCube(Vector3 spawnPos, Vector3 spawnDir)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
			val.transform.position = spawnPos;
			val.transform.localScale = Vector3.one * 0.2f;
			Rigidbody val2 = val.AddComponent<Rigidbody>();
			val2.velocity = spawnDir * 20f;
			Object.Destroy((Object)(object)val, 5f);
		}

		public void SendShot(ShotEffect effect, Vector3 pos, Vector3 dir, float duration)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0034: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			INetworkProvider provider = NetworkRegistry.Provider;
			if (provider != null)
			{
				provider.Send("mszguns.shot", (object)new float[8]
				{
					pos.x,
					pos.y,
					pos.z,
					dir.x,
					dir.y,
					dir.z,
					duration,
					(float)effect
				}, true);
			}
		}

		public void SendEquip(string? gunId)
		{
			INetworkProvider provider = NetworkRegistry.Provider;
			if (provider != null)
			{
				provider.Send("mszguns.equip", (object)(gunId ?? ""), true);
			}
		}
	}
	public enum ShotEffect
	{
		Normal,
		Shotgun,
		Cube
	}
}

UserLibs/NAudio.Core.dll

Decompiled a day 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

UserLibs/NAudio.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using NAudio.Wave.SampleProviders;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Mark Heath & Contributors")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Mark Heath 2026")]
[assembly: AssemblyDescription("NAudio, an audio library for .NET")]
[assembly: AssemblyFileVersion("2.3.0.0")]
[assembly: AssemblyInformationalVersion("2.3.0+c89fee940ee6f8d7374d18714a6b85d8b7a18ab0")]
[assembly: AssemblyProduct("NAudio")]
[assembly: AssemblyTitle("NAudio")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.3.0.0")]
[module: UnverifiableCode]
namespace NAudio.Wave;

public class AudioFileReader : WaveStream, ISampleProvider
{
	private WaveStream readerStream;

	private readonly SampleChannel sampleChannel;

	private readonly int destBytesPerSample;

	private readonly int sourceBytesPerSample;

	private readonly long length;

	private readonly object lockObject;

	public string FileName { get; }

	public override WaveFormat WaveFormat => sampleChannel.WaveFormat;

	public override long Length => length;

	public override long Position
	{
		get
		{
			return SourceToDest(((Stream)(object)readerStream).Position);
		}
		set
		{
			lock (lockObject)
			{
				((Stream)(object)readerStream).Position = DestToSource(value);
			}
		}
	}

	public float Volume
	{
		get
		{
			return sampleChannel.Volume;
		}
		set
		{
			sampleChannel.Volume = value;
		}
	}

	public AudioFileReader(string fileName)
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Expected O, but got Unknown
		lockObject = new object();
		FileName = fileName;
		CreateReaderStream(fileName);
		sourceBytesPerSample = readerStream.WaveFormat.BitsPerSample / 8 * readerStream.WaveFormat.Channels;
		sampleChannel = new SampleChannel((IWaveProvider)(object)readerStream, false);
		destBytesPerSample = 4 * sampleChannel.WaveFormat.Channels;
		length = SourceToDest(((Stream)(object)readerStream).Length);
	}

	private void CreateReaderStream(string fileName)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Invalid comparison between Unknown and I4
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Invalid comparison between Unknown and I4
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Expected O, but got Unknown
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Expected O, but got Unknown
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Expected O, but got Unknown
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Expected O, but got Unknown
		if (fileName.EndsWith(".wav", StringComparison.OrdinalIgnoreCase))
		{
			readerStream = (WaveStream)new WaveFileReader(fileName);
			if ((int)readerStream.WaveFormat.Encoding != 1 && (int)readerStream.WaveFormat.Encoding != 3)
			{
				readerStream = WaveFormatConversionStream.CreatePcmStream(readerStream);
				readerStream = (WaveStream)new BlockAlignReductionStream(readerStream);
			}
		}
		else if (fileName.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase))
		{
			if (Environment.OSVersion.Version.Major < 6)
			{
				readerStream = (WaveStream)(object)new Mp3FileReader(fileName);
			}
			else
			{
				readerStream = (WaveStream)new MediaFoundationReader(fileName);
			}
		}
		else if (fileName.EndsWith(".aiff", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".aif", StringComparison.OrdinalIgnoreCase))
		{
			readerStream = (WaveStream)new AiffFileReader(fileName);
		}
		else
		{
			readerStream = (WaveStream)new MediaFoundationReader(fileName);
		}
	}

	public override int Read(byte[] buffer, int offset, int count)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		WaveBuffer val = new WaveBuffer(buffer);
		int count2 = count / 4;
		return Read(val.FloatBuffer, offset / 4, count2) * 4;
	}

	public int Read(float[] buffer, int offset, int count)
	{
		lock (lockObject)
		{
			return sampleChannel.Read(buffer, offset, count);
		}
	}

	private long SourceToDest(long sourceBytes)
	{
		return destBytesPerSample * (sourceBytes / sourceBytesPerSample);
	}

	private long DestToSource(long destBytes)
	{
		return sourceBytesPerSample * (destBytes / destBytesPerSample);
	}

	protected override void Dispose(bool disposing)
	{
		if (disposing && readerStream != null)
		{
			((Stream)(object)readerStream).Dispose();
			readerStream = null;
		}
		((Stream)this).Dispose(disposing);
	}
}
public class Mp3FileReader : Mp3FileReaderBase
{
	public Mp3FileReader(string mp3FileName)
		: base((Stream)File.OpenRead(mp3FileName), new FrameDecompressorBuilder(CreateAcmFrameDecompressor), true)
	{
	}//IL_000e: Unknown result type (might be due to invalid IL or missing references)
	//IL_0019: Expected O, but got Unknown


	public Mp3FileReader(Stream inputStream)
		: base(inputStream, new FrameDecompressorBuilder(CreateAcmFrameDecompressor), false)
	{
	}//IL_0009: Unknown result type (might be due to invalid IL or missing references)
	//IL_0014: Expected O, but got Unknown


	public static IMp3FrameDecompressor CreateAcmFrameDecompressor(WaveFormat mp3Format)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		return (IMp3FrameDecompressor)new AcmMp3FrameDecompressor(mp3Format);
	}
}

UserLibs/NAudio.Wasapi.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using NAudio.CoreAudioApi;
using NAudio.CoreAudioApi.Interfaces;
using NAudio.Dmo;
using NAudio.Dmo.Effect;
using NAudio.MediaFoundation;
using NAudio.Utils;
using NAudio.Wasapi.CoreAudioApi;
using NAudio.Wasapi.CoreAudioApi.Interfaces;
using NAudio.Wave;

[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.Wasapi")]
[assembly: AssemblyTitle("NAudio.Wasapi")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.3.0.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 NAudio.MediaFoundation
{
	public static class AudioSubtypes
	{
		[FieldDescription("AAC")]
		public static readonly Guid MFAudioFormat_AAC = new Guid("00001610-0000-0010-8000-00aa00389b71");

		[FieldDescription("ADTS")]
		public static readonly Guid MFAudioFormat_ADTS = new Guid("00001600-0000-0010-8000-00aa00389b71");

		[FieldDescription("Dolby AC3 SPDIF")]
		public static readonly Guid MFAudioFormat_Dolby_AC3_SPDIF = new Guid("00000092-0000-0010-8000-00aa00389b71");

		[FieldDescription("DRM")]
		public static readonly Guid MFAudioFormat_DRM = new Guid("00000009-0000-0010-8000-00aa00389b71");

		[FieldDescription("DTS")]
		public static readonly Guid MFAudioFormat_DTS = new Guid("00000008-0000-0010-8000-00aa00389b71");

		[FieldDescription("IEEE floating-point")]
		public static readonly Guid MFAudioFormat_Float = new Guid("00000003-0000-0010-8000-00aa00389b71");

		[FieldDescription("MP3")]
		public static readonly Guid MFAudioFormat_MP3 = new Guid("00000055-0000-0010-8000-00aa00389b71");

		[FieldDescription("MPEG")]
		public static readonly Guid MFAudioFormat_MPEG = new Guid("00000050-0000-0010-8000-00aa00389b71");

		[FieldDescription("WMA 9 Voice codec")]
		public static readonly Guid MFAudioFormat_MSP1 = new Guid("0000000a-0000-0010-8000-00aa00389b71");

		[FieldDescription("PCM")]
		public static readonly Guid MFAudioFormat_PCM = new Guid("00000001-0000-0010-8000-00aa00389b71");

		[FieldDescription("WMA SPDIF")]
		public static readonly Guid MFAudioFormat_WMASPDIF = new Guid("00000164-0000-0010-8000-00aa00389b71");

		[FieldDescription("WMAudio Lossless")]
		public static readonly Guid MFAudioFormat_WMAudio_Lossless = new Guid("00000163-0000-0010-8000-00aa00389b71");

		[FieldDescription("Windows Media Audio")]
		public static readonly Guid MFAudioFormat_WMAudioV8 = new Guid("00000161-0000-0010-8000-00aa00389b71");

		[FieldDescription("Windows Media Audio Professional")]
		public static readonly Guid MFAudioFormat_WMAudioV9 = new Guid("00000162-0000-0010-8000-00aa00389b71");

		[FieldDescription("Dolby AC3")]
		public static readonly Guid MFAudioFormat_Dolby_AC3 = new Guid("e06d802c-db46-11cf-b4d1-00805f6cbbea");

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

		public static readonly Guid MFAudioFormat_ALAC = new Guid("63616c61-0000-0010-8000-00aa00389b71");

		[FieldDescription("MPEG-4 and AAC Audio Types")]
		public static readonly Guid MEDIASUBTYPE_RAW_AAC1 = new Guid("000000ff-0000-0010-8000-00aa00389b71");

		[FieldDescription("Dolby Audio Types")]
		public static readonly Guid MEDIASUBTYPE_DVM = new Guid("00002000-0000-0010-8000-00aa00389b71");

		[FieldDescription("Dolby Audio Types")]
		public static readonly Guid MEDIASUBTYPE_DOLBY_DDPLUS = new Guid("a7fb87af-2d02-42fb-a4d4-05cd93843bdd");

		[FieldDescription("μ-law")]
		public static readonly Guid KSDATAFORMAT_SUBTYPE_MULAW = new Guid("00000007-0000-0010-8000-00aa00389b71");

		[FieldDescription("ADPCM")]
		public static readonly Guid KSDATAFORMAT_SUBTYPE_ADPCM = new Guid("00000002-0000-0010-8000-00aa00389b71");

		[FieldDescription("Dolby Digital Plus for HDMI")]
		public static readonly Guid KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS = new Guid("0000000a-0cea-0010-8000-00aa00389b71");

		[FieldDescription("MSAudio1")]
		public static readonly Guid MEDIASUBTYPE_MSAUDIO1 = new Guid("00000160-0000-0010-8000-00aa00389b71");

		[FieldDescription("IMA ADPCM")]
		public static readonly Guid ImaAdpcm = new Guid("00000011-0000-0010-8000-00aa00389b71");

		[FieldDescription("WMSP2")]
		public static readonly Guid WMMEDIASUBTYPE_WMSP2 = new Guid("0000000b-0000-0010-8000-00aa00389b71");
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("7FEE9E9A-4A89-47a6-899C-B6A53A70FB67")]
	public interface IMFActivate : IMFAttributes
	{
		new void GetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][Out] IntPtr pValue);

		new void GetItemType([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pType);

		new void CompareItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, int matchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void GetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

		new void GetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

		new void GetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

		new void GetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

		new void GetStringLength([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

		new void GetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

		new void GetAllocatedString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

		new void GetBlobSize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

		new void GetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

		new void GetAllocatedBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

		new void GetUnknown([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

		new void SetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value);

		new void DeleteItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

		new void DeleteAllItems();

		new void SetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

		new void SetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

		new void SetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

		new void SetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

		new void SetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPWStr)] string wszValue);

		new void SetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

		new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

		new void LockStore();

		new void UnlockStore();

		new void GetCount(out int pcItems);

		new void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] IntPtr pValue);

		new void CopyAllItems([In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);

		void ActivateObject([In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppv);

		void ShutdownObject();

		void DetachObject();
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("2CD2D921-C447-44A7-A13C-4ADABFC247E3")]
	public interface IMFAttributes
	{
		void GetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][Out] IntPtr pValue);

		void GetItemType([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pType);

		void CompareItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, int matchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		void GetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

		void GetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

		void GetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

		void GetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

		void GetStringLength([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

		void GetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

		void GetAllocatedString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

		void GetBlobSize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

		void GetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

		void GetAllocatedBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

		void GetUnknown([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

		void SetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value);

		void DeleteItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

		void DeleteAllItems();

		void SetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

		void SetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

		void SetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

		void SetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

		void SetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPWStr)] string wszValue);

		void SetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

		void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

		void LockStore();

		void UnlockStore();

		void GetCount(out int pcItems);

		void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] IntPtr pValue);

		void CopyAllItems([In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("ad4c1b00-4bf7-422f-9175-756693d9130d")]
	public interface IMFByteStream
	{
		void GetCapabilities(ref int pdwCapabiities);

		void GetLength(ref long pqwLength);

		void SetLength(long qwLength);

		void GetCurrentPosition(ref long pqwPosition);

		void SetCurrentPosition(long qwPosition);

		void IsEndOfStream([MarshalAs(UnmanagedType.Bool)] ref bool pfEndOfStream);

		void Read(IntPtr pb, int cb, ref int pcbRead);

		void BeginRead(IntPtr pb, int cb, IntPtr pCallback, IntPtr punkState);

		void EndRead(IntPtr pResult, ref int pcbRead);

		void Write(IntPtr pb, int cb, ref int pcbWritten);

		void BeginWrite(IntPtr pb, int cb, IntPtr pCallback, IntPtr punkState);

		void EndWrite(IntPtr pResult, ref int pcbWritten);

		void Seek(int SeekOrigin, long llSeekOffset, int dwSeekFlags, ref long pqwCurrentPosition);

		void Flush();

		void Close();
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("5BC8A76B-869A-46A3-9B03-FA218A66AEBE")]
	public interface IMFCollection
	{
		void GetElementCount(out int pcElements);

		void GetElement([In] int dwElementIndex, [MarshalAs(UnmanagedType.IUnknown)] out object ppUnkElement);

		void AddElement([In][MarshalAs(UnmanagedType.IUnknown)] object pUnkElement);

		void RemoveElement([In] int dwElementIndex, [MarshalAs(UnmanagedType.IUnknown)] out object ppUnkElement);

		void InsertElementAt([In] int dwIndex, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

		void RemoveAllElements();
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("045FA593-8799-42b8-BC8D-8968C6453507")]
	public interface IMFMediaBuffer
	{
		void Lock(out IntPtr ppbBuffer, out int pcbMaxLength, out int pcbCurrentLength);

		void Unlock();

		void GetCurrentLength(out int pcbCurrentLength);

		void SetCurrentLength(int cbCurrentLength);

		void GetMaxLength(out int pcbMaxLength);
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("DF598932-F10C-4E39-BBA2-C308F101DAA3")]
	public interface IMFMediaEvent : IMFAttributes
	{
		new void GetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][Out] IntPtr pValue);

		new void GetItemType([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pType);

		new void CompareItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, int matchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void GetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

		new void GetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

		new void GetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

		new void GetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

		new void GetStringLength([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

		new void GetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

		new void GetAllocatedString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

		new void GetBlobSize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

		new void GetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

		new void GetAllocatedBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

		new void GetUnknown([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

		new void SetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value);

		new void DeleteItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

		new void DeleteAllItems();

		new void SetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

		new void SetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

		new void SetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

		new void SetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

		new void SetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPWStr)] string wszValue);

		new void SetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

		new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

		new void LockStore();

		new void UnlockStore();

		new void GetCount(out int pcItems);

		new void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] IntPtr pValue);

		new void CopyAllItems([In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);

		void GetType(out MediaEventType pmet);

		void GetExtendedType(out Guid pguidExtendedType);

		void GetStatus([MarshalAs(UnmanagedType.Error)] out int phrStatus);

		void GetValue([Out] IntPtr pvValue);
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("44AE0FA8-EA31-4109-8D2E-4CAE4997C555")]
	public interface IMFMediaType : IMFAttributes
	{
		new void GetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][Out] IntPtr pValue);

		new void GetItemType([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pType);

		new void CompareItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, int matchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void GetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

		new void GetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

		new void GetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

		new void GetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

		new void GetStringLength([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

		new void GetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

		new void GetAllocatedString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

		new void GetBlobSize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

		new void GetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

		new void GetAllocatedBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

		new void GetUnknown([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

		new void SetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value);

		new void DeleteItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

		new void DeleteAllItems();

		new void SetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

		new void SetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

		new void SetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

		new void SetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

		new void SetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPWStr)] string wszValue);

		new void SetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

		new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

		new void LockStore();

		new void UnlockStore();

		new void GetCount(out int pcItems);

		new void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] IntPtr pValue);

		new void CopyAllItems([In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);

		void GetMajorType(out Guid pguidMajorType);

		void IsCompressedFormat([MarshalAs(UnmanagedType.Bool)] out bool pfCompressed);

		[PreserveSig]
		int IsEqual([In][MarshalAs(UnmanagedType.Interface)] IMFMediaType pIMediaType, ref int pdwFlags);

		void GetRepresentation([In] Guid guidRepresentation, ref IntPtr ppvRepresentation);

		void FreeRepresentation([In] Guid guidRepresentation, [In] IntPtr pvRepresentation);
	}
	[ComImport]
	[Guid("E7FE2E12-661C-40DA-92F9-4F002AB67627")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	public interface IMFReadWriteClassFactory
	{
		void CreateInstanceFromURL([In][MarshalAs(UnmanagedType.LPStruct)] Guid clsid, [In][MarshalAs(UnmanagedType.LPWStr)] string pwszURL, [In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pAttributes, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject);

		void CreateInstanceFromObject([In][MarshalAs(UnmanagedType.LPStruct)] Guid clsid, [In][MarshalAs(UnmanagedType.IUnknown)] object punkObject, [In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pAttributes, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject);
	}
	[ComImport]
	[Guid("48e2ed0f-98c2-4a37-bed5-166312ddd83f")]
	public class MFReadWriteClassFactory
	{
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("c40a00f2-b93a-4d80-ae8c-5a1c634f58e4")]
	public interface IMFSample : IMFAttributes
	{
		new void GetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][Out] IntPtr pValue);

		new void GetItemType([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pType);

		new void CompareItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, int matchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void GetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

		new void GetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

		new void GetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

		new void GetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

		new void GetStringLength([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

		new void GetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

		new void GetAllocatedString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

		new void GetBlobSize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

		new void GetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

		new void GetAllocatedBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

		new void GetUnknown([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

		new void SetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value);

		new void DeleteItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

		new void DeleteAllItems();

		new void SetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

		new void SetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

		new void SetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

		new void SetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

		new void SetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPWStr)] string wszValue);

		new void SetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

		new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

		new void LockStore();

		new void UnlockStore();

		new void GetCount(out int pcItems);

		new void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] IntPtr pValue);

		new void CopyAllItems([In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);

		void GetSampleFlags(out int pdwSampleFlags);

		void SetSampleFlags(int dwSampleFlags);

		void GetSampleTime(out long phnsSampletime);

		void SetSampleTime(long hnsSampleTime);

		void GetSampleDuration(out long phnsSampleDuration);

		void SetSampleDuration(long hnsSampleDuration);

		void GetBufferCount(out int pdwBufferCount);

		void GetBufferByIndex(int dwIndex, out IMFMediaBuffer ppBuffer);

		void ConvertToContiguousBuffer(out IMFMediaBuffer ppBuffer);

		void AddBuffer(IMFMediaBuffer pBuffer);

		void RemoveBufferByIndex(int dwIndex);

		void RemoveAllBuffers();

		void GetTotalLength(out int pcbTotalLength);

		void CopyToBuffer(IMFMediaBuffer pBuffer);
	}
	[ComImport]
	[Guid("3137f1cd-fe5e-4805-a5d8-fb477448cb3d")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	public interface IMFSinkWriter
	{
		void AddStream([In][MarshalAs(UnmanagedType.Interface)] IMFMediaType pTargetMediaType, out int pdwStreamIndex);

		void SetInputMediaType([In] int dwStreamIndex, [In][MarshalAs(UnmanagedType.Interface)] IMFMediaType pInputMediaType, [In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pEncodingParameters);

		void BeginWriting();

		void WriteSample([In] int dwStreamIndex, [In][MarshalAs(UnmanagedType.Interface)] IMFSample pSample);

		void SendStreamTick([In] int dwStreamIndex, [In] long llTimestamp);

		void PlaceMarker([In] int dwStreamIndex, [In] IntPtr pvContext);

		void NotifyEndOfSegment([In] int dwStreamIndex);

		void Flush([In] int dwStreamIndex);

		void DoFinalize();

		void GetServiceForStream([In] int dwStreamIndex, [In] ref Guid guidService, [In] ref Guid riid, out IntPtr ppvObject);

		void GetStatistics([In] int dwStreamIndex, [In][Out] MF_SINK_WRITER_STATISTICS pStats);
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("70ae66f2-c809-4e4f-8915-bdcb406b7993")]
	public interface IMFSourceReader
	{
		void GetStreamSelection([In] int dwStreamIndex, [MarshalAs(UnmanagedType.Bool)] out bool pSelected);

		void SetStreamSelection([In] int dwStreamIndex, [In][MarshalAs(UnmanagedType.Bool)] bool pSelected);

		void GetNativeMediaType([In] int dwStreamIndex, [In] int dwMediaTypeIndex, out IMFMediaType ppMediaType);

		void GetCurrentMediaType([In] int dwStreamIndex, out IMFMediaType ppMediaType);

		void SetCurrentMediaType([In] int dwStreamIndex, IntPtr pdwReserved, [In] IMFMediaType pMediaType);

		void SetCurrentPosition([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidTimeFormat, [In] IntPtr varPosition);

		void ReadSample([In] int dwStreamIndex, [In] int dwControlFlags, out int pdwActualStreamIndex, out MF_SOURCE_READER_FLAG pdwStreamFlags, out ulong pllTimestamp, out IMFSample ppSample);

		void Flush([In] int dwStreamIndex);

		void GetServiceForStream([In] int dwStreamIndex, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidService, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IntPtr ppvObject);

		[PreserveSig]
		int GetPresentationAttribute([In] int dwStreamIndex, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidAttribute, [Out] IntPtr pvarAttribute);
	}
	[Flags]
	public enum MF_SOURCE_READER_FLAG
	{
		None = 0,
		MF_SOURCE_READERF_ERROR = 1,
		MF_SOURCE_READERF_ENDOFSTREAM = 2,
		MF_SOURCE_READERF_NEWSTREAM = 4,
		MF_SOURCE_READERF_NATIVEMEDIATYPECHANGED = 0x10,
		MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED = 0x20,
		MF_SOURCE_READERF_STREAMTICK = 0x100,
		MF_SOURCE_READERF_ALLEFFECTSREMOVED = 0x200
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("bf94c121-5b05-4e6f-8000-ba598961414d")]
	public interface IMFTransform
	{
		void GetStreamLimits(out int pdwInputMinimum, out int pdwInputMaximum, out int pdwOutputMinimum, out int pdwOutputMaximum);

		void GetStreamCount(out int pcInputStreams, out int pcOutputStreams);

		void GetStreamIds([In] int dwInputIdArraySize, [In][Out] IntPtr pdwInputIDs, [In] int dwOutputIdArraySize, [In][Out] IntPtr pdwOutputIDs);

		void GetInputStreamInfo([In] int dwInputStreamId, out MFT_INPUT_STREAM_INFO pStreamInfo);

		void GetOutputStreamInfo([In] int dwOutputStreamId, out MFT_OUTPUT_STREAM_INFO pStreamInfo);

		void GetAttributes(out IMFAttributes pAttributes);

		void GetInputStreamAttributes([In] int dwInputStreamId, out IMFAttributes pAttributes);

		void GetOutputStreamAttributes([In] int dwOutputStreamId, out IMFAttributes pAttributes);

		void DeleteInputStream([In] int dwOutputStreamId);

		void AddInputStreams([In] int cStreams, [In] IntPtr adwStreamIDs);

		void GetInputAvailableType([In] int dwInputStreamId, [In] int dwTypeIndex, out IMFMediaType ppType);

		void GetOutputAvailableType([In] int dwOutputStreamId, [In] int dwTypeIndex, out IMFMediaType ppType);

		void SetInputType([In] int dwInputStreamId, [In] IMFMediaType pType, [In] _MFT_SET_TYPE_FLAGS dwFlags);

		void SetOutputType([In] int dwOutputStreamId, [In] IMFMediaType pType, [In] _MFT_SET_TYPE_FLAGS dwFlags);

		void GetInputCurrentType([In] int dwInputStreamId, out IMFMediaType ppType);

		void GetOutputCurrentType([In] int dwOutputStreamId, out IMFMediaType ppType);

		void GetInputStatus([In] int dwInputStreamId, out _MFT_INPUT_STATUS_FLAGS pdwFlags);

		void GetOutputStatus([In] int dwInputStreamId, out _MFT_OUTPUT_STATUS_FLAGS pdwFlags);

		void SetOutputBounds([In] long hnsLowerBound, [In] long hnsUpperBound);

		void ProcessEvent([In] int dwInputStreamId, [In] IMFMediaEvent pEvent);

		void ProcessMessage([In] MFT_MESSAGE_TYPE eMessage, [In] IntPtr ulParam);

		void ProcessInput([In] int dwInputStreamId, [In] IMFSample pSample, int dwFlags);

		[PreserveSig]
		int ProcessOutput([In] _MFT_PROCESS_OUTPUT_FLAGS dwFlags, [In] int cOutputBufferCount, [In][Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] MFT_OUTPUT_DATA_BUFFER[] pOutputSamples, out _MFT_PROCESS_OUTPUT_STATUS pdwStatus);
	}
	public enum MediaEventType
	{
		MEUnknown = 0,
		MEError = 1,
		MEExtendedType = 2,
		MENonFatalError = 3,
		MESessionUnknown = 100,
		MESessionTopologySet = 101,
		MESessionTopologiesCleared = 102,
		MESessionStarted = 103,
		MESessionPaused = 104,
		MESessionStopped = 105,
		MESessionClosed = 106,
		MESessionEnded = 107,
		MESessionRateChanged = 108,
		MESessionScrubSampleComplete = 109,
		MESessionCapabilitiesChanged = 110,
		MESessionTopologyStatus = 111,
		MESessionNotifyPresentationTime = 112,
		MENewPresentation = 113,
		MELicenseAcquisitionStart = 114,
		MELicenseAcquisitionCompleted = 115,
		MEIndividualizationStart = 116,
		MEIndividualizationCompleted = 117,
		MEEnablerProgress = 118,
		MEEnablerCompleted = 119,
		MEPolicyError = 120,
		MEPolicyReport = 121,
		MEBufferingStarted = 122,
		MEBufferingStopped = 123,
		MEConnectStart = 124,
		MEConnectEnd = 125,
		MEReconnectStart = 126,
		MEReconnectEnd = 127,
		MERendererEvent = 128,
		MESessionStreamSinkFormatChanged = 129,
		MESourceUnknown = 200,
		MESourceStarted = 201,
		MEStreamStarted = 202,
		MESourceSeeked = 203,
		MEStreamSeeked = 204,
		MENewStream = 205,
		MEUpdatedStream = 206,
		MESourceStopped = 207,
		MEStreamStopped = 208,
		MESourcePaused = 209,
		MEStreamPaused = 210,
		MEEndOfPresentation = 211,
		MEEndOfStream = 212,
		MEMediaSample = 213,
		MEStreamTick = 214,
		MEStreamThinMode = 215,
		MEStreamFormatChanged = 216,
		MESourceRateChanged = 217,
		MEEndOfPresentationSegment = 218,
		MESourceCharacteristicsChanged = 219,
		MESourceRateChangeRequested = 220,
		MESourceMetadataChanged = 221,
		MESequencerSourceTopologyUpdated = 222,
		MESinkUnknown = 300,
		MEStreamSinkStarted = 301,
		MEStreamSinkStopped = 302,
		MEStreamSinkPaused = 303,
		MEStreamSinkRateChanged = 304,
		MEStreamSinkRequestSample = 305,
		MEStreamSinkMarker = 306,
		MEStreamSinkPrerolled = 307,
		MEStreamSinkScrubSampleComplete = 308,
		MEStreamSinkFormatChanged = 309,
		MEStreamSinkDeviceChanged = 310,
		MEQualityNotify = 311,
		MESinkInvalidated = 312,
		MEAudioSessionNameChanged = 313,
		MEAudioSessionVolumeChanged = 314,
		MEAudioSessionDeviceRemoved = 315,
		MEAudioSessionServerShutdown = 316,
		MEAudioSessionGroupingParamChanged = 317,
		MEAudioSessionIconChanged = 318,
		MEAudioSessionFormatChanged = 319,
		MEAudioSessionDisconnected = 320,
		MEAudioSessionExclusiveModeOverride = 321,
		METrustUnknown = 400,
		MEPolicyChanged = 401,
		MEContentProtectionMessage = 402,
		MEPolicySet = 403,
		MEWMDRMLicenseBackupCompleted = 500,
		MEWMDRMLicenseBackupProgress = 501,
		MEWMDRMLicenseRestoreCompleted = 502,
		MEWMDRMLicenseRestoreProgress = 503,
		MEWMDRMLicenseAcquisitionCompleted = 506,
		MEWMDRMIndividualizationCompleted = 508,
		MEWMDRMIndividualizationProgress = 513,
		MEWMDRMProximityCompleted = 514,
		MEWMDRMLicenseStoreCleaned = 515,
		MEWMDRMRevocationDownloadCompleted = 516,
		METransformUnknown = 600,
		METransformNeedInput = 601,
		METransformHaveOutput = 602,
		METransformDrainComplete = 603,
		METransformMarker = 604
	}
	public static class MediaFoundationAttributes
	{
		public static readonly Guid MF_TRANSFORM_ASYNC = new Guid("f81a699a-649a-497d-8c73-29f8fed6ad7a");

		public static readonly Guid MF_TRANSFORM_ASYNC_UNLOCK = new Guid("e5666d6b-3422-4eb6-a421-da7db1f8e207");

		[FieldDescription("Transform Flags")]
		public static readonly Guid MF_TRANSFORM_FLAGS_Attribute = new Guid("9359bb7e-6275-46c4-a025-1c01e45f1a86");

		[FieldDescription("Transform Category")]
		public static readonly Guid MF_TRANSFORM_CATEGORY_Attribute = new Guid("ceabba49-506d-4757-a6ff-66c184987e4e");

		[FieldDescription("Class identifier")]
		public static readonly Guid MFT_TRANSFORM_CLSID_Attribute = new Guid("6821c42b-65a4-4e82-99bc-9a88205ecd0c");

		[FieldDescription("Container type")]
		public static readonly Guid MF_TRANSCODE_CONTAINERTYPE = new Guid(353366591, 19132, 18315, 172, 79, 225, 145, 111, 186, 28, 202);

		[FieldDescription("Input Types")]
		public static readonly Guid MFT_INPUT_TYPES_Attributes = new Guid("4276c9b1-759d-4bf3-9cd0-0d723d138f96");

		[FieldDescription("Output Types")]
		public static readonly Guid MFT_OUTPUT_TYPES_Attributes = new Guid("8eae8cf3-a44f-4306-ba5c-bf5dda242818");

		public static readonly Guid MFT_ENUM_HARDWARE_URL_Attribute = new Guid("2fb866ac-b078-4942-ab6c-003d05cda674");

		[FieldDescription("Name")]
		public static readonly Guid MFT_FRIENDLY_NAME_Attribute = new Guid("314ffbae-5b41-4c95-9c19-4e7d586face3");

		public static readonly Guid MFT_CONNECTED_STREAM_ATTRIBUTE = new Guid("71eeb820-a59f-4de2-bcec-38db1dd611a4");

		public static readonly Guid MFT_CONNECTED_TO_HW_STREAM = new Guid("34e6e728-06d6-4491-a553-4795650db912");

		[FieldDescription("Preferred Output Format")]
		public static readonly Guid MFT_PREFERRED_OUTPUTTYPE_Attribute = new Guid("7e700499-396a-49ee-b1b4-f628021e8c9d");

		public static readonly Guid MFT_PROCESS_LOCAL_Attribute = new Guid("543186e4-4649-4e65-b588-4aa352aff379");

		public static readonly Guid MFT_PREFERRED_ENCODER_PROFILE = new Guid("53004909-1ef5-46d7-a18e-5a75f8b5905f");

		public static readonly Guid MFT_HW_TIMESTAMP_WITH_QPC_Attribute = new Guid("8d030fb8-cc43-4258-a22e-9210bef89be4");

		public static readonly Guid MFT_FIELDOFUSE_UNLOCK_Attribute = new Guid("8ec2e9fd-9148-410d-831e-702439461a8e");

		public static readonly Guid MFT_CODEC_MERIT_Attribute = new Guid("88a7cb15-7b07-4a34-9128-e64c6703c4d3");

		public static readonly Guid MFT_ENUM_TRANSCODE_ONLY_ATTRIBUTE = new Guid("111ea8cd-b62a-4bdb-89f6-67ffcdc2458b");

		[FieldDescription("PMP Host Context")]
		public static readonly Guid MF_PD_PMPHOST_CONTEXT = new Guid("6c990d31-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("App Context")]
		public static readonly Guid MF_PD_APP_CONTEXT = new Guid("6c990d32-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Duration")]
		public static readonly Guid MF_PD_DURATION = new Guid("6c990d33-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Total File Size")]
		public static readonly Guid MF_PD_TOTAL_FILE_SIZE = new Guid("6c990d34-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Audio encoding bitrate")]
		public static readonly Guid MF_PD_AUDIO_ENCODING_BITRATE = new Guid("6c990d35-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Video Encoding Bitrate")]
		public static readonly Guid MF_PD_VIDEO_ENCODING_BITRATE = new Guid("6c990d36-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("MIME Type")]
		public static readonly Guid MF_PD_MIME_TYPE = new Guid("6c990d37-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Last Modified Time")]
		public static readonly Guid MF_PD_LAST_MODIFIED_TIME = new Guid("6c990d38-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Element ID")]
		public static readonly Guid MF_PD_PLAYBACK_ELEMENT_ID = new Guid("6c990d39-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Preferred Language")]
		public static readonly Guid MF_PD_PREFERRED_LANGUAGE = new Guid("6c990d3a-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Playback boundary time")]
		public static readonly Guid MF_PD_PLAYBACK_BOUNDARY_TIME = new Guid("6c990d3b-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Audio is variable bitrate")]
		public static readonly Guid MF_PD_AUDIO_ISVARIABLEBITRATE = new Guid("33026ee0-e387-4582-ae0a-34a2ad3baa18");

		[FieldDescription("Major Media Type")]
		public static readonly Guid MF_MT_MAJOR_TYPE = new Guid("48eba18e-f8c9-4687-bf11-0a74c9f96a8f");

		[FieldDescription("Media Subtype")]
		public static readonly Guid MF_MT_SUBTYPE = new Guid("f7e34c9a-42e8-4714-b74b-cb29d72c35e5");

		[FieldDescription("Audio block alignment")]
		public static readonly Guid MF_MT_AUDIO_BLOCK_ALIGNMENT = new Guid("322de230-9eeb-43bd-ab7a-ff412251541d");

		[FieldDescription("Audio average bytes per second")]
		public static readonly Guid MF_MT_AUDIO_AVG_BYTES_PER_SECOND = new Guid("1aab75c8-cfef-451c-ab95-ac034b8e1731");

		[FieldDescription("Audio number of channels")]
		public static readonly Guid MF_MT_AUDIO_NUM_CHANNELS = new Guid("37e48bf5-645e-4c5b-89de-ada9e29b696a");

		[FieldDescription("Audio samples per second")]
		public static readonly Guid MF_MT_AUDIO_SAMPLES_PER_SECOND = new Guid("5faeeae7-0290-4c31-9e8a-c534f68d9dba");

		[FieldDescription("Audio bits per sample")]
		public static readonly Guid MF_MT_AUDIO_BITS_PER_SAMPLE = new Guid("f2deb57f-40fa-4764-aa33-ed4f2d1ff669");

		[FieldDescription("Enable Hardware Transforms")]
		public static readonly Guid MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS = new Guid("a634a91c-822b-41b9-a494-4de4643612b0");

		[FieldDescription("Disable Sink Writer Throttling")]
		public static readonly Guid MF_SINK_WRITER_DISABLE_THROTTLING = new Guid("08b845d8-2b74-4afe-9d53-be16d2d5ae4f");

		[FieldDescription("User data")]
		public static readonly Guid MF_MT_USER_DATA = new Guid("b6bc765f-4c3b-40a4-bd51-2535b66fe09d");

		[FieldDescription("All samples independent")]
		public static readonly Guid MF_MT_ALL_SAMPLES_INDEPENDENT = new Guid("c9173739-5e56-461c-b713-46fb995cb95f");

		[FieldDescription("Fixed size samples")]
		public static readonly Guid MF_MT_FIXED_SIZE_SAMPLES = new Guid("b8ebefaf-b718-4e04-b0a9-116775e3321b");

		[FieldDescription("DirectShow Format Guid")]
		public static readonly Guid MF_MT_AM_FORMAT_TYPE = new Guid("73d1072d-1870-4174-a063-29ff4ff6c11e");

		[FieldDescription("Preferred legacy format structure")]
		public static readonly Guid MF_MT_AUDIO_PREFER_WAVEFORMATEX = new Guid("a901aaba-e037-458a-bdf6-545be2074042");

		[FieldDescription("Is Compressed")]
		public static readonly Guid MF_MT_COMPRESSED = new Guid("3afd0cee-18f2-4ba5-a110-8bea502e1f92");

		[FieldDescription("Average bitrate")]
		public static readonly Guid MF_MT_AVG_BITRATE = new Guid("20332624-fb0d-4d9e-bd0d-cbf6786c102e");

		[FieldDescription("AAC payload type")]
		public static readonly Guid MF_MT_AAC_PAYLOAD_TYPE = new Guid("bfbabe79-7434-4d1c-94f0-72a3b9e17188");

		[FieldDescription("AAC Audio Profile Level Indication")]
		public static readonly Guid MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION = new Guid("7632f0e6-9538-4d61-acda-ea29c8c14456");
	}
	public static class MediaFoundationErrors
	{
		public const int MF_E_PLATFORM_NOT_INITIALIZED = -1072875856;

		public const int MF_E_BUFFERTOOSMALL = -1072875855;

		public const int MF_E_INVALIDREQUEST = -1072875854;

		public const int MF_E_INVALIDSTREAMNUMBER = -1072875853;

		public const int MF_E_INVALIDMEDIATYPE = -1072875852;

		public const int MF_E_NOTACCEPTING = -1072875851;

		public const int MF_E_NOT_INITIALIZED = -1072875850;

		public const int MF_E_UNSUPPORTED_REPRESENTATION = -1072875849;

		public const int MF_E_NO_MORE_TYPES = -1072875847;

		public const int MF_E_UNSUPPORTED_SERVICE = -1072875846;

		public const int MF_E_UNEXPECTED = -1072875845;

		public const int MF_E_INVALIDNAME = -1072875844;

		public const int MF_E_INVALIDTYPE = -1072875843;

		public const int MF_E_INVALID_FILE_FORMAT = -1072875842;

		public const int MF_E_INVALIDINDEX = -1072875841;

		public const int MF_E_INVALID_TIMESTAMP = -1072875840;

		public const int MF_E_UNSUPPORTED_SCHEME = -1072875837;

		public const int MF_E_UNSUPPORTED_BYTESTREAM_TYPE = -1072875836;

		public const int MF_E_UNSUPPORTED_TIME_FORMAT = -1072875835;

		public const int MF_E_NO_SAMPLE_TIMESTAMP = -1072875832;

		public const int MF_E_NO_SAMPLE_DURATION = -1072875831;

		public const int MF_E_INVALID_STREAM_DATA = -1072875829;

		public const int MF_E_RT_UNAVAILABLE = -1072875825;

		public const int MF_E_UNSUPPORTED_RATE = -1072875824;

		public const int MF_E_THINNING_UNSUPPORTED = -1072875823;

		public const int MF_E_REVERSE_UNSUPPORTED = -1072875822;

		public const int MF_E_UNSUPPORTED_RATE_TRANSITION = -1072875821;

		public const int MF_E_RATE_CHANGE_PREEMPTED = -1072875820;

		public const int MF_E_NOT_FOUND = -1072875819;

		public const int MF_E_NOT_AVAILABLE = -1072875818;

		public const int MF_E_NO_CLOCK = -1072875817;

		public const int MF_S_MULTIPLE_BEGIN = 866008;

		public const int MF_E_MULTIPLE_BEGIN = -1072875815;

		public const int MF_E_MULTIPLE_SUBSCRIBERS = -1072875814;

		public const int MF_E_TIMER_ORPHANED = -1072875813;

		public const int MF_E_STATE_TRANSITION_PENDING = -1072875812;

		public const int MF_E_UNSUPPORTED_STATE_TRANSITION = -1072875811;

		public const int MF_E_UNRECOVERABLE_ERROR_OCCURRED = -1072875810;

		public const int MF_E_SAMPLE_HAS_TOO_MANY_BUFFERS = -1072875809;

		public const int MF_E_SAMPLE_NOT_WRITABLE = -1072875808;

		public const int MF_E_INVALID_KEY = -1072875806;

		public const int MF_E_BAD_STARTUP_VERSION = -1072875805;

		public const int MF_E_UNSUPPORTED_CAPTION = -1072875804;

		public const int MF_E_INVALID_POSITION = -1072875803;

		public const int MF_E_ATTRIBUTENOTFOUND = -1072875802;

		public const int MF_E_PROPERTY_TYPE_NOT_ALLOWED = -1072875801;

		public const int MF_E_PROPERTY_TYPE_NOT_SUPPORTED = -1072875800;

		public const int MF_E_PROPERTY_EMPTY = -1072875799;

		public const int MF_E_PROPERTY_NOT_EMPTY = -1072875798;

		public const int MF_E_PROPERTY_VECTOR_NOT_ALLOWED = -1072875797;

		public const int MF_E_PROPERTY_VECTOR_REQUIRED = -1072875796;

		public const int MF_E_OPERATION_CANCELLED = -1072875795;

		public const int MF_E_BYTESTREAM_NOT_SEEKABLE = -1072875794;

		public const int MF_E_DISABLED_IN_SAFEMODE = -1072875793;

		public const int MF_E_CANNOT_PARSE_BYTESTREAM = -1072875792;

		public const int MF_E_SOURCERESOLVER_MUTUALLY_EXCLUSIVE_FLAGS = -1072875791;

		public const int MF_E_MEDIAPROC_WRONGSTATE = -1072875790;

		public const int MF_E_RT_THROUGHPUT_NOT_AVAILABLE = -1072875789;

		public const int MF_E_RT_TOO_MANY_CLASSES = -1072875788;

		public const int MF_E_RT_WOULDBLOCK = -1072875787;

		public const int MF_E_NO_BITPUMP = -1072875786;

		public const int MF_E_RT_OUTOFMEMORY = -1072875785;

		public const int MF_E_RT_WORKQUEUE_CLASS_NOT_SPECIFIED = -1072875784;

		public const int MF_E_INSUFFICIENT_BUFFER = -1072860816;

		public const int MF_E_CANNOT_CREATE_SINK = -1072875782;

		public const int MF_E_BYTESTREAM_UNKNOWN_LENGTH = -1072875781;

		public const int MF_E_SESSION_PAUSEWHILESTOPPED = -1072875780;

		public const int MF_S_ACTIVATE_REPLACED = 866045;

		public const int MF_E_FORMAT_CHANGE_NOT_SUPPORTED = -1072875778;

		public const int MF_E_INVALID_WORKQUEUE = -1072875777;

		public const int MF_E_DRM_UNSUPPORTED = -1072875776;

		public const int MF_E_UNAUTHORIZED = -1072875775;

		public const int MF_E_OUT_OF_RANGE = -1072875774;

		public const int MF_E_INVALID_CODEC_MERIT = -1072875773;

		public const int MF_E_HW_MFT_FAILED_START_STREAMING = -1072875772;

		public const int MF_S_ASF_PARSEINPROGRESS = 1074608792;

		public const int MF_E_ASF_PARSINGINCOMPLETE = -1072874856;

		public const int MF_E_ASF_MISSINGDATA = -1072874855;

		public const int MF_E_ASF_INVALIDDATA = -1072874854;

		public const int MF_E_ASF_OPAQUEPACKET = -1072874853;

		public const int MF_E_ASF_NOINDEX = -1072874852;

		public const int MF_E_ASF_OUTOFRANGE = -1072874851;

		public const int MF_E_ASF_INDEXNOTLOADED = -1072874850;

		public const int MF_E_ASF_TOO_MANY_PAYLOADS = -1072874849;

		public const int MF_E_ASF_UNSUPPORTED_STREAM_TYPE = -1072874848;

		public const int MF_E_ASF_DROPPED_PACKET = -1072874847;

		public const int MF_E_NO_EVENTS_AVAILABLE = -1072873856;

		public const int MF_E_INVALID_STATE_TRANSITION = -1072873854;

		public const int MF_E_END_OF_STREAM = -1072873852;

		public const int MF_E_SHUTDOWN = -1072873851;

		public const int MF_E_MP3_NOTFOUND = -1072873850;

		public const int MF_E_MP3_OUTOFDATA = -1072873849;

		public const int MF_E_MP3_NOTMP3 = -1072873848;

		public const int MF_E_MP3_NOTSUPPORTED = -1072873847;

		public const int MF_E_NO_DURATION = -1072873846;

		public const int MF_E_INVALID_FORMAT = -1072873844;

		public const int MF_E_PROPERTY_NOT_FOUND = -1072873843;

		public const int MF_E_PROPERTY_READ_ONLY = -1072873842;

		public const int MF_E_PROPERTY_NOT_ALLOWED = -1072873841;

		public const int MF_E_MEDIA_SOURCE_NOT_STARTED = -1072873839;

		public const int MF_E_UNSUPPORTED_FORMAT = -1072873832;

		public const int MF_E_MP3_BAD_CRC = -1072873831;

		public const int MF_E_NOT_PROTECTED = -1072873830;

		public const int MF_E_MEDIA_SOURCE_WRONGSTATE = -1072873829;

		public const int MF_E_MEDIA_SOURCE_NO_STREAMS_SELECTED = -1072873828;

		public const int MF_E_CANNOT_FIND_KEYFRAME_SAMPLE = -1072873827;

		public const int MF_E_NETWORK_RESOURCE_FAILURE = -1072872856;

		public const int MF_E_NET_WRITE = -1072872855;

		public const int MF_E_NET_READ = -1072872854;

		public const int MF_E_NET_REQUIRE_NETWORK = -1072872853;

		public const int MF_E_NET_REQUIRE_ASYNC = -1072872852;

		public const int MF_E_NET_BWLEVEL_NOT_SUPPORTED = -1072872851;

		public const int MF_E_NET_STREAMGROUPS_NOT_SUPPORTED = -1072872850;

		public const int MF_E_NET_MANUALSS_NOT_SUPPORTED = -1072872849;

		public const int MF_E_NET_INVALID_PRESENTATION_DESCRIPTOR = -1072872848;

		public const int MF_E_NET_CACHESTREAM_NOT_FOUND = -1072872847;

		public const int MF_I_MANUAL_PROXY = 1074610802;

		public const int MF_E_NET_REQUIRE_INPUT = -1072872844;

		public const int MF_E_NET_REDIRECT = -1072872843;

		public const int MF_E_NET_REDIRECT_TO_PROXY = -1072872842;

		public const int MF_E_NET_TOO_MANY_REDIRECTS = -1072872841;

		public const int MF_E_NET_TIMEOUT = -1072872840;

		public const int MF_E_NET_CLIENT_CLOSE = -1072872839;

		public const int MF_E_NET_BAD_CONTROL_DATA = -1072872838;

		public const int MF_E_NET_INCOMPATIBLE_SERVER = -1072872837;

		public const int MF_E_NET_UNSAFE_URL = -1072872836;

		public const int MF_E_NET_CACHE_NO_DATA = -1072872835;

		public const int MF_E_NET_EOL = -1072872834;

		public const int MF_E_NET_BAD_REQUEST = -1072872833;

		public const int MF_E_NET_INTERNAL_SERVER_ERROR = -1072872832;

		public const int MF_E_NET_SESSION_NOT_FOUND = -1072872831;

		public const int MF_E_NET_NOCONNECTION = -1072872830;

		public const int MF_E_NET_CONNECTION_FAILURE = -1072872829;

		public const int MF_E_NET_INCOMPATIBLE_PUSHSERVER = -1072872828;

		public const int MF_E_NET_SERVER_ACCESSDENIED = -1072872827;

		public const int MF_E_NET_PROXY_ACCESSDENIED = -1072872826;

		public const int MF_E_NET_CANNOTCONNECT = -1072872825;

		public const int MF_E_NET_INVALID_PUSH_TEMPLATE = -1072872824;

		public const int MF_E_NET_INVALID_PUSH_PUBLISHING_POINT = -1072872823;

		public const int MF_E_NET_BUSY = -1072872822;

		public const int MF_E_NET_RESOURCE_GONE = -1072872821;

		public const int MF_E_NET_ERROR_FROM_PROXY = -1072872820;

		public const int MF_E_NET_PROXY_TIMEOUT = -1072872819;

		public const int MF_E_NET_SERVER_UNAVAILABLE = -1072872818;

		public const int MF_E_NET_TOO_MUCH_DATA = -1072872817;

		public const int MF_E_NET_SESSION_INVALID = -1072872816;

		public const int MF_E_OFFLINE_MODE = -1072872815;

		public const int MF_E_NET_UDP_BLOCKED = -1072872814;

		public const int MF_E_NET_UNSUPPORTED_CONFIGURATION = -1072872813;

		public const int MF_E_NET_PROTOCOL_DISABLED = -1072872812;

		public const int MF_E_ALREADY_INITIALIZED = -1072871856;

		public const int MF_E_BANDWIDTH_OVERRUN = -1072871855;

		public const int MF_E_LATE_SAMPLE = -1072871854;

		public const int MF_E_FLUSH_NEEDED = -1072871853;

		public const int MF_E_INVALID_PROFILE = -1072871852;

		public const int MF_E_INDEX_NOT_COMMITTED = -1072871851;

		public const int MF_E_NO_INDEX = -1072871850;

		public const int MF_E_CANNOT_INDEX_IN_PLACE = -1072871849;

		public const int MF_E_MISSING_ASF_LEAKYBUCKET = -1072871848;

		public const int MF_E_INVALID_ASF_STREAMID = -1072871847;

		public const int MF_E_STREAMSINK_REMOVED = -1072870856;

		public const int MF_E_STREAMSINKS_OUT_OF_SYNC = -1072870854;

		public const int MF_E_STREAMSINKS_FIXED = -1072870853;

		public const int MF_E_STREAMSINK_EXISTS = -1072870852;

		public const int MF_E_SAMPLEALLOCATOR_CANCELED = -1072870851;

		public const int MF_E_SAMPLEALLOCATOR_EMPTY = -1072870850;

		public const int MF_E_SINK_ALREADYSTOPPED = -1072870849;

		public const int MF_E_ASF_FILESINK_BITRATE_UNKNOWN = -1072870848;

		public const int MF_E_SINK_NO_STREAMS = -1072870847;

		public const int MF_S_SINK_NOT_FINALIZED = 870978;

		public const int MF_E_METADATA_TOO_LONG = -1072870845;

		public const int MF_E_SINK_NO_SAMPLES_PROCESSED = -1072870844;

		public const int MF_E_VIDEO_REN_NO_PROCAMP_HW = -1072869856;

		public const int MF_E_VIDEO_REN_NO_DEINTERLACE_HW = -1072869855;

		public const int MF_E_VIDEO_REN_COPYPROT_FAILED = -1072869854;

		public const int MF_E_VIDEO_REN_SURFACE_NOT_SHARED = -1072869853;

		public const int MF_E_VIDEO_DEVICE_LOCKED = -1072869852;

		public const int MF_E_NEW_VIDEO_DEVICE = -1072869851;

		public const int MF_E_NO_VIDEO_SAMPLE_AVAILABLE = -1072869850;

		public const int MF_E_NO_AUDIO_PLAYBACK_DEVICE = -1072869756;

		public const int MF_E_AUDIO_PLAYBACK_DEVICE_IN_USE = -1072869755;

		public const int MF_E_AUDIO_PLAYBACK_DEVICE_INVALIDATED = -1072869754;

		public const int MF_E_AUDIO_SERVICE_NOT_RUNNING = -1072869753;

		public const int MF_E_TOPO_INVALID_OPTIONAL_NODE = -1072868850;

		public const int MF_E_TOPO_CANNOT_FIND_DECRYPTOR = -1072868847;

		public const int MF_E_TOPO_CODEC_NOT_FOUND = -1072868846;

		public const int MF_E_TOPO_CANNOT_CONNECT = -1072868845;

		public const int MF_E_TOPO_UNSUPPORTED = -1072868844;

		public const int MF_E_TOPO_INVALID_TIME_ATTRIBUTES = -1072868843;

		public const int MF_E_TOPO_LOOPS_IN_TOPOLOGY = -1072868842;

		public const int MF_E_TOPO_MISSING_PRESENTATION_DESCRIPTOR = -1072868841;

		public const int MF_E_TOPO_MISSING_STREAM_DESCRIPTOR = -1072868840;

		public const int MF_E_TOPO_STREAM_DESCRIPTOR_NOT_SELECTED = -1072868839;

		public const int MF_E_TOPO_MISSING_SOURCE = -1072868838;

		public const int MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED = -1072868837;

		public const int MF_E_SEQUENCER_UNKNOWN_SEGMENT_ID = -1072864852;

		public const int MF_S_SEQUENCER_CONTEXT_CANCELED = 876973;

		public const int MF_E_NO_SOURCE_IN_CACHE = -1072864850;

		public const int MF_S_SEQUENCER_SEGMENT_AT_END_OF_STREAM = 876975;

		public const int MF_E_TRANSFORM_TYPE_NOT_SET = -1072861856;

		public const int MF_E_TRANSFORM_STREAM_CHANGE = -1072861855;

		public const int MF_E_TRANSFORM_INPUT_REMAINING = -1072861854;

		public const int MF_E_TRANSFORM_PROFILE_MISSING = -1072861853;

		public const int MF_E_TRANSFORM_PROFILE_INVALID_OR_CORRUPT = -1072861852;

		public const int MF_E_TRANSFORM_PROFILE_TRUNCATED = -1072861851;

		public const int MF_E_TRANSFORM_PROPERTY_PID_NOT_RECOGNIZED = -1072861850;

		public const int MF_E_TRANSFORM_PROPERTY_VARIANT_TYPE_WRONG = -1072861849;

		public const int MF_E_TRANSFORM_PROPERTY_NOT_WRITEABLE = -1072861848;

		public const int MF_E_TRANSFORM_PROPERTY_ARRAY_VALUE_WRONG_NUM_DIM = -1072861847;

		public const int MF_E_TRANSFORM_PROPERTY_VALUE_SIZE_WRONG = -1072861846;

		public const int MF_E_TRANSFORM_PROPERTY_VALUE_OUT_OF_RANGE = -1072861845;

		public const int MF_E_TRANSFORM_PROPERTY_VALUE_INCOMPATIBLE = -1072861844;

		public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_OUTPUT_MEDIATYPE = -1072861843;

		public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_INPUT_MEDIATYPE = -1072861842;

		public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION = -1072861841;

		public const int MF_E_TRANSFORM_CONFLICTS_WITH_OTHER_CURRENTLY_ENABLED_FEATURES = -1072861840;

		public const int MF_E_TRANSFORM_NEED_MORE_INPUT = -1072861838;

		public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_SPKR_CONFIG = -1072861837;

		public const int MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING = -1072861836;

		public const int MF_S_TRANSFORM_DO_NOT_PROPAGATE_EVENT = 879989;

		public const int MF_E_UNSUPPORTED_D3D_TYPE = -1072861834;

		public const int MF_E_TRANSFORM_ASYNC_LOCKED = -1072861833;

		public const int MF_E_TRANSFORM_CANNOT_INITIALIZE_ACM_DRIVER = -1072861832;

		public const int MF_E_LICENSE_INCORRECT_RIGHTS = -1072860856;

		public const int MF_E_LICENSE_OUTOFDATE = -1072860855;

		public const int MF_E_LICENSE_REQUIRED = -1072860854;

		public const int MF_E_DRM_HARDWARE_INCONSISTENT = -1072860853;

		public const int MF_E_NO_CONTENT_PROTECTION_MANAGER = -1072860852;

		public const int MF_E_LICENSE_RESTORE_NO_RIGHTS = -1072860851;

		public const int MF_E_BACKUP_RESTRICTED_LICENSE = -1072860850;

		public const int MF_E_LICENSE_RESTORE_NEEDS_INDIVIDUALIZATION = -1072860849;

		public const int MF_S_PROTECTION_NOT_REQUIRED = 880976;

		public const int MF_E_COMPONENT_REVOKED = -1072860847;

		public const int MF_E_TRUST_DISABLED = -1072860846;

		public const int MF_E_WMDRMOTA_NO_ACTION = -1072860845;

		public const int MF_E_WMDRMOTA_ACTION_ALREADY_SET = -1072860844;

		public const int MF_E_WMDRMOTA_DRM_HEADER_NOT_AVAILABLE = -1072860843;

		public const int MF_E_WMDRMOTA_DRM_ENCRYPTION_SCHEME_NOT_SUPPORTED = -1072860842;

		public const int MF_E_WMDRMOTA_ACTION_MISMATCH = -1072860841;

		public const int MF_E_WMDRMOTA_INVALID_POLICY = -1072860840;

		public const int MF_E_POLICY_UNSUPPORTED = -1072860839;

		public const int MF_E_OPL_NOT_SUPPORTED = -1072860838;

		public const int MF_E_TOPOLOGY_VERIFICATION_FAILED = -1072860837;

		public const int MF_E_SIGNATURE_VERIFICATION_FAILED = -1072860836;

		public const int MF_E_DEBUGGING_NOT_ALLOWED = -1072860835;

		public const int MF_E_CODE_EXPIRED = -1072860834;

		public const int MF_E_GRL_VERSION_TOO_LOW = -1072860833;

		public const int MF_E_GRL_RENEWAL_NOT_FOUND = -1072860832;

		public const int MF_E_GRL_EXTENSIBLE_ENTRY_NOT_FOUND = -1072860831;

		public const int MF_E_KERNEL_UNTRUSTED = -1072860830;

		public const int MF_E_PEAUTH_UNTRUSTED = -1072860829;

		public const int MF_E_NON_PE_PROCESS = -1072860827;

		public const int MF_E_REBOOT_REQUIRED = -1072860825;

		public const int MF_S_WAIT_FOR_POLICY_SET = 881000;

		public const int MF_S_VIDEO_DISABLED_WITH_UNKNOWN_SOFTWARE_OUTPUT = 881001;

		public const int MF_E_GRL_INVALID_FORMAT = -1072860822;

		public const int MF_E_GRL_UNRECOGNIZED_FORMAT = -1072860821;

		public const int MF_E_ALL_PROCESS_RESTART_REQUIRED = -1072860820;

		public const int MF_E_PROCESS_RESTART_REQUIRED = -1072860819;

		public const int MF_E_USERMODE_UNTRUSTED = -1072860818;

		public const int MF_E_PEAUTH_SESSION_NOT_STARTED = -1072860817;

		public const int MF_E_PEAUTH_PUBLICKEY_REVOKED = -1072860815;

		public const int MF_E_GRL_ABSENT = -1072860814;

		public const int MF_S_PE_TRUSTED = 881011;

		public const int MF_E_PE_UNTRUSTED = -1072860812;

		public const int MF_E_PEAUTH_NOT_STARTED = -1072860811;

		public const int MF_E_INCOMPATIBLE_SAMPLE_PROTECTION = -1072860810;

		public const int MF_E_PE_SESSIONS_MAXED = -1072860809;

		public const int MF_E_HIGH_SECURITY_LEVEL_CONTENT_NOT_ALLOWED = -1072860808;

		public const int MF_E_TEST_SIGNED_COMPONENTS_NOT_ALLOWED = -1072860807;

		public const int MF_E_ITA_UNSUPPORTED_ACTION = -1072860806;

		public const int MF_E_ITA_ERROR_PARSING_SAP_PARAMETERS = -1072860805;

		public const int MF_E_POLICY_MGR_ACTION_OUTOFBOUNDS = -1072860804;

		public const int MF_E_BAD_OPL_STRUCTURE_FORMAT = -1072860803;

		public const int MF_E_ITA_UNRECOGNIZED_ANALOG_VIDEO_PROTECTION_GUID = -1072860802;

		public const int MF_E_NO_PMP_HOST = -1072860801;

		public const int MF_E_ITA_OPL_DATA_NOT_INITIALIZED = -1072860800;

		public const int MF_E_ITA_UNRECOGNIZED_ANALOG_VIDEO_OUTPUT = -1072860799;

		public const int MF_E_ITA_UNRECOGNIZED_DIGITAL_VIDEO_OUTPUT = -1072860798;

		public const int MF_E_CLOCK_INVALID_CONTINUITY_KEY = -1072849856;

		public const int MF_E_CLOCK_NO_TIME_SOURCE = -1072849855;

		public const int MF_E_CLOCK_STATE_ALREADY_SET = -1072849854;

		public const int MF_E_CLOCK_NOT_SIMPLE = -1072849853;

		public const int MF_S_CLOCK_STOPPED = 891972;

		public const int MF_E_NO_MORE_DROP_MODES = -1072848856;

		public const int MF_E_NO_MORE_QUALITY_LEVELS = -1072848855;

		public const int MF_E_DROPTIME_NOT_SUPPORTED = -1072848854;

		public const int MF_E_QUALITYKNOB_WAIT_LONGER = -1072848853;

		public const int MF_E_QM_INVALIDSTATE = -1072848852;

		public const int MF_E_TRANSCODE_NO_CONTAINERTYPE = -1072847856;

		public const int MF_E_TRANSCODE_PROFILE_NO_MATCHING_STREAMS = -1072847855;

		public const int MF_E_TRANSCODE_NO_MATCHING_ENCODER = -1072847854;

		public const int MF_E_ALLOCATOR_NOT_INITIALIZED = -1072846856;

		public const int MF_E_ALLOCATOR_NOT_COMMITED = -1072846855;

		public const int MF_E_ALLOCATOR_ALREADY_COMMITED = -1072846854;

		public const int MF_E_STREAM_ERROR = -1072846853;

		public const int MF_E_INVALID_STREAM_STATE = -1072846852;

		public const int MF_E_HW_STREAM_NOT_CONNECTED = -1072846851;
	}
	public static class MediaFoundationApi
	{
		[CompilerGenerated]
		private sealed class <EnumerateTransforms>d__2 : IEnumerable<IMFActivate>, IEnumerable, IEnumerator<IMFActivate>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private IMFActivate <>2__current;

			private int <>l__initialThreadId;

			private Guid category;

			public Guid <>3__category;

			private IntPtr <interfacesPointer>5__2;

			private IMFActivate[] <>7__wrap2;

			private int <>7__wrap3;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					MediaFoundationInterop.MFTEnumEx(category, _MFT_ENUM_FLAG.MFT_ENUM_FLAG_ALL, null, null, out <interfacesPointer>5__2, out var pcMFTActivate);
					IMFActivate[] array = new IMFActivate[pcMFTActivate];
					for (int i = 0; i < pcMFTActivate; i++)
					{
						IntPtr pUnk = Marshal.ReadIntPtr(new IntPtr(<interfacesPointer>5__2.ToInt64() + i * Marshal.SizeOf(<interfacesPointer>5__2)));
						array[i] = (IMFActivate)Marshal.GetObjectForIUnknown(pUnk);
					}
					<>7__wrap2 = array;
					<>7__wrap3 = 0;
					break;
				}
				case 1:
					<>1__state = -1;
					<>7__wrap3++;
					break;
				}
				if (<>7__wrap3 < <>7__wrap2.Length)
				{
					IMFActivate iMFActivate = <>7__wrap2[<>7__wrap3];
					<>2__current = iMFActivate;
					<>1__state = 1;
					return true;
				}
				<>7__wrap2 = null;
				Marshal.FreeCoTaskMem(<interfacesPointer>5__2);
				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<IMFActivate> IEnumerable<IMFActivate>.GetEnumerator()
			{
				<EnumerateTransforms>d__2 <EnumerateTransforms>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<EnumerateTransforms>d__ = this;
				}
				else
				{
					<EnumerateTransforms>d__ = new <EnumerateTransforms>d__2(0);
				}
				<EnumerateTransforms>d__.category = <>3__category;
				return <EnumerateTransforms>d__;
			}

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

		private static bool initialized;

		public static void Startup()
		{
			if (!initialized)
			{
				int num = 2;
				OperatingSystem oSVersion = Environment.OSVersion;
				if (oSVersion.Version.Major == 6 && oSVersion.Version.Minor == 0)
				{
					num = 1;
				}
				MediaFoundationInterop.MFStartup((num << 16) | 0x70);
				initialized = true;
			}
		}

		[IteratorStateMachine(typeof(<EnumerateTransforms>d__2))]
		public static IEnumerable<IMFActivate> EnumerateTransforms(Guid category)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnumerateTransforms>d__2(-2)
			{
				<>3__category = category
			};
		}

		public static void Shutdown()
		{
			if (initialized)
			{
				MediaFoundationInterop.MFShutdown();
				initialized = false;
			}
		}

		public static IMFMediaType CreateMediaType()
		{
			MediaFoundationInterop.MFCreateMediaType(out var ppMFType);
			return ppMFType;
		}

		public static IMFMediaType CreateMediaTypeFromWaveFormat(WaveFormat waveFormat)
		{
			IMFMediaType iMFMediaType = CreateMediaType();
			try
			{
				MediaFoundationInterop.MFInitMediaTypeFromWaveFormatEx(iMFMediaType, waveFormat, Marshal.SizeOf<WaveFormat>(waveFormat));
				return iMFMediaType;
			}
			catch (Exception)
			{
				Marshal.ReleaseComObject(iMFMediaType);
				throw;
			}
		}

		public static IMFMediaBuffer CreateMemoryBuffer(int bufferSize)
		{
			MediaFoundationInterop.MFCreateMemoryBuffer(bufferSize, out var ppBuffer);
			return ppBuffer;
		}

		public static IMFSample CreateSample()
		{
			MediaFoundationInterop.MFCreateSample(out var ppIMFSample);
			return ppIMFSample;
		}

		public static IMFAttributes CreateAttributes(int initialSize)
		{
			MediaFoundationInterop.MFCreateAttributes(out var ppMFAttributes, initialSize);
			return ppMFAttributes;
		}

		public static IMFByteStream CreateByteStream(object stream)
		{
			if (stream is IStream)
			{
				MediaFoundationInterop.MFCreateMFByteStreamOnStream(stream as IStream, out var ppByteStream);
				return ppByteStream;
			}
			throw new ArgumentException("Stream must be IStream in desktop apps");
		}

		public static IMFSourceReader CreateSourceReaderFromByteStream(IMFByteStream byteStream)
		{
			MediaFoundationInterop.MFCreateSourceReaderFromByteStream(byteStream, null, out var ppSourceReader);
			return ppSourceReader;
		}
	}
	public static class MediaFoundationInterop
	{
		public const int MF_SOURCE_READER_ALL_STREAMS = -2;

		public const int MF_SOURCE_READER_FIRST_AUDIO_STREAM = -3;

		public const int MF_SOURCE_READER_FIRST_VIDEO_STREAM = -4;

		public const int MF_SOURCE_READER_MEDIASOURCE = -1;

		public const int MF_SDK_VERSION = 2;

		public const int MF_API_VERSION = 112;

		public const int MF_VERSION = 131184;

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFStartup(int version, int dwFlags = 0);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFShutdown();

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		internal static extern void MFCreateMediaType(out IMFMediaType ppMFType);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		internal static extern void MFInitMediaTypeFromWaveFormatEx([In] IMFMediaType pMFType, [In] WaveFormat pWaveFormat, [In] int cbBufSize);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		internal static extern void MFCreateWaveFormatExFromMFMediaType(IMFMediaType pMFType, ref IntPtr ppWF, ref int pcbSize, int flags = 0);

		[DllImport("mfreadwrite.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFCreateSourceReaderFromURL([In][MarshalAs(UnmanagedType.LPWStr)] string pwszURL, [In] IMFAttributes pAttributes, [MarshalAs(UnmanagedType.Interface)] out IMFSourceReader ppSourceReader);

		[DllImport("mfreadwrite.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFCreateSourceReaderFromByteStream([In] IMFByteStream pByteStream, [In] IMFAttributes pAttributes, [MarshalAs(UnmanagedType.Interface)] out IMFSourceReader ppSourceReader);

		[DllImport("mfreadwrite.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFCreateSinkWriterFromURL([In][MarshalAs(UnmanagedType.LPWStr)] string pwszOutputURL, [In] IMFByteStream pByteStream, [In] IMFAttributes pAttributes, out IMFSinkWriter ppSinkWriter);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFCreateMFByteStreamOnStreamEx([MarshalAs(UnmanagedType.IUnknown)] object punkStream, out IMFByteStream ppByteStream);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFCreateMFByteStreamOnStream([In] IStream punkStream, out IMFByteStream ppByteStream);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFTEnumEx([In] Guid guidCategory, [In] _MFT_ENUM_FLAG flags, [In] MFT_REGISTER_TYPE_INFO pInputType, [In] MFT_REGISTER_TYPE_INFO pOutputType, out IntPtr pppMFTActivate, out int pcMFTActivate);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		internal static extern void MFCreateSample(out IMFSample ppIMFSample);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		internal static extern void MFCreateMemoryBuffer(int cbMaxLength, out IMFMediaBuffer ppBuffer);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		internal static extern void MFCreateAttributes([MarshalAs(UnmanagedType.Interface)] out IMFAttributes ppMFAttributes, [In] int cInitialSize);

		[DllImport("mf.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFTranscodeGetAudioOutputAvailableTypes([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidSubType, [In] _MFT_ENUM_FLAG dwMFTFlags, [In] IMFAttributes pCodecConfig, [MarshalAs(UnmanagedType.Interface)] out IMFCollection ppAvailableTypes);
	}
	public abstract class MediaFoundationTransform : IWaveProvider, IDisposable
	{
		protected readonly IWaveProvider sourceProvider;

		protected readonly WaveFormat outputWaveFormat;

		private readonly byte[] sourceBuffer;

		private byte[] outputBuffer;

		private int outputBufferOffset;

		private int outputBufferCount;

		private IMFTransform transform;

		private bool disposed;

		private long inputPosition;

		private long outputPosition;

		private bool initializedForStreaming;

		public WaveFormat WaveFormat => outputWaveFormat;

		public MediaFoundationTransform(IWaveProvider sourceProvider, WaveFormat outputFormat)
		{
			outputWaveFormat = outputFormat;
			this.sourceProvider = sourceProvider;
			sourceBuffer = new byte[sourceProvider.WaveFormat.AverageBytesPerSecond];
			outputBuffer = new byte[outputWaveFormat.AverageBytesPerSecond + outputWaveFormat.BlockAlign];
		}

		private void InitializeTransformForStreaming()
		{
			transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_COMMAND_FLUSH, IntPtr.Zero);
			transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, IntPtr.Zero);
			transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_NOTIFY_START_OF_STREAM, IntPtr.Zero);
			initializedForStreaming = true;
		}

		protected abstract IMFTransform CreateTransform();

		protected virtual void Dispose(bool disposing)
		{
			if (transform != null)
			{
				Marshal.ReleaseComObject(transform);
			}
		}

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

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

		public int Read(byte[] buffer, int offset, int count)
		{
			if (transform == null)
			{
				transform = CreateTransform();
				InitializeTransformForStreaming();
			}
			int i = 0;
			if (outputBufferCount > 0)
			{
				i += ReadFromOutputBuffer(buffer, offset, count - i);
			}
			for (; i < count; i += ReadFromOutputBuffer(buffer, offset + i, count - i))
			{
				IMFSample iMFSample = ReadFromSource();
				if (iMFSample == null)
				{
					EndStreamAndDrain();
					i += ReadFromOutputBuffer(buffer, offset + i, count - i);
					ClearOutputBuffer();
					break;
				}
				if (!initializedForStreaming)
				{
					InitializeTransformForStreaming();
				}
				transform.ProcessInput(0, iMFSample, 0);
				Marshal.ReleaseComObject(iMFSample);
				ReadFromTransform();
			}
			return i;
		}

		private void EndStreamAndDrain()
		{
			transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_NOTIFY_END_OF_STREAM, IntPtr.Zero);
			transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_COMMAND_DRAIN, IntPtr.Zero);
			int num;
			do
			{
				num = ReadFromTransform();
			}
			while (num > 0);
			inputPosition = 0L;
			outputPosition = 0L;
			transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_NOTIFY_END_STREAMING, IntPtr.Zero);
			initializedForStreaming = false;
		}

		private void ClearOutputBuffer()
		{
			outputBufferCount = 0;
			outputBufferOffset = 0;
		}

		private int ReadFromTransform()
		{
			MFT_OUTPUT_DATA_BUFFER[] array = new MFT_OUTPUT_DATA_BUFFER[1];
			IMFSample iMFSample = MediaFoundationApi.CreateSample();
			IMFMediaBuffer iMFMediaBuffer = MediaFoundationApi.CreateMemoryBuffer(outputBuffer.Length);
			iMFSample.AddBuffer(iMFMediaBuffer);
			iMFSample.SetSampleTime(outputPosition);
			array[0].pSample = iMFSample;
			_MFT_PROCESS_OUTPUT_STATUS pdwStatus;
			int num = transform.ProcessOutput(_MFT_PROCESS_OUTPUT_FLAGS.None, 1, array, out pdwStatus);
			switch (num)
			{
			case -1072861838:
				Marshal.ReleaseComObject(iMFMediaBuffer);
				Marshal.ReleaseComObject(iMFSample);
				return 0;
			default:
				Marshal.ThrowExceptionForHR(num);
				break;
			case 0:
				break;
			}
			array[0].pSample.ConvertToContiguousBuffer(out var ppBuffer);
			ppBuffer.Lock(out var ppbBuffer, out var _, out var pcbCurrentLength);
			outputBuffer = BufferHelpers.Ensure(outputBuffer, pcbCurrentLength);
			Marshal.Copy(ppbBuffer, outputBuffer, 0, pcbCurrentLength);
			outputBufferOffset = 0;
			outputBufferCount = pcbCurrentLength;
			ppBuffer.Unlock();
			outputPosition += BytesToNsPosition(outputBufferCount, WaveFormat);
			Marshal.ReleaseComObject(iMFMediaBuffer);
			iMFSample.RemoveAllBuffers();
			Marshal.ReleaseComObject(iMFSample);
			Marshal.ReleaseComObject(ppBuffer);
			return pcbCurrentLength;
		}

		private static long BytesToNsPosition(int bytes, WaveFormat waveFormat)
		{
			return 10000000L * (long)bytes / waveFormat.AverageBytesPerSecond;
		}

		private IMFSample ReadFromSource()
		{
			int num = sourceProvider.Read(sourceBuffer, 0, sourceBuffer.Length);
			if (num == 0)
			{
				return null;
			}
			IMFMediaBuffer iMFMediaBuffer = MediaFoundationApi.CreateMemoryBuffer(num);
			iMFMediaBuffer.Lock(out var ppbBuffer, out var _, out var _);
			Marshal.Copy(sourceBuffer, 0, ppbBuffer, num);
			iMFMediaBuffer.Unlock();
			iMFMediaBuffer.SetCurrentLength(num);
			IMFSample iMFSample = MediaFoundationApi.CreateSample();
			iMFSample.AddBuffer(iMFMediaBuffer);
			iMFSample.SetSampleTime(inputPosition);
			long num2 = BytesToNsPosition(num, sourceProvider.WaveFormat);
			iMFSample.SetSampleDuration(num2);
			inputPosition += num2;
			Marshal.ReleaseComObject(iMFMediaBuffer);
			return iMFSample;
		}

		private int ReadFromOutputBuffer(byte[] buffer, int offset, int needed)
		{
			int num = Math.Min(needed, outputBufferCount);
			Array.Copy(outputBuffer, outputBufferOffset, buffer, offset, num);
			outputBufferOffset += num;
			outputBufferCount -= num;
			if (outputBufferCount == 0)
			{
				outputBufferOffset = 0;
			}
			return num;
		}

		public void Reposition()
		{
			if (initializedForStreaming)
			{
				EndStreamAndDrain();
				ClearOutputBuffer();
				InitializeTransformForStreaming();
			}
		}
	}
	public static class MediaFoundationTransformCategories
	{
		[FieldDescription("Video Decoder")]
		public static readonly Guid VideoDecoder = new Guid("{d6c02d4b-6833-45b4-971a-05a4b04bab91}");

		[FieldDescription("Video Encoder")]
		public static readonly Guid VideoEncoder = new Guid("{f79eac7d-e545-4387-bdee-d647d7bde42a}");

		[FieldDescription("Video Effect")]
		public static readonly Guid VideoEffect = new Guid("{12e17c21-532c-4a6e-8a1c-40825a736397}");

		[FieldDescription("Multiplexer")]
		public static readonly Guid Multiplexer = new Guid("{059c561e-05ae-4b61-b69d-55b61ee54a7b}");

		[FieldDescription("Demultiplexer")]
		public static readonly Guid Demultiplexer = new Guid("{a8700a7a-939b-44c5-99d7-76226b23b3f1}");

		[FieldDescription("Audio Decoder")]
		public static readonly Guid AudioDecoder = new Guid("{9ea73fb4-ef7a-4559-8d5d-719d8f0426c7}");

		[FieldDescription("Audio Encoder")]
		public static readonly Guid AudioEncoder = new Guid("{91c64bd0-f91e-4d8c-9276-db248279d975}");

		[FieldDescription("Audio Effect")]
		public static readonly Guid AudioEffect = new Guid("{11064c48-3648-4ed0-932e-05ce8ac811b7}");

		[FieldDescription("Video Processor")]
		public static readonly Guid VideoProcessor = new Guid("{302EA3FC-AA5F-47f9-9F7A-C2188BB16302}");

		[FieldDescription("Other")]
		public static readonly Guid Other = new Guid("{90175d57-b7ea-4901-aeb3-933a8747756f}");
	}
	public class MediaType
	{
		private readonly IMFMediaType mediaType;

		public int SampleRate
		{
			get
			{
				return GetUInt32(MediaFoundationAttributes.MF_MT_AUDIO_SAMPLES_PER_SECOND);
			}
			set
			{
				mediaType.SetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_SAMPLES_PER_SECOND, value);
			}
		}

		public int ChannelCount
		{
			get
			{
				return GetUInt32(MediaFoundationAttributes.MF_MT_AUDIO_NUM_CHANNELS);
			}
			set
			{
				mediaType.SetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_NUM_CHANNELS, value);
			}
		}

		public int BitsPerSample
		{
			get
			{
				return GetUInt32(MediaFoundationAttributes.MF_MT_AUDIO_BITS_PER_SAMPLE);
			}
			set
			{
				mediaType.SetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_BITS_PER_SAMPLE, value);
			}
		}

		public int AverageBytesPerSecond => GetUInt32(MediaFoundationAttributes.MF_MT_AUDIO_AVG_BYTES_PER_SECOND);

		public Guid SubType
		{
			get
			{
				return GetGuid(MediaFoundationAttributes.MF_MT_SUBTYPE);
			}
			set
			{
				mediaType.SetGUID(MediaFoundationAttributes.MF_MT_SUBTYPE, value);
			}
		}

		public Guid MajorType
		{
			get
			{
				return GetGuid(MediaFoundationAttributes.MF_MT_MAJOR_TYPE);
			}
			set
			{
				mediaType.SetGUID(MediaFoundationAttributes.MF_MT_MAJOR_TYPE, value);
			}
		}

		public IMFMediaType MediaFoundationObject => mediaType;

		public MediaType(IMFMediaType mediaType)
		{
			this.mediaType = mediaType;
		}

		public MediaType()
		{
			mediaType = MediaFoundationApi.CreateMediaType();
		}

		public MediaType(WaveFormat waveFormat)
		{
			mediaType = MediaFoundationApi.CreateMediaTypeFromWaveFormat(waveFormat);
		}

		private int GetUInt32(Guid key)
		{
			mediaType.GetUINT32(key, out var punValue);
			return punValue;
		}

		private Guid GetGuid(Guid key)
		{
			mediaType.GetGUID(key, out var pguidValue);
			return pguidValue;
		}

		public int TryGetUInt32(Guid key, int defaultValue = -1)
		{
			int punValue = defaultValue;
			try
			{
				mediaType.GetUINT32(key, out punValue);
			}
			catch (COMException ex)
			{
				if (HResult.GetHResult(ex) != -1072875802)
				{
					if (HResult.GetHResult(ex) == -1072875843)
					{
						throw new ArgumentException("Not a UINT32 parameter");
					}
					throw;
				}
			}
			return punValue;
		}

		public void SetUInt32(Guid key, int value)
		{
			mediaType.SetUINT32(key, value);
		}
	}
	public static class MediaTypes
	{
		public static readonly Guid MFMediaType_Default = new Guid("81A412E6-8103-4B06-857F-1862781024AC");

		[FieldDescription("Audio")]
		public static readonly Guid MFMediaType_Audio = new Guid("73647561-0000-0010-8000-00aa00389b71");

		[FieldDescription("Video")]
		public static readonly Guid MFMediaType_Video = new Guid("73646976-0000-0010-8000-00aa00389b71");

		[FieldDescription("Protected Media")]
		public static readonly Guid MFMediaType_Protected = new Guid("7b4b6fe6-9d04-4494-be14-7e0bd076c8e4");

		[FieldDescription("SAMI captions")]
		public static readonly Guid MFMediaType_SAMI = new Guid("e69669a0-3dcd-40cb-9e2e-3708387c0616");

		[FieldDescription("Script stream")]
		public static readonly Guid MFMediaType_Script = new Guid("72178c22-e45b-11d5-bc2a-00b0d0f3f4ab");

		[FieldDescription("Still image stream")]
		public static readonly Guid MFMediaType_Image = new Guid("72178c23-e45b-11d5-bc2a-00b0d0f3f4ab");

		[FieldDescription("HTML stream")]
		public static readonly Guid MFMediaType_HTML = new Guid("72178c24-e45b-11d5-bc2a-00b0d0f3f4ab");

		[FieldDescription("Binary stream")]
		public static readonly Guid MFMediaType_Binary = new Guid("72178c25-e45b-11d5-bc2a-00b0d0f3f4ab");

		[FieldDescription("File transfer")]
		public static readonly Guid MFMediaType_FileTransfer = new Guid("72178c26-e45b-11d5-bc2a-00b0d0f3f4ab");
	}
	public struct MFT_INPUT_STREAM_INFO
	{
		public long hnsMaxLatency;

		public _MFT_INPUT_STREAM_INFO_FLAGS dwFlags;

		public int cbSize;

		public int cbMaxLookahead;

		public int cbAlignment;
	}
	public enum MFT_MESSAGE_TYPE
	{
		MFT_MESSAGE_COMMAND_FLUSH = 0,
		MFT_MESSAGE_COMMAND_DRAIN = 1,
		MFT_MESSAGE_SET_D3D_MANAGER = 2,
		MFT_MESSAGE_DROP_SAMPLES = 3,
		MFT_MESSAGE_COMMAND_TICK = 4,
		MFT_MESSAGE_NOTIFY_BEGIN_STREAMING = 268435456,
		MFT_MESSAGE_NOTIFY_END_STREAMING = 268435457,
		MFT_MESSAGE_NOTIFY_END_OF_STREAM = 268435458,
		MFT_MESSAGE_NOTIFY_START_OF_STREAM = 268435459,
		MFT_MESSAGE_COMMAND_MARKER = 536870912
	}
	public struct MFT_OUTPUT_DATA_BUFFER
	{
		public int dwStreamID;

		public IMFSample pSample;

		public _MFT_OUTPUT_DATA_BUFFER_FLAGS dwStatus;

		public IMFCollection pEvents;
	}
	public struct MFT_OUTPUT_STREAM_INFO
	{
		public _MFT_OUTPUT_STREAM_INFO_FLAGS dwFlags;

		public int cbSize;

		public int cbAlignment;
	}
	[StructLayout(LayoutKind.Sequential)]
	public class MFT_REGISTER_TYPE_INFO
	{
		public Guid guidMajorType;

		public Guid guidSubtype;
	}
	[StructLayout(LayoutKind.Sequential)]
	public class MF_SINK_WRITER_STATISTICS
	{
		public int cb;

		public long llLastTimestampReceived;

		public long llLastTimestampEncoded;

		public long llLastTimestampProcessed;

		public long llLastStreamTickReceived;

		public long llLastSinkSampleRequest;

		public long qwNumSamplesReceived;

		public long qwNumSamplesEncoded;

		public long qwNumSamplesProcessed;

		public long qwNumStreamTicksReceived;

		public int dwByteCountQueued;

		public long qwByteCountProcessed;

		public int dwNumOutstandingSinkSampleRequests;

		public int dwAverageSampleRateReceived;

		public int dwAverageSampleRateEncoded;

		public int dwAverageSampleRateProcessed;
	}
	public static class TranscodeContainerTypes
	{
		public static readonly Guid MFTranscodeContainerType_ASF = new Guid(1125085038u, 46783, 20417, 160, 189, 158, 228, 110, 238, 42, 251);

		public static readonly Guid MFTranscodeContainerType_MPEG4 = new Guid(3698118749u, 47568, 16623, 189, 53, 250, 98, 44, 26, 178, 138);

		public static readonly Guid MFTranscodeContainerType_MP3 = new Guid(3828922642u, 33777, 19942, 158, 58, 159, 251, 198, 221, 36, 209);

		public static readonly Guid MFTranscodeContainerType_3GP = new Guid(885326183, 17522, 20276, 158, 160, 196, 159, 186, 207, 3, 125);

		public static readonly Guid MFTranscodeContainerType_AC3 = new Guid(1837994435u, 35985, 20177, 135, 66, 140, 52, 125, 91, 68, 208);

		public static readonly Guid MFTranscodeContainerType_ADTS = new Guid(321901181, 3842, 17374, 163, 1, 56, 251, 187, 179, 131, 78);

		public static readonly Guid MFTranscodeContainerType_MPEG2 = new Guid(3217218553u, 31668, 20367, 175, 222, 225, 18, 196, 75, 168, 130);

		public static readonly Guid MFTranscodeContainerType_FMPEG4 = new Guid(2611508977u, 16799, 19319, 161, 224, 53, 149, 157, 157, 64, 4);

		public static readonly Guid MFTranscodeContainerType_WAVE = new Guid(1690518844, 3878, 18241, 190, 99, 135, 189, 248, 187, 147, 91);

		public static readonly Guid MFTranscodeContainerType_AVI = new Guid(2128603311, 16431, 19830, 163, 60, 97, 159, 209, 87, 208, 241);

		public static readonly Guid MFTranscodeContainerType_AMR = new Guid(39672531, 25114, 18267, 150, 77, 102, 177, 200, 36, 240, 121);
	}
	[Flags]
	public enum _MFT_ENUM_FLAG
	{
		None = 0,
		MFT_ENUM_FLAG_SYNCMFT = 1,
		MFT_ENUM_FLAG_ASYNCMFT = 2,
		MFT_ENUM_FLAG_HARDWARE = 4,
		MFT_ENUM_FLAG_FIELDOFUSE = 8,
		MFT_ENUM_FLAG_LOCALMFT = 0x10,
		MFT_ENUM_FLAG_TRANSCODE_ONLY = 0x20,
		MFT_ENUM_FLAG_SORTANDFILTER = 0x40,
		MFT_ENUM_FLAG_ALL = 0x3F
	}
	[Flags]
	public enum _MFT_INPUT_STATUS_FLAGS
	{
		None = 0,
		MFT_INPUT_STATUS_ACCEPT_DATA = 1
	}
	[Flags]
	public enum _MFT_INPUT_STREAM_INFO_FLAGS
	{
		None = 0,
		MFT_INPUT_STREAM_WHOLE_SAMPLES = 1,
		MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER = 2,
		MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE = 4,
		MFT_INPUT_STREAM_HOLDS_BUFFERS = 8,
		MFT_INPUT_STREAM_DOES_NOT_ADDREF = 0x100,
		MFT_INPUT_STREAM_REMOVABLE = 0x200,
		MFT_INPUT_STREAM_OPTIONAL = 0x400,
		MFT_INPUT_STREAM_PROCESSES_IN_PLACE = 0x800
	}
	[Flags]
	public enum _MFT_OUTPUT_DATA_BUFFER_FLAGS
	{
		None = 0,
		MFT_OUTPUT_DATA_BUFFER_INCOMPLETE = 0x1000000,
		MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE = 0x100,
		MFT_OUTPUT_DATA_BUFFER_STREAM_END = 0x200,
		MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE = 0x300
	}
	[Flags]
	public enum _MFT_OUTPUT_STATUS_FLAGS
	{
		None = 0,
		MFT_OUTPUT_STATUS_SAMPLE_READY = 1
	}
	[Flags]
	public enum _MFT_OUTPUT_STREAM_INFO_FLAGS
	{
		None = 0,
		MFT_OUTPUT_STREAM_WHOLE_SAMPLES = 1,
		MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER = 2,
		MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE = 4,
		MFT_OUTPUT_STREAM_DISCARDABLE = 8,
		MFT_OUTPUT_STREAM_OPTIONAL = 0x10,
		MFT_OUTPUT_STREAM_PROVIDES_SAMPLES = 0x100,
		MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES = 0x200,
		MFT_OUTPUT_STREAM_LAZY_READ = 0x400,
		MFT_OUTPUT_STREAM_REMOVABLE = 0x800
	}
	[Flags]
	public enum _MFT_PROCESS_OUTPUT_FLAGS
	{
		None = 0,
		MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER = 1,
		MFT_PROCESS_OUTPUT_REGENERATE_LAST_OUTPUT = 2
	}
	[Flags]
	public enum _MFT_PROCESS_OUTPUT_STATUS
	{
		None = 0,
		MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS = 0x100
	}
	[Flags]
	public enum _MFT_SET_TYPE_FLAGS
	{
		None = 0,
		MFT_SET_TYPE_TEST_ONLY = 1
	}
}
namespace NAudio.Dmo
{
	public class DmoDescriptor
	{
		public string Name { get; private set; }

		public Guid Clsid { get; private set; }

		public DmoDescriptor(string name, Guid clsid)
		{
			Name = name;
			Clsid = clsid;
		}
	}
	public class DmoEnumerator
	{
		[CompilerGenerated]
		private sealed class <GetDmos>d__3 : IEnumerable<DmoDescriptor>, IEnumerable, IEnumerator<DmoDescriptor>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private DmoDescriptor <>2__current;

			private int <>l__initialThreadId;

			private Guid category;

			public Guid <>3__category;

			private IEnumDmo <enumDmo>5__2;

			private int <itemsFetched>5__3;

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

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

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

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

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_007c;
				}
				<>1__state = -1;
				Marshal.ThrowExceptionForHR(DmoInterop.DMOEnum(ref category, DmoEnumFlags.None, 0, null, 0, null, out <enumDmo>5__2));
				goto IL_0032;
				IL_007c:
				if (<itemsFetched>5__3 <= 0)
				{
					return false;
				}
				goto IL_0032;
				IL_0032:
				<enumDmo>5__2.Next(1, out var clsid, out var name, out <itemsFetched>5__3);
				if (<itemsFetched>5__3 == 1)
				{
					string name2 = Marshal.PtrToStringUni(name);
					Marshal.FreeCoTaskMem(name);
					<>2__current = new DmoDescriptor(name2, clsid);
					<>1__state = 1;
					return true;
				}
				goto IL_007c;
			}

			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<DmoDescriptor> IEnumerable<DmoDescriptor>.GetEnumerator()
			{
				<GetDmos>d__3 <GetDmos>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetDmos>d__ = this;
				}
				else
				{
					<GetDmos>d__ = new <GetDmos>d__3(0);
				}
				<GetDmos>d__.category = <>3__category;
				return <GetDmos>d__;
			}

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

		public static IEnumerable<DmoDescriptor> GetAudioEffectNames()
		{
			return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_EFFECT);
		}

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

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

		[IteratorStateMachine(typeof(<GetDmos>d__3))]
		private static IEnumerable<DmoDescriptor> GetDmos(Guid category)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetDmos>d__3(-2)
			{
				<>3__category = category
			};
		}
	}
	[Flags]
	internal enum DmoEnumFlags
	{
		None = 0,
		DMO_ENUMF_INCLUDE_KEYED = 1
	}
	internal static class DmoGuids
	{
		public static readonly Guid DMOCATEGORY_AUDIO_DECODER = new Guid("57f2db8b-e6bb-4513-9d43-dcd2a6593125");

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

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

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

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

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

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

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

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

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

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

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

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

		public static readonly Guid FORMAT_525WSS = new Guid("C7ECF04D-4582-4869-9ABB-BFB523B62EDF");
	}
	internal enum DmoHResults
	{
		DMO_E_INVALIDSTREAMINDEX = -2147220991,
		DMO_E_INVALIDTYPE,
		DMO_E_TYPE_NOT_SET,
		DMO_E_NOTACCEPTING,
		DMO_E_TYPE_NOT_ACCEPTED,
		DMO_E_NO_MORE_ITEMS
	}
	[Flags]
	public enum DmoInPlaceProcessFlags
	{
		Normal = 0,
		Zero = 1
	}
	public enum DmoInPlaceProcessReturn
	{
		Normal,
		HasEffectTail
	}
	[Flags]
	public enum DmoInputDataBufferFlags
	{
		None = 0,
		SyncPoint = 1,
		Time = 2,
		TimeLength = 4
	}
	[Flags]
	internal enum DmoInputStatusFlags
	{
		None = 0,
		DMO_INPUT_STATUSF_ACCEPT_DATA = 1
	}
	internal static class DmoInterop
	{
		[DllImport("msdmo.dll")]
		public static extern int DMOEnum([In] ref Guid guidCategory, DmoEnumFlags flags, int inTypes, [In] DmoPartialMediaType[] inTypesArray, int outTypes, [In] DmoPartialMediaType[] outTypesArray, out IEnumDmo enumDmo);

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

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

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

		private Guid subtype;

		private bool bFixedSizeSamples;

		private bool bTemporalCompression;

		private int lSampleSize;

		private Guid formattype;

		private IntPtr pUnk;

		private int cbFormat;

		private IntPtr pbFormat;

		public Guid MajorType => majortype;

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

		public Guid SubType => subtype;

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

		public bool FixedSizeSamples => bFixedSizeSamples;

		public int SampleSize => lSampleSize;

		public Guid FormatType => formattype;

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

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

		public void SetWaveFormat(WaveFormat waveFormat)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_002c: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			majortype = MediaTypes.MEDIATYPE_Audio;
			WaveFormatExtensible val = (WaveFormatExtensible)(object)((waveFormat is WaveFormatExtensible) ? waveFormat : null);
			if (val != null)
			{
				subtype = val.SubFormat;
			}
			else
			{
				WaveFormatEncoding encoding = waveFormat.Encoding;
				if ((int)encoding != 1)
				{
					if ((int)encoding != 3)
					{
						if ((int)encoding != 85)
						{
							throw new ArgumentException($"Not a supported encoding {waveFormat.Encoding}");
						}
						subtype = AudioMediaSubtypes.WMMEDIASUBTYPE_MP3;
					}
					else
					{
						subtype = AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT;
					}
				}
				else
				{
					subtype = AudioMediaSubtypes.MEDIASUBTYPE_PCM;
				}
			}
			bFixedSizeSamples = SubType == AudioMediaSubtypes.MEDIASUBTYPE_PCM || SubType == AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT;
			formattype = DmoMediaTypeGuids.FORMAT_WaveFormatEx;
			if (cbFormat < Marshal.SizeOf<WaveFormat>(waveFormat))
			{
				throw new InvalidOperationException("Not enough memory assigned for a WaveFormat structure");
			}
			Marshal.StructureToPtr<WaveFormat>(waveFormat, pbFormat, fDeleteOld: false);
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 8)]
	public struct DmoOutputDataBuffer : IDisposable
	{
		[MarshalAs(UnmanagedType.Interface)]
		private IMediaBuffer pBuffer;

		private DmoOutputDataBufferFlags dwStatus;

		private long rtTimestamp;

		private long referenceTimeDuration;

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

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

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

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

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

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

		public DmoOutputDataBuffer(int maxBufferSize)
		{
			pBuffer = new MediaBuffer(maxBufferSize);
			dwStatus = DmoOutputDataBufferFlags.None;
			rtTimestamp = 0L;
			referenceTimeDuration = 0L;
		}

		public void Dispose()
		{
			if (pBuffer != null)
			{
				((MediaBuffer)pBuffer).Dispose();
				pBuffer = null;
				GC.SuppressFinalize(this);
			}
		}

		public void RetrieveData(byte[] data, int offset)
		{
			((MediaBuffer)pBuffer).RetrieveData(data, offset);
		}
	}
	[Flags]
	public enum DmoOutputDataBufferFlags
	{
		None = 0,
		SyncPoint = 1,
		Time = 2,
		TimeLength = 4,
		Incomplete = 0x1000000
	}
	internal struct DmoPartialMediaType
	{
		private Guid type;

		private Guid subtype;

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

		public Guid Subtype
		{
			get
			{
				return subtype;
			}
			internal set
			{
				subtype = value;
			}
		}
	}
	[Flags]
	public enum DmoProcessOutputFlags
	{
		None = 0,
		DiscardWhenNoBuffer = 1
	}
	[Flags]
	internal enum DmoSetTypeFlags
	{
		None = 0,
		DMO_SET_TYPEF_TEST_ONLY = 1,
		DMO_SET_TYPEF_CLEAR = 2
	}
	[ComImport]
	[Guid("2c3cd98a-2bfa-4a53-9c27-5249ba64ba0f")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface IEnumDmo
	{
		int Next(int itemsToFetch, out Guid clsid, out IntPtr name, out int itemsFetched);

		int Skip(int itemsToSkip);

		int Reset();

		int Clone(out IEnumDmo enumPointer);
	}
	[ComImport]
	[SuppressUnmanagedCodeSecurity]
	[Guid("59eff8b9-938c-4a26-82f2-95cb84cdc837")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	public interface IMediaBuffer
	{
		[PreserveSig]
		int SetLength(int length);

		[PreserveSig]
		int GetMaxLength(out int maxLength);

		[PreserveSig]
		int GetBufferAndLength(IntPtr bufferPointerPointer, IntPtr validDataLengthPointer);
	}
	[ComImport]
	[SuppressUnmanagedCodeSecurity]
	[Guid("d8ad0f58-5494-4102-97c5-ec798e59bcf4")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface IMediaObject
	{
		[PreserveSig]
		int GetStreamCount(out int inputStreams, out int outputStreams);

		[PreserveSig]
		int GetInputStreamInfo(int inputStreamIndex, out InputStreamInfoFlags flags);

		[PreserveSig]
		int GetOutputStreamInfo(int outputStreamIndex, out OutputStreamInfoFlags flags);

		[PreserveSig]
		int GetInputType(int inputStreamIndex, int typeIndex, out DmoMediaType mediaType);

		[PreserveSig]
		int GetOutputType(int outputStreamIndex, int typeIndex, out DmoMediaType mediaType);

		[PreserveSig]
		int SetInputType(int inputStreamIndex, [In] ref DmoMediaType mediaType, DmoSetTypeFlags flags);

		[PreserveSig]
		int SetOutputType(int outputStreamIndex, [In] ref DmoMediaType mediaType, DmoSetTypeFlags flags);

		[PreserveSig]
		int GetInputCurrentType(int inputStreamIndex, out DmoMediaType mediaType);

		[PreserveSig]
		int GetOutputCurrentType(int outputStreamIndex, out DmoMediaType mediaType);

		[PreserveSig]
		int GetInputSizeInfo(int inputStreamIndex, out int size, out int maxLookahead, out int alignment);

		[PreserveSig]
		int GetOutputSizeInfo(int outputStreamIndex, out int size, out int alignment);

		[PreserveSig]
		int GetInputMaxLatency(int inputStreamIndex, out long referenceTimeMaxLatency);

		[PreserveSig]
		int SetInputMaxLatency(int inputStreamIndex, long referenceTimeMaxLatency);

		[PreserveSig]
		int Flush();

		[PreserveSig]
		int Discontinuity(int inputStreamIndex);

		[PreserveSig]
		int AllocateStreamingResources();

		[PreserveSig]
		int FreeStreamingResources();

		[PreserveSig]
		int GetInputStatus(int inputStreamIndex, out DmoInputStatusFlags flags);

		[PreserveSig]
		int ProcessInput(int inputStreamIndex, [In] IMediaBuffer mediaBuffer, DmoInputDataBufferFlags flags, long referenceTimeTimestamp, long referenceTimeDuration);

		[PreserveSig]
		int ProcessOutput(DmoProcessOutputFlags flags, int outputBufferCount, [In][Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] DmoOutputDataBuffer[] outputBuffers, out int statusReserved);

		[PreserveSig]
		int Lock(bool acquireLock);
	}
	[ComImport]
	[SuppressUnmanagedCodeSecurity]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("651B9AD0-0FC7-4AA9-9538-D89931010741")]
	internal interface IMediaObjectInPlace
	{
		[PreserveSig]
		int Process([In] int size, [In] IntPtr data, [In] long refTimeStart, [In] DmoInPlaceProcessFlags dwFlags);

		[PreserveSig]
		int Clone([MarshalAs(UnmanagedType.Interface)] out IMediaObjectInPlace mediaObjectInPlace);

		[PreserveSig]
		int GetLatency(out long latencyTime);
	}
	[ComImport]
	[SuppressUnmanagedCodeSecurity]
	[Guid("6d6cbb60-a223-44aa-842f-a2f06750be6d")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface IMediaParamInfo
	{
		[PreserveSig]
		int GetParamCount(out int paramCount);

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

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

		[PreserveSig]
		int GetNumTimeFormats(out int numTimeFormats);

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

		[PreserveSig]
		int GetCurrentTimeFormat(out Guid guidTimeFormat, out int mediaTimeData);
	}
	[Flags]
	internal enum InputStreamInfoFlags
	{
		None = 0,
		DMO_INPUT_STREAMF_WHOLE_SAMPLES = 1,
		DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER = 2,
		DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE = 4,
		DMO_INPUT_STREAMF_HOLDS_BUFFERS = 8
	}
	[ComImport]
	[Guid("E7E9984F-F09F-4da4-903F-6E2E0EFE56B5")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface IWMResamplerProps
	{
		int SetHalfFilterLength(int outputQuality);

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

		private int length;

		private readonly int maxLength;

		public int Length
		{
			get
			{
				return length;
			}
			set
			{
				if (length > maxLength)
				{
					throw new ArgumentException("Cannot be gr

UserLibs/NAudio.WinMM.dll

Decompiled a day 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.CodeAnalysis;
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(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.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 Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_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)
				{
	

UserLibs/VGltf.dll

Decompiled a day 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.Versioning;
using VGltf.Glb;
using VGltf.Types;
using VJson;
using VJson.Schema;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("yutopp")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2019")]
[assembly: AssemblyDescription("A glTF and GLB serializer/deserializer library written in pure C#.")]
[assembly: AssemblyFileVersion("0.0.0.0")]
[assembly: AssemblyInformationalVersion("0.0.0")]
[assembly: AssemblyProduct("VGltf")]
[assembly: AssemblyTitle("VGltf")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace VGltf
{
	public sealed class BufferBuilder
	{
		private sealed class AsView
		{
			public ArraySegment<byte> Payload;

			public int? ByteStride;

			public BufferView.TargetEnum? Target;
		}

		private readonly List<AsView> _asViews = new List<AsView>();

		public int AddView(ArraySegment<byte> payload, int? byteStride = null, BufferView.TargetEnum? target = null)
		{
			int count = _asViews.Count;
			_asViews.Add(new AsView
			{
				Payload = payload,
				ByteStride = byteStride,
				Target = target
			});
			return count;
		}

		public byte[] BuildBytes(out List<BufferView> views)
		{
			views = new List<BufferView>();
			using MemoryStream memoryStream = new MemoryStream();
			uint num = 0u;
			foreach (AsView asView in _asViews)
			{
				uint num2 = Align.WritePadding(memoryStream, num, 4u, 0);
				num += num2;
				uint byteOffset = num;
				memoryStream.Write(asView.Payload.Array, asView.Payload.Offset, asView.Payload.Count);
				num += (uint)asView.Payload.Count;
				uint num3 = Align.WritePadding(memoryStream, num, 4u, 0);
				num += num3;
				views.Add(new BufferView
				{
					Buffer = 0,
					ByteOffset = (int)byteOffset,
					ByteLength = asView.Payload.Count,
					ByteStride = asView.ByteStride,
					Target = asView.Target
				});
			}
			return memoryStream.ToArray();
		}
	}
	public sealed class GltfContainer
	{
		public Gltf Gltf { get; }

		public StoredBuffer Buffer { get; }

		public JsonSchemaRegistry JsonSchemas { get; }

		public GltfContainer(Gltf gltf, StoredBuffer buffer = null, JsonSchemaRegistry reg = null)
		{
			Gltf = gltf;
			Buffer = buffer;
			JsonSchemas = reg;
		}

		public static GltfContainer FromGltf(Stream s, StoredBuffer buffer = null)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			JsonSchemaRegistry reg = new JsonSchemaRegistry();
			return new GltfContainer(GltfReader.Read(s, reg), buffer, reg);
		}

		public static void FromGltf(Stream s, GltfContainer container)
		{
			GltfWriter.Write(s, container.Gltf, container.JsonSchemas);
		}

		public static GltfContainer FromGlb(Stream s)
		{
			return Reader.ReadAsContainer(s);
		}

		public static void ToGlb(Stream s, GltfContainer container)
		{
			Writer.WriteFromContainer(s, container);
		}
	}
	public static class GltfReader
	{
		public static Gltf Read(Stream s, JsonSchemaRegistry reg, bool withRepairment = true)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			JsonReader val = new JsonReader(s);
			try
			{
				INode val2 = val.Read();
				if (withRepairment)
				{
					RepairKnownInvalidFormat(val2);
				}
				Gltf gltf = (Gltf)new JsonDeserializer(typeof(Gltf)).DeserializeFromNode(val2);
				if (reg != null)
				{
					ConstraintsViolationException val3 = JsonSchemaExtensions.Validate(JsonSchema.CreateFromType<Gltf>(reg, false), (object)gltf, reg);
					if (val3 != null)
					{
						throw val3;
					}
				}
				return gltf;
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}

		public static Gltf ReadWithoutValidation(Stream s, bool withRepairment = true)
		{
			return Read(s, null, withRepairment);
		}

		public static void RepairKnownInvalidFormat(INode node)
		{
			RepairUniGLTFInvalidNamesForImages(node);
			RepairUniGLTFInvalidTargets(node);
			RepairUniGLTFInvalidTargets2(node);
			RepairUniGLTFInvalidIndexValues(node);
			RepairUniGLTFInvalidScene(node);
		}

		public static void RepairUniGLTFInvalidNamesForImages(INode node)
		{
			INode obj = node["images"];
			ArrayNode val = (ArrayNode)(object)((obj is ArrayNode) ? obj : null);
			if (val == null)
			{
				return;
			}
			foreach (INode item in val)
			{
				ObjectNode val2 = (ObjectNode)(object)((item is ObjectNode) ? item : null);
				if (val2 != null)
				{
					INode obj2 = item["extra"]["name"];
					StringNode val3 = (StringNode)(object)((obj2 is StringNode) ? obj2 : null);
					if (val3 != null && item["name"] is UndefinedNode)
					{
						val2.AddElement("name", (INode)(object)val3);
					}
				}
			}
		}

		public static void RepairUniGLTFInvalidTargets(INode node)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Expected O, but got Unknown
			INode obj = node["meshes"];
			ArrayNode val = (ArrayNode)(object)((obj is ArrayNode) ? obj : null);
			if (val == null)
			{
				return;
			}
			foreach (INode item in val)
			{
				INode val2 = item["extras"];
				if (val2 is UndefinedNode)
				{
					val2 = (INode)new ObjectNode();
					((ObjectNode)item).AddElement("extras", val2);
				}
				INode obj2 = item["primitives"];
				ArrayNode val3 = (ArrayNode)(object)((obj2 is ArrayNode) ? obj2 : null);
				if (val3 == null)
				{
					continue;
				}
				List<string> list = null;
				foreach (INode item2 in val3)
				{
					INode obj3 = item2["targets"];
					ArrayNode val4 = (ArrayNode)(object)((obj3 is ArrayNode) ? obj3 : null);
					if (val4 == null)
					{
						continue;
					}
					List<string> list2 = new List<string>();
					foreach (INode item3 in val4)
					{
						ObjectNode val5 = (ObjectNode)(object)((item3 is ObjectNode) ? item3 : null);
						if (val5 == null)
						{
							continue;
						}
						List<string> list3 = new List<string>();
						foreach (KeyValuePair<string, INode> item4 in val5)
						{
							string key = item4.Key;
							if (key == "extra")
							{
								list3.Add(key);
								INode obj4 = item3[key]["name"];
								StringNode val6 = (StringNode)(object)((obj4 is StringNode) ? obj4 : null);
								if (val6 == null)
								{
									continue;
								}
								list2.Add(val6.Value);
							}
							if (!IsValidMorphTargetProperty(key))
							{
								list3.Add(key);
							}
						}
						foreach (string item5 in list3)
						{
							val5.RemoveElement(item5);
						}
					}
					if (list == null || list.Count == list2.Count)
					{
						list = list2;
					}
				}
				if (list == null)
				{
					continue;
				}
				ArrayNode val7 = null;
				ObjectNode val8 = (ObjectNode)(object)((val2 is ObjectNode) ? val2 : null);
				if (val8 != null)
				{
					INode val9 = val8["targetNames"];
					if (val9 is UndefinedNode)
					{
						val9 = (INode)new ArrayNode();
						val8.AddElement("targetNames", val9);
					}
					val7 = (ArrayNode)(object)((val9 is ArrayNode) ? val9 : null);
				}
				if (val7 == null)
				{
					continue;
				}
				foreach (string item6 in list)
				{
					val7.AddElement((INode)new StringNode(item6));
				}
			}
		}

		public static void RepairUniGLTFInvalidTargets2(INode node)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Expected O, but got Unknown
			INode obj = node["meshes"];
			ArrayNode val = (ArrayNode)(object)((obj is ArrayNode) ? obj : null);
			if (val == null)
			{
				return;
			}
			foreach (INode item in val)
			{
				INode val2 = item["extras"];
				if (val2 is UndefinedNode)
				{
					val2 = (INode)new ObjectNode();
					((ObjectNode)item).AddElement("extras", val2);
				}
				INode obj2 = item["primitives"];
				ArrayNode val3 = (ArrayNode)(object)((obj2 is ArrayNode) ? obj2 : null);
				if (val3 == null)
				{
					continue;
				}
				List<string> list = null;
				foreach (INode item2 in val3)
				{
					INode val4 = item2["extras"];
					if (val4 is UndefinedNode)
					{
						continue;
					}
					INode val5 = val4["targetNames"];
					if (val5 is UndefinedNode)
					{
						continue;
					}
					ArrayNode val6 = (ArrayNode)(object)((val5 is ArrayNode) ? val5 : null);
					if (val6 == null)
					{
						continue;
					}
					List<string> list2 = new List<string>();
					foreach (INode elem in val6.Elems)
					{
						StringNode val7 = (StringNode)(object)((elem is StringNode) ? elem : null);
						if (val7 != null)
						{
							list2.Add(val7.Value);
						}
					}
					if (list == null || list.Count == list2.Count)
					{
						list = list2;
					}
				}
				if (list == null)
				{
					continue;
				}
				ArrayNode val8 = null;
				ObjectNode val9 = (ObjectNode)(object)((val2 is ObjectNode) ? val2 : null);
				if (val9 != null)
				{
					INode val10 = val9["targetNames"];
					if (val10 is UndefinedNode)
					{
						val10 = (INode)new ArrayNode();
						val9.AddElement("targetNames", val10);
					}
					val8 = (ArrayNode)(object)((val10 is ArrayNode) ? val10 : null);
				}
				if (val8 == null)
				{
					continue;
				}
				foreach (string item3 in list)
				{
					val8.AddElement((INode)new StringNode(item3));
				}
			}
		}

		public static void RepairUniGLTFInvalidIndexValues(INode node)
		{
			RepairUniGLTFInvalidIndexValuesForMeshes(node);
		}

		public static void RepairUniGLTFInvalidIndexValuesForMeshes(INode node)
		{
			INode obj = node["meshes"];
			ArrayNode val = (ArrayNode)(object)((obj is ArrayNode) ? obj : null);
			if (val == null)
			{
				return;
			}
			foreach (INode item in val)
			{
				INode obj2 = item["primitives"];
				ArrayNode val2 = (ArrayNode)(object)((obj2 is ArrayNode) ? obj2 : null);
				if (val2 == null)
				{
					continue;
				}
				foreach (INode item2 in val2)
				{
					ObjectNode val3 = (ObjectNode)(object)((item2 is ObjectNode) ? item2 : null);
					if (val3 == null)
					{
						continue;
					}
					INode obj3 = item2["indices"];
					IntegerNode val4 = (IntegerNode)(object)((obj3 is IntegerNode) ? obj3 : null);
					if (val4 != null && val4.Value == -1)
					{
						val3.RemoveElement("indices");
					}
					INode obj4 = item2["material"];
					IntegerNode val5 = (IntegerNode)(object)((obj4 is IntegerNode) ? obj4 : null);
					if (val5 != null && val5.Value == -1)
					{
						val3.RemoveElement("material");
					}
					INode obj5 = item2["mode"];
					IntegerNode val6 = (IntegerNode)(object)((obj5 is IntegerNode) ? obj5 : null);
					if (val6 != null && val6.Value == -1)
					{
						val3.RemoveElement("mode");
					}
					INode obj6 = item2["targets"];
					ArrayNode val7 = (ArrayNode)(object)((obj6 is ArrayNode) ? obj6 : null);
					if (val7 == null)
					{
						continue;
					}
					foreach (INode item3 in val7)
					{
						ObjectNode val8 = (ObjectNode)(object)((item3 is ObjectNode) ? item3 : null);
						if (val8 == null)
						{
							continue;
						}
						List<string> list = new List<string>();
						foreach (KeyValuePair<string, INode> item4 in val8)
						{
							INode value = item4.Value;
							IntegerNode val9 = (IntegerNode)(object)((value is IntegerNode) ? value : null);
							if (val9 != null && val9.Value == -1)
							{
								list.Add(item4.Key);
							}
						}
						foreach (string item5 in list)
						{
							val8.RemoveElement(item5);
						}
					}
				}
			}
		}

		public static void RepairUniGLTFInvalidScene(INode node)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			ObjectNode val = (ObjectNode)(object)((node is ObjectNode) ? node : null);
			if (val != null)
			{
				INode obj = node["asset"]["generator"];
				StringNode val2 = (StringNode)(object)((obj is StringNode) ? obj : null);
				if (val2 != null && !(val2.Value != "UniGLTF") && node["scene"] is UndefinedNode)
				{
					val.AddElement("scene", (INode)new IntegerNode(0L));
				}
			}
		}

		private static bool IsValidMorphTargetProperty(string name)
		{
			if (name.StartsWith("_"))
			{
				return true;
			}
			switch (name)
			{
			case "POSITION":
			case "NORMAL":
			case "TANGENT":
				return true;
			default:
				return false;
			}
		}
	}
	public class GltfWriter
	{
		public static void Write(Stream s, Gltf gltf, JsonSchemaRegistry reg)
		{
			ConstraintsViolationException val = JsonSchemaExtensions.Validate(JsonSchema.CreateFromType<Gltf>(reg, false), (object)gltf, reg);
			if (val != null)
			{
				throw val;
			}
			WriteWithoutValidation(s, gltf);
		}

		public static void WriteWithoutValidation(Stream s, Gltf gltf)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			new JsonSerializer(typeof(Gltf)).Serialize<Gltf>(s, gltf, 0);
		}
	}
	public sealed class Resource
	{
		public ArraySegment<byte> Data;
	}
	public interface IResourceLoader
	{
		Resource Load(string uri);

		string FullPathOf(string uri);
	}
	public sealed class ResourceLoaderFromFileStorage : IResourceLoader
	{
		private readonly string _baseDir;

		public ResourceLoaderFromFileStorage(string baseDir)
		{
			_baseDir = baseDir;
		}

		public Resource Load(string uri)
		{
			if (DataUriUtil.IsData(uri))
			{
				return DataUriUtil.Extract(uri);
			}
			return LoadFromFile(_baseDir, uri);
		}

		public string FullPathOf(string uri)
		{
			if (DataUriUtil.IsData(uri))
			{
				throw new InvalidOperationException("uri is data form");
			}
			return EnsureCleanedPath(_baseDir, uri);
		}

		public static string EnsureCleanedPath(string baseDir, string uri)
		{
			string fullPath = Path.GetFullPath(baseDir);
			string fullPath2 = Path.GetFullPath(Path.Combine(baseDir, uri));
			if (!fullPath2.StartsWith(fullPath))
			{
				throw new ArgumentException($"Path must be a child of baseDir: Uri = {uri}, BaseDir = {baseDir}, FullPath = {fullPath2}");
			}
			return fullPath2;
		}

		public static Resource LoadFromFile(string baseDir, string uri)
		{
			byte[] array = File.ReadAllBytes(EnsureCleanedPath(baseDir, uri));
			return new Resource
			{
				Data = new ArraySegment<byte>(array)
			};
		}
	}
	public sealed class ResourceLoaderFromEmbedOnly : IResourceLoader
	{
		public Resource Load(string uri)
		{
			if (!DataUriUtil.IsData(uri))
			{
				throw new InvalidOperationException("uri is not data form");
			}
			return DataUriUtil.Extract(uri);
		}

		public string FullPathOf(string uri)
		{
			throw new NotImplementedException(uri);
		}
	}
	public static class DataUriUtil
	{
		public static bool IsData(string uri)
		{
			return uri.StartsWith("data:");
		}

		public static Resource Extract(string uri)
		{
			int num = uri.IndexOf(',');
			if (num == -1)
			{
				throw new ArgumentException("Invalid DataURI format (',' is missing)");
			}
			return new Resource
			{
				Data = new ArraySegment<byte>(Convert.FromBase64String(uri.Substring(num + 1)))
			};
		}
	}
	public sealed class ResourcesStore
	{
		private readonly Dictionary<int, Resource> _bufferResources = new Dictionary<int, Resource>();

		private readonly Dictionary<int, Resource> _imageResources = new Dictionary<int, Resource>();

		public GltfContainer Container { get; }

		public IResourceLoader Loader { get; }

		public Gltf Gltf => Container.Gltf;

		public StoredBuffer Buffer => Container.Buffer;

		public ResourcesStore(GltfContainer container, IResourceLoader loader)
		{
			Container = container;
			Loader = loader;
		}

		public Resource GetOrLoadBufferResourceAt(int index)
		{
			if (GetBufferResourceAt(index, out var resource))
			{
				return resource;
			}
			VGltf.Types.Buffer buffer = Gltf.Buffers[index];
			if (buffer.Uri != null)
			{
				resource = Loader.Load(buffer.Uri);
				resource.Data = new ArraySegment<byte>(resource.Data.Array, resource.Data.Offset, buffer.ByteLength);
			}
			else
			{
				if (index != 0)
				{
					throw new InvalidOperationException("When referencing binaryBuffer, index must be 0");
				}
				if (Buffer == null)
				{
					throw new InvalidOperationException("GLB stored buffer is null");
				}
				resource = new Resource
				{
					Data = new ArraySegment<byte>(Buffer.Payload.Array, Buffer.Payload.Offset, buffer.ByteLength)
				};
			}
			_bufferResources.Add(index, resource);
			return resource;
		}

		public bool GetBufferResourceAt(int index, out Resource resource)
		{
			return _bufferResources.TryGetValue(index, out resource);
		}

		public Resource GetOrLoadBufferViewResourceAt(int index)
		{
			BufferView bufferView = Gltf.BufferViews[index];
			Resource orLoadBufferResourceAt = GetOrLoadBufferResourceAt(bufferView.Buffer);
			ArraySegment<byte> data = new ArraySegment<byte>(orLoadBufferResourceAt.Data.Array, orLoadBufferResourceAt.Data.Offset + bufferView.ByteOffset, bufferView.ByteLength);
			return new Resource
			{
				Data = data
			};
		}

		public Resource GetOrLoadImageResourceAt(int index)
		{
			if (GetImageResourceAt(index, out var resource))
			{
				return resource;
			}
			Image image = Gltf.Images[index];
			resource = ((image.Uri == null) ? GetOrLoadBufferViewResourceAt(image.BufferView.Value) : Loader.Load(image.Uri));
			_imageResources.Add(index, resource);
			return resource;
		}

		public bool GetImageResourceAt(int index, out Resource resource)
		{
			return _imageResources.TryGetValue(index, out resource);
		}

		public TypedBuffer GetOrLoadTypedBufferByAccessorIndex(int index)
		{
			Accessor accessor = Gltf.Accessors[index];
			return new TypedBuffer(this, accessor);
		}
	}
	public interface ITypedView<T> where T : struct
	{
	}
	public delegate Out Mapper<Elem, Out>(Elem[] xs, int i) where Elem : struct where Out : struct;
	public sealed class TypedArrayView<T> where T : struct
	{
		public readonly T[] TypedBuffer;

		private TypedArrayView(T[] typedBuffer)
		{
			TypedBuffer = typedBuffer;
		}

		public static TypedArrayView<T> CreateFromPrimitive<Prim>(ArraySegment<byte> buffer, int stride, int componentSize, int componentNum, int count, Mapper<Prim, T> mapper) where Prim : struct
		{
			T[] array = new T[count];
			if (componentSize * componentNum == stride)
			{
				Prim[] array2 = new Prim[componentNum * count];
				byte[]? array3 = buffer.Array;
				int offset = buffer.Offset;
				System.Buffer.BlockCopy(array3, offset, array2, 0, componentSize * componentNum * count);
				for (int i = 0; i < array2.Length / componentNum; i++)
				{
					array[i] = mapper(array2, i * componentNum);
				}
			}
			else
			{
				Prim[] array4 = new Prim[componentNum];
				byte[] array5 = buffer.Array;
				int offset2 = buffer.Offset;
				for (int j = 0; j < count; j++)
				{
					int num = j * stride;
					System.Buffer.BlockCopy(array5, offset2 + num, array4, 0, componentSize * componentNum);
					array[j] = mapper(array4, 0);
				}
			}
			return new TypedArrayView<T>(array);
		}
	}
	public static class TypedArrayStorageFromBufferView
	{
		public static TypedArrayView<T> CreateFrom<Prim, T>(ResourcesStore store, int bufferViewIndex, int byteOffset, int componentSize, int componentNum, int count, Mapper<Prim, T> mapper) where Prim : struct where T : struct
		{
			BufferView bufferView = store.Gltf.BufferViews[bufferViewIndex];
			Resource orLoadBufferViewResourceAt = store.GetOrLoadBufferViewResourceAt(bufferViewIndex);
			int num = componentSize * componentNum;
			int num2 = (bufferView.ByteStride.HasValue ? bufferView.ByteStride.Value : num);
			return TypedArrayView<T>.CreateFromPrimitive(new ArraySegment<byte>(orLoadBufferViewResourceAt.Data.Array, orLoadBufferViewResourceAt.Data.Offset + byteOffset, count * num2), num2, componentSize, componentNum, count, mapper);
		}
	}
	public sealed class TypedArrayEntity<T, U> where T : struct where U : struct
	{
		public readonly TypedArrayView<U> DenseView;

		public readonly TypedArrayView<uint> SparseIndices;

		public readonly TypedArrayView<U> SparseValues;

		public readonly int Length;

		private readonly int _componentNum;

		public TypedArrayEntity(ResourcesStore store, Accessor accessor, Mapper<T, U> mapper)
		{
			Length = accessor.Count;
			_componentNum = accessor.Type.NumOfComponents();
			if (accessor.BufferView.HasValue)
			{
				DenseView = TypedArrayStorageFromBufferView.CreateFrom(store, accessor.BufferView.Value, accessor.ByteOffset, accessor.ComponentType.SizeInBytes(), accessor.Type.NumOfComponents(), accessor.Count, mapper);
			}
			if (accessor.Sparse == null)
			{
				return;
			}
			Accessor.SparseType sparse = accessor.Sparse;
			Accessor.SparseType.IndicesType indices = sparse.Indices;
			switch (indices.ComponentType)
			{
			case Accessor.SparseType.IndicesType.ComponentTypeEnum.UNSIGNED_BYTE:
				SparseIndices = TypedArrayStorageFromBufferView.CreateFrom(store, indices.BufferView, indices.ByteOffset, indices.ComponentType.SizeInBytes(), 1, sparse.Count, (Mapper<byte, uint>)((byte[] xs, int i) => xs[i]));
				break;
			case Accessor.SparseType.IndicesType.ComponentTypeEnum.UNSIGNED_SHORT:
				SparseIndices = TypedArrayStorageFromBufferView.CreateFrom(store, indices.BufferView, indices.ByteOffset, indices.ComponentType.SizeInBytes(), 1, sparse.Count, (Mapper<ushort, uint>)((ushort[] xs, int i) => xs[i]));
				break;
			case Accessor.SparseType.IndicesType.ComponentTypeEnum.UNSIGNED_INT:
				SparseIndices = TypedArrayStorageFromBufferView.CreateFrom(store, indices.BufferView, indices.ByteOffset, indices.ComponentType.SizeInBytes(), 1, sparse.Count, (uint[] xs, int i) => xs[i]);
				break;
			default:
				throw new NotSupportedException();
			}
			Accessor.SparseType.ValuesType values = sparse.Values;
			SparseValues = TypedArrayStorageFromBufferView.CreateFrom(store, values.BufferView, values.ByteOffset, accessor.ComponentType.SizeInBytes(), accessor.Type.NumOfComponents(), sparse.Count, mapper);
		}

		public U[] AsArray()
		{
			U[] array = ((DenseView != null) ? DenseView.TypedBuffer : null);
			if (SparseValues == null)
			{
				return array;
			}
			U[] typedBuffer = SparseValues.TypedBuffer;
			uint num = SparseIndices.TypedBuffer[0];
			U[] array2 = new U[Length];
			int num2 = 0;
			for (int i = 0; i < array2.Length; i++)
			{
				U val = default(U);
				if (array != null)
				{
					val = array[i];
				}
				if (i == num)
				{
					val = typedBuffer[num2];
					num2++;
					num = ((num2 < SparseIndices.TypedBuffer.Length) ? SparseIndices.TypedBuffer[num2] : uint.MaxValue);
				}
				array2[i] = val;
			}
			return array2;
		}
	}
	public sealed class TypedBuffer
	{
		public readonly ResourcesStore Store;

		public readonly Accessor Accessor;

		public TypedBuffer(ResourcesStore store, Accessor accessor)
		{
			Store = store;
			Accessor = accessor;
		}

		public TypedArrayEntity<T, U> GetEntity<T, U>(Mapper<T, U> mapper) where T : struct where U : struct
		{
			return new TypedArrayEntity<T, U>(Store, Accessor, mapper);
		}

		public int[] GetPrimitivesAsInt()
		{
			if (Accessor.Type != 0)
			{
				throw new InvalidOperationException("Type must be Scalar: Actual = " + Accessor.Type);
			}
			return Accessor.ComponentType switch
			{
				Accessor.ComponentTypeEnum.BYTE => GetEntity((Mapper<sbyte, int>)((sbyte[] xs, int i) => xs[i])).AsArray(), 
				Accessor.ComponentTypeEnum.UNSIGNED_BYTE => GetEntity((Mapper<byte, int>)((byte[] xs, int i) => xs[i])).AsArray(), 
				Accessor.ComponentTypeEnum.SHORT => GetEntity((Mapper<short, int>)((short[] xs, int i) => xs[i])).AsArray(), 
				Accessor.ComponentTypeEnum.UNSIGNED_SHORT => GetEntity((Mapper<ushort, int>)((ushort[] xs, int i) => xs[i])).AsArray(), 
				Accessor.ComponentTypeEnum.UNSIGNED_INT => GetEntity((uint[] xs, int i) => (int)xs[i]).AsArray(), 
				Accessor.ComponentTypeEnum.FLOAT => throw new InvalidOperationException("Cannot convert from float to int"), 
				_ => throw new InvalidOperationException("Unexpected ComponentType: Actual = " + Accessor.ComponentType), 
			};
		}
	}
}
namespace VGltf.Types
{
	[JsonSchema(Id = "accessor.schema.json")]
	public sealed class Accessor : GltfChildOfRootProperty
	{
		[Json]
		public enum ComponentTypeEnum
		{
			[JsonField]
			BYTE = 5120,
			[JsonField]
			UNSIGNED_BYTE = 5121,
			[JsonField]
			SHORT = 5122,
			[JsonField]
			UNSIGNED_SHORT = 5123,
			[JsonField]
			UNSIGNED_INT = 5125,
			[JsonField]
			FLOAT = 5126
		}

		[Json(/*Could not decode attribute arguments.*/)]
		public enum TypeEnum
		{
			[JsonField(Name = "SCALAR")]
			Scalar,
			[JsonField(Name = "VEC2")]
			Vec2,
			[JsonField(Name = "VEC3")]
			Vec3,
			[JsonField(Name = "VEC4")]
			Vec4,
			[JsonField(Name = "MAT2")]
			Mat2,
			[JsonField(Name = "MAT3")]
			Mat3,
			[JsonField(Name = "MAT4")]
			Mat4
		}

		[JsonSchema(Id = "accessor.sparse.schema.json")]
		public sealed class SparseType : GltfProperty
		{
			[JsonSchema(Id = "accessor.sparse.indices.schema.json")]
			public class IndicesType : GltfProperty
			{
				[Json]
				public enum ComponentTypeEnum
				{
					[JsonField]
					UNSIGNED_BYTE = 5121,
					[JsonField]
					UNSIGNED_SHORT = 5123,
					[JsonField]
					UNSIGNED_INT = 5125
				}

				[JsonField(Name = "bufferView")]
				[JsonSchemaRequired]
				[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
				public int BufferView;

				[JsonField(Name = "byteOffset")]
				[JsonSchema(Minimum = 0.0)]
				public int ByteOffset;

				[JsonField(Name = "componentType")]
				[JsonSchemaRequired]
				public ComponentTypeEnum ComponentType;
			}

			[JsonSchema(Id = "accessor.sparse.values.schema.json")]
			public sealed class ValuesType : GltfProperty
			{
				[JsonField(Name = "bufferView")]
				[JsonSchemaRequired]
				[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
				public int BufferView;

				[JsonField(Name = "byteOffset")]
				[JsonSchema(Minimum = 0.0)]
				public int ByteOffset;
			}

			[JsonField(Name = "count")]
			[JsonSchema(Minimum = 0.0)]
			[JsonSchemaRequired]
			public int Count;

			[JsonField(Name = "indices")]
			[JsonSchemaRequired]
			public IndicesType Indices;

			[JsonField(Name = "values")]
			[JsonSchemaRequired]
			public ValuesType Values;
		}

		[JsonField(Name = "bufferView")]
		[JsonFieldIgnorable]
		[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int? BufferView;

		[JsonField(Name = "byteOffset")]
		[JsonSchema(Minimum = 0.0)]
		[JsonSchemaDependencies(new string[] { "bufferView" })]
		public int ByteOffset;

		[JsonField(Name = "componentType")]
		[JsonSchemaRequired]
		public ComponentTypeEnum ComponentType;

		[JsonField(Name = "normalized")]
		public bool Normalized;

		[JsonField(Name = "count")]
		[JsonSchema(Minimum = 1.0)]
		[JsonSchemaRequired]
		public int Count;

		[JsonField(Name = "type")]
		[JsonSchemaRequired]
		public TypeEnum Type;

		[JsonField(Name = "max")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1, MaxItems = 16)]
		public float[] Max;

		[JsonField(Name = "min")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1, MaxItems = 16)]
		public float[] Min;

		[JsonField(Name = "sparse")]
		[JsonFieldIgnorable]
		public SparseType Sparse;
	}
	public static class AccessorComponentTypeEnumExtensions
	{
		public static int SizeInBytes(this Accessor.ComponentTypeEnum e)
		{
			return e switch
			{
				Accessor.ComponentTypeEnum.BYTE => 1, 
				Accessor.ComponentTypeEnum.UNSIGNED_BYTE => 1, 
				Accessor.ComponentTypeEnum.SHORT => 2, 
				Accessor.ComponentTypeEnum.UNSIGNED_SHORT => 2, 
				Accessor.ComponentTypeEnum.UNSIGNED_INT => 4, 
				Accessor.ComponentTypeEnum.FLOAT => 4, 
				_ => throw new NotImplementedException(), 
			};
		}

		public static Type TypeOf(this Accessor.ComponentTypeEnum e)
		{
			return e switch
			{
				Accessor.ComponentTypeEnum.BYTE => typeof(sbyte), 
				Accessor.ComponentTypeEnum.UNSIGNED_BYTE => typeof(byte), 
				Accessor.ComponentTypeEnum.SHORT => typeof(short), 
				Accessor.ComponentTypeEnum.UNSIGNED_SHORT => typeof(ushort), 
				Accessor.ComponentTypeEnum.UNSIGNED_INT => typeof(uint), 
				Accessor.ComponentTypeEnum.FLOAT => typeof(float), 
				_ => throw new NotImplementedException(), 
			};
		}
	}
	public static class AccessorTypeEnumExtensions
	{
		public static int NumOfComponents(this Accessor.TypeEnum t)
		{
			return t switch
			{
				Accessor.TypeEnum.Scalar => 1, 
				Accessor.TypeEnum.Vec2 => 2, 
				Accessor.TypeEnum.Vec3 => 3, 
				Accessor.TypeEnum.Vec4 => 4, 
				Accessor.TypeEnum.Mat2 => 4, 
				Accessor.TypeEnum.Mat3 => 9, 
				Accessor.TypeEnum.Mat4 => 16, 
				_ => throw new NotImplementedException(), 
			};
		}
	}
	public static class AccessorSparseIndicesComponentTypeEnumExtensions
	{
		public static Accessor.ComponentTypeEnum CommonType(this Accessor.SparseType.IndicesType.ComponentTypeEnum e)
		{
			return e switch
			{
				Accessor.SparseType.IndicesType.ComponentTypeEnum.UNSIGNED_BYTE => Accessor.ComponentTypeEnum.UNSIGNED_BYTE, 
				Accessor.SparseType.IndicesType.ComponentTypeEnum.UNSIGNED_SHORT => Accessor.ComponentTypeEnum.UNSIGNED_SHORT, 
				Accessor.SparseType.IndicesType.ComponentTypeEnum.UNSIGNED_INT => Accessor.ComponentTypeEnum.UNSIGNED_INT, 
				_ => throw new NotImplementedException(), 
			};
		}

		public static int SizeInBytes(this Accessor.SparseType.IndicesType.ComponentTypeEnum e)
		{
			return e.CommonType().SizeInBytes();
		}

		public static Type TypeOf(this Accessor.SparseType.IndicesType.ComponentTypeEnum e)
		{
			return e.CommonType().TypeOf();
		}
	}
	[JsonSchema(Id = "animation.schema.json")]
	public sealed class Animation : GltfChildOfRootProperty
	{
		[JsonSchema(Id = "animation.channel.schema.json")]
		public class ChannelType : GltfProperty
		{
			[JsonSchema(Id = "animation.channel.target.schema.json")]
			public class TargetType : GltfProperty
			{
				[Json(/*Could not decode attribute arguments.*/)]
				public enum PathEnum
				{
					[JsonField(Name = "translation")]
					Translation,
					[JsonField(Name = "rotation")]
					Rotation,
					[JsonField(Name = "scale")]
					Scale,
					[JsonField(Name = "weights")]
					Weights
				}

				[JsonField(Name = "node")]
				[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
				public int Node;

				[JsonField(Name = "path")]
				[JsonSchemaRequired]
				public PathEnum Path;
			}

			[JsonField(Name = "sampler")]
			[JsonSchemaRequired]
			[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
			public int Sampler;

			[JsonField(Name = "target")]
			[JsonSchemaRequired]
			public TargetType Target;
		}

		[JsonSchema(Id = "animation.sampler.schema.json")]
		public class SamplerType
		{
			[Json(/*Could not decode attribute arguments.*/)]
			public enum InterpolationEnum
			{
				[JsonField(Name = "LINEAR")]
				LINEAR,
				[JsonField(Name = "STEP")]
				STEP,
				[JsonField(Name = "CUBICSPLINE")]
				CUBICSPLINE
			}

			[JsonField(Name = "input")]
			[JsonSchemaRequired]
			[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
			public int Input;

			[JsonField(Name = "interpolation")]
			public InterpolationEnum Interpolation;

			[JsonField(Name = "output")]
			[JsonSchemaRequired]
			[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
			public int Output;
		}

		[JsonField(Name = "channels")]
		[JsonSchema(MinItems = 1)]
		[JsonSchemaRequired]
		public List<ChannelType> Channels;

		[JsonField(Name = "samplers")]
		[JsonSchema(MinItems = 1)]
		[JsonSchemaRequired]
		public List<SamplerType> Samplers;
	}
	[JsonSchema(Id = "asset.schema.json")]
	public sealed class Asset : GltfProperty
	{
		[JsonField(Name = "copyright")]
		[JsonFieldIgnorable]
		public string Copyright;

		[JsonField(Name = "generator")]
		[JsonFieldIgnorable]
		public string Generator;

		[JsonField(Name = "version")]
		[JsonSchema(Pattern = "^[0-9]+\\.[0-9]+$")]
		[JsonSchemaRequired]
		public string Version;

		[JsonField(Name = "minVersion")]
		[JsonFieldIgnorable]
		[JsonSchema(Pattern = "^[0-9]+\\.[0-9]+$")]
		public string MinVersion;
	}
	[JsonSchema(Id = "buffer.schema.json")]
	public sealed class Buffer : GltfChildOfRootProperty
	{
		[JsonField(Name = "uri")]
		[JsonFieldIgnorable]
		public string Uri;

		[JsonField(Name = "byteLength")]
		[JsonSchema(Minimum = 1.0)]
		[JsonSchemaRequired]
		public int ByteLength;
	}
	[JsonSchema(Id = "bufferView.schema.json")]
	public sealed class BufferView : GltfChildOfRootProperty
	{
		[Json]
		public enum TargetEnum
		{
			[JsonField]
			ARRAY_BUFFER = 34962,
			[JsonField]
			ELEMENT_ARRAY_BUFFER
		}

		[JsonField(Name = "buffer")]
		[JsonSchemaRequired]
		[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int Buffer;

		[JsonField(Name = "byteOffset")]
		[JsonFieldIgnorable]
		[JsonSchema(Minimum = 0.0)]
		public int ByteOffset;

		[JsonField(Name = "byteLength")]
		[JsonSchema(Minimum = 1.0)]
		[JsonSchemaRequired]
		public int ByteLength;

		[JsonField(Name = "byteStride")]
		[JsonFieldIgnorable]
		[JsonSchema(Minimum = 4.0, Maximum = 252.0, MultipleOf = 4.0)]
		public int? ByteStride;

		[JsonField(Name = "target")]
		[JsonFieldIgnorable]
		public TargetEnum? Target;
	}
	[JsonSchema(Id = "camera.schema.json")]
	public sealed class Camera : GltfChildOfRootProperty
	{
		[JsonSchema(Id = "camera.orthographic.schema.json")]
		public sealed class OrthographicType : GltfProperty
		{
			[JsonField(Name = "xmag")]
			[JsonSchemaRequired]
			public float Xmag;

			[JsonField(Name = "ymag")]
			[JsonSchemaRequired]
			public float Ymag;

			[JsonField(Name = "zfar")]
			[JsonSchema(ExclusiveMinimum = 0.0)]
			[JsonSchemaRequired]
			public float Zfar;

			[JsonField(Name = "znear")]
			[JsonSchema(Minimum = 0.0)]
			[JsonSchemaRequired]
			public float Znear;
		}

		[JsonSchema(Id = "camera.perspective.schema.json")]
		public sealed class PerspectiveType
		{
			[JsonField(Name = "aspectRatio")]
			[JsonFieldIgnorable]
			[JsonSchema(ExclusiveMinimum = 0.0)]
			public float? AspectRatio;

			[JsonField(Name = "yfov")]
			[JsonSchema(ExclusiveMinimum = 0.0)]
			[JsonSchemaRequired]
			public float Yfov;

			[JsonField(Name = "zfar")]
			[JsonFieldIgnorable]
			[JsonSchema(ExclusiveMinimum = 0.0)]
			public float? Zfar;

			[JsonField(Name = "znear")]
			[JsonSchema(ExclusiveMinimum = 0.0)]
			[JsonSchemaRequired]
			public float Znear;
		}

		[Json(/*Could not decode attribute arguments.*/)]
		public enum TypeEnum
		{
			[JsonField(Name = "perspective")]
			Perspective,
			[JsonField(Name = "orthographic")]
			Orthographic
		}

		[JsonField(Name = "orthographic")]
		[JsonFieldIgnorable]
		public OrthographicType Orthographic;

		[JsonField(Name = "perspective")]
		[JsonFieldIgnorable]
		public PerspectiveType Perspective;

		[JsonField(Name = "type")]
		[JsonSchemaRequired]
		public TypeEnum Type;
	}
	[JsonSchema(Id = "glTF.schema.json")]
	public sealed class Gltf : GltfProperty
	{
		[JsonField(Name = "extensionsUsed")]
		[JsonFieldIgnorable]
		[JsonSchema(UniqueItems = true, MinItems = 1)]
		public List<string> ExtensionsUsed;

		[JsonField(Name = "extensionsRequired")]
		[JsonFieldIgnorable]
		[JsonSchema(UniqueItems = true, MinItems = 1)]
		public List<string> ExtensionsRequired;

		[JsonField(Name = "accessors")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<Accessor> Accessors;

		[JsonField(Name = "animations")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<Animation> Animations;

		[JsonField(Name = "asset")]
		[JsonSchemaRequired]
		public Asset Asset;

		[JsonField(Name = "buffers")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<Buffer> Buffers;

		[JsonField(Name = "bufferViews")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<BufferView> BufferViews;

		[JsonField(Name = "cameras")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<Camera> Cameras;

		[JsonField(Name = "images")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<Image> Images;

		[JsonField(Name = "materials")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<Material> Materials;

		[JsonField(Name = "meshes")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<Mesh> Meshes;

		[JsonField(Name = "nodes")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<Node> Nodes;

		[JsonField(Name = "samplers")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<Sampler> Samplers;

		[JsonField(Name = "scene")]
		[JsonFieldIgnorable]
		[JsonSchemaDependencies(new string[] { "scenes" })]
		[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int? Scene;

		[JsonField(Name = "scenes")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<Scene> Scenes;

		[JsonField(Name = "skins")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<Skin> Skins;

		[JsonField(Name = "textures")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public List<Texture> Textures;

		public IEnumerable<int> RootNodesIndices
		{
			get
			{
				if (!Scene.HasValue)
				{
					return Enumerable.Empty<int>();
				}
				Scene scene = Scenes[Scene.Value];
				if (scene.Nodes == null)
				{
					return Enumerable.Empty<int>();
				}
				return scene.Nodes;
			}
		}

		public IEnumerable<Node> RootNodes => RootNodesIndices.Select((int i) => Nodes[i]);
	}
	[Json]
	public abstract class GltfChildOfRootProperty : GltfProperty
	{
		[JsonField(Name = "name")]
		[JsonFieldIgnorable]
		public string Name;
	}
	[JsonSchema(Minimum = 0.0)]
	public sealed class GltfID : RefTag<int>
	{
	}
	[Json]
	public abstract class GltfProperty
	{
		[JsonField(Name = "extensions")]
		[JsonFieldIgnorable]
		public Dictionary<string, INode> Extensions;

		[JsonField(Name = "extras")]
		[JsonFieldIgnorable]
		public Dictionary<string, INode> Extras;

		public void AddExtension<T>(string name, T value)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (Extensions == null)
			{
				Extensions = new Dictionary<string, INode>();
			}
			INode value2 = new JsonSerializer(typeof(T)).SerializeToNode<T>(value);
			Extensions.Add(name, value2);
		}

		public bool TryGetExtension<T>(string name, JsonSchemaRegistry reg, out T value)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (Extensions == null)
			{
				value = default(T);
				return false;
			}
			if (!Extensions.TryGetValue(name, out var value2))
			{
				value = default(T);
				return false;
			}
			ConstraintsViolationException val = JsonSchemaExtensions.Validate(JsonSchema.CreateFromType<T>(reg, false), (object)value2, reg);
			if (val != null)
			{
				throw val;
			}
			object obj = new JsonDeserializer(typeof(T)).DeserializeFromNode(value2);
			value = (T)obj;
			return true;
		}

		public void AddExtra<T>(string name, T value)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (Extras == null)
			{
				Extras = new Dictionary<string, INode>();
			}
			INode value2 = new JsonSerializer(typeof(T)).SerializeToNode<T>(value);
			Extras.Add(name, value2);
		}

		public bool TryGetExtra<T>(string name, JsonSchemaRegistry reg, out T value)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (Extras == null)
			{
				value = default(T);
				return false;
			}
			if (!Extras.TryGetValue(name, out var value2))
			{
				value = default(T);
				return false;
			}
			ConstraintsViolationException val = JsonSchemaExtensions.Validate(JsonSchema.CreateFromType<T>(reg, false), (object)value2, reg);
			if (val != null)
			{
				throw val;
			}
			object obj = new JsonDeserializer(typeof(T)).DeserializeFromNode(value2);
			value = (T)obj;
			return true;
		}
	}
	[JsonSchema(Id = "image.schema.json")]
	public sealed class Image : GltfChildOfRootProperty
	{
		public const string MimeTypeImageJpeg = "image/jpeg";

		public const string MimeTypeImagePng = "image/png";

		[JsonField(Name = "uri")]
		[JsonFieldIgnorable]
		public string Uri;

		[JsonField(Name = "mimeType")]
		[JsonFieldIgnorable(WhenValueIs = "")]
		public string MimeType = "";

		[JsonField(Name = "bufferView")]
		[JsonFieldIgnorable]
		[JsonSchemaDependencies(new string[] { "mimeType" })]
		[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int? BufferView;
	}
	public static class ImageExtensions
	{
		public static string GetExtension(this Image img)
		{
			string mimeType = img.MimeType;
			if (!(mimeType == "image/jpeg"))
			{
				if (mimeType == "image/png")
				{
					return ".png";
				}
				if (img.Uri.StartsWith("data:image/jpeg;"))
				{
					return ".jpg";
				}
				if (img.Uri.StartsWith("data:image/png;"))
				{
					return ".png";
				}
				return Path.GetExtension(img.Uri).ToLower();
			}
			return ".jpg";
		}
	}
	[JsonSchema(Id = "material.schema.json")]
	public sealed class Material : GltfChildOfRootProperty
	{
		[JsonSchema(Id = "material.pbrMetallicRoughness.schema.json")]
		public sealed class PbrMetallicRoughnessType : GltfProperty
		{
			[JsonField(Name = "baseColorFactor")]
			[JsonSchema(MinItems = 4, MaxItems = 4)]
			[ItemsJsonSchema(Minimum = 0.0, Maximum = 1.0)]
			public float[] BaseColorFactor = new float[4] { 1f, 1f, 1f, 1f };

			[JsonField(Name = "baseColorTexture")]
			[JsonFieldIgnorable]
			public BaseColorTextureInfoType BaseColorTexture;

			[JsonField(Name = "metallicFactor")]
			[JsonSchema(Minimum = 0.0, Maximum = 1.0)]
			public float MetallicFactor = 1f;

			[JsonField(Name = "roughnessFactor")]
			[JsonSchema(Minimum = 0.0, Maximum = 1.0)]
			public float RoughnessFactor = 1f;

			[JsonField(Name = "metallicRoughnessTexture")]
			[JsonFieldIgnorable]
			public MetallicRoughnessTextureInfoType MetallicRoughnessTexture;
		}

		[Json]
		public sealed class BaseColorTextureInfoType : TextureInfo
		{
			public override TextureInfoKind Kind => TextureInfoKind.BaseColor;
		}

		[Json]
		public sealed class MetallicRoughnessTextureInfoType : TextureInfo
		{
			public override TextureInfoKind Kind => TextureInfoKind.MetallicRoughness;
		}

		[JsonSchema(Id = "material.normalTextureInfo.schema.json")]
		public sealed class NormalTextureInfoType : TextureInfo
		{
			[JsonField(Name = "scale")]
			public float Scale = 1f;

			public override TextureInfoKind Kind => TextureInfoKind.Normal;
		}

		[JsonSchema(Id = "material.occlusionTextureInfo.schema.json")]
		public sealed class OcclusionTextureInfoType : TextureInfo
		{
			[JsonField(Name = "strength")]
			[JsonSchema(Minimum = 0.0, Maximum = 1.0)]
			public float Strength = 1f;

			public override TextureInfoKind Kind => TextureInfoKind.Occlusion;
		}

		[Json]
		public sealed class EmissiveTextureInfoType : TextureInfo
		{
			public override TextureInfoKind Kind => TextureInfoKind.Emissive;
		}

		[Json(/*Could not decode attribute arguments.*/)]
		public enum AlphaModeEnum
		{
			[JsonField(Name = "OPAQUE")]
			Opaque,
			[JsonField(Name = "MASK")]
			Mask,
			[JsonField(Name = "BLEND")]
			Blend
		}

		[JsonField(Name = "pbrMetallicRoughness")]
		[JsonFieldIgnorable]
		public PbrMetallicRoughnessType PbrMetallicRoughness;

		[JsonField(Name = "normalTexture")]
		[JsonFieldIgnorable]
		public NormalTextureInfoType NormalTexture;

		[JsonField(Name = "occlusionTexture")]
		[JsonFieldIgnorable]
		public OcclusionTextureInfoType OcclusionTexture;

		[JsonField(Name = "emissiveTexture")]
		[JsonFieldIgnorable]
		public EmissiveTextureInfoType EmissiveTexture;

		[JsonField(Name = "emissiveFactor")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 3, MaxItems = 3)]
		[ItemsJsonSchema(Minimum = 0.0, Maximum = 1.0)]
		public float[] EmissiveFactor = new float[3];

		[JsonField(Name = "alphaMode")]
		public AlphaModeEnum AlphaMode;

		[JsonField(Name = "alphaCutoff")]
		[JsonSchema(Minimum = 0.0)]
		[JsonFieldIgnorable(WhenValueIs = 0f)]
		[JsonSchemaDependencies(new string[] { "alphaMode" })]
		public float AlphaCutoff = 0.5f;

		[JsonField(Name = "doubleSided")]
		public bool DoubleSided;
	}
	public static class MaterialExtensions
	{
		public static IEnumerable<TextureInfo> GetTextures(this Material mat)
		{
			if (mat.PbrMetallicRoughness != null)
			{
				yield return mat.PbrMetallicRoughness.BaseColorTexture;
				yield return mat.PbrMetallicRoughness.MetallicRoughnessTexture;
			}
			yield return mat.NormalTexture;
			yield return mat.OcclusionTexture;
			yield return mat.EmissiveTexture;
		}
	}
	[JsonSchema(Id = "mesh.schema.json")]
	public sealed class Mesh : GltfChildOfRootProperty
	{
		[JsonSchema(Id = "mesh.primitive.schema.json")]
		public sealed class PrimitiveType : GltfProperty
		{
			[Json]
			public enum ModeEnum
			{
				[JsonField]
				POINTS,
				[JsonField]
				LINES,
				[JsonField]
				LINE_LOOP,
				[JsonField]
				LINE_STRIP,
				[JsonField]
				TRIANGLES,
				[JsonField]
				TRIANGLE_STRIP,
				[JsonField]
				TRIANGLE_FAN
			}

			public static class AttributeName
			{
				public static readonly string POSITION = "POSITION";

				public static readonly string NORMAL = "NORMAL";

				public static readonly string TANGENT = "TANGENT";

				public static readonly string TEXCOORD_0 = "TEXCOORD_0";

				public static readonly string TEXCOORD_1 = "TEXCOORD_1";

				public static readonly string COLOR_0 = "COLOR_0";

				public static readonly string JOINTS_0 = "JOINTS_0";

				public static readonly string WEIGHTS_0 = "WEIGHTS_0";
			}

			[JsonField(Name = "attributes")]
			[JsonSchema(MinProperties = 1)]
			[JsonSchemaRequired]
			[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
			public Dictionary<string, int> Attributes;

			[JsonField(Name = "indices")]
			[JsonFieldIgnorable]
			[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
			public int? Indices;

			[JsonField(Name = "material")]
			[JsonFieldIgnorable]
			[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
			public int? Material;

			[JsonField(Name = "mode")]
			[JsonFieldIgnorable]
			public ModeEnum? Mode = ModeEnum.TRIANGLES;

			[JsonField(Name = "targets")]
			[JsonFieldIgnorable]
			[JsonSchema(MinItems = 1)]
			[ItemsJsonSchema(MinProperties = 1)]
			[ItemsJsonSchemaRef(/*Could not decode attribute arguments.*/)]
			public List<Dictionary<string, int>> Targets;
		}

		[JsonField(Name = "primitives")]
		[JsonSchema(MinItems = 1)]
		[JsonSchemaRequired]
		public List<PrimitiveType> Primitives;

		[JsonField(Name = "weights")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		public float[] Weights;
	}
	[JsonSchema(Id = "node.schema.json")]
	public sealed class Node : GltfChildOfRootProperty
	{
		[JsonField(Name = "camera")]
		[JsonFieldIgnorable]
		[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int? Camera;

		[JsonField(Name = "children")]
		[JsonFieldIgnorable]
		[JsonSchema(UniqueItems = true, MinItems = 1)]
		[ItemsJsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int[] Children;

		[JsonField(Name = "skin")]
		[JsonFieldIgnorable]
		[JsonSchemaDependencies(new string[] { "mesh" })]
		[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int? Skin;

		[JsonField(Name = "matrix")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 16, MaxItems = 16)]
		public float[] Matrix = new float[16]
		{
			1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f,
			1f, 0f, 0f, 0f, 0f, 1f
		};

		[JsonField(Name = "mesh")]
		[JsonFieldIgnorable]
		[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int? Mesh;

		[JsonField(Name = "rotation")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 4, MaxItems = 4)]
		[ItemsJsonSchema(Minimum = -1.0, Maximum = 1.0)]
		public float[] Rotation = new float[4] { 0f, 0f, 0f, 1f };

		[JsonField(Name = "scale")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 3, MaxItems = 3)]
		public float[] Scale = new float[3] { 1f, 1f, 1f };

		[JsonField(Name = "translation")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 3, MaxItems = 3)]
		public float[] Translation = new float[3];

		[JsonField(Name = "weights")]
		[JsonFieldIgnorable]
		[JsonSchema(MinItems = 1)]
		[JsonSchemaDependencies(new string[] { "mesh" })]
		public float[] Weights;
	}
	[JsonSchema(Id = "sampler.schema.json")]
	public sealed class Sampler : GltfChildOfRootProperty
	{
		[Json]
		public enum MagFilterEnum
		{
			[JsonField]
			NEAREST = 9728,
			[JsonField]
			LINEAR
		}

		[Json]
		public enum MinFilterEnum
		{
			[JsonField]
			NEAREST = 9728,
			[JsonField]
			LINEAR = 9729,
			[JsonField]
			NEAREST_MIPMAP_NEAREST = 9984,
			[JsonField]
			LINEAR_MIPMAP_NEAREST = 9985,
			[JsonField]
			NEAREST_MIPMAP_LINEAR = 9986,
			[JsonField]
			LINEAR_MIPMAP_LINEAR = 9987
		}

		[Json]
		public enum WrapEnum
		{
			[JsonField]
			ClampToEdge = 33071,
			[JsonField]
			MirroredRepeat = 33648,
			[JsonField]
			Repeat = 10497
		}

		[JsonField(Name = "magFilter")]
		[JsonFieldIgnorable]
		public MagFilterEnum? MagFilter;

		[JsonField(Name = "minFilter")]
		[JsonFieldIgnorable]
		public MinFilterEnum? MinFilter;

		[JsonField(Name = "wrapS")]
		[JsonFieldIgnorable(WhenValueIs = WrapEnum.Repeat)]
		public WrapEnum WrapS = WrapEnum.Repeat;

		[JsonField(Name = "wrapT")]
		[JsonFieldIgnorable(WhenValueIs = WrapEnum.Repeat)]
		public WrapEnum WrapT = WrapEnum.Repeat;
	}
	[JsonSchema(Id = "scene.schema.json")]
	public sealed class Scene : GltfChildOfRootProperty
	{
		[JsonField(Name = "nodes")]
		[JsonSchema(UniqueItems = true, MinItems = 1)]
		[ItemsJsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int[] Nodes;
	}
	[JsonSchema(Id = "skin.schema.json")]
	public sealed class Skin : GltfChildOfRootProperty
	{
		[JsonField(Name = "inverseBindMatrices")]
		[JsonFieldIgnorable]
		[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int? InverseBindMatrices;

		[JsonField(Name = "skeleton")]
		[JsonFieldIgnorable]
		[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int? Skeleton;

		[JsonField(Name = "joints")]
		[JsonSchema(UniqueItems = true, MinItems = 1)]
		[JsonSchemaRequired]
		[ItemsJsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int[] Joints;
	}
	[JsonSchema(Id = "texture.schema.json")]
	public sealed class Texture : GltfChildOfRootProperty
	{
		[JsonField(Name = "sampler")]
		[JsonFieldIgnorable]
		[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int? Sampler;

		[JsonField(Name = "source")]
		[JsonFieldIgnorable]
		[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int? Source;
	}
	public enum TextureInfoKind
	{
		BaseColor,
		MetallicRoughness,
		Normal,
		Occlusion,
		Emissive
	}
	[Json]
	public abstract class TextureInfo : GltfProperty
	{
		[JsonField(Name = "index")]
		[JsonSchemaRequired]
		[JsonSchemaRef(/*Could not decode attribute arguments.*/)]
		public int Index;

		[JsonField(Name = "texCoord")]
		[JsonSchema(Minimum = 0.0)]
		[JsonSchemaRequired]
		public int TexCoord;

		public abstract TextureInfoKind Kind { get; }
	}
}
namespace VGltf.Types.Extensions
{
	public static class GltfExtensions
	{
		public static Scene GetSceneObject(this Gltf gltf)
		{
			if (!gltf.Scene.HasValue)
			{
				throw new Exception("Scene is null");
			}
			return gltf.Scenes[gltf.Scene.Value];
		}

		public static Image GetImageByTextureIndex(this Gltf gltf, int index, out int? imageIndex)
		{
			Texture texture = gltf.Textures[index];
			imageIndex = texture.Source;
			return gltf.Images[imageIndex.Value];
		}

		public static Image GetImageByTextureIndex(this Gltf gltf, int index)
		{
			int? imageIndex;
			return gltf.GetImageByTextureIndex(index, out imageIndex);
		}

		public static Sampler GetSamplerByTextureIndex(this Gltf gltf, int index, out int? samplerIndex)
		{
			Texture texture = gltf.Textures[index];
			samplerIndex = texture.Sampler;
			return gltf.Samplers[samplerIndex.Value];
		}

		public static Sampler GetSamplerByTextureIndex(this Gltf gltf, int index)
		{
			int? samplerIndex;
			return gltf.GetSamplerByTextureIndex(index, out samplerIndex);
		}

		public static int AddImage(this Gltf gltf, Image item)
		{
			if (gltf.Images == null)
			{
				gltf.Images = new List<Image>();
			}
			int count = gltf.Images.Count;
			gltf.Images.Add(item);
			return count;
		}

		public static int AddAccessor(this Gltf gltf, Accessor item)
		{
			if (gltf.Accessors == null)
			{
				gltf.Accessors = new List<Accessor>();
			}
			int count = gltf.Accessors.Count;
			gltf.Accessors.Add(item);
			return count;
		}

		public static int AddMesh(this Gltf gltf, Mesh item)
		{
			if (gltf.Meshes == null)
			{
				gltf.Meshes = new List<Mesh>();
			}
			int count = gltf.Meshes.Count;
			gltf.Meshes.Add(item);
			return count;
		}

		public static int AddNode(this Gltf gltf, Node item)
		{
			if (gltf.Nodes == null)
			{
				gltf.Nodes = new List<Node>();
			}
			int count = gltf.Nodes.Count;
			gltf.Nodes.Add(item);
			return count;
		}

		public static int AddScene(this Gltf gltf, Scene item)
		{
			if (gltf.Scenes == null)
			{
				gltf.Scenes = new List<Scene>();
			}
			int count = gltf.Scenes.Count;
			gltf.Scenes.Add(item);
			return count;
		}

		public static int AddMaterial(this Gltf gltf, Material item)
		{
			if (gltf.Materials == null)
			{
				gltf.Materials = new List<Material>();
			}
			int count = gltf.Materials.Count;
			gltf.Materials.Add(item);
			return count;
		}

		public static int AddSampler(this Gltf gltf, Sampler item)
		{
			if (gltf.Samplers == null)
			{
				gltf.Samplers = new List<Sampler>();
			}
			int count = gltf.Samplers.Count;
			gltf.Samplers.Add(item);
			return count;
		}

		public static int AddTexture(this Gltf gltf, Texture item)
		{
			if (gltf.Textures == null)
			{
				gltf.Textures = new List<Texture>();
			}
			int count = gltf.Textures.Count;
			gltf.Textures.Add(item);
			return count;
		}

		public static int AddSkin(this Gltf gltf, Skin item)
		{
			if (gltf.Skins == null)
			{
				gltf.Skins = new List<Skin>();
			}
			int count = gltf.Skins.Count;
			gltf.Skins.Add(item);
			return count;
		}

		public static void AddExtensionUsed(this Gltf gltf, string name)
		{
			if (gltf.ExtensionsUsed == null)
			{
				gltf.ExtensionsUsed = new List<string>();
			}
			if (!gltf.ContainsExtensionUsed(name))
			{
				gltf.ExtensionsUsed.Add(name);
			}
		}

		public static bool ContainsExtensionUsed(this Gltf gltf, string name)
		{
			if (gltf.ExtensionsUsed == null)
			{
				return false;
			}
			return gltf.ExtensionsUsed.Contains(name);
		}

		public static void AddExtensionRequired(this Gltf gltf, string name)
		{
			if (gltf.ExtensionsRequired == null)
			{
				gltf.ExtensionsRequired = new List<string>();
			}
			if (!gltf.ContainsExtensionRequired(name))
			{
				gltf.ExtensionsRequired.Add(name);
			}
		}

		public static bool ContainsExtensionRequired(this Gltf gltf, string name)
		{
			if (gltf.ExtensionsRequired == null)
			{
				return false;
			}
			return gltf.ExtensionsRequired.Contains(name);
		}
	}
}
namespace VGltf.Glb
{
	public static class Align
	{
		public static uint CalcPadding(uint offset, uint alignment)
		{
			return (alignment - offset % alignment) % alignment;
		}

		public static uint WritePadding(Stream s, uint offset, uint alignment, byte pad = 0)
		{
			uint num = CalcPadding(offset, alignment);
			for (int i = 0; i < num; i++)
			{
				s.WriteByte(pad);
			}
			return num;
		}
	}
	public sealed class Header
	{
		public uint Magic;

		public uint Version;

		public uint Length;
	}
	public sealed class Chunk
	{
		public uint ChunkLength;

		public uint ChunkType;

		public byte[] ChunkData;
	}
	public sealed class StoredBuffer
	{
		public ArraySegment<byte> Payload;
	}
	public sealed class Reader : IDisposable
	{
		private readonly BinaryReader _r;

		public Reader(Stream s)
		{
			_r = new BinaryReader(s);
		}

		public void Dispose()
		{
			if (_r != null)
			{
				((IDisposable)_r).Dispose();
			}
		}

		public Header ReadHeader()
		{
			return new Header
			{
				Magic = _r.ReadUInt32(),
				Version = _r.ReadUInt32(),
				Length = _r.ReadUInt32()
			};
		}

		public Chunk ReadChunk()
		{
			try
			{
				Chunk chunk = new Chunk();
				chunk.ChunkLength = _r.ReadUInt32();
				chunk.ChunkType = _r.ReadUInt32();
				chunk.ChunkData = _r.ReadBytes((int)chunk.ChunkLength);
				return chunk;
			}
			catch (EndOfStreamException)
			{
				return null;
			}
		}

		public static GltfContainer ReadAsContainer(Stream s)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			using Reader reader = new Reader(s);
			Header header = reader.ReadHeader();
			if (header.Magic != 1179937895)
			{
				throw new NotImplementedException();
			}
			if (header.Version != 2)
			{
				throw new NotImplementedException();
			}
			Gltf gltf = null;
			StoredBuffer storedBuffer = null;
			JsonSchemaRegistry reg = new JsonSchemaRegistry();
			int num = 0;
			while (true)
			{
				Chunk chunk = reader.ReadChunk();
				if (chunk == null)
				{
					break;
				}
				switch (chunk.ChunkType)
				{
				case 1313821514u:
				{
					if (num != 0)
					{
						throw new NotImplementedException("Json");
					}
					if (gltf != null)
					{
						throw new NotImplementedException("Json");
					}
					using (MemoryStream s2 = new MemoryStream(chunk.ChunkData))
					{
						gltf = GltfReader.Read(s2, reg);
					}
					break;
				}
				case 5130562u:
					if (num != 1)
					{
						throw new NotImplementedException("BinaryBuffer");
					}
					if (storedBuffer != null)
					{
						throw new NotImplementedException("BinaryBuffer");
					}
					storedBuffer = new StoredBuffer
					{
						Payload = new ArraySegment<byte>(chunk.ChunkData)
					};
					break;
				}
				num++;
			}
			if (gltf == null)
			{
				throw new NotImplementedException("Json is empty");
			}
			return new GltfContainer(gltf, storedBuffer, reg);
		}
	}
	public sealed class Writer : IDisposable
	{
		private readonly BinaryWriter _w;

		public Writer(Stream s)
		{
			_w = new BinaryWriter(s);
		}

		public void Dispose()
		{
			if (_w != null)
			{
				((IDisposable)_w).Dispose();
			}
		}

		public void WriteHeader(Header h)
		{
			_w.Write(h.Magic);
			_w.Write(h.Version);
			_w.Write(h.Length);
		}

		public void WriteChunk(Chunk c)
		{
			_w.Write(c.ChunkLength);
			_w.Write(c.ChunkType);
			_w.Write(c.ChunkData);
		}

		public static void WriteFromContainer(Stream s, GltfContainer container)
		{
			using Writer writer = new Writer(s);
			uint num = 0u;
			byte[] array = null;
			if (container.Gltf == null)
			{
				throw new NotImplementedException("Json is empty");
			}
			using (MemoryStream memoryStream = new MemoryStream())
			{
				GltfWriter.Write(memoryStream, container.Gltf, container.JsonSchemas);
				array = memoryStream.ToArray();
			}
			num += (uint)(8 + array.Length);
			uint num2 = Align.CalcPadding(num, 4u);
			num += num2;
			byte[] array2 = null;
			if (container.Buffer != null)
			{
				using (MemoryStream memoryStream2 = new MemoryStream())
				{
					ArraySegment<byte> payload = container.Buffer.Payload;
					memoryStream2.Write(payload.Array, payload.Offset, payload.Count);
					array2 = memoryStream2.ToArray();
				}
				num += (uint)(8 + array2.Length);
			}
			writer.WriteHeader(new Header
			{
				Magic = 1179937895u,
				Version = 2u,
				Length = 12 + num
			});
			writer.WriteChunk(new Chunk
			{
				ChunkLength = (uint)array.Length + num2,
				ChunkType = 1313821514u,
				ChunkData = array
			});
			writer._w.Write(new byte[4] { 32, 32, 32, 32 }, 0, (int)num2);
			if (array2 != null)
			{
				writer.WriteChunk(new Chunk
				{
					ChunkLength = (uint)array2.Length,
					ChunkType = 5130562u,
					ChunkData = array2
				});
			}
		}
	}
}
namespace VGltf.Ext.KhrMaterialsUnlit.Types
{
	[JsonSchema(Title = "KHR_materials_unlit glTF extension", Description = "glTF extension that defines the unlit material model.", Id = "glTF.KHR_materials_unlit.schema.json")]
	public sealed class KhrMaterialsUnlit
	{
		public static readonly string ExtensionName = "KHR_materials_unlit";
	}
}
namespace VGltf.Ext.KhrMaterialsEmissiveStrength.Types
{
	[JsonSchema(Title = "KHR_materials_emissive_strength glTF extension", Description = "glTF extension that adjusts the strength of emissive material properties.", Id = "glTF.KHR_materials_emissive_strength.schema.json")]
	public sealed class KhrMaterialsEmissiveStrength
	{
		public static readonly string ExtensionName = "KHR_materials_emissive_strength";

		[JsonField(Name = "emissiveStrength")]
		[JsonFieldIgnorable(WhenValueIs = 1f)]
		[JsonSchema(Minimum = 0.0)]
		public float EmissiveStrength = 1f;
	}
}

UserLibs/VJson.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using VJson.Internal;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("yutopp")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2019 -")]
[assembly: AssemblyDescription("A JSON serializer/deserializer library written in pure C#.")]
[assembly: AssemblyFileVersion("0.0.0.0")]
[assembly: AssemblyInformationalVersion("0.0.0")]
[assembly: AssemblyProduct("VJson")]
[assembly: AssemblyTitle("VJson")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace VJson
{
	public enum EnumConversionType
	{
		AsInt,
		AsString
	}
	public class PreserveAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)]
	public sealed class JsonAttribute : PreserveAttribute
	{
		public bool ImplicitConstructable;

		public EnumConversionType EnumConversion;
	}
	[AttributeUsage(AttributeTargets.Field)]
	public sealed class JsonFieldAttribute : PreserveAttribute
	{
		public string Name;

		public int Order;

		public Type[] TypeHints;

		public static string FieldName(JsonFieldAttribute f, FieldInfo fi)
		{
			if (f != null && !string.IsNullOrEmpty(f.Name))
			{
				return f.Name;
			}
			return fi.Name;
		}

		public static int FieldOrder(JsonFieldAttribute f)
		{
			return f?.Order ?? 0;
		}
	}
	[AttributeUsage(AttributeTargets.Field)]
	public sealed class JsonFieldIgnorableAttribute : PreserveAttribute
	{
		public object WhenValueIs;

		public int WhenLengthIs;

		public static bool IsIgnorable<T>(JsonFieldIgnorableAttribute f, T o)
		{
			if (f == null)
			{
				return false;
			}
			if (object.Equals(o, f.WhenValueIs))
			{
				return true;
			}
			if ((object)o is Array array)
			{
				return array.Length == f.WhenLengthIs;
			}
			if ((object)o is IList list)
			{
				return list.Count == f.WhenLengthIs;
			}
			return false;
		}
	}
	public interface IValidator
	{
	}
	public sealed class JsonDeserializer
	{
		private Type _expectedInitialType;

		public JsonDeserializer(Type type)
		{
			_expectedInitialType = type;
		}

		public object Deserialize(string text)
		{
			using MemoryStream s = new MemoryStream(Encoding.UTF8.GetBytes(text));
			return Deserialize(s);
		}

		public object Deserialize(Stream s)
		{
			using JsonReader jsonReader = new JsonReader(s);
			INode node = jsonReader.Read();
			return DeserializeFromNode(node);
		}

		public object DeserializeFromNode(INode node)
		{
			return DeserializeValue(node, _expectedInitialType, default(State));
		}

		private object DeserializeValue(INode node, Type expectedType, State state)
		{
			NodeKindWrapped targetKind = Node.KindOfTypeWrapped(expectedType);
			if (targetKind.Wrapped)
			{
				expectedType = Node.ValueTypeOfKind(targetKind.Kind);
			}
			return DeserializeValueAs(node, targetKind, expectedType, state);
		}

		private object DeserializeValueAs(INode node, NodeKindWrapped targetKind, Type targetType, State state)
		{
			switch (targetKind.Kind)
			{
			case NodeKind.Boolean:
				return DeserializeToBoolean(node, targetKind, targetType, state);
			case NodeKind.Integer:
			case NodeKind.Float:
				return DeserializeToNumber(node, targetKind, targetType, state);
			case NodeKind.String:
				return DeserializeToString(node, targetKind, targetType, state);
			case NodeKind.Array:
				return DeserializeToArray(node, targetKind, targetType, state);
			case NodeKind.Object:
				return DeserializeToObject(node, targetKind, targetType, state);
			case NodeKind.Null:
				return DeserializeToNull(node, targetKind, targetType, state);
			default:
				throw new NotImplementedException("Unmatched kind: " + targetKind.Kind);
			}
		}

		private object DeserializeToBoolean(INode node, NodeKindWrapped targetKind, Type targetType, State state)
		{
			if (node is NullNode)
			{
				if (!TypeHelper.IsBoxed(targetType))
				{
					throw new DeserializeFailureException(state.CreateNodeConversionFailureMessage(node, targetType));
				}
				if (!targetKind.Wrapped)
				{
					return null;
				}
				return NullNode.Null;
			}
			if (node is BooleanNode booleanNode)
			{
				if (!targetKind.Wrapped)
				{
					return CreateInstanceIfConstrucutable(targetType, booleanNode.Value, state);
				}
				return node;
			}
			throw new DeserializeFailureException(state.CreateNodeConversionFailureMessage(node, targetType));
		}

		private object DeserializeToNumber(INode node, NodeKindWrapped targetKind, Type targetType, State state)
		{
			if (node is NullNode)
			{
				if (!TypeHelper.IsBoxed(targetType))
				{
					throw new DeserializeFailureException(state.CreateNodeConversionFailureMessage(node, targetType));
				}
				if (!targetKind.Wrapped)
				{
					return null;
				}
				return NullNode.Null;
			}
			if (node is IntegerNode integerNode)
			{
				if (!targetKind.Wrapped)
				{
					return CreateInstanceIfConstrucutable(targetType, integerNode.Value, state);
				}
				return node;
			}
			if (node is FloatNode floatNode)
			{
				if (!targetKind.Wrapped)
				{
					return CreateInstanceIfConstrucutable(targetType, floatNode.Value, state);
				}
				return node;
			}
			throw new DeserializeFailureException(state.CreateNodeConversionFailureMessage(node, targetType));
		}

		private object DeserializeToString(INode node, NodeKindWrapped targetKind, Type targetType, State state)
		{
			if (node is NullNode)
			{
				if (!TypeHelper.IsBoxed(targetType))
				{
					throw new DeserializeFailureException(state.CreateNodeConversionFailureMessage(node, targetType));
				}
				if (!targetKind.Wrapped)
				{
					return null;
				}
				return NullNode.Null;
			}
			if (node is StringNode stringNode)
			{
				if (!targetKind.Wrapped)
				{
					return CreateInstanceIfConstrucutable(targetType, stringNode.Value, state);
				}
				return node;
			}
			throw new DeserializeFailureException(state.CreateNodeConversionFailureMessage(node, targetType));
		}

		private object DeserializeToArray(INode node, NodeKindWrapped targetKind, Type targetType, State state)
		{
			if (!(targetType == typeof(object)) && !targetType.IsArray && (!TypeHelper.TypeWrap(targetType).IsGenericType || !(targetType.GetGenericTypeDefinition() == typeof(List<>))))
			{
				throw new DeserializeFailureException(state.CreateNodeConversionFailureMessage(node, targetType));
			}
			if (node is NullNode)
			{
				if (!targetKind.Wrapped)
				{
					return null;
				}
				return NullNode.Null;
			}
			if (node is ArrayNode arrayNode)
			{
				if (targetType.IsArray || targetType == typeof(object))
				{
					Type type = targetType;
					if (type == typeof(object))
					{
						type = typeof(object[]);
					}
					int num = ((arrayNode.Elems != null) ? arrayNode.Elems.Count : 0);
					Array array = (Array)Activator.CreateInstance(type, num);
					Type elementType = type.GetElementType();
					for (int i = 0; i < num; i++)
					{
						object value = DeserializeValue(arrayNode.Elems[i], elementType, state.NestAsElem(i));
						array.SetValue(value, i);
					}
					return array;
				}
				int num2 = ((arrayNode.Elems != null) ? arrayNode.Elems.Count : 0);
				IList list = (IList)Activator.CreateInstance(targetType);
				Type expectedType = TypeHelper.TypeWrap(targetType).GetGenericArguments()[0];
				for (int j = 0; j < num2; j++)
				{
					object value2 = DeserializeValue(arrayNode.Elems[j], expectedType, state.NestAsElem(j));
					list.Add(value2);
				}
				if (targetKind.Wrapped)
				{
					return new ArrayNode(list as List<INode>);
				}
				return list;
			}
			throw new DeserializeFailureException(state.CreateNodeConversionFailureMessage(node, targetType));
		}

		private object DeserializeToObject(INode node, NodeKindWrapped targetKind, Type targetType, State state)
		{
			if (targetKind.Kind != 0)
			{
				throw new DeserializeFailureException(state.CreateNodeConversionFailureMessage(node, targetType));
			}
			if (node is NullNode)
			{
				if (!targetKind.Wrapped)
				{
					return null;
				}
				return NullNode.Null;
			}
			if (node is ObjectNode objectNode)
			{
				if (targetType == typeof(object) || (TypeHelper.TypeWrap(targetType).IsGenericType && targetType.GetGenericTypeDefinition() == typeof(Dictionary<, >)))
				{
					Type type = targetType;
					if (type == typeof(object))
					{
						type = (targetKind.Wrapped ? typeof(Dictionary<string, INode>) : typeof(Dictionary<string, object>));
					}
					if (TypeHelper.TypeWrap(type).GetGenericArguments()[0] != typeof(string))
					{
						throw new NotImplementedException();
					}
					IDictionary dictionary = (IDictionary)Activator.CreateInstance(type);
					if (objectNode.Elems != null)
					{
						Type type2 = TypeHelper.TypeWrap(type).GetGenericArguments()[1];
						foreach (KeyValuePair<string, INode> elem in objectNode.Elems)
						{
							Type expectedType = type2;
							object value = DeserializeValue(elem.Value, expectedType, state.NestAsElem(elem.Key));
							dictionary.Add(elem.Key, value);
						}
					}
					if (targetKind.Wrapped)
					{
						return new ObjectNode(dictionary as Dictionary<string, INode>);
					}
					return dictionary;
				}
				object obj = Activator.CreateInstance(targetType);
				{
					foreach (FieldInfo serializableField in TypeHelper.GetSerializableFields(targetType))
					{
						JsonFieldAttribute customAttribute = TypeHelper.GetCustomAttribute<JsonFieldAttribute>(serializableField);
						string text = JsonFieldAttribute.FieldName(customAttribute, serializableField);
						INode value2 = null;
						if (objectNode.Elems == null || !objectNode.Elems.TryGetValue(text, out value2))
						{
							continue;
						}
						State state2 = state.NestAsElem(text);
						if (customAttribute != null && customAttribute.TypeHints != null)
						{
							bool flag = false;
							Type[] typeHints = customAttribute.TypeHints;
							foreach (Type expectedType2 in typeHints)
							{
								try
								{
									object value3 = DeserializeValue(value2, expectedType2, state2);
									serializableField.SetValue(obj, value3);
									flag = true;
								}
								catch (Exception)
								{
									continue;
								}
								break;
							}
							if (!flag)
							{
								throw new DeserializeFailureException(state2.CreateNodeConversionFailureMessage(value2, customAttribute.TypeHints));
							}
						}
						else
						{
							Type fieldType = serializableField.FieldType;
							object value4 = DeserializeValue(value2, fieldType, state2);
							serializableField.SetValue(obj, value4);
						}
					}
					return obj;
				}
			}
			NodeKindWrapped nodeKindWrapped = default(NodeKindWrapped);
			nodeKindWrapped.Kind = node.Kind;
			nodeKindWrapped.Wrapped = targetKind.Wrapped;
			NodeKindWrapped targetKind2 = nodeKindWrapped;
			if (targetKind.Wrapped)
			{
				targetType = Node.ValueTypeOfKind(node.Kind);
			}
			return DeserializeValueAs(node, targetKind2, targetType, state);
		}

		private object DeserializeToNull(INode node, NodeKindWrapped targetKind, Type targetType, State state)
		{
			if (node is NullNode)
			{
				if (!targetKind.Wrapped)
				{
					return null;
				}
				return NullNode.Null;
			}
			throw new NotImplementedException();
		}

		private static object CreateInstanceIfConstrucutable<T>(Type targetType, T value, State state)
		{
			if (targetType == typeof(object))
			{
				return value;
			}
			Type underlyingType = Nullable.GetUnderlyingType(targetType);
			if (underlyingType != null)
			{
				targetType = underlyingType;
			}
			if (TypeHelper.GetConverter(typeof(T), targetType, out var converter))
			{
				if (converter == null)
				{
					return value;
				}
				if (converter(value, out var output))
				{
					return output;
				}
				throw new DeserializeFailureException(state.CreateTypeConversionFailureMessage(value, targetType));
			}
			if (TypeHelper.TypeWrap(targetType).IsEnum)
			{
				switch (TypeHelper.GetCustomAttribute<JsonAttribute>(targetType)?.EnumConversion ?? EnumConversionType.AsInt)
				{
				case EnumConversionType.AsInt:
				{
					Type underlyingType2 = Enum.GetUnderlyingType(targetType);
					if (!TypeHelper.GetConverter(typeof(T), underlyingType2, out var converter2))
					{
						throw new DeserializeFailureException(state.CreateTypeConversionFailureMessage(value, targetType));
					}
					object output2;
					if (converter2 != null)
					{
						if (!converter2(value, out output2))
						{
							throw new DeserializeFailureException(state.CreateTypeConversionFailureMessage(value, targetType));
						}
					}
					else
					{
						output2 = value;
					}
					if (!Enum.IsDefined(targetType, output2))
					{
						throw new DeserializeFailureException(state.CreateTypeConversionFailureMessage(value, targetType, "Enum value is not defined"));
					}
					return Enum.ToObject(targetType, output2);
				}
				case EnumConversionType.AsString:
				{
					int num = Array.IndexOf(TypeHelper.GetStringEnumNames(targetType), value);
					if (num == -1)
					{
						throw new DeserializeFailureException(state.CreateTypeConversionFailureMessage(value, targetType, "Enum name is not defined"));
					}
					return Enum.GetValues(targetType).GetValue(num);
				}
				}
			}
			JsonAttribute customAttribute = TypeHelper.GetCustomAttribute<JsonAttribute>(targetType);
			if (customAttribute == null || !customAttribute.ImplicitConstructable)
			{
				throw new DeserializeFailureException(state.CreateTypeConversionFailureMessage(value, targetType, "Not implicit constructable"));
			}
			ConstructorInfo? constructor = TypeHelper.TypeWrap(targetType).GetConstructor(new Type[1] { typeof(T) });
			if (constructor == null)
			{
				throw new DeserializeFailureException(state.CreateTypeConversionFailureMessage(value, targetType, "Suitable constructers are not found"));
			}
			return constructor.Invoke(new object[1] { value });
		}
	}
	public class DeserializeFailureException : Exception
	{
		public DeserializeFailureException(string message)
			: base(message)
		{
		}

		public DeserializeFailureException(string message, DeserializeFailureException inner)
			: base($"{message}.{inner.Message}")
		{
		}
	}
	public sealed class JsonReader : IDisposable
	{
		private class ReaderWrapper : IDisposable
		{
			private StreamReader _reader;

			private int _lastToken;

			public ulong Position { get; private set; }

			public string LastToken
			{
				get
				{
					if (_lastToken == -1)
					{
						return "<EOS>";
					}
					return ((char)_lastToken).ToString();
				}
			}

			public ReaderWrapper(Stream s)
			{
				_reader = new StreamReader(s);
				Position = 0uL;
			}

			public void Dispose()
			{
				if (_reader != null)
				{
					((IDisposable)_reader).Dispose();
				}
			}

			public int Peek()
			{
				_lastToken = _reader.Peek();
				return _lastToken;
			}

			public int Read()
			{
				ulong position = Position + 1;
				Position = position;
				_lastToken = _reader.Read();
				return _lastToken;
			}
		}

		private ReaderWrapper _reader;

		private StringBuilder _strCache = new StringBuilder();

		public JsonReader(Stream s)
		{
			_reader = new ReaderWrapper(s);
		}

		public void Dispose()
		{
			if (_reader != null)
			{
				((IDisposable)_reader).Dispose();
			}
		}

		public INode Read()
		{
			INode result = ReadElement();
			if (_reader.Peek() != -1)
			{
				throw NodeExpectedError("EOS");
			}
			return result;
		}

		private INode ReadElement()
		{
			SkipWS();
			INode result = ReadValue();
			SkipWS();
			return result;
		}

		private INode ReadValue()
		{
			INode node = null;
			if ((node = ReadObject()) != null)
			{
				return node;
			}
			if ((node = ReadArray()) != null)
			{
				return node;
			}
			if ((node = ReadString()) != null)
			{
				return node;
			}
			if ((node = ReadNumber()) != null)
			{
				return node;
			}
			if ((node = ReadLiteral()) != null)
			{
				return node;
			}
			throw NodeExpectedError("value");
		}

		private INode ReadObject()
		{
			int num = _reader.Peek();
			if (num != 123)
			{
				return null;
			}
			_reader.Read();
			ObjectNode objectNode = new ObjectNode();
			int num2 = 0;
			while (true)
			{
				SkipWS();
				num = _reader.Peek();
				if (num == 125)
				{
					_reader.Read();
					return objectNode;
				}
				if (num2 > 0)
				{
					if (num != 44)
					{
						throw TokenExpectedError(',');
					}
					_reader.Read();
				}
				SkipWS();
				INode node = ReadString();
				if (node == null)
				{
					throw NodeExpectedError("string");
				}
				SkipWS();
				num = _reader.Peek();
				if (num != 58)
				{
					throw TokenExpectedError(':');
				}
				_reader.Read();
				INode node2 = ReadElement();
				if (node2 == null)
				{
					break;
				}
				objectNode.AddElement(((StringNode)node).Value, node2);
				num2++;
			}
			throw NodeExpectedError("element");
		}

		private INode ReadArray()
		{
			int num = _reader.Peek();
			if (num != 91)
			{
				return null;
			}
			_reader.Read();
			ArrayNode arrayNode = new ArrayNode();
			int num2 = 0;
			while (true)
			{
				SkipWS();
				num = _reader.Peek();
				if (num == 93)
				{
					_reader.Read();
					return arrayNode;
				}
				if (num2 > 0)
				{
					if (num != 44)
					{
						throw TokenExpectedError(',');
					}
					_reader.Read();
				}
				INode node = ReadElement();
				if (node == null)
				{
					break;
				}
				arrayNode.AddElement(node);
				num2++;
			}
			throw NodeExpectedError("element");
		}

		private INode ReadString()
		{
			int num = _reader.Peek();
			if (num != 34)
			{
				return null;
			}
			_reader.Read();
			while (true)
			{
				num = _reader.Peek();
				switch (num)
				{
				case 34:
					_reader.Read();
					return new StringNode(Regex.Unescape(CommitBuffer()));
				case 92:
					_reader.Read();
					if (!ReadEscape())
					{
						throw NodeExpectedError("escape");
					}
					continue;
				}
				int num2 = _reader.Read();
				int num3 = num2;
				bool num4 = char.IsHighSurrogate((char)num2);
				if (num4)
				{
					num = _reader.Read();
					if (!char.IsLowSurrogate((char)num))
					{
						throw NodeExpectedError("low-surrogate");
					}
					num3 = char.ConvertToUtf32((char)num2, (char)num);
				}
				if (num3 < 32 || num3 > 1114111)
				{
					throw NodeExpectedError("unicode char (0x20 <= char <= 0x10ffff");
				}
				SaveToBuffer(num2);
				if (num4)
				{
					SaveToBuffer(num);
				}
			}
		}

		private bool ReadEscape()
		{
			switch (_reader.Peek())
			{
			case 34:
				SaveToBuffer(92);
				SaveToBuffer(_reader.Read());
				return true;
			case 92:
				SaveToBuffer(92);
				SaveToBuffer(_reader.Read());
				return true;
			case 47:
				SaveToBuffer(_reader.Read());
				return true;
			case 98:
				SaveToBuffer(92);
				SaveToBuffer(_reader.Read());
				return true;
			case 110:
				SaveToBuffer(92);
				SaveToBuffer(_reader.Read());
				return true;
			case 114:
				SaveToBuffer(92);
				SaveToBuffer(_reader.Read());
				return true;
			case 116:
				SaveToBuffer(92);
				SaveToBuffer(_reader.Read());
				return true;
			case 117:
			{
				SaveToBuffer(92);
				SaveToBuffer(_reader.Read());
				for (int i = 0; i < 4; i++)
				{
					if (!ReadHex())
					{
						throw NodeExpectedError("hex");
					}
				}
				return true;
			}
			default:
				return false;
			}
		}

		private bool ReadHex()
		{
			if (ReadDigit())
			{
				return true;
			}
			int num = _reader.Peek();
			if (num >= 65 && num <= 70)
			{
				SaveToBuffer(_reader.Read());
				return true;
			}
			if (num >= 97 && num <= 102)
			{
				SaveToBuffer(_reader.Read());
				return true;
			}
			return false;
		}

		private INode ReadNumber()
		{
			if (!ReadInt())
			{
				return null;
			}
			int num = 0 | (ReadFrac() ? 1 : 0) | (ReadExp() ? 1 : 0);
			string s = CommitBuffer();
			if (num != 0)
			{
				return new FloatNode(double.Parse(s));
			}
			return new IntegerNode(long.Parse(s));
		}

		private bool ReadInt()
		{
			if (ReadOneNine())
			{
				ReadDigits();
				return true;
			}
			if (ReadDigit())
			{
				return true;
			}
			if (_reader.Peek() != 45)
			{
				return false;
			}
			SaveToBuffer(_reader.Read());
			if (ReadOneNine())
			{
				ReadDigits();
				return true;
			}
			if (ReadDigit())
			{
				return true;
			}
			throw NodeExpectedError("number");
		}

		private bool ReadDigits()
		{
			if (!ReadDigit())
			{
				return false;
			}
			while (ReadDigit())
			{
			}
			return true;
		}

		private bool ReadDigit()
		{
			if (_reader.Peek() != 48)
			{
				return ReadOneNine();
			}
			SaveToBuffer(_reader.Read());
			return true;
		}

		private bool ReadOneNine()
		{
			int num = _reader.Peek();
			if (num < 49 || num > 57)
			{
				return false;
			}
			SaveToBuffer(_reader.Read());
			return true;
		}

		private bool ReadFrac()
		{
			if (_reader.Peek() != 46)
			{
				return false;
			}
			SaveToBuffer(_reader.Read());
			if (!ReadDigits())
			{
				throw NodeExpectedError("digits");
			}
			return true;
		}

		private bool ReadExp()
		{
			int num = _reader.Peek();
			if (num != 69 && num != 101)
			{
				return false;
			}
			SaveToBuffer(_reader.Read());
			ReadSign();
			if (!ReadDigits())
			{
				throw NodeExpectedError("digits");
			}
			return true;
		}

		private bool ReadSign()
		{
			int num = _reader.Peek();
			if (num != 43 && num != 45)
			{
				return false;
			}
			SaveToBuffer(_reader.Read());
			return true;
		}

		private INode ReadLiteral()
		{
			_ = string.Empty;
			switch (_reader.Peek())
			{
			case 116:
				if (ConsumeChars(4).ToLower() != "true")
				{
					throw NodeExpectedError("true");
				}
				return new BooleanNode(v: true);
			case 102:
				if (ConsumeChars(5).ToLower() != "false")
				{
					throw NodeExpectedError("false");
				}
				return new BooleanNode(v: false);
			case 110:
				if (ConsumeChars(4).ToLower() != "null")
				{
					throw NodeExpectedError("null");
				}
				return new NullNode();
			default:
				return null;
			}
		}

		private void SkipWS()
		{
			while (true)
			{
				int num = _reader.Peek();
				if ((uint)(num - 9) <= 1u || num == 13 || num == 32)
				{
					_reader.Read();
					continue;
				}
				break;
			}
		}

		private void SaveToBuffer(int c)
		{
			_strCache.Append((char)c);
		}

		private string CommitBuffer()
		{
			string result = _strCache.ToString();
			_strCache.Length = 0;
			return result;
		}

		private string ConsumeChars(int length)
		{
			for (int i = 0; i < length; i++)
			{
				int c = _reader.Read();
				SaveToBuffer(c);
			}
			return CommitBuffer();
		}

		private ParseFailedException NodeExpectedError(string expected)
		{
			return new ParseFailedException($"A node \"{expected}\" is expected but '{_reader.LastToken}' is provided", _reader.Position);
		}

		private ParseFailedException TokenExpectedError(char expected)
		{
			return new ParseFailedException($"A charactor '{expected}' is expected but '{_reader.LastToken}' is provided", _reader.Position);
		}
	}
	public class ParseFailedException : Exception
	{
		public ParseFailedException(string message, ulong pos)
			: base($"{message} (at position {pos})")
		{
		}
	}
	public sealed class JsonSerializer
	{
		private Type _type;

		public JsonSerializer(Type type)
		{
			_type = type;
		}

		public void Serialize<T>(Stream s, T o, int indent = 0)
		{
			using JsonWriter writer = new JsonWriter(s, indent);
			SerializeValue(writer, o);
		}

		public string Serialize<T>(T o, int indent = 0)
		{
			using MemoryStream memoryStream = new MemoryStream();
			Serialize(memoryStream, o, indent);
			return Encoding.UTF8.GetString(memoryStream.ToArray());
		}

		public INode SerializeToNode<T>(T o)
		{
			byte[] buffer = null;
			using (MemoryStream memoryStream = new MemoryStream())
			{
				Serialize(memoryStream, o);
				buffer = memoryStream.ToArray();
			}
			using MemoryStream s = new MemoryStream(buffer);
			return new JsonDeserializer(typeof(INode)).Deserialize(s) as INode;
		}

		private void SerializeValue<T>(JsonWriter writer, T o)
		{
			if (o is INode)
			{
				SerializeValue(writer, (o as INode).GenericContent);
				return;
			}
			switch (Node.KindOfValue(o))
			{
			case NodeKind.String:
			case NodeKind.Integer:
			case NodeKind.Float:
			case NodeKind.Boolean:
				SerializePrimitive(writer, o);
				break;
			case NodeKind.Array:
				SerializeArray(writer, o);
				break;
			case NodeKind.Object:
				SerializeObject(writer, o);
				break;
			case NodeKind.Null:
				SerializeNull(writer, o);
				break;
			}
		}

		private void SerializePrimitive<T>(JsonWriter writer, T o)
		{
			if (TypeHelper.TypeWrap(o.GetType()).IsEnum)
			{
				switch (TypeHelper.GetCustomAttribute<JsonAttribute>(o.GetType())?.EnumConversion ?? EnumConversionType.AsInt)
				{
				case EnumConversionType.AsInt:
					SerializeValue(writer, Convert.ChangeType(o, Enum.GetUnderlyingType(o.GetType())));
					break;
				case EnumConversionType.AsString:
					SerializeValue(writer, TypeHelper.GetStringEnumNameOf(o));
					break;
				}
			}
			else
			{
				TypeHelper.TypeWrap(typeof(JsonWriter)).GetMethod("WriteValue", new Type[1] { o.GetType() }).Invoke(writer, new object[1] { o });
			}
		}

		private void SerializeArray<T>(JsonWriter writer, T o)
		{
			writer.WriteArrayStart();
			foreach (object item in TypeHelper.ToIEnumerable(o))
			{
				SerializeValue(writer, item);
			}
			writer.WriteArrayEnd();
		}

		private void SerializeObject<T>(JsonWriter writer, T o)
		{
			writer.WriteObjectStart();
			foreach (KeyValuePair<string, object> item in TypeHelper.ToKeyValues(o))
			{
				writer.WriteObjectKey(item.Key);
				SerializeValue(writer, item.Value);
			}
			writer.WriteObjectEnd();
		}

		private void SerializeNull<T>(JsonWriter writer, T o)
		{
			writer.WriteValueNull();
		}

		public object Deserialize(string text)
		{
			return new JsonDeserializer(_type).Deserialize(text);
		}

		public object Deserialize(Stream s)
		{
			return new JsonDeserializer(_type).Deserialize(s);
		}
	}
	public sealed class JsonWriter : IDisposable
	{
		private struct State
		{
			public StateKind Kind;

			public int Depth;
		}

		private enum StateKind
		{
			ObjectKeyHead,
			ObjectKeyOther,
			ObjectValue,
			ArrayHead,
			ArrayOther,
			None
		}

		private StreamWriter _writer;

		private int _indent;

		private string _indentStr;

		private Stack<State> _states = new Stack<State>();

		public JsonWriter(Stream s, int indent = 0)
		{
			_writer = new StreamWriter(s);
			_indent = indent;
			if (_indent > 0)
			{
				_indentStr = new string(' ', _indent);
			}
			_states.Push(new State
			{
				Kind = StateKind.None,
				Depth = 0
			});
		}

		public void Dispose()
		{
			if (_writer != null)
			{
				((IDisposable)_writer).Dispose();
			}
		}

		public void WriteObjectStart()
		{
			State state = _states.Peek();
			if (state.Kind == StateKind.ObjectKeyHead || state.Kind == StateKind.ObjectKeyOther)
			{
				throw new Exception("");
			}
			WriteDelimiter();
			_writer.Write("{");
			_states.Push(new State
			{
				Kind = StateKind.ObjectKeyHead,
				Depth = state.Depth + 1
			});
		}

		public void WriteObjectKey(string key)
		{
			State state = _states.Peek();
			if (state.Kind != 0 && state.Kind != StateKind.ObjectKeyOther)
			{
				throw new Exception("");
			}
			WriteValue(key);
			_writer.Write(":");
			_states.Pop();
			_states.Push(new State
			{
				Kind = StateKind.ObjectValue,
				Depth = state.Depth
			});
		}

		public void WriteObjectEnd()
		{
			State state = _states.Peek();
			if (state.Kind != 0 && state.Kind != StateKind.ObjectKeyOther)
			{
				throw new Exception("");
			}
			_states.Pop();
			if (state.Kind == StateKind.ObjectKeyOther)
			{
				WriteIndentBreakForHuman(_states.Peek().Depth);
			}
			_writer.Write("}");
		}

		public void WriteArrayStart()
		{
			State state = _states.Peek();
			if (state.Kind == StateKind.ObjectKeyHead || state.Kind == StateKind.ObjectKeyOther)
			{
				throw new Exception("");
			}
			WriteDelimiter();
			_writer.Write("[");
			_states.Push(new State
			{
				Kind = StateKind.ArrayHead,
				Depth = state.Depth + 1
			});
		}

		public void WriteArrayEnd()
		{
			State state = _states.Peek();
			if (state.Kind != StateKind.ArrayHead && state.Kind != StateKind.ArrayOther)
			{
				throw new Exception("");
			}
			_states.Pop();
			if (state.Kind == StateKind.ArrayOther)
			{
				WriteIndentBreakForHuman(_states.Peek().Depth);
			}
			_writer.Write("]");
		}

		public void WriteValue(bool v)
		{
			WriteDelimiter();
			_writer.Write(v ? "true" : "false");
		}

		public void WriteValue(byte v)
		{
			WritePrimitive(v);
		}

		public void WriteValue(sbyte v)
		{
			WritePrimitive(v);
		}

		public void WriteValue(char v)
		{
			WritePrimitive(v);
		}

		public void WriteValue(decimal v)
		{
			WritePrimitive(v);
		}

		public void WriteValue(double v)
		{
			WritePrimitive(v);
		}

		public void WriteValue(float v)
		{
			WritePrimitive(v);
		}

		public void WriteValue(int v)
		{
			WritePrimitive(v);
		}

		public void WriteValue(uint v)
		{
			WritePrimitive(v);
		}

		public void WriteValue(long v)
		{
			WritePrimitive(v);
		}

		public void WriteValue(ulong v)
		{
			WritePrimitive(v);
		}

		public void WriteValue(short v)
		{
			WritePrimitive(v);
		}

		public void WriteValue(ushort v)
		{
			WritePrimitive(v);
		}

		public void WriteValue(string v)
		{
			WriteDelimiter();
			_writer.Write('"');
			_writer.Write(Escape(v).ToArray());
			_writer.Write('"');
		}

		public void WriteValueNull()
		{
			WriteDelimiter();
			_writer.Write("null");
		}

		private void WritePrimitive(char v)
		{
			WritePrimitive((int)v);
		}

		private void WritePrimitive(float v)
		{
			WritePrimitive($"{v:G9}");
		}

		private void WritePrimitive(double v)
		{
			WritePrimitive($"{v:G17}");
		}

		private void WritePrimitive<T>(T v)
		{
			WriteDelimiter();
			_writer.Write(v);
		}

		private void WriteIndentBreakForHuman(int depth)
		{
			if (_indent > 0)
			{
				_writer.Write('\n');
				for (int i = 0; i < depth; i++)
				{
					_writer.Write(_indentStr);
				}
			}
		}

		private void WriteSpaceForHuman()
		{
			if (_indent > 0)
			{
				_writer.Write(' ');
			}
		}

		private void WriteDelimiter()
		{
			State state = _states.Peek();
			if (state.Kind == StateKind.ArrayHead)
			{
				WriteIndentBreakForHuman(state.Depth);
				_states.Pop();
				_states.Push(new State
				{
					Kind = StateKind.ArrayOther,
					Depth = state.Depth
				});
				return;
			}
			if (state.Kind == StateKind.ObjectKeyHead)
			{
				WriteIndentBreakForHuman(state.Depth);
			}
			if (state.Kind == StateKind.ArrayOther || state.Kind == StateKind.ObjectKeyOther)
			{
				_writer.Write(",");
				WriteIndentBreakForHuman(state.Depth);
			}
			if (state.Kind == StateKind.ObjectValue)
			{
				WriteSpaceForHuman();
				_states.Pop();
				_states.Push(new State
				{
					Kind = StateKind.ObjectKeyOther,
					Depth = state.Depth
				});
			}
		}

		private IEnumerable<char> Escape(string s)
		{
			foreach (char c in s)
			{
				char modified = '\0';
				if (c <= ' ' || c == '"' || c == '\\')
				{
					switch (c)
					{
					case '"':
						modified = '"';
						break;
					case '\\':
						modified = '\\';
						break;
					case '\b':
						modified = 'b';
						break;
					case '\n':
						modified = 'n';
						break;
					case '\r':
						modified = 'r';
						break;
					case '\t':
						modified = 't';
						break;
					}
				}
				if (modified != 0)
				{
					yield return '\\';
					yield return modified;
				}
				else
				{
					yield return c;
				}
			}
		}
	}
	public enum NodeKind
	{
		Object,
		Array,
		String,
		Integer,
		Float,
		Boolean,
		Null,
		Undefined
	}
	public struct NodeKindWrapped
	{
		public NodeKind Kind;

		public bool Wrapped;
	}
	public interface INode
	{
		NodeKind Kind { get; }

		INode this[int index] { get; }

		INode this[string key] { get; }

		object GenericContent { get; }
	}
	public sealed class BooleanNode : INode
	{
		public static NodeKind KIND = NodeKind.Boolean;

		public static Type TYPE = typeof(bool);

		public NodeKind Kind => KIND;

		public INode this[int index] => UndefinedNode.Undef;

		public INode this[string key] => UndefinedNode.Undef;

		public bool Value { get; private set; }

		public object GenericContent => Value;

		public BooleanNode(bool v)
		{
			Value = v;
		}

		public override bool Equals(object rhsObj)
		{
			if (!(rhsObj is BooleanNode booleanNode))
			{
				return false;
			}
			return Value.Equals(booleanNode.Value);
		}

		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		public override string ToString()
		{
			return "BOOLEAN: " + Value;
		}
	}
	public sealed class NullNode : INode
	{
		public static NodeKind KIND = NodeKind.Null;

		public static Type TYPE = typeof(object);

		public static readonly INode Null = new NullNode();

		public NodeKind Kind => KIND;

		public INode this[int index] => UndefinedNode.Undef;

		public INode this[string key] => UndefinedNode.Undef;

		public object GenericContent => null;

		public override bool Equals(object rhsObj)
		{
			if (!(rhsObj is NullNode))
			{
				return false;
			}
			return true;
		}

		public override int GetHashCode()
		{
			return 0;
		}

		public override string ToString()
		{
			return "NULL";
		}
	}
	public sealed class UndefinedNode : INode
	{
		public static NodeKind KIND = NodeKind.Undefined;

		public static Type TYPE = typeof(object);

		public static readonly INode Undef = new UndefinedNode();

		public NodeKind Kind => KIND;

		public INode this[int index] => Undef;

		public INode this[string key] => Undef;

		public object GenericContent => null;

		public override bool Equals(object rhsObj)
		{
			if (!(rhsObj is UndefinedNode))
			{
				return false;
			}
			return true;
		}

		public override int GetHashCode()
		{
			return 0;
		}

		public override string ToString()
		{
			return "UNDEFINED";
		}
	}
	public sealed class IntegerNode : INode
	{
		public static NodeKind KIND = NodeKind.Integer;

		public static Type TYPE = typeof(long);

		public NodeKind Kind => KIND;

		public INode this[int index] => UndefinedNode.Undef;

		public INode this[string key] => UndefinedNode.Undef;

		public long Value { get; private set; }

		public object GenericContent => Value;

		public IntegerNode(long v)
		{
			Value = v;
		}

		public override bool Equals(object rhsObj)
		{
			if (!(rhsObj is IntegerNode integerNode))
			{
				return false;
			}
			return Value.Equals(integerNode.Value);
		}

		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		public override string ToString()
		{
			return "NUMBER(Int): " + Value;
		}
	}
	public sealed class FloatNode : INode
	{
		public static NodeKind KIND = NodeKind.Float;

		public static Type TYPE = typeof(double);

		public NodeKind Kind => KIND;

		public INode this[int index] => UndefinedNode.Undef;

		public INode this[string key] => UndefinedNode.Undef;

		public double Value { get; private set; }

		public object GenericContent => Value;

		public FloatNode(double v)
		{
			Value = v;
		}

		public override bool Equals(object rhsObj)
		{
			if (!(rhsObj is FloatNode floatNode))
			{
				return false;
			}
			return Value.Equals(floatNode.Value);
		}

		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		public override string ToString()
		{
			return "NUMBER(Float): " + Value;
		}
	}
	public sealed class StringNode : INode
	{
		public static NodeKind KIND = NodeKind.String;

		public static Type TYPE = typeof(string);

		public NodeKind Kind => KIND;

		public INode this[int index] => UndefinedNode.Undef;

		public INode this[string key] => UndefinedNode.Undef;

		public string Value { get; private set; }

		public object GenericContent => Value;

		public StringNode(string v)
		{
			Value = v;
		}

		public override bool Equals(object rhsObj)
		{
			if (!(rhsObj is StringNode stringNode))
			{
				return false;
			}
			return Value.Equals(stringNode.Value);
		}

		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		public override string ToString()
		{
			return "STRING: " + Value;
		}
	}
	public sealed class ObjectNode : INode, IEnumerable<KeyValuePair<string, INode>>, IEnumerable
	{
		public static NodeKind KIND = NodeKind.Object;

		public static Type TYPE = typeof(Dictionary<string, INode>);

		public Dictionary<string, INode> Elems;

		public NodeKind Kind => KIND;

		public INode this[int index] => UndefinedNode.Undef;

		public INode this[string key]
		{
			get
			{
				INode value = null;
				if (Elems != null)
				{
					Elems.TryGetValue(key, out value);
				}
				if (value == null)
				{
					return UndefinedNode.Undef;
				}
				return value;
			}
		}

		public object GenericContent
		{
			get
			{
				if (Elems == null)
				{
					return new Dictionary<string, INode>();
				}
				return Elems;
			}
		}

		public ObjectNode()
		{
		}

		public ObjectNode(Dictionary<string, INode> v)
		{
			Elems = v;
		}

		public void AddElement(string key, INode elem)
		{
			if (Elems == null)
			{
				Elems = new Dictionary<string, INode>();
			}
			Elems.Add(key, elem);
		}

		public void RemoveElement(string key)
		{
			if (Elems != null)
			{
				Elems.Remove(key);
			}
		}

		public IEnumerator<KeyValuePair<string, INode>> GetEnumerator()
		{
			if (Elems != null)
			{
				return Elems.OrderBy((KeyValuePair<string, INode> p) => p.Key).GetEnumerator();
			}
			return Enumerable.Empty<KeyValuePair<string, INode>>().GetEnumerator();
		}

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

		public override bool Equals(object rhsObj)
		{
			if (!(rhsObj is ObjectNode objectNode))
			{
				return false;
			}
			if (Elems == null)
			{
				return objectNode.Elems == null;
			}
			return Elems.OrderBy((KeyValuePair<string, INode> p) => p.Key).SequenceEqual(objectNode.Elems.OrderBy((KeyValuePair<string, INode> p) => p.Key));
		}

		public override int GetHashCode()
		{
			if (Elems == null)
			{
				return 0;
			}
			return Elems.GetHashCode();
		}

		public override string ToString()
		{
			if (Elems == null)
			{
				return "OBJECT: {}";
			}
			return "OBJECT: " + string.Join("; ", (from p in Elems
				orderby p.Key
				select p.Key + " = " + p.Value).ToArray());
		}
	}
	public sealed class ArrayNode : INode, IEnumerable<INode>, IEnumerable
	{
		public static NodeKind KIND = NodeKind.Array;

		public static Type TYPE = typeof(List<INode>);

		public List<INode> Elems;

		public NodeKind Kind => KIND;

		public INode this[int index]
		{
			get
			{
				INode node = ((Elems != null) ? Elems.ElementAtOrDefault(index) : null);
				if (node == null)
				{
					return UndefinedNode.Undef;
				}
				return node;
			}
		}

		public INode this[string key] => UndefinedNode.Undef;

		public object GenericContent
		{
			get
			{
				if (Elems == null)
				{
					return new List<INode>();
				}
				return Elems;
			}
		}

		public ArrayNode()
		{
		}

		public ArrayNode(List<INode> v)
		{
			Elems = v;
		}

		public void AddElement(INode elem)
		{
			if (Elems == null)
			{
				Elems = new List<INode>();
			}
			Elems.Add(elem);
		}

		public void RemoveElementAt(int index)
		{
			if (Elems != null && index >= 0 && index < Elems.Count)
			{
				Elems.RemoveAt(index);
			}
		}

		public IEnumerator<INode> GetEnumerator()
		{
			if (Elems != null)
			{
				return Elems.GetEnumerator();
			}
			return Enumerable.Empty<INode>().GetEnumerator();
		}

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

		public override bool Equals(object rhsObj)
		{
			if (!(rhsObj is ArrayNode arrayNode))
			{
				return false;
			}
			if (Elems == null)
			{
				return arrayNode.Elems == null;
			}
			return Elems.SequenceEqual(arrayNode.Elems);
		}

		public override int GetHashCode()
		{
			if (Elems == null)
			{
				return 0;
			}
			return Elems.GetHashCode();
		}

		public override string ToString()
		{
			if (Elems == null)
			{
				return "ARRAY: []";
			}
			return "ARRAY: " + string.Join("; ", Elems.Select((INode e) => e.ToString()).ToArray());
		}
	}
	public static class Node
	{
		private static Dictionary<Type, NodeKind> _primitiveTable = new Dictionary<Type, NodeKind>
		{
			{
				typeof(bool),
				NodeKind.Boolean
			},
			{
				typeof(byte),
				NodeKind.Integer
			},
			{
				typeof(sbyte),
				NodeKind.Integer
			},
			{
				typeof(char),
				NodeKind.Integer
			},
			{
				typeof(decimal),
				NodeKind.Integer
			},
			{
				typeof(double),
				NodeKind.Float
			},
			{
				typeof(float),
				NodeKind.Float
			},
			{
				typeof(int),
				NodeKind.Integer
			},
			{
				typeof(uint),
				NodeKind.Integer
			},
			{
				typeof(long),
				NodeKind.Integer
			},
			{
				typeof(ulong),
				NodeKind.Integer
			},
			{
				typeof(short),
				NodeKind.Integer
			},
			{
				typeof(ushort),
				NodeKind.Integer
			},
			{
				typeof(string),
				NodeKind.String
			}
		};

		private static Dictionary<Type, NodeKind> _nodeKindTable = new Dictionary<Type, NodeKind>
		{
			{
				typeof(INode),
				ObjectNode.KIND
			},
			{
				typeof(BooleanNode),
				BooleanNode.KIND
			},
			{
				typeof(NullNode),
				NullNode.KIND
			},
			{
				typeof(UndefinedNode),
				UndefinedNode.KIND
			},
			{
				typeof(IntegerNode),
				IntegerNode.KIND
			},
			{
				typeof(FloatNode),
				FloatNode.KIND
			},
			{
				typeof(StringNode),
				StringNode.KIND
			},
			{
				typeof(ObjectNode),
				ObjectNode.KIND
			},
			{
				typeof(ArrayNode),
				ArrayNode.KIND
			}
		};

		private static Dictionary<NodeKind, Type> _nodeTypeTable = new Dictionary<NodeKind, Type>
		{
			{
				BooleanNode.KIND,
				BooleanNode.TYPE
			},
			{
				NullNode.KIND,
				NullNode.TYPE
			},
			{
				UndefinedNode.KIND,
				UndefinedNode.TYPE
			},
			{
				IntegerNode.KIND,
				IntegerNode.TYPE
			},
			{
				FloatNode.KIND,
				FloatNode.TYPE
			},
			{
				StringNode.KIND,
				StringNode.TYPE
			},
			{
				ObjectNode.KIND,
				ObjectNode.TYPE
			},
			{
				ArrayNode.KIND,
				ArrayNode.TYPE
			}
		};

		public static NodeKind KindOfValue<T>(T o)
		{
			if (o == null)
			{
				return NodeKind.Null;
			}
			return KindOfType(o.GetType());
		}

		public static NodeKindWrapped KindOfTypeWrapped(Type ty)
		{
			NodeKindWrapped result;
			if (TypeHelper.TypeWrap(typeof(INode)).IsAssignableFrom(ty))
			{
				result = default(NodeKindWrapped);
				result.Kind = _nodeKindTable[ty];
				result.Wrapped = true;
				return result;
			}
			result = default(NodeKindWrapped);
			result.Kind = KindOfType(ty);
			result.Wrapped = false;
			return result;
		}

		public static NodeKind KindOfType(Type ty)
		{
			if (TypeHelper.TypeWrap(ty).IsGenericType && ty.GetGenericTypeDefinition() == typeof(Nullable<>))
			{
				return KindOfType(TypeHelper.TypeWrap(ty).GetGenericArguments()[0]);
			}
			if (_primitiveTable.TryGetValue(ty, out var value))
			{
				return value;
			}
			if (TypeHelper.TypeWrap(ty).IsEnum)
			{
				JsonAttribute customAttribute = TypeHelper.GetCustomAttribute<JsonAttribute>(ty);
				if (customAttribute == null || customAttribute.EnumConversion != EnumConversionType.AsString)
				{
					return NodeKind.Integer;
				}
				return NodeKind.String;
			}
			if (TypeHelper.ElemTypeOfIEnumerable(ty) != null)
			{
				return NodeKind.Array;
			}
			return NodeKind.Object;
		}

		public static Type ValueTypeOfKind(NodeKind kind)
		{
			return _nodeTypeTable[kind];
		}
	}
	internal static class TypeHelper
	{
		private struct RankedKey
		{
			public int Order;

			public string Key;
		}

		private class RankedKeyValueComparer : IComparer<KeyValuePair<RankedKey, object>>
		{
			public int Compare(KeyValuePair<RankedKey, object> a, KeyValuePair<RankedKey, object> b)
			{
				throw new NotImplementedException();
			}

			int IComparer<KeyValuePair<RankedKey, object>>.Compare(KeyValuePair<RankedKey, object> a, KeyValuePair<RankedKey, object> b)
			{
				if (a.Key.Order != b.Key.Order)
				{
					return a.Key.Order - b.Key.Order;
				}
				return string.Compare(a.Key.Key, b.Key.Key);
			}
		}

		private class DeepEqualityComparer : EqualityComparer<object>
		{
			public override bool Equals(object a, object b)
			{
				return DeepEquals(a, b);
			}

			public override int GetHashCode(object a)
			{
				return a.GetHashCode();
			}
		}

		public delegate bool Converter(object input, out object output);

		private static readonly Dictionary<Type, Dictionary<Type, Converter>> _convTable = new Dictionary<Type, Dictionary<Type, Converter>>
		{
			{
				typeof(bool),
				new Dictionary<Type, Converter> { 
				{
					typeof(bool),
					null
				} }
			},
			{
				typeof(double),
				new Dictionary<Type, Converter>
				{
					{
						typeof(decimal),
						delegate(object i, out object o)
						{
							return ConvertFromDoubleToDecimal((double)i, out o);
						}
					},
					{
						typeof(double),
						null
					},
					{
						typeof(float),
						delegate(object i, out object o)
						{
							return ConvertFromDoubleToFloat((double)i, out o);
						}
					}
				}
			},
			{
				typeof(long),
				new Dictionary<Type, Converter>
				{
					{
						typeof(byte),
						delegate(object i, out object o)
						{
							return ConvertFromLongToByte((long)i, out o);
						}
					},
					{
						typeof(sbyte),
						delegate(object i, out object o)
						{
							return ConvertFromLongToSbyte((long)i, out o);
						}
					},
					{
						typeof(char),
						delegate(object i, out object o)
						{
							return ConvertFromLongToChar((long)i, out o);
						}
					},
					{
						typeof(decimal),
						delegate(object i, out object o)
						{
							return ConvertFromLongToDecimal((long)i, out o);
						}
					},
					{
						typeof(double),
						delegate(object i, out object o)
						{
							return ConvertFromLongToDouble((long)i, out o);
						}
					},
					{
						typeof(float),
						delegate(object i, out object o)
						{
							return ConvertFromLongToFloat((long)i, out o);
						}
					},
					{
						typeof(int),
						delegate(object i, out object o)
						{
							return ConvertFromLongToInt((long)i, out o);
						}
					},
					{
						typeof(uint),
						delegate(object i, out object o)
						{
							return ConvertFromLongToUint((long)i, out o);
						}
					},
					{
						typeof(long),
						null
					},
					{
						typeof(ulong),
						delegate(object i, out object o)
						{
							return ConvertFromLongToUlong((long)i, out o);
						}
					},
					{
						typeof(short),
						delegate(object i, out object o)
						{
							return ConvertFromLongToShort((long)i, out o);
						}
					},
					{
						typeof(ushort),
						delegate(object i, out object o)
						{
							return ConvertFromLongToUshort((long)i, out o);
						}
					}
				}
			},
			{
				typeof(string),
				new Dictionary<Type, Converter> { 
				{
					typeof(string),
					null
				} }
			}
		};

		public static TypeInfo TypeWrap(Type ty)
		{
			return ty.GetTypeInfo();
		}

		public static bool IsBoxed(Type ty)
		{
			TypeInfo typeInfo = TypeWrap(ty);
			if (typeInfo.IsClass)
			{
				return true;
			}
			if (typeInfo.IsGenericType)
			{
				return ty.GetGenericTypeDefinition() == typeof(Nullable<>);
			}
			return false;
		}

		public static T GetCustomAttribute<T>(FieldInfo fi) where T : Attribute
		{
			return (T)(from a in fi.GetCustomAttributes(typeof(T), inherit: false)
				where a.GetType() == typeof(T)
				select a).FirstOrDefault();
		}

		public static T GetCustomAttribute<T>(Type ty) where T : Attribute
		{
			return (T)(from a in TypeWrap(ty).GetCustomAttributes(typeof(T), inherit: false)
				where a.GetType() == typeof(T)
				select a).FirstOrDefault();
		}

		public static string[] GetStringEnumNames(Type ty)
		{
			return TypeWrap(ty).GetFields(BindingFlags.Static | BindingFlags.Public).Select(delegate(FieldInfo fi)
			{
				JsonFieldAttribute customAttribute = GetCustomAttribute<JsonFieldAttribute>(fi);
				return (customAttribute != null && customAttribute.Name != null) ? customAttribute.Name : fi.Name;
			}).ToArray();
		}

		public static string GetStringEnumNameOf(object e)
		{
			Type type = e.GetType();
			int num = Array.IndexOf(Enum.GetValues(type), e);
			return GetStringEnumNames(type)[num];
		}

		public static IEnumerable<object> ToIEnumerable(object o)
		{
			Type type = o.GetType();
			if (type.IsArray)
			{
				if (type.HasElementType && TypeWrap(type.GetElementType()).IsClass)
				{
					return (IEnumerable<object>)o;
				}
				return ((IEnumerable)o).Cast<object>();
			}
			return ((IEnumerable)o).Cast<object>();
		}

		public static Type ElemTypeOfIEnumerable(Type ty)
		{
			if (ty.IsArray)
			{
				if (ty.HasElementType)
				{
					return ty.GetElementType();
				}
				return null;
			}
			if (TypeWrap(ty).IsGenericType && ty.GetGenericTypeDefinition() == typeof(List<>))
			{
				return TypeWrap(ty).GetGenericArguments()[0];
			}
			return null;
		}

		public static IEnumerable<KeyValuePair<string, object>> ToKeyValues(object o)
		{
			List<KeyValuePair<RankedKey, object>> list = ToRankedKeyValuesUnordered(o).ToList();
			list.Sort(new RankedKeyValueComparer());
			return list.Select((KeyValuePair<RankedKey, object> v) => new KeyValuePair<string, object>(v.Key.Key, v.Value));
		}

		public static IEnumerable<FieldInfo> GetSerializableFields(Type ty)
		{
			TypeInfo typeInfo = TypeWrap(ty);
			FieldInfo[] fields = typeInfo.GetFields(BindingFlags.Instance | BindingFlags.Public);
			IEnumerable<FieldInfo> second = from field in typeInfo.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
				where GetCustomAttribute<JsonFieldAttribute>(field) != null
				select field;
			return fields.Concat(second);
		}

		private static IEnumerable<KeyValuePair<RankedKey, object>> ToRankedKeyValuesUnordered(object o)
		{
			Type type = o.GetType();
			if (TypeWrap(type).IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >))
			{
				if (TypeWrap(type).GetGenericArguments()[0] != typeof(string))
				{
					throw new NotImplementedException();
				}
				foreach (DictionaryEntry item in (IDictionary)o)
				{
					yield return new KeyValuePair<RankedKey, object>(new RankedKey
					{
						Order = 0,
						Key = (string)item.Key
					}, item.Value);
				}
				yield break;
			}
			IEnumerable<FieldInfo> serializableFields = GetSerializableFields(type);
			foreach (FieldInfo item2 in serializableFields)
			{
				JsonFieldAttribute customAttribute = GetCustomAttribute<JsonFieldAttribute>(item2);
				string key = JsonFieldAttribute.FieldName(customAttribute, item2);
				object value = item2.GetValue(o);
				if (!JsonFieldIgnorableAttribute.IsIgnorable(GetCustomAttribute<JsonFieldIgnorableAttribute>(item2), value))
				{
					yield return new KeyValuePair<RankedKey, object>(new RankedKey
					{
						Order = JsonFieldAttribute.FieldOrder(customAttribute),
						Key = key
					}, value);
				}
			}
		}

		public static bool DeepEquals(object lhs, object rhs)
		{
			NodeKind nodeKind = Node.KindOfValue(lhs);
			NodeKind nodeKind2 = Node.KindOfValue(rhs);
			if (nodeKind != nodeKind2)
			{
				return false;
			}
			switch (nodeKind)
			{
			case NodeKind.String:
			case NodeKind.Integer:
			case NodeKind.Float:
			case NodeKind.Boolean:
				return object.Equals(lhs, rhs);
			case NodeKind.Array:
			{
				IEnumerable<object> first = ToIEnumerable(lhs);
				IEnumerable<object> second = ToIEnumerable(rhs);
				return first.SequenceEqual(second, new DeepEqualityComparer());
			}
			case NodeKind.Object:
			{
				Dictionary<string, object> dictionary = new Dictionary<string, object>();
				foreach (KeyValuePair<string, object> item in ToKeyValues(lhs))
				{
					dictionary.Add(item.Key, item.Value);
				}
				Dictionary<string, object> rhsKvs = new Dictionary<string, object>();
				foreach (KeyValuePair<string, object> item2 in ToKeyValues(rhs))
				{
					rhsKvs.Add(item2.Key, item2.Value);
				}
				if (!dictionary.Keys.SequenceEqual(rhsKvs.Keys))
				{
					return false;
				}
				return dictionary.All((KeyValuePair<string, object> kv) => DeepEquals(kv.Value, rhsKvs[kv.Key]));
			}
			case NodeKind.Null:
				return true;
			default:
				throw new NotImplementedException();
			}
		}

		private static bool ConvertFromDoubleToDecimal(double i, out object o)
		{
			try
			{
				o = (decimal)i;
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		private static bool ConvertFromDoubleToFloat(double i, out object o)
		{
			try
			{
				o = (float)i;
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		private static bool ConvertFromLongToByte(long i, out object o)
		{
			try
			{
				if (i < 0)
				{
					throw new OverflowException();
				}
				o = checked((byte)i);
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		private static bool ConvertFromLongToSbyte(long i, out object o)
		{
			try
			{
				o = checked((sbyte)i);
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		private static bool ConvertFromLongToChar(long i, out object o)
		{
			try
			{
				if (i < 0)
				{
					throw new OverflowException();
				}
				o = (char)checked((ushort)i);
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		private static bool ConvertFromLongToDecimal(long i, out object o)
		{
			try
			{
				o = (decimal)i;
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		private static bool ConvertFromLongToDouble(long i, out object o)
		{
			try
			{
				o = (double)i;
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		private static bool ConvertFromLongToFloat(long i, out object o)
		{
			try
			{
				o = (float)i;
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		private static bool ConvertFromLongToInt(long i, out object o)
		{
			try
			{
				o = checked((int)i);
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		private static bool ConvertFromLongToUint(long i, out object o)
		{
			try
			{
				if (i < 0)
				{
					throw new OverflowException();
				}
				o = checked((uint)i);
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		private static bool ConvertFromLongToUlong(long i, out object o)
		{
			try
			{
				if (i < 0)
				{
					throw new OverflowException();
				}
				o = checked((ulong)i);
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		private static bool ConvertFromLongToShort(long i, out object o)
		{
			try
			{
				o = checked((short)i);
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		private static bool ConvertFromLongToUshort(long i, out object o)
		{
			try
			{
				if (i < 0)
				{
					throw new OverflowException();
				}
				o = checked((ushort)i);
				return true;
			}
			catch (OverflowException)
			{
				o = null;
				return false;
			}
		}

		public static bool GetConverter(Type fromTy, Type toTy, out Converter converter)
		{
			if (!_convTable.TryGetValue(fromTy, out var value))
			{
				converter = null;
				return false;
			}
			return value.TryGetValue(toTy, out converter);
		}
	}
}
namespace VJson.Schema
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field, Inherited = false)]
	public class JsonSchemaAttribute : PreserveAttribute
	{
		public string Schema;

		public string Id;

		public string Ref;

		public string Title;

		public string Description;

		public double MultipleOf = double.MinValue;

		public double Maximum = double.MinValue;

		public double ExclusiveMaximum = double.MinValue;

		public double Minimum = double.MaxValue;

		public double ExclusiveMinimum = double.MaxValue;

		public int MaxLength = int.MinValue;

		public int MinLength = int.MaxValue;

		public string Pattern;

		public int MaxItems = int.MinValue;

		public int MinItems = int.MaxValue;

		public bool UniqueItems;

		public int MaxProperties = int.MinValue;

		public int MinProperties = int.MaxValue;

		public string[] Required;
	}
	[AttributeUsage(AttributeTargets.Field, Inherited = false)]
	public sealed class ItemsJsonSchemaAttribute : JsonSchemaAttribute
	{
	}
	[AttributeUsage(AttributeTargets.Field, Inherited = false)]
	public sealed class JsonSchemaRequiredAttribute : PreserveAttribute
	{
	}
	[AttributeUsage(AttributeTargets.Field, Inherited = false)]
	public sealed class JsonSchemaDependenciesAttribute : PreserveAttribute
	{
		public string[] Dependencies { get; private set; }

		public JsonSchemaDependenciesAttribute(params string[] deps)
		{
			Dependencies = deps;
		}
	}
	public enum InfluenceRange
	{
		Entiry,
		AdditionalProperties
	}
	[AttributeUsage(AttributeTargets.Field, Inherited = false)]
	public class JsonSchemaRefAttribute : PreserveAttribute
	{
		public Type TagType { get; private set; }

		public InfluenceRange Influence { get; private set; }

		public JsonSchemaRefAttribute(Type tagType, InfluenceRange influence = InfluenceRange.Entiry)
		{
			if (!RefChecker.IsRefTagDerived(tagType, out var _))
			{
				throw new ArgumentException("IRefTag<T> must be derived by tagType");
			}
			TagType = tagType;
			Influence = influence;
		}
	}
	[AttributeUsage(AttributeTargets.Field, Inherited = false)]
	public sealed class ItemsJsonSchemaRefAttribute : JsonSchemaRefAttribute
	{
		public ItemsJsonSchemaRefAttribute(Type tagType, InfluenceRange influence = InfluenceRange.Entiry)
			: base(tagType, influence)
		{
		}
	}
	[Json(ImplicitConstructable = true)]
	public sealed class JsonSchema
	{
		[JsonField(Name = "$schema", Order = -10)]
		[JsonFieldIgnorable]
		public string Schema;

		[JsonField(Name = "$id", Order = -11)]
		[JsonFieldIgnorable]
		public string Id;

		[JsonField(Name = "$ref", Order = -12)]
		[JsonFieldIgnorable]
		public string Ref;

		[JsonField(Name = "title", Order = 0)]
		[JsonFieldIgnorable]
		public string Title;

		[JsonField(Name = "description", Order = 1)]
		[JsonFieldIgnorable]
		public string Description;

		[JsonField(Name = "type", TypeHints = new Type[]
		{
			typeof(string),
			typeof(string[])
		}, Order = 10)]
		[JsonFieldIgnorable]
		public object Type;

		[JsonField(Name = "enum", Order = 11)]
		[JsonFieldIgnorable]
		public object[] Enum;

		[JsonField(Name = "const", Order = 12)]
		[JsonFieldIgnorable]
		public object Const;

		[JsonField(Name = "multipleOf", Order = 20)]
		[JsonFieldIgnorable(WhenValueIs = double.MinValue)]
		public double MultipleOf = double.MinValue;

		[JsonField(Name = "maximum", Order = 21)]
		[JsonFieldIgnorable(WhenValueIs = double.MinValue)]
		public double Maximum = double.MinValue;

		[JsonField(Name = "exclusiveMaximum", Order = 22)]
		[JsonFieldIgnorable(WhenValueIs = double.MinValue)]
		public double ExclusiveMaximum = double.MinValue;

		[JsonField(Name = "minimum", Order = 23)]
		[JsonFieldIgnorable(WhenValueIs = double.MaxValue)]
		public double Minimum = double.MaxValue;

		[JsonField(Name = "exclusiveMinimum", Order = 24)]
		[JsonFieldIgnorable(WhenValueIs = double.MaxValue)]
		public double ExclusiveMinimum = double.MaxValue;

		[JsonField(Name = "maxLength", Order = 30)]
		[JsonFieldIgnorable(WhenValueIs = int.MinValue)]
		public int MaxLength = int.MinValue;

		[JsonField(Name = "minLength", Order = 31)]
		[JsonFieldIgnorable(WhenValueIs = int.MaxValue)]
		public int MinLength = int.MaxValue;

		[JsonField(Name = "pattern", Order = 32)]
		[JsonFieldIgnorable]
		public string Pattern;

		[JsonField(Name = "items", TypeHints = new Type[]
		{
			typeof(JsonSchema),
			typeof(JsonSchema[])
		}, Order = 40)]
		[JsonFieldIgnorable]
		private object items;

		[JsonField(Name = "additionalItems", Order = 41)]
		[JsonFieldIgnorable]
		public JsonSchema AdditionalItems;

		[JsonField(Name = "maxItems", Order = 42)]
		[JsonFieldIgnorable(WhenValueIs = int.MinValue)]
		public int MaxItems = int.MinValue;

		[JsonField(Name = "minItems", Order = 43)]
		[JsonFieldIgnorable(WhenValueIs = int.MaxValue)]
		public int MinItems = int.MaxValue;

		[JsonField(Name = "uniqueItems", Order = 44)]
		[JsonFieldIgnorable(WhenValueIs = false)]
		public bool UniqueItems;

		[JsonField(Name = "maxProperties", Order = 50)]
		[JsonFieldIgnorable(WhenValueIs = int.MinValue)]
		public int MaxProperties = int.MinValue;

		[JsonField(Name = "minProperties", Order = 51)]
		[JsonFieldIgnorable(WhenValueIs = int.MaxValue)]
		public int MinProperties = int.MaxValue;

		[JsonField(Name = "required", Order = 52)]
		[JsonFieldIgnorable]
		public string[] Required;

		[JsonField(Name = "properties", Order = 53)]
		[JsonFieldIgnorable]
		public Dictionary<string, JsonSchema> Properties;

		[JsonField(Name = "patternProperties", Order = 54)]
		[JsonFieldIgnorable]
		public Dictionary<string, JsonSchema> PatternProperties;

		[JsonField(Name = "additionalProperties", Order = 55)]
		[JsonFieldIgnorable]
		public JsonSchema AdditionalProperties;

		[JsonField(Name = "dependencies", TypeHints = new Type[]
		{
			typeof(Dictionary<string, string[]>),
			typeof(Dictionary<string, JsonSchema>)
		}, Order = 56)]
		[JsonFieldIgnorable]
		public object Dependencies;

		[JsonField(Name = "allOf", Order = 70)]
		[JsonFieldIgnorable]
		public List<JsonSchema> AllOf;

		[JsonField(Name = "anyOf", Order = 71)]
		[JsonFieldIgnorable]
		public List<JsonSchema> AnyOf;

		[JsonField(Name = "oneOf", Order = 72)]
		[JsonFieldIgnorable]
		public List<JsonSchema> OneOf;

		[JsonField(Name = "not", Order = 73)]
		[JsonFieldIgnorable]
		public JsonSchema Not;

		public object Items => items;

		public JsonSchema TypedItems
		{
			set
			{
				items = value;
			}
		}

		private bool EqualsOnlyAny(JsonSchema rhs)
		{
			if (EqualsSingletonOrArray<string>(Type, rhs.Type) && EqualsEnumerable(Enum, rhs.Enum))
			{
				return object.Equals(Const, rhs.Const);
			}
			return false;
		}

		private bool EqualsOnlyNum(JsonSchema rhs)
		{
			if (MultipleOf == rhs.MultipleOf && Maximum == rhs.Maximum && ExclusiveMaximum == rhs.ExclusiveMaximum && Minimum == rhs.Minimum)
			{
				return ExclusiveMinimum == rhs.ExclusiveMinimum;
			}
			return false;
		}

		private bool EqualsOnlyString(JsonSchema rhs)
		{
			if (MaxLength == rhs.MaxLength && MinLength == rhs.MinLength)
			{
				return object.Equals(Pattern, rhs.Pattern);
			}
			return false;
		}

		private bool EqualsOnlyArray(JsonSchema rhs)
		{
			if (EqualsSingletonOrArray<JsonSchema>(Items, rhs.Items) && object.Equals(AdditionalItems, rhs.AdditionalItems) && MaxItems == rhs.MaxItems && MinItems == rhs.MinItems)
			{
				return UniqueItems == rhs.UniqueItems;
			}
			return false;
		}

		private bool EqualsOnlyObject(JsonSchema rhs)
		{
			return true;
		}

		private void AddToAllOf(JsonSchema s)
		{
			if (AllOf == null)
			{
				AllOf = new List<JsonSchema>();
			}
			AllOf.Add(s);
		}

		private void AddToAnyOf(JsonSchema s)
		{
			if (AnyOf == null)
			{
				AnyOf = new List<JsonSchema>();
			}
			AnyOf.Add(s);
		}

		private void AddToOneOf(JsonSchema s)
		{
			if (OneOf == null)
			{
				OneOf = new List<JsonSchema>();
			}
			OneOf.Add(s);
		}

		private bool EqualsOnlySubBool(JsonSchema rhs)
		{
			if (EqualsEnumerable(AllOf, rhs.AllOf) && EqualsEnumerable(AnyOf, rhs.AnyOf) && EqualsEnumerable(OneOf, rhs.OneOf))
			{
				return object.Equals(Not, rhs.Not);
			}
			return false;
		}

		public override bool Equals(object rhsObj)
		{
			if (!(rhsObj is JsonSchema jsonSchema))
			{
				return false;
			}
			if (Title == jsonSchema.Title && Description == jsonSchema.Description && EqualsOnlyAny(jsonSchema) && EqualsOnlyNum(jsonSchema) && EqualsOnlyString(jsonSchema) && EqualsOnlyArray(jsonSchema) && EqualsOnlyObject(jsonSchema))
			{
				return EqualsOnlySubBool(jsonSchema);
			}
			return false;
		}

		public override int GetHashCode()
		{
			throw new NotImplementedException();
		}

		public override string ToString()
		{
			return new JsonSerializer(typeof(JsonSchema)).Serialize(this);
		}

		public JsonSchema()
		{
		}

		[Preserve]
		public JsonSchema(bool b)
		{
			if (!b)
			{
				Not = new JsonSchema();
			}
		}

		public static JsonSchema CreateFromType<T>(JsonSchemaRegistry reg = null, bool asRef = false)
		{
			return CreateFromType(typeof(T), reg, asRef);
		}

		public static JsonSchema CreateFromType(Type ty, JsonSchemaRegistry reg = null, bool asRef = false)
		{
			string text;
			JsonSchema jsonSchema2;
			switch (Node.KindOfType(ty))
			{
			case NodeKind.Boolean:
				return new JsonSchema
				{
					Type = "boolean"
				};
			case NodeKind.Integer:
			{
				object[] enum2 = null;
				if (TypeHelper.TypeWrap(ty).IsEnum)
				{
					enum2 = System.Enum.GetValues(ty).Cast<object>().ToArray();
				}
				return new JsonSchema
				{
					Type = "integer",
					Enum = enum2
				};
			}
			case NodeKind.Float:
				return new JsonSchema
				{
					Type = "number"
				};
			case NodeKind.String:
			{
				object[] @enum = null;
				if (TypeHelper.TypeWrap(ty).IsEnum)
				{
					object[] stringEnumNames = TypeHelper.GetStringEnumNames(ty);
					@enum = stringEnumNames;
				}
				return new JsonSchema
				{
					Type = "string",
					Enum = @enum
				};
			}
			case NodeKind.Array:
			{
				Type type = TypeHelper.ElemTypeOfIEnumerable(ty);
				return new JsonSchema
				{
					Type = "array",
					TypedItems = ((type != null) ? CreateFromType(type, reg, asRef: true) : null)
				};
			}
			case NodeKind.Object:
			{
				if (ty == typeof(object))
				{
					return new JsonSchema();
				}
				if (TypeHelper.TypeWrap(ty).IsGenericType && ty.GetGenericTypeDefinition() == typeof(Dictionary<, >))
				{
					return new JsonSchema
					{
						Type = "object"
					};
				}
				if (reg == null)
				{
					reg = new JsonSchemaRegistry();
				}
				JsonSchemaAttribute customAttribute = TypeHelper.GetCustomAttribute<JsonSchemaAttribute>(ty);
				text = customAttribute?.Id;
				if (string.IsNullOrEmpty(text))
				{
					text = ty.ToString();
				}
				JsonSchema jsonSchema = reg.Resolve(text);
				if (jsonSchema != null)
				{
					if (asRef)
					{
						return new JsonSchema
						{
							Ref = text
						};
					}
					return jsonSchema;
				}
				jsonSchema2 = CreateFromSchemaAttr(customAttribute);
				jsonSchema2.Type = "object";
				Type baseType = TypeHelper.TypeWrap(ty).BaseType;
				HashSet<string> hashSet = null;
				if (baseType != null)
				{
					if (RefChecker.IsRefTag(baseType, out var elemType))
					{
						JsonSchema jsonSchema3 = CreateFromType(elemType, reg);
						jsonSchema2.Type = jsonSchema3.Type;
						goto IL_0581;
					}
					JsonSchema jsonSchema4 = CreateFromType(baseType, reg, asRef: true);
					if (jsonSchema4 != null && jsonSchema4.Ref != null)
					{
						jsonSchema2.AddToAllOf(jsonSchema4);
						hashSet = new HashSet<string>(from f in TypeHelper.GetSerializableFields(baseType)
							select f.Name);
					}
				}
				Dictionary<string, JsonSchema> dictionary = new Dictionary<string, JsonSchema>();
				List<string> list = new List<string>();
				Dictionary<string, string[]> dictionary2 = new Dictionary<string, string[]>();
				foreach (FieldInfo serializableField in TypeHelper.GetSerializableFields(ty))
				{
					Type fieldType = serializableField.FieldType;
					string text2 = JsonFieldAttribute.FieldName(TypeHelper.GetCustomAttribute<JsonFieldAttribute>(serializableField), serializableField);
					if (hashSet != null && hashSet.Contains(serializableField.Name))
					{
						dictionary.Add(text2, new JsonSchema());
						continue;
					}
					JsonSchema jsonSchema5 = CreateFromSchemaAttr(TypeHelper.GetCustomAttribute<JsonSchemaAttribute>(serializableField));
					ItemsJsonSchemaAttribute customAttribute2 = TypeHelper.GetCustomAttribute<ItemsJsonSchemaAttribute>(serializableField);
					if (customAttribute2 != null)
					{
						jsonSchema5.TypedItems = CreateFromSchemaAttr(customAttribute2);
					}
					if (TypeHelper.GetCustomAttribute<JsonSchemaRequiredAttribute>(serializableField) != null)
					{
						list.Add(text2);
					}
					JsonSchemaDependenciesAttribute customAttribute3 = TypeHelper.GetCustomAttribute<JsonSchemaDependenciesAttribute>(serializableField);
					if (customAttribute3 != null)
					{
						dictionary2.Add(text2, customAttribute3.Dependencies);
					}
					JsonSchema jsonSchema6 = CreateFromType(fieldType, reg, asRef: true);
					if (jsonSchema6.Ref != null)
					{
						jsonSchema5 = jsonSchema6;
					}
					else
					{
						if (jsonSchema5.Type == null)
						{
							jsonSchema5.Type = jsonSchema6.Type;
						}
						if (jsonSchema5.Enum == null)
						{
							jsonSchema5.Enum = jsonSchema6.Enum;
						}
						if (jsonSchema6.Items != null)
						{
							JsonSchema jsonSchema7 = jsonSchema6.Items as JsonSchema;
							if (jsonSchema7.Ref != null)
							{
								jsonSchema5.TypedItems = jsonSchema7;
							}
							else
							{
								if (jsonSchema7.Type != null)
								{
									if (jsonSchema5.Items is JsonSchema jsonSchema8)
									{
										jsonSchema8.Type = jsonSchema7.Type;
									}
									else
									{
										jsonSchema5.TypedItems = new JsonSchema
										{
											Type = jsonSchema7.Type
										};
									}
								}
								if (jsonSchema7.Enum != null)
								{
									(jsonSchema5.Items as JsonSchema).Enum = jsonSchema7.Enum;
								}
							}
						}
					}
					JsonSchemaRefAttribute customAttribute4 = TypeHelper.GetCustomAttribute<JsonSchemaRefAttribute>(serializableField);
					if (customAttribute4 != null)
					{
						if (!RefChecker.IsRefTagDerived(customAttribute4.TagType, out var _))
						{
							throw new ArgumentException("IRefTag<T> must be derived by tagType");
						}
						JsonSchema s = CreateFromType(customAttribute4.TagType, reg, asRef: true);
						switch (customAttribute4.Influence)
						{
						case InfluenceRange.Entiry:
							jsonSchema5.AddToAllOf(s);
							break;
						case InfluenceRange.AdditionalProperties:
							if (jsonSchema5.AdditionalProperties == null)
							{
								jsonSchema5.AdditionalProperties = new JsonSchema();
							}
							jsonSchema5.AdditionalProperties.AddToAllOf(s);
							break;
						}
					}
					ItemsJsonSchemaRefAttribute customAttribute5 = TypeHelper.GetCustomAttribute<ItemsJsonSchemaRefAttribute>(serializableField);
					if (customAttribute5 != null)
					{
						if (!RefChecker.IsRefTagDerived(customAttribute5.TagType, out var _))
						{
							throw new ArgumentException("IRefTag<T> must be derived by tagType");
						}
						JsonSchema s2 = CreateFromType(customAttribute5.TagType, reg, asRef: true);
						switch (customAttribute5.Influence)
						{
						case InfluenceRange.Entiry:
							if (jsonSchema5.Items == null)
							{
								jsonSchema5.TypedItems = new JsonSchema();
							}
							((JsonSchema)jsonSchema5.Items).AddToAllOf(s2);
							break;
						case InfluenceRange.AdditionalProperties:
							if (jsonSchema5.Items == null)
							{
								jsonSchema5.TypedItems = new JsonSchema();
							}
							if (((JsonSchema)jsonSchema5.Items).AdditionalProperties == null)
							{
								((JsonSchema)jsonSchema5.Items).AdditionalProperties = new JsonSchema();
							}
							((JsonSchema)jsonSchema5.Items).AdditionalProperties.AddToAllOf(s2);
							break;
						}
					}
					dictionary.Add(text2, jsonSchema5);
				}
				jsonSchema2.Properties = dictionary;
				if (list.Count != 0)
				{
					jsonSchema2.Required = list.ToArray();
				}
				if (dictionary2.Count != 0)
				{
					jsonSchema2.Dependencies = dictionary2;
				}
				goto IL_0581;
			}
			default:
				{
					throw new NotImplementedException();
				}
				IL_0581:
				reg.Register(text, jsonSchema2);
				if (asRef)
				{
					return new JsonSchema
					{
						Ref = text
					};
				}
				return jsonSchema2;
			}
		}

		private static JsonSchema CreateFromSchemaAttr(JsonSchemaAttribute attr)
		{
			JsonSchema jsonSchema = new JsonSchema();
			if (attr == null)
			{
				return jsonSchema;
			}
			jsonSchema.Schema = attr.Schema;
			jsonSchema.Id = attr.Id;
			jsonSchema.Ref = attr.Ref;
			jsonSchema.Title = attr.Title;
			jsonSchema.Description = attr.Description;
			jsonSchema.MultipleOf = attr.MultipleOf;
			jsonSchema.Maximum = attr.Maximum;
			jsonSchema.ExclusiveMaximum = attr.ExclusiveMaximum;
			jsonSchema.Minimum = attr.Minimum;
			jsonSchema.ExclusiveMinimum = attr.ExclusiveMinimum;
			jsonSchema.MaxLength = attr.MaxLength;
			jsonSchema.MinLength = attr.MinLength;
			jsonSchema.Pattern = attr.Pattern;
			jsonSchema.MaxItems = attr.MaxItems;
			jsonSchema.MinItems = attr.MinItems;
			jsonSchema.UniqueItems = attr.UniqueItems;
			jsonSchema.MaxProperties = attr.MaxProperties;
			jsonSchema.MinProperties = attr.MinProperties;
			jsonSchema.Required = attr.Required;
			return jsonSchema;
		}

		private static bool EqualsSingletonOrArray<T>(object lhs, object rhs) where T : class
		{
			if (lhs == null && rhs == null)
			{
				return true;
			}
			if (lhs == null || rhs == null)
			{
				return false;
			}
			T[] array = lhs as T[];
			T[] array2 = rhs as T[];
			if (array != null && array2 != null)
			{
				return EqualsEnumerable(array, array2);
			}
			T objA = lhs as T;
			T objB = rhs as T;
			return object.Equals(objA, objB);
		}

		private static bool EqualsEnumerable<E>(IEnumerable<E> lhs, IEnumerable<E> rhs)
		{
			if (lhs != null || rhs != null)
			{
				if (lhs != null && lhs != null)
				{
					return lhs.SequenceEqual(rhs);
				}
				return false;
			}
			return true;
		}
	}
	public static class JsonSchemaExtensions
	{
		public static ConstraintsViolationException Validate(this JsonSchema j, object o, JsonSchemaRegistry reg = null)
		{
			return new JsonSchemaValidator(j).Validate(o, reg);
		}

		internal static ConstraintsViolationException Validate(this JsonSchema j, object o, State state, JsonSchemaRegistry reg)
		{
			return new JsonSchemaValidator(j).Validate(o, state, reg);
		}
	}
	public class RefTag<T> where T : struct
	{
	}
	internal static class RefChecker
	{
		public static bool IsRefTagDerived(Type ty, out Type elemType)
		{
			Type baseType = TypeHelper.TypeWrap(ty).BaseType;
			if (baseType != null)
			{
				return IsRefTag(baseType, out elemType);
			}
			elemType = null;
			return false;
		}

		public static bool IsRefTag(Type ty, out Type elemType)
		{
			if (TypeHelper.TypeWrap(ty).IsGenericType && ty.GetGenericTypeDefinition() == typeof(RefTag<>))
			{
				elemType = TypeHelper.TypeWrap(ty).GetGenericArguments()[0];
				return true;
			}
			elemType = null;
			return false;
		}
	}
	public sealed class JsonSchemaRegistry
	{
		private readonly Dictionary<string, JsonSchema> _registory = new Dictionary<string, JsonSchema>();

		public JsonSchema Resolve(string id)
		{
			JsonSchema value = null;
			if (_registory.TryGetValue(id, out value))
			{
				return value;
			}
			return null;
		}

		public void Register(string id, JsonSchema j)
		{
			_registory.Add(id, j);
		}

		public IEnumerable<string> GetRegisteredIDs()
		{
			return _registory.Keys;
		}
	}
	public sealed class JsonSchemaValidator
	{
		private readonly JsonSchema _schema;

		public JsonSchemaValidator(JsonSchema j)
		{
			_schema = j;
		}

		public ConstraintsViolationException Validate(object o, JsonSchemaRegistry reg = null)
		{
			return Validate(o, default(State), reg);
		}

		internal ConstraintsViolationException Validate(object o, State state, JsonSchemaRegistry reg)
		{
			if (_schema.Ref != null)
			{
				return (reg?.Resolve(_schema.Ref) ?? throw new Exception("Schema is not registered or registory is null: Ref=" + _schema.Ref)).Validate(o, state, reg);
			}
			ConstraintsViolationException ex = null;
			if (o is INode)
			{
				return Validate((o as INode).GenericContent, state, reg);
			}
			NodeKind nodeKind = Node.KindOfValue(o);
			if (_schema.Type != null)
			{
				if (_schema.Type.GetType().IsArray)
				{
					string[] array = (string[])_schema.Type;
					bool flag = false;
					string[] array2 = array;
					foreach (string typeName in array2)
					{
						if (ValidateKind(nodeKind, typeName))
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						string text = nodeKind.ToString();
						string text2 = string.Join(", ", array);
						return new ConstraintsViolationException(state.CreateMessage("Type is not contained(Actual: {0}; Expected: [{1}])", text, text2));
					}
				}
				else
				{
					string text3 = (string)_schema.Type;
					if (!ValidateKind(nodeKind, text3))
					{
						string text4 = nodeKind.ToString();
						string text5 = text3.ToString();
						return new ConstraintsViolationException(state.CreateMessage("Type is not matched(Actual: {0}; Expected: {1})", text4, text5));
					}
				}
			}
			if (_schema.Enum != null)
			{
				object lhs = o;
				if (o != null && TypeHelper.TypeWrap(o.GetType()).IsEnum && nodeKind == NodeKind.String)
				{
					lhs = TypeHelper.GetStringEnumNameOf(o);
				}
				bool flag2 = false;
				object[] @enum = _schema.Enum;
				foreach (object rhs in @enum)
				{
					if (TypeHelper.DeepEquals(lhs, rhs))
					{
						flag2 = true;
						break;
					}
				}
				if (!flag2)
				{
					return new ConstraintsViolationException(state.CreateMessage("Enum is not matched"));
				}
			}
			if (_schema.Not != null)
			{
				ex = _schema.Not.Validate(o, state, reg);
				if (ex == null)
				{
					return new ConstraintsViolationException(state.CreateMessage("Not"));
				}
			}
			if (_schema.AllOf != null)
			{
				int num = 0;
				foreach (JsonSchema item in _schema.AllOf)
				{
					ex = item.Validate(o, state, reg);
					if (ex != null)
					{
						return new ConstraintsViolationException(state.CreateMessage("AllOf[{0}] is failed", num), ex);
					}
					num++;
				}
			}
			if (_schema.AnyOf != null)
			{
				bool flag3 = false;
				foreach (JsonSchema item2 in _schema.AnyOf)
				{
					ex = item2.Validate(o, state, reg);
					if (ex == null)
					{
						flag3 = true;
						break;
					}
				}
				if (!flag3)
				{
					return new ConstraintsViolationException(state.CreateMessage("None of AnyOf is matched"));
				}
			}
			if (_schema.OneOf != null)
			{
				int num2 = -1;
				int num3 = 0;
				foreach (JsonSchema item3 in _schema.OneOf)
				{
					ex = item3.Validate(o, state, reg);
					if (ex == null)
					{
						if (num2 != -1)
						{
							return new ConstraintsViolationException(state.CreateMessage("Both of OneOf[{0}] and OneOf[{1}] are matched", num2, num3));
						}
						num2 = num3;
					}
					num3++;
				}
				if (num2 == -1)
				{
					return new ConstraintsViolationException(state.CreateMessage("None of AnyOf is matched"));
				}
			}
			switch (nodeKind)
			{
			case NodeKind.Integer:
			case NodeKind.Float:
				ex = ValidateNumber(Convert.ToDouble(o), state, reg);
				if (ex != null)
				{
					return new ConstraintsViolationException("Number", ex);
				}
				break;
			case NodeKind.String:
			{
				string v = ((o != null && TypeHelper.TypeWrap(o.GetType()).IsEnum) ? TypeHelper.GetStringEnumNameOf(o) : ((string)o));
				ex = ValidateString(v, state, reg);
				if (ex != null)
				{
					return new ConstraintsViolationException("String", ex);
				}
				break;
			}
			case NodeKind.Array:
				ex = ValidateArray(TypeHelper.ToIEnumerable(o), state, reg);
				if (ex != null)
				{
					return new ConstraintsViolationException("Array", ex);
				}
				break;
			case NodeKind.Object:
				ex = ValidateObject(o, state, reg);
				if (ex != null)
				{
					return new ConstraintsViolationException("Object", ex);
				}
				break;
			default:
				throw new NotImplementedException(nodeKind.ToString());
			case NodeKind.Boolean:
			case NodeKind.Null:
				break;
			}
			return null;
		}

		private ConstraintsViolationException ValidateNumber(double v, State state, JsonSchemaRegistry reg)
		{
			if (_schema.MultipleOf != double.MinValue)
			{
				if (_schema.MultipleOf <= 0.0)
				{
					throw new InvalidOperationException("MultipleOf must be greater than 0: Value = " + _schema.MultipleOf);
				}
				double num = v / _schema.MultipleOf;
				if (num != Math.Truncate(num))
				{
					return new ConstraintsViolationException(state.CreateMessage("MultipleOf assertion !({0} % {1} == 0)", v, _schema.MultipleOf));
				}
			}
			if (_schema.Maximum != double.MinValue && !(v <= _schema.Maximum))
			{
				return new ConstraintsViolationException(state.CreateMessage("Maximum assertion !({0} <= {1})", v, _schema.Maximum));
			}
			if (_schema.ExclusiveMaximum != double.MinValue && !(v < _schema.ExclusiveMaximum))
			{
				return new ConstraintsViolationException(state.CreateMessage("ExclusiveMaximum assertion !({0} < {1})", v, _schema.ExclusiveMaximum));
			}
			if (_schema.Minimum != double.MaxValue && !(v >= _schema.Minimum))
			{
				return new ConstraintsViolationException(state.CreateMessage("Minimum assertion !({0} >= {1})", v, _schema.Minimum));
			}
			if (_schema.ExclusiveMinimum != double.MaxValue && !(v > _schema.ExclusiveMinimum))
			{
				return new ConstraintsViolationException(state.CreateMessage("ExclusiveMinimum assertion !({0} > {1})", v, _schema.ExclusiveMinimum));
			}
			return null;
		}

		private ConstraintsViolationException ValidateString(string v, State state, JsonSchemaRegistry reg)
		{
			StringInfo stringInfo = null;
			if (_schema.MaxLength != int.MinValue)
			{
				stringInfo = stringInfo ?? new StringInfo(v);
				if (stringInfo.LengthInTextElements > _schema.MaxLength)
				{
					return new ConstraintsViolationException(state.CreateMessage("MaxLength assertion !({0} <= {1})", stringInfo.LengthInTextElements, _schema.MaxLength));
				}
			}
			if (_schema.MinLength != int.MaxValue)
			{
				stringInfo = stringInfo ?? new StringInfo(v);
				if (stringInfo.LengthInTextElements < _schema.MinLength)
				{
					return new ConstraintsViolationException(state.CreateMessage("MinLength assertion !({0} >= {1})", stringInfo.LengthInTextElements, _schema.MinLength));
				}
			}
			if (_schema.Pattern != null && !Regex.IsMatch(v, _schema.Pattern))
			{
				return new ConstraintsViolationException(state.CreateMessage("Pattern assertion !(\"{0}\" matched \"{1}\")", v, _schema.Pattern));
			}
			return null;
		}

		private ConstraintsViolationException ValidateArray(IEnumerable<object> vsIter, State state, JsonSchemaRegistry reg)
		{
			object[] array = vsIter.ToArray();
			int num = array.Length;
			if (_schema.MaxItems != int.MinValue && num > _schema.MaxItems)
			{
				return new ConstraintsViolationException(state.CreateMessage("MaxItems assertion !({0} <= {1})", num, _schema.MaxItems));
			}
			if (_schema.MinItems != int.MaxValue && num < _schema.MinItems)
			{
				return new ConstraintsViolationException(state.CreateMessage("MinItems assertion !({0} >= {1})", num, _schema.MinItems));
			}
			if (_schema.UniqueItems)
			{
				for (int i = 0; i < array.Length; i++)
				{
					for (int j = 0; j < array.Length; j++)
					{
						if (i != j && TypeHelper.DeepEquals(array[i], array[j]))
						{
							return new ConstraintsViolationException(state.CreateMessage("UniqueItems assertion: Elements at {0} and {1} are duplicated", i, j));
						}
					}
				}
			}
			List<object> list = null;
			if (_schema.Items != null)
			{
				if (_schema.Items.GetType().IsArray)
				{
					JsonSchema[] source = (JsonSchema[])_schema.Items;
					int num2 = 0;
					object[] array2 = array;
					foreach (object obj in array2)
					{
						JsonSchema jsonSchema = source.ElementAtOrDefault(num2);
						if (jsonSchema == null)
						{
							if (list == null)
							{
								list = new List<object>();
							}
							list.Add(obj);
							continue;
						}
						ConstraintsViolationException ex = jsonSchema.Validate(obj, state.NestAsElem(num2), reg);
						if (ex != null)
						{
							return new ConstraintsViolationException("Items", ex);
						}
						num2++;
					}
				}
				else
				{
					JsonSchema j2 = (JsonSchema)_schema.Items;
					int num3 = 0;
					object[] array2 = array;
					foreach (object o in array2)
					{
						ConstraintsViolationException ex2 = j2.Validate(o, state.NestAsElem(num3), reg);
						if (ex2 != null)
						{
							return new ConstraintsViolationException("Items", ex2);
						}
						num3++;
					}
				}
			}
			if (_schema.AdditionalItems != null && list != null)
			{
				foreach (object item in list)
				{
					ConstraintsViolationException ex3 = _schema.AdditionalItems.Validate(item, state, reg);
					if (ex3 != null)
					{
						return new ConstraintsViolationException("AdditionalItems", ex3);
					}
				}
			}
			return null;
		}

		private ConstraintsViolationException ValidateObject(object v, State state, JsonSchemaRegistry reg)
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>();
			foreach (KeyValuePair<string, object> item in TypeHelper.ToKeyValues(v))
			{
				ConstraintsViolationException ex = ValidateObjectField(item.Key, item.Value, state.NestAsElem(item.Key), reg);
				if (ex != null)
				{
					return ex;
				}
				dictionary.Add(item.Key, item.Value);
			}
			if (_schema.Required != null)
			{
				HashSet<string> hashSet = new HashSet<string>(_schema.Required);
				hashSet.IntersectWith(dictionary.Keys);
				if (hashSet.Count != _schema.Required.Count())
				{
					string text = string.Join(", ", hashSet.ToArray());
					string text2 = string.Join(", ", _schema.Required);
					return new ConstraintsViolationException(state.CreateMessage("Lack of required fields(Actual: [{0}]; Expected: [{1}])", text, text2));
				}
			}
			if (_schema.MaxProperties != int.MinValue && dictionary.Count > _schema.MaxProperties)
			{
				return new ConstraintsViolationException(state.CreateMessage("MaxProperties assertion !({0} <= {1})", dictionary.Count, _schema.MaxProperties));
			}
			if (_schema.MinProperties != int.MaxValue && dictionary.Count < _schema.MinProperties)
			{
				return new ConstraintsViolationException(state.CreateMessage("MaxProperties assertion !({0} >= {1})", dictionary.Count, _schema.MinProperties));
			}
			if (_schema.Dependencies != null)
			{
				if (_schema.Dependencies is Dictionary<string, string[]> dictionary2)
				{
					foreach (KeyValuePair<string, object> item2 in dictionary)
					{
						string[] value = null;
						if (dictionary2.TryGetValue(item2.Key, out value))
						{
							IEnumerable<string> source = ((string[])value.Clone()).Intersect(dictionary.Keys);
							if (source.Count() != value.Count())
							{
								string text3 = string.Join(", ", source.ToArray());
								string text4 = string.Join(", ", value);
								return new ConstraintsViolationException(state.CreateMessage("Dependencies assertion. Lack of depended fields for {0}(Actual: [{1}]; Expected: [{2}])", item2.Key, text3, text4));
							}
						}
					}
				}
				else if (_schema.Dependencies is Dictionary<string, JsonSchema> dictionary3)
				{
					foreach (KeyValuePair<string, object> item3 in dictionary)
					{
						JsonSchema value2 = null;
						if (dictionary3.TryGetValue(item3.Key, out value2))
						{
							ConstraintsViolationException ex2 = value2.Validate(v, default(State).NestAsElem(item3.Key), reg);
							if (ex2 != null)
							{
								return new ConstraintsViolationException(state.CreateMessage("Dependencies assertion. Failed to validation for {0}", item3.Key), ex2);
							}
						}
					}
				}
			}
			return null;
		}

		private ConstraintsViolationException ValidateObjectField(string key, object value, State state, JsonSchemaRegistry reg)
		{
			bool flag = false;
			if (_schema.Properties != null)
			{
				JsonSchema value2 = null;
				if (_schema.Properties.TryGetValue(key, out value2))
				{
					flag = true;
					ConstraintsViolationException ex = value2.Validate(value, state, reg);
					if (ex != null)
					{
						return new ConstraintsViolationException("Property", ex);
					}
				}
			}
			if (_schema.PatternProperties != null)
			{
				foreach (KeyValuePair<string, JsonSchema> patternProperty in _schema.PatternProperties)
				{
					if (Regex.IsMatch(key, patternProperty.Key))
					{
						flag = true;
						ConstraintsViolationException ex2 = patternProperty.Value.Validate(value, state, reg);
						if (ex2 != null)
						{
							return new ConstraintsViolationException("PatternProperties", ex2);
						}
					}
				}
			}
			if (_schema.AdditionalProperties != null && !flag)
			{
				ConstraintsViolationException ex3 = _schema.AdditionalProperties.Validate(value, state, reg);
				if (ex3 != null)
				{
					return new ConstraintsViolationException("AdditionalProperties", ex3);
				}
			}
			return null;
		}

		private static bool ValidateKind(NodeKind kind, string typeName)
		{
			switch (typeName)
			{
			case "null":
				return kind == NodeKind.Null;
			case "boolean":
				return kind == NodeKind.Boolean;
			case "object":
				return kind == NodeKind.Object;
			case "array":
				return kind == NodeKind.Array;
			case "number":
				if (kind != NodeKind.Integer)
				{
					return kind == NodeKind.Float;
				}
				return true;
			case "string":
				return kind == NodeKind.String;
			case "integer":
				return kind == NodeKind.Integer;
			default:
				throw new NotImplementedException();
			}
		}
	}
	public class ConstraintsViolationException : Exception
	{
		public ConstraintsViolationException(string message)
			: base(message)
		{
		}

		public ConstraintsViolationException(string message, ConstraintsViolationException inner)
			: base($"{message}.{inner.Message}")
		{
		}
	}
}
namespace VJson.Internal
{
	internal struct State
	{
		private string _elemName;

		private string ElemName
		{
			get
			{
				if (string.IsNullOrEmpty(_elemName))
				{
					return "(root)";
				}
				return _elemName;
			}
		}

		internal State NestAsElem(int elem)
		{
			State result = default(State);
			result._elemName = $"{ElemName}[{elem}]";
			return result;
		}

		internal State NestAsElem(string elem)
		{
			State result = default(State);
			result._elemName = $"{ElemName}[\"{elem}\"]";
			return result;
		}

		internal string CreateMessage(string format, params object[] args)
		{
			return $"{ElemName}: {string.Format(format, args)}.";
		}
	}
	internal static class StateExtension
	{
		public static string CreateNodeConversionFailureMessage(this State s, INode fromNode, IEnumerable<Type> toTypes)
		{
			string toDetail = string.Format("one of [{0}]", string.Join(", ", toTypes.Select((Type t) => t.ToString()).ToArray()));
			return s.CreateNodeConversionFailureMessage(fromNode, toDetail);
		}

		public static string CreateNodeConversionFailureMessage(this State s, INode fromNode, Type toType)
		{
			string text = toType.ToString();
			if (fromNode.Kind == NodeKind.Null && !TypeHelper.IsBoxed(toType))
			{
				text = $"non-boxed value({text})";
			}
			return s.CreateNodeConversionFailureMessage(fromNode, text);
		}

		private static string CreateNodeConversionFailureMessage(this State s, INode fromNode, string toDetail)
		{
			string text = $"{fromNode.Kind} node";
			switch (fromNode.Kind)
			{
			case NodeKind.Boolean:
				text = $"{text} ({((BooleanNode)fromNode).Value})";
				break;
			case NodeKind.Integer:
				text = $"{text} ({((IntegerNode)fromNode).Value})";
				break;
			case NodeKind.Float:
				text = $"{text} ({((FloatNode)fromNode).Value})";
				break;
			}
			return s.CreateMessage("{0} cannot convert to {1}", text, toDetail);
		}

		public static string CreateTypeConversionFailureMessage<T>(this State s, T fromValue, Type toType, string reason = null)
		{
			string arg = $"{typeof(T).ToString()} value";
			NodeKind nodeKind = Node.KindOfType(typeof(T));
			if ((uint)(nodeKind - 3) <= 2u)
			{
				arg = $"{arg} ({fromValue})";
			}
			string text = $"{arg} cannot convert to {toType}";
			if (reason != null)
			{
				text = $"{text} (Reason: {reason})";
			}
			return s.CreateMessage(text);
		}
	}
}