Decompiled source of MicControl v1.0.0

MicControl.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dissonance.Config;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 MicControl
{
	internal static class AudioProcessor
	{
		private static volatile float _gain = 1f;

		private static volatile float _gateThresholdRms;

		private const int HoldFrames = 20;

		private const float ReleasePerSample = 0.00041666668f;

		private const float AttackPerSample = 0.004166667f;

		private static int _holdLeft;

		private static float _gateGain = 1f;

		public static void Refresh()
		{
			_gain = (float)Plugin.MicVolume.Value / 100f;
			int value = Plugin.GateThreshold.Value;
			_gateThresholdRms = ((value <= 0) ? 0f : ((float)Math.Pow(10.0, (-70.0 + 45.0 * (double)(value - 1) / 99.0) / 20.0)));
		}

		public static void Process(float[] frame)
		{
			float gain = _gain;
			float gateThresholdRms = _gateThresholdRms;
			if (gain != 1f)
			{
				for (int i = 0; i < frame.Length; i++)
				{
					float num = frame[i] * gain;
					frame[i] = ((num > 1f) ? 1f : ((num < -1f) ? (-1f) : num));
				}
			}
			if (gateThresholdRms <= 0f)
			{
				_gateGain = 1f;
				_holdLeft = 0;
				return;
			}
			double num2 = 0.0;
			for (int j = 0; j < frame.Length; j++)
			{
				num2 += (double)(frame[j] * frame[j]);
			}
			bool flag = (float)Math.Sqrt(num2 / (double)frame.Length) >= gateThresholdRms;
			if (flag)
			{
				_holdLeft = 20;
			}
			else if (_holdLeft > 0)
			{
				_holdLeft--;
				flag = true;
			}
			float num3 = (flag ? 1f : 0f);
			for (int k = 0; k < frame.Length; k++)
			{
				if (_gateGain < num3)
				{
					_gateGain = Math.Min(num3, _gateGain + 0.004166667f);
				}
				else if (_gateGain > num3)
				{
					_gateGain = Math.Max(num3, _gateGain - 0.00041666668f);
				}
				frame[k] *= _gateGain;
			}
		}
	}
	[HarmonyPatch]
	internal static class PreprocessPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(AccessTools.TypeByName("Dissonance.Audio.Capture.WebRtcPreprocessingPipeline"), "PreprocessAudioFrame", (Type[])null, (Type[])null);
		}

		private static void Postfix(float[] frame)
		{
			MicMonitor.Push(frame);
		}

		private static void Prefix(float[] frame)
		{
			AudioProcessor.Process(frame);
		}
	}
	[HarmonyPatch(typeof(SettingsOption), "OnEnable")]
	internal static class MenuInjector
	{
		private const string Marker = "MicControl_Row_";

		private static bool _injecting;

		private const float ShiftX = 18f;

		private static void Postfix(SettingsOption __instance)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			if (_injecting || (Object)(object)__instance == (Object)null || (int)__instance.optionType != 3)
			{
				return;
			}
			try
			{
				_injecting = true;
				Inject(__instance);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Could not add mic sliders: {arg}");
			}
			finally
			{
				_injecting = false;
			}
		}

		private static void Inject(SettingsOption anchor)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			Transform anchorTf = ((Component)anchor).transform;
			Transform parent = anchorTf.parent;
			if ((Object)(object)parent == (Object)null)
			{
				return;
			}
			foreach (Transform item in parent)
			{
				if (((Object)item).name.StartsWith("MicControl_Row_"))
				{
					return;
				}
			}
			SettingsOption val = (from o in Object.FindObjectsOfType<SettingsOption>(true)
				where (int)o.optionType == 0 && !((Object)o).name.StartsWith("MicControl_Row_")
				orderby (Object)(object)((Component)o).transform.root == (Object)(object)anchorTf.root descending
				select o).FirstOrDefault();
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"No slider template (look sensitivity) found, sliders not added.");
				return;
			}
			DumpHierarchy(anchor, val);
			RectTransform val2 = (RectTransform)anchorTf;
			RectTransform val3 = (RectTransform)((Component)val).transform;
			float[] array = new float[3];
			Rect rect = val3.rect;
			array[0] = ((Rect)(ref rect)).height;
			rect = val2.rect;
			array[1] = ((Rect)(ref rect)).height;
			array[2] = 30f;
			float step = Mathf.Max(array);
			AddRow(val, parent, val2, 2.9f, step, "MicVolume", "MIC VOLUME", 0, 300, Plugin.MicVolume, "%");
			AddRow(val, parent, val2, 4.15f, step, "NoiseGate", "NOISE GATE", 0, 100, Plugin.GateThreshold, "");
			AddRow(val, parent, val2, 5.4f, step, "NoiseSuppression", "NOISE SUPPRESSION", 0, 100, Plugin.NoiseSuppression, "%");
			AddTestButton(anchor, parent, step, 6.9f);
			AddInfoText(val, parent, step);
			AddFrame(parent, step);
		}

		private static void AddInfoText(SettingsOption template, Transform parent, float step)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			Transform val = parent.Find("MicControl_Row_MicTest");
			TextMeshProUGUI val2 = ((IEnumerable<TextMeshProUGUI>)((Component)((Component)template).transform.parent).GetComponentsInChildren<TextMeshProUGUI>(true)).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI t) => !((TMP_Text)t).transform.IsChildOf(((Component)template).transform)));
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				RectTransform val3 = (RectTransform)val;
				GameObject obj = Object.Instantiate<GameObject>(((Component)val2).gameObject, parent);
				((Object)obj).name = "MicControl_Row_MicTestInfo";
				obj.SetActive(true);
				RectTransform val4 = (RectTransform)obj.transform;
				val4.anchorMin = val3.anchorMin;
				val4.anchorMax = val3.anchorMax;
				val4.pivot = new Vector2(0.5f, 1f);
				((Transform)val4).localScale = Vector3.one;
				Rect rect = val3.rect;
				val4.sizeDelta = new Vector2(((Rect)(ref rect)).width * 1.3f, step * 0.7f);
				float x = ((Transform)val3).localPosition.x;
				float y = ((Transform)val3).localPosition.y;
				rect = val3.rect;
				((Transform)val4).localPosition = new Vector3(x, y - ((Rect)(ref rect)).height * 0.5f - step * 0.1f, 0f);
				TextMeshProUGUI component = obj.GetComponent<TextMeshProUGUI>();
				((TMP_Text)component).text = "MIC TEST only works in-game.";
				((TMP_Text)component).fontSize = ((TMP_Text)val2).fontSize * 0.55f;
				((TMP_Text)component).alignment = (TextAlignmentOptions)258;
				((TMP_Text)component).enableWordWrapping = true;
				((TMP_Text)component).overflowMode = (TextOverflowModes)0;
				((Graphic)component).color = new Color(((Graphic)component).color.r, ((Graphic)component).color.g, ((Graphic)component).color.b, 0.7f);
			}
		}

		private static void AddFrame(Transform parent, float step)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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)
			//IL_0079: Expected O, but got Unknown
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: 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_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			Transform val = parent.Find("BoxFrame");
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"BoxFrame not found, no frame added.");
				return;
			}
			bool flag = false;
			Vector2 val2 = Vector2.zero;
			Vector2 val3 = Vector2.zero;
			float? num = null;
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			RectTransform val4 = null;
			foreach (Transform item in parent)
			{
				Transform val5 = item;
				if (!((Object)val5).name.StartsWith("MicControl_Row_"))
				{
					continue;
				}
				RectTransform val6 = (RectTransform)(object)((val5 is RectTransform) ? val5 : null);
				if ((Object)(object)val6 == (Object)null)
				{
					continue;
				}
				val4 = val4 ?? val6;
				val6.GetWorldCorners(array);
				Vector3[] array2 = array;
				foreach (Vector3 val7 in array2)
				{
					Vector3 val8 = parent.InverseTransformPoint(val7);
					if (!flag)
					{
						val2 = (val3 = Vector2.op_Implicit(val8));
						flag = true;
					}
					val2 = Vector2.Min(val2, Vector2.op_Implicit(val8));
					val3 = Vector2.Max(val3, Vector2.op_Implicit(val8));
					if (!((Object)val5).name.EndsWith("_Label") && !((Object)val5).name.EndsWith("Info"))
					{
						num = (num.HasValue ? Mathf.Max(num.Value, val8.x) : val8.x);
					}
				}
			}
			if (flag)
			{
				float num2 = step * 0.25f;
				float num3 = step * 0.2f;
				float num4 = step * 0.9f;
				val2 -= new Vector2(num2, num3);
				val3 += new Vector2(num2, num4);
				if (num.HasValue)
				{
					val3.x = num.Value + num2;
				}
				_ = (RectTransform)val;
				GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
				((Object)obj).name = "MicControl_Row_Box";
				obj.SetActive(true);
				RectTransform val9 = (RectTransform)obj.transform;
				val9.anchorMin = val4.anchorMin;
				val9.anchorMax = val4.anchorMax;
				val9.pivot = new Vector2(0.5f, 0.5f);
				((Transform)val9).localScale = Vector3.one;
				val9.SetSizeWithCurrentAnchors((Axis)0, val3.x - val2.x);
				val9.SetSizeWithCurrentAnchors((Axis)1, val3.y - val2.y);
				((Transform)val9).localPosition = new Vector3((val2.x + val3.x) / 2f, (val2.y + val3.y) / 2f, 0f);
				obj.transform.SetAsFirstSibling();
				TextMeshProUGUI val10 = (from t in Object.FindObjectsOfType<TextMeshProUGUI>(true)
					where (Object)(object)((TMP_Text)t).transform.root == (Object)(object)parent.root && ((TMP_Text)t).text != null && ((TMP_Text)t).text.Trim().ToUpper() == "CONTROLS"
					select t).FirstOrDefault();
				if (!((Object)(object)val10 == (Object)null))
				{
					GameObject obj2 = Object.Instantiate<GameObject>(((Component)val10).gameObject, parent);
					((Object)obj2).name = "MicControl_Row_Title";
					obj2.SetActive(true);
					RectTransform val11 = (RectTransform)obj2.transform;
					val11.anchorMin = val4.anchorMin;
					val11.anchorMax = val4.anchorMax;
					val11.pivot = new Vector2(0f, 1f);
					((Transform)val11).localScale = Vector3.one;
					((Transform)val11).localPosition = new Vector3(val2.x + num2 * 1.6f, val3.y - step * 0.12f, 0f);
					TextMeshProUGUI component = obj2.GetComponent<TextMeshProUGUI>();
					((TMP_Text)component).text = "MIC CONTROL";
					((TMP_Text)component).enableWordWrapping = false;
					((TMP_Text)component).overflowMode = (TextOverflowModes)0;
				}
			}
		}

		private static void AddTestButton(SettingsOption anchor, Transform parent, float step, float index)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0037: 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_003e: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0062: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(((Component)anchor).gameObject, parent);
			((Object)val).name = "MicControl_Row_MicTest";
			val.SetActive(true);
			RectTransform val2 = (RectTransform)((Component)anchor).transform;
			RectTransform val3 = (RectTransform)val.transform;
			val3.anchorMin = val2.anchorMin;
			val3.anchorMax = val2.anchorMax;
			val3.pivot = val2.pivot;
			val3.sizeDelta = val2.sizeDelta;
			((Transform)val3).localScale = Vector3.one;
			val3.anchoredPosition = val2.anchoredPosition + new Vector2(18f, (0f - step) * index);
			val.GetComponent<SettingsOption>().optionType = (SettingsOptionType)2;
			Button componentInChildren = val.GetComponentInChildren<Button>(true);
			TextMeshProUGUI text = val.GetComponentInChildren<TextMeshProUGUI>(true);
			if ((Object)(object)componentInChildren == (Object)null || (Object)(object)text == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Push-to-talk button has no Button/Text, mic test button not added.");
				return;
			}
			for (int i = 0; i < ((UnityEventBase)componentInChildren.onClick).GetPersistentEventCount(); i++)
			{
				((UnityEventBase)componentInChildren.onClick).SetPersistentListenerState(i, (UnityEventCallState)0);
			}
			((UnityEventBase)componentInChildren.onClick).RemoveAllListeners();
			Show();
			((UnityEvent)componentInChildren.onClick).AddListener((UnityAction)delegate
			{
				MicMonitor.SetEnabled(!MicMonitor.Enabled);
				Show();
			});
			void Show()
			{
				((TMP_Text)text).text = (MicMonitor.Enabled ? "MIC TEST: ON" : "MIC TEST: OFF");
			}
		}

		private static void AddRow(SettingsOption template, Transform parent, RectTransform anchorRect, float index, float step, string id, string label, int min, int max, ConfigEntry<int> entry, string unit)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_005d: 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)
			//IL_0075: 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)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			//IL_01b0: 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_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: 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_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(((Component)template).gameObject, parent);
			((Object)obj).name = "MicControl_Row_" + id;
			obj.SetActive(true);
			RectTransform val = (RectTransform)obj.transform;
			val.anchorMin = anchorRect.anchorMin;
			val.anchorMax = anchorRect.anchorMax;
			val.pivot = anchorRect.pivot;
			val.anchoredPosition = anchorRect.anchoredPosition + new Vector2(18f, (0f - step) * index);
			((Transform)val).localScale = Vector3.one;
			obj.GetComponent<SettingsOption>().optionType = (SettingsOptionType)2;
			Slider componentInChildren = obj.GetComponentInChildren<Slider>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				Plugin.Log.LogWarning((object)("Template has no slider (" + id + ")"));
				return;
			}
			for (int i = 0; i < ((UnityEventBase)componentInChildren.onValueChanged).GetPersistentEventCount(); i++)
			{
				((UnityEventBase)componentInChildren.onValueChanged).SetPersistentListenerState(i, (UnityEventCallState)0);
			}
			((UnityEventBase)componentInChildren.onValueChanged).RemoveAllListeners();
			componentInChildren.minValue = min;
			componentInChildren.maxValue = max;
			componentInChildren.wholeNumbers = true;
			TextMeshProUGUI text = null;
			TextMeshProUGUI val2 = ((IEnumerable<TextMeshProUGUI>)((Component)((Component)template).transform.parent).GetComponentsInChildren<TextMeshProUGUI>(true)).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI t) => !((TMP_Text)t).transform.IsChildOf(((Component)template).transform)));
			if ((Object)(object)val2 != (Object)null)
			{
				GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, parent);
				((Object)val3).name = "MicControl_Row_" + id + "_Label";
				val3.SetActive(true);
				RectTransform val4 = (RectTransform)val3.transform;
				RectTransform val5 = (RectTransform)((TMP_Text)val2).transform;
				val4.anchorMin = val.anchorMin;
				val4.anchorMax = val.anchorMax;
				val4.pivot = val5.pivot;
				val4.sizeDelta = val5.sizeDelta;
				((Transform)val4).localScale = Vector3.one;
				((Transform)val4).localPosition = ((Transform)val).localPosition + (((Transform)val5).localPosition - ((Component)template).transform.localPosition);
				text = val3.GetComponent<TextMeshProUGUI>();
			}
			componentInChildren.SetValueWithoutNotify((float)entry.Value);
			Show(entry.Value);
			((UnityEvent<float>)(object)componentInChildren.onValueChanged).AddListener((UnityAction<float>)delegate(float value)
			{
				int num = Mathf.RoundToInt(value);
				entry.Value = num;
				Show(num);
				AudioProcessor.Refresh();
			});
			void Show(int v)
			{
				if ((Object)(object)text != (Object)null)
				{
					((TMP_Text)text).text = $"{label}: {v}{unit}";
				}
			}
		}

		private static void DumpHierarchy(SettingsOption anchor, SettingsOption template)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("[MicControl] anchor: " + PathOf(((Component)anchor).transform));
			stringBuilder.AppendLine("[MicControl] template: " + PathOf(((Component)template).transform));
			foreach (Transform item in ((Component)anchor).transform.parent)
			{
				Transform val = item;
				RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
				object[] obj = new object[4]
				{
					((Object)val).name,
					((Object)(object)val2 != (Object)null) ? ((object)val2.anchoredPosition/*cast due to .constrained prefix*/).ToString() : "-",
					null,
					null
				};
				object obj2;
				if (!((Object)(object)val2 != (Object)null))
				{
					obj2 = "-";
				}
				else
				{
					Rect rect = val2.rect;
					obj2 = ((object)((Rect)(ref rect)).size/*cast due to .constrained prefix*/).ToString();
				}
				obj[2] = obj2;
				obj[3] = ((Component)val).GetComponent<SettingsOption>()?.optionType;
				stringBuilder.AppendLine(string.Format("  sibling '{0}' pos={1} size={2} opt={3}", obj));
			}
			TextMeshProUGUI[] componentsInChildren = ((Component)template).GetComponentsInChildren<TextMeshProUGUI>(true);
			foreach (TextMeshProUGUI val3 in componentsInChildren)
			{
				stringBuilder.AppendLine("  template text '" + ((Object)val3).name + "' = '" + ((TMP_Text)val3).text + "'");
			}
			Plugin.Log.LogInfo((object)stringBuilder.ToString());
		}

		private static string PathOf(Transform t)
		{
			StringBuilder stringBuilder = new StringBuilder(((Object)t).name);
			while ((Object)(object)t.parent != (Object)null)
			{
				t = t.parent;
				stringBuilder.Insert(0, ((Object)t).name + "/");
			}
			return stringBuilder.ToString();
		}
	}
	internal class MicMonitor : MonoBehaviour
	{
		private const int InputRate = 48000;

		private const int Capacity = 48000;

		private const int PrimeSamples = 3200;

		private const int MaxBuffered = 9600;

		private static readonly object Lock = new object();

		private static readonly float[] Ring = new float[48000];

		private static long _write;

		private static double _read;

		private static bool _primed;

		private static volatile bool _enabled;

		private static MicMonitor _instance;

		private double _ratio = 1.0;

		public static bool Enabled => _enabled;

		public static void SetEnabled(bool value)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (value)
			{
				if ((Object)(object)_instance == (Object)null)
				{
					GameObject val = new GameObject("MicControl_Monitor");
					Object.DontDestroyOnLoad((Object)val);
					_instance = val.AddComponent<MicMonitor>();
				}
				lock (Lock)
				{
					_read = _write;
					_primed = false;
				}
				_enabled = true;
			}
			else
			{
				_enabled = false;
			}
		}

		private void Awake()
		{
			_ratio = 48000.0 / (double)AudioSettings.outputSampleRate;
			AudioClip clip = AudioClip.Create("MicControl_Silence", 1024, 1, AudioSettings.outputSampleRate, false);
			AudioSource obj = ((Component)this).gameObject.AddComponent<AudioSource>();
			obj.clip = clip;
			obj.loop = true;
			obj.spatialBlend = 0f;
			obj.playOnAwake = false;
			obj.ignoreListenerPause = true;
			obj.Play();
		}

		public static void Push(float[] frame)
		{
			if (!_enabled)
			{
				return;
			}
			lock (Lock)
			{
				for (int i = 0; i < frame.Length; i++)
				{
					Ring[(_write + i) % 48000] = frame[i];
				}
				_write += frame.Length;
				if ((double)_write - _read > 9600.0)
				{
					_read = _write - 3200;
				}
			}
		}

		private void OnAudioFilterRead(float[] data, int channels)
		{
			int num = data.Length / channels;
			if (!_enabled)
			{
				Array.Clear(data, 0, data.Length);
				return;
			}
			lock (Lock)
			{
				double num2 = (double)_write - _read;
				if (!_primed)
				{
					if (num2 < 3200.0)
					{
						Array.Clear(data, 0, data.Length);
						return;
					}
					_primed = true;
				}
				if (num2 < (double)num * _ratio + 2.0)
				{
					_primed = false;
					Array.Clear(data, 0, data.Length);
					return;
				}
				for (int i = 0; i < num; i++)
				{
					long num3 = (long)_read;
					float num4 = (float)(_read - (double)num3);
					float num5 = Ring[num3 % 48000];
					float num6 = Ring[(num3 + 1) % 48000];
					float num7 = num5 + (num6 - num5) * num4;
					for (int j = 0; j < channels; j++)
					{
						data[i * channels + j] = num7;
					}
					_read += _ratio;
				}
			}
		}
	}
	[BepInPlugin("nergy.miccontrol", "MicControl", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "nergy.miccontrol";

		public const string Name = "MicControl";

		public const string Version = "1.0.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<int> MicVolume;

		internal static ConfigEntry<int> GateThreshold;

		internal static ConfigEntry<int> NoiseSuppression;

		private int _appliedSuppression = -1;

		private void Awake()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			MicVolume = ((BaseUnityPlugin)this).Config.Bind<int>("Mic", "MicVolume", 100, new ConfigDescription("Microphone input volume in percent.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>()));
			GateThreshold = ((BaseUnityPlugin)this).Config.Bind<int>("Mic", "NoiseGate", 0, new ConfigDescription("Noise gate threshold (0 = off, 100 = very strict).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			NoiseSuppression = ((BaseUnityPlugin)this).Config.Bind<int>("Mic", "NoiseSuppression", 0, new ConfigDescription("RNNoise background noise removal in percent (0 = off).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			AudioProcessor.Refresh();
			new Harmony("nergy.miccontrol").PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"MicControl 1.0.0 loaded");
		}

		private void Update()
		{
			ApplySuppression();
		}

		internal void ApplySuppression()
		{
			int value = NoiseSuppression.Value;
			if (value == _appliedSuppression)
			{
				return;
			}
			try
			{
				VoiceSettings instance = VoiceSettings.Instance;
				if (!((Object)(object)instance == (Object)null))
				{
					instance.BackgroundSoundRemovalEnabled = value > 0;
					instance.BackgroundSoundRemovalAmount = (float)value / 100f;
					_appliedSuppression = value;
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Could not apply noise suppression yet: " + ex.Message));
			}
		}
	}
}