Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RiskOfMusic v1.0.0
NAudio.dll
Decompiled 6 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Windows.Forms; using Microsoft.Win32; using NAudio.CoreAudioApi; using NAudio.CoreAudioApi.Interfaces; using NAudio.Dmo; using NAudio.Dsp; using NAudio.FileFormats.Wav; using NAudio.MediaFoundation; using NAudio.Mixer; using NAudio.Utils; using NAudio.Wave; using NAudio.Wave.Asio; using NAudio.Wave.Compression; using NAudio.Wave.SampleProviders; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("NAudio")] [assembly: AssemblyDescription("NAudio .NET Audio Library")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Mark Heath")] [assembly: AssemblyProduct("NAudio")] [assembly: AssemblyCopyright("© 2001-2017 Mark Heath")] [assembly: AssemblyTrademark("")] [assembly: InternalsVisibleTo("NAudioTests")] [assembly: ComVisible(false)] [assembly: Guid("e82fa7f0-f952-4d93-b7b0-392bbf53b2a4")] [assembly: AssemblyFileVersion("1.8.4.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.8.4.0")] [module: UnverifiableCode] namespace NAudio { public enum Manufacturers { Microsoft = 1, Creative = 2, Mediavision = 3, Fujitsu = 4, Artisoft = 20, TurtleBeach = 21, Ibm = 22, Vocaltec = 23, Roland = 24, DspSolutions = 25, Nec = 26, Ati = 27, Wanglabs = 28, Tandy = 29, Voyetra = 30, Antex = 31, IclPS = 32, Intel = 33, Gravis = 34, Val = 35, Interactive = 36, Yamaha = 37, Everex = 38, Echo = 39, Sierra = 40, Cat = 41, Apps = 42, DspGroup = 43, Melabs = 44, ComputerFriends = 45, Ess = 46, Audiofile = 47, Motorola = 48, Canopus = 49, Epson = 50, Truevision = 51, Aztech = 52, Videologic = 53, Scalacs = 54, Korg = 55, Apt = 56, Ics = 57, Iteratedsys = 58, Metheus = 59, Logitech = 60, Winnov = 61, Ncr = 62, Exan = 63, Ast = 64, Willowpond = 65, Sonicfoundry = 66, Vitec = 67, Moscom = 68, Siliconsoft = 69, Supermac = 73, Audiopt = 74, Speechcomp = 76, Ahead = 77, Dolby = 78, Oki = 79, Auravision = 80, Olivetti = 81, Iomagic = 82, Matsushita = 83, Controlres = 84, Xebec = 85, Newmedia = 86, Nms = 87, Lyrrus = 88, Compusic = 89, Opti = 90, Adlacc = 91, Compaq = 92, Dialogic = 93, Insoft = 94, Mptus = 95, Weitek = 96, LernoutAndHauspie = 97, Qciar = 98, Apple = 99, Digital = 100, Motu = 101, Workbit = 102, Ositech = 103, Miro = 104, Cirruslogic = 105, Isolution = 106, Horizons = 107, Concepts = 108, Vtg = 109, Radius = 110, Rockwell = 111, Xyz = 112, Opcode = 113, Voxware = 114, NorthernTelecom = 115, Apicom = 116, Grande = 117, Addx = 118, Wildcat = 119, Rhetorex = 120, Brooktree = 121, Ensoniq = 125, Fast = 126, Nvidia = 127, Oksori = 128, Diacoustics = 129, Gulbransen = 130, KayElemetrics = 131, Crystal = 132, SplashStudios = 133, Quarterdeck = 134, Tdk = 135, DigitalAudioLabs = 136, Seersys = 137, Picturetel = 138, AttMicroelectronics = 139, Osprey = 140, Mediatrix = 141, Soundesigns = 142, Aldigital = 143, SpectrumSignalProcessing = 144, Ecs = 145, Amd = 146, Coredynamics = 147, Canam = 148, Softsound = 149, Norris = 150, Ddd = 151, Euphonics = 152, Precept = 153, CrystalNet = 154, Chromatic = 155, Voiceinfo = 156, Viennasys = 157, Connectix = 158, Gadgetlabs = 159, Frontier = 160, Viona = 161, Casio = 162, Diamondmm = 163, S3 = 164, FraunhoferIis = 172 } public class MmException : Exception { private MmResult result; private string function; public MmResult Result => result; public MmException(MmResult result, string function) : base(ErrorMessage(result, function)) { this.result = result; this.function = function; } private static string ErrorMessage(MmResult result, string function) { return $"{result} calling {function}"; } public static void Try(MmResult result, string function) { if (result != 0) { throw new MmException(result, function); } } } public enum MmResult { NoError = 0, UnspecifiedError = 1, BadDeviceId = 2, NotEnabled = 3, AlreadyAllocated = 4, InvalidHandle = 5, NoDriver = 6, MemoryAllocationError = 7, NotSupported = 8, BadErrorNumber = 9, InvalidFlag = 10, InvalidParameter = 11, HandleBusy = 12, InvalidAlias = 13, BadRegistryDatabase = 14, RegistryKeyNotFound = 15, RegistryReadError = 16, RegistryWriteError = 17, RegistryDeleteError = 18, RegistryValueNotFound = 19, NoDriverCallback = 20, MoreData = 21, WaveBadFormat = 32, WaveStillPlaying = 33, WaveHeaderUnprepared = 34, WaveSync = 35, AcmNotPossible = 512, AcmBusy = 513, AcmHeaderUnprepared = 514, AcmCancelled = 515, MixerInvalidLine = 1024, MixerInvalidControl = 1025, MixerInvalidValue = 1026 } } namespace NAudio.Mixer { public class BooleanMixerControl : MixerControl { private MixerInterop.MIXERCONTROLDETAILS_BOOLEAN boolDetails; public bool Value { get { GetControlDetails(); return boolDetails.fValue == 1; } set { boolDetails.fValue = (value ? 1 : 0); mixerControlDetails.paDetails = Marshal.AllocHGlobal(Marshal.SizeOf((object)boolDetails)); Marshal.StructureToPtr((object)boolDetails, mixerControlDetails.paDetails, fDeleteOld: false); MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails"); Marshal.FreeHGlobal(mixerControlDetails.paDetails); } } internal BooleanMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { boolDetails = (MixerInterop.MIXERCONTROLDETAILS_BOOLEAN)Marshal.PtrToStructure(pDetails, typeof(MixerInterop.MIXERCONTROLDETAILS_BOOLEAN)); } } public class CustomMixerControl : MixerControl { internal CustomMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { } } public class ListTextMixerControl : MixerControl { internal ListTextMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { } } public class Mixer { private MixerInterop.MIXERCAPS caps; private IntPtr mixerHandle; private MixerFlags mixerHandleType; public static int NumberOfDevices => MixerInterop.mixerGetNumDevs(); public int DestinationCount => (int)caps.cDestinations; public string Name => caps.szPname; public Manufacturers Manufacturer => (Manufacturers)caps.wMid; public int ProductID => caps.wPid; public IEnumerable<MixerLine> Destinations { get { for (int destination = 0; destination < DestinationCount; destination++) { yield return GetDestination(destination); } } } public static IEnumerable<Mixer> Mixers { get { for (int device = 0; device < NumberOfDevices; device++) { yield return new Mixer(device); } } } public Mixer(int mixerIndex) { if (mixerIndex < 0 || mixerIndex >= NumberOfDevices) { throw new ArgumentOutOfRangeException("mixerID"); } caps = default(MixerInterop.MIXERCAPS); MmException.Try(MixerInterop.mixerGetDevCaps((IntPtr)mixerIndex, ref caps, Marshal.SizeOf((object)caps)), "mixerGetDevCaps"); mixerHandle = (IntPtr)mixerIndex; mixerHandleType = MixerFlags.Mixer; } public MixerLine GetDestination(int destinationIndex) { if (destinationIndex < 0 || destinationIndex >= DestinationCount) { throw new ArgumentOutOfRangeException("destinationIndex"); } return new MixerLine(mixerHandle, destinationIndex, mixerHandleType); } } public abstract class MixerControl { internal MixerInterop.MIXERCONTROL mixerControl; internal MixerInterop.MIXERCONTROLDETAILS mixerControlDetails; protected IntPtr mixerHandle; protected int nChannels; protected MixerFlags mixerHandleType; public string Name => mixerControl.szName; public MixerControlType ControlType => mixerControl.dwControlType; public bool IsBoolean => IsControlBoolean(mixerControl.dwControlType); public bool IsListText => IsControlListText(mixerControl.dwControlType); public bool IsSigned => IsControlSigned(mixerControl.dwControlType); public bool IsUnsigned => IsControlUnsigned(mixerControl.dwControlType); public bool IsCustom => IsControlCustom(mixerControl.dwControlType); public static IList<MixerControl> GetMixerControls(IntPtr mixerHandle, MixerLine mixerLine, MixerFlags mixerHandleType) { List<MixerControl> list = new List<MixerControl>(); if (mixerLine.ControlsCount > 0) { int num = Marshal.SizeOf(typeof(MixerInterop.MIXERCONTROL)); MixerInterop.MIXERLINECONTROLS mixerLineControls = default(MixerInterop.MIXERLINECONTROLS); IntPtr intPtr = Marshal.AllocHGlobal(num * mixerLine.ControlsCount); mixerLineControls.cbStruct = Marshal.SizeOf((object)mixerLineControls); mixerLineControls.dwLineID = mixerLine.LineId; mixerLineControls.cControls = mixerLine.ControlsCount; mixerLineControls.pamxctrl = intPtr; mixerLineControls.cbmxctrl = Marshal.SizeOf(typeof(MixerInterop.MIXERCONTROL)); try { MmResult mmResult = MixerInterop.mixerGetLineControls(mixerHandle, ref mixerLineControls, MixerFlags.Mixer | mixerHandleType); if (mmResult != 0) { throw new MmException(mmResult, "mixerGetLineControls"); } for (int i = 0; i < mixerLineControls.cControls; i++) { MixerInterop.MIXERCONTROL mIXERCONTROL = (MixerInterop.MIXERCONTROL)Marshal.PtrToStructure((IntPtr)(intPtr.ToInt64() + num * i), typeof(MixerInterop.MIXERCONTROL)); MixerControl item = GetMixerControl(mixerHandle, mixerLine.LineId, mIXERCONTROL.dwControlID, mixerLine.Channels, mixerHandleType); list.Add(item); } } finally { Marshal.FreeHGlobal(intPtr); } } return list; } public static MixerControl GetMixerControl(IntPtr mixerHandle, int nLineID, int controlId, int nChannels, MixerFlags mixerFlags) { MixerInterop.MIXERLINECONTROLS mixerLineControls = default(MixerInterop.MIXERLINECONTROLS); MixerInterop.MIXERCONTROL mIXERCONTROL = default(MixerInterop.MIXERCONTROL); IntPtr intPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf((object)mIXERCONTROL)); mixerLineControls.cbStruct = Marshal.SizeOf((object)mixerLineControls); mixerLineControls.cControls = 1; mixerLineControls.dwControlID = controlId; mixerLineControls.cbmxctrl = Marshal.SizeOf((object)mIXERCONTROL); mixerLineControls.pamxctrl = intPtr; mixerLineControls.dwLineID = nLineID; MmResult mmResult = MixerInterop.mixerGetLineControls(mixerHandle, ref mixerLineControls, MixerFlags.ListText | mixerFlags); if (mmResult != 0) { Marshal.FreeCoTaskMem(intPtr); throw new MmException(mmResult, "mixerGetLineControls"); } mIXERCONTROL = (MixerInterop.MIXERCONTROL)Marshal.PtrToStructure(mixerLineControls.pamxctrl, typeof(MixerInterop.MIXERCONTROL)); Marshal.FreeCoTaskMem(intPtr); if (IsControlBoolean(mIXERCONTROL.dwControlType)) { return new BooleanMixerControl(mIXERCONTROL, mixerHandle, mixerFlags, nChannels); } if (IsControlSigned(mIXERCONTROL.dwControlType)) { return new SignedMixerControl(mIXERCONTROL, mixerHandle, mixerFlags, nChannels); } if (IsControlUnsigned(mIXERCONTROL.dwControlType)) { return new UnsignedMixerControl(mIXERCONTROL, mixerHandle, mixerFlags, nChannels); } if (IsControlListText(mIXERCONTROL.dwControlType)) { return new ListTextMixerControl(mIXERCONTROL, mixerHandle, mixerFlags, nChannels); } if (IsControlCustom(mIXERCONTROL.dwControlType)) { return new CustomMixerControl(mIXERCONTROL, mixerHandle, mixerFlags, nChannels); } throw new InvalidOperationException($"Unknown mixer control type {mIXERCONTROL.dwControlType}"); } protected void GetControlDetails() { mixerControlDetails.cbStruct = Marshal.SizeOf((object)mixerControlDetails); mixerControlDetails.dwControlID = mixerControl.dwControlID; if (IsCustom) { mixerControlDetails.cChannels = 0; } else if ((mixerControl.fdwControl & (true ? 1u : 0u)) != 0) { mixerControlDetails.cChannels = 1; } else { mixerControlDetails.cChannels = nChannels; } if ((mixerControl.fdwControl & 2u) != 0) { mixerControlDetails.hwndOwner = (IntPtr)mixerControl.cMultipleItems; } else if (IsCustom) { mixerControlDetails.hwndOwner = IntPtr.Zero; } else { mixerControlDetails.hwndOwner = IntPtr.Zero; } if (IsBoolean) { mixerControlDetails.cbDetails = Marshal.SizeOf((object)default(MixerInterop.MIXERCONTROLDETAILS_BOOLEAN)); } else if (IsListText) { mixerControlDetails.cbDetails = Marshal.SizeOf((object)default(MixerInterop.MIXERCONTROLDETAILS_LISTTEXT)); } else if (IsSigned) { mixerControlDetails.cbDetails = Marshal.SizeOf((object)default(MixerInterop.MIXERCONTROLDETAILS_SIGNED)); } else if (IsUnsigned) { mixerControlDetails.cbDetails = Marshal.SizeOf((object)default(MixerInterop.MIXERCONTROLDETAILS_UNSIGNED)); } else { mixerControlDetails.cbDetails = mixerControl.Metrics.customData; } int num = mixerControlDetails.cbDetails * mixerControlDetails.cChannels; if ((mixerControl.fdwControl & 2u) != 0) { num *= (int)mixerControl.cMultipleItems; } IntPtr intPtr = Marshal.AllocCoTaskMem(num); mixerControlDetails.paDetails = intPtr; MmResult mmResult = MixerInterop.mixerGetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType); if (mmResult == MmResult.NoError) { GetDetails(mixerControlDetails.paDetails); } Marshal.FreeCoTaskMem(intPtr); if (mmResult != 0) { throw new MmException(mmResult, "mixerGetControlDetails"); } } protected abstract void GetDetails(IntPtr pDetails); private static bool IsControlBoolean(MixerControlType controlType) { switch (controlType) { case MixerControlType.BooleanMeter: case MixerControlType.Boolean: case MixerControlType.OnOff: case MixerControlType.Mute: case MixerControlType.Mono: case MixerControlType.Loudness: case MixerControlType.StereoEnhance: case MixerControlType.Button: case MixerControlType.SingleSelect: case MixerControlType.Mux: case MixerControlType.MultipleSelect: case MixerControlType.Mixer: return true; default: return false; } } private static bool IsControlListText(MixerControlType controlType) { if (controlType == MixerControlType.Equalizer || (uint)(controlType - 1879113728) <= 1u || (uint)(controlType - 1895890944) <= 1u) { return true; } return false; } private static bool IsControlSigned(MixerControlType controlType) { switch (controlType) { case MixerControlType.SignedMeter: case MixerControlType.PeakMeter: case MixerControlType.Signed: case MixerControlType.Decibels: case MixerControlType.Slider: case MixerControlType.Pan: case MixerControlType.QSoundPan: return true; default: return false; } } private static bool IsControlUnsigned(MixerControlType controlType) { switch (controlType) { case MixerControlType.UnsignedMeter: case MixerControlType.Unsigned: case MixerControlType.Percent: case MixerControlType.Fader: case MixerControlType.Volume: case MixerControlType.Bass: case MixerControlType.Treble: case MixerControlType.Equalizer: case MixerControlType.MicroTime: case MixerControlType.MilliTime: return true; default: return false; } } private static bool IsControlCustom(MixerControlType controlType) { return controlType == MixerControlType.Custom; } public override string ToString() { return $"{Name} {ControlType}"; } } [Flags] internal enum MixerControlClass { Custom = 0, Meter = 0x10000000, Switch = 0x20000000, Number = 0x30000000, Slider = 0x40000000, Fader = 0x50000000, Time = 0x60000000, List = 0x70000000, Mask = 0x70000000 } [Flags] internal enum MixerControlSubclass { SwitchBoolean = 0, SwitchButton = 0x1000000, MeterPolled = 0, TimeMicrosecs = 0, TimeMillisecs = 0x1000000, ListSingle = 0, ListMultiple = 0x1000000, Mask = 0xF000000 } [Flags] internal enum MixerControlUnits { Custom = 0, Boolean = 0x10000, Signed = 0x20000, Unsigned = 0x30000, Decibels = 0x40000, Percent = 0x50000, Mask = 0xFF0000 } public enum MixerControlType { Custom = 0, BooleanMeter = 268500992, SignedMeter = 268566528, PeakMeter = 268566529, UnsignedMeter = 268632064, Boolean = 536936448, OnOff = 536936449, Mute = 536936450, Mono = 536936451, Loudness = 536936452, StereoEnhance = 536936453, Button = 553713664, Decibels = 805568512, Signed = 805437440, Unsigned = 805502976, Percent = 805634048, Slider = 1073872896, Pan = 1073872897, QSoundPan = 1073872898, Fader = 1342373888, Volume = 1342373889, Bass = 1342373890, Treble = 1342373891, Equalizer = 1342373892, SingleSelect = 1879113728, Mux = 1879113729, MultipleSelect = 1895890944, Mixer = 1895890945, MicroTime = 1610809344, MilliTime = 1627586560 } public class MixerLine { private MixerInterop.MIXERLINE mixerLine; private IntPtr mixerHandle; private MixerFlags mixerHandleType; public string Name => mixerLine.szName; public string ShortName => mixerLine.szShortName; public int LineId => mixerLine.dwLineID; public MixerLineComponentType ComponentType => mixerLine.dwComponentType; public string TypeDescription => mixerLine.dwComponentType switch { MixerLineComponentType.DestinationUndefined => "Undefined Destination", MixerLineComponentType.DestinationDigital => "Digital Destination", MixerLineComponentType.DestinationLine => "Line Level Destination", MixerLineComponentType.DestinationMonitor => "Monitor Destination", MixerLineComponentType.DestinationSpeakers => "Speakers Destination", MixerLineComponentType.DestinationHeadphones => "Headphones Destination", MixerLineComponentType.DestinationTelephone => "Telephone Destination", MixerLineComponentType.DestinationWaveIn => "Wave Input Destination", MixerLineComponentType.DestinationVoiceIn => "Voice Recognition Destination", MixerLineComponentType.SourceUndefined => "Undefined Source", MixerLineComponentType.SourceDigital => "Digital Source", MixerLineComponentType.SourceLine => "Line Level Source", MixerLineComponentType.SourceMicrophone => "Microphone Source", MixerLineComponentType.SourceSynthesizer => "Synthesizer Source", MixerLineComponentType.SourceCompactDisc => "Compact Disk Source", MixerLineComponentType.SourceTelephone => "Telephone Source", MixerLineComponentType.SourcePcSpeaker => "PC Speaker Source", MixerLineComponentType.SourceWaveOut => "Wave Out Source", MixerLineComponentType.SourceAuxiliary => "Auxiliary Source", MixerLineComponentType.SourceAnalog => "Analog Source", _ => "Invalid Component Type", }; public int Channels => mixerLine.cChannels; public int SourceCount => mixerLine.cConnections; public int ControlsCount => mixerLine.cControls; public bool IsActive => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_ACTIVE) != 0; public bool IsDisconnected => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_DISCONNECTED) != 0; public bool IsSource => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_SOURCE) != 0; public IEnumerable<MixerControl> Controls => MixerControl.GetMixerControls(mixerHandle, this, mixerHandleType); public IEnumerable<MixerLine> Sources { get { for (int source = 0; source < SourceCount; source++) { yield return GetSource(source); } } } public string TargetName => mixerLine.szPname; public MixerLine(IntPtr mixerHandle, int destinationIndex, MixerFlags mixerHandleType) { this.mixerHandle = mixerHandle; this.mixerHandleType = mixerHandleType; mixerLine = default(MixerInterop.MIXERLINE); mixerLine.cbStruct = Marshal.SizeOf((object)mixerLine); mixerLine.dwDestination = destinationIndex; MmException.Try(MixerInterop.mixerGetLineInfo(mixerHandle, ref mixerLine, mixerHandleType | MixerFlags.Mixer), "mixerGetLineInfo"); } public MixerLine(IntPtr mixerHandle, int destinationIndex, int sourceIndex, MixerFlags mixerHandleType) { this.mixerHandle = mixerHandle; this.mixerHandleType = mixerHandleType; mixerLine = default(MixerInterop.MIXERLINE); mixerLine.cbStruct = Marshal.SizeOf((object)mixerLine); mixerLine.dwDestination = destinationIndex; mixerLine.dwSource = sourceIndex; MmException.Try(MixerInterop.mixerGetLineInfo(mixerHandle, ref mixerLine, mixerHandleType | MixerFlags.ListText), "mixerGetLineInfo"); } public static int GetMixerIdForWaveIn(int waveInDevice) { int mixerID = -1; MmException.Try(MixerInterop.mixerGetID((IntPtr)waveInDevice, out mixerID, MixerFlags.WaveIn), "mixerGetID"); return mixerID; } public MixerLine GetSource(int sourceIndex) { if (sourceIndex < 0 || sourceIndex >= SourceCount) { throw new ArgumentOutOfRangeException("sourceIndex"); } return new MixerLine(mixerHandle, mixerLine.dwDestination, sourceIndex, mixerHandleType); } public override string ToString() { return $"{Name} {TypeDescription} ({ControlsCount} controls, ID={mixerLine.dwLineID})"; } } [Flags] public enum MixerFlags { Handle = int.MinValue, Mixer = 0, MixerHandle = int.MinValue, WaveOut = 0x10000000, WaveOutHandle = -1879048192, WaveIn = 0x20000000, WaveInHandle = -1610612736, MidiOut = 0x30000000, MidiOutHandle = -1342177280, MidiIn = 0x40000000, MidiInHandle = -1073741824, Aux = 0x50000000, Value = 0, ListText = 1, QueryMask = 0xF, All = 0, OneById = 1, OneByType = 2, GetLineInfoOfDestination = 0, GetLineInfoOfSource = 1, GetLineInfoOfLineId = 2, GetLineInfoOfComponentType = 3, GetLineInfoOfTargetType = 4, GetLineInfoOfQueryMask = 0xF } internal class MixerInterop { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)] public struct MIXERCONTROLDETAILS { public int cbStruct; public int dwControlID; public int cChannels; public IntPtr hwndOwner; public int cbDetails; public IntPtr paDetails; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERCAPS { public ushort wMid; public ushort wPid; public uint vDriverVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szPname; public uint fdwSupport; public uint cDestinations; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERLINECONTROLS { public int cbStruct; public int dwLineID; public int dwControlID; public int cControls; public int cbmxctrl; public IntPtr pamxctrl; } [Flags] public enum MIXERLINE_LINEF { MIXERLINE_LINEF_ACTIVE = 1, MIXERLINE_LINEF_DISCONNECTED = 0x8000, MIXERLINE_LINEF_SOURCE = int.MinValue } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERLINE { public int cbStruct; public int dwDestination; public int dwSource; public int dwLineID; public MIXERLINE_LINEF fdwLine; public IntPtr dwUser; public MixerLineComponentType dwComponentType; public int cChannels; public int cConnections; public int cControls; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string szShortName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string szName; public uint dwType; public uint dwDeviceID; public ushort wMid; public ushort wPid; public uint vDriverVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szPname; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct Bounds { public int minimum; public int maximum; public int reserved2; public int reserved3; public int reserved4; public int reserved5; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct Metrics { public int step; public int customData; public int reserved2; public int reserved3; public int reserved4; public int reserved5; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERCONTROL { public uint cbStruct; public int dwControlID; public MixerControlType dwControlType; public uint fdwControl; public uint cMultipleItems; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string szShortName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string szName; public Bounds Bounds; public Metrics Metrics; } public struct MIXERCONTROLDETAILS_BOOLEAN { public int fValue; } public struct MIXERCONTROLDETAILS_SIGNED { public int lValue; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERCONTROLDETAILS_LISTTEXT { public uint dwParam1; public uint dwParam2; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string szName; } public struct MIXERCONTROLDETAILS_UNSIGNED { public uint dwValue; } public const uint MIXERCONTROL_CONTROLF_UNIFORM = 1u; public const uint MIXERCONTROL_CONTROLF_MULTIPLE = 2u; public const uint MIXERCONTROL_CONTROLF_DISABLED = 2147483648u; public const int MAXPNAMELEN = 32; public const int MIXER_SHORT_NAME_CHARS = 16; public const int MIXER_LONG_NAME_CHARS = 64; [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern int mixerGetNumDevs(); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerOpen(out IntPtr hMixer, int uMxId, IntPtr dwCallback, IntPtr dwInstance, MixerFlags dwOpenFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerClose(IntPtr hMixer); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetControlDetails(IntPtr hMixer, ref MIXERCONTROLDETAILS mixerControlDetails, MixerFlags dwDetailsFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetDevCaps(IntPtr nMixerID, ref MIXERCAPS mixerCaps, int mixerCapsSize); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetID(IntPtr hMixer, out int mixerID, MixerFlags dwMixerIDFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetLineControls(IntPtr hMixer, ref MIXERLINECONTROLS mixerLineControls, MixerFlags dwControlFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetLineInfo(IntPtr hMixer, ref MIXERLINE mixerLine, MixerFlags dwInfoFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerMessage(IntPtr hMixer, uint nMessage, IntPtr dwParam1, IntPtr dwParam2); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerSetControlDetails(IntPtr hMixer, ref MIXERCONTROLDETAILS mixerControlDetails, MixerFlags dwDetailsFlags); } public enum MixerLineComponentType { DestinationUndefined = 0, DestinationDigital = 1, DestinationLine = 2, DestinationMonitor = 3, DestinationSpeakers = 4, DestinationHeadphones = 5, DestinationTelephone = 6, DestinationWaveIn = 7, DestinationVoiceIn = 8, SourceUndefined = 4096, SourceDigital = 4097, SourceLine = 4098, SourceMicrophone = 4099, SourceSynthesizer = 4100, SourceCompactDisc = 4101, SourceTelephone = 4102, SourcePcSpeaker = 4103, SourceWaveOut = 4104, SourceAuxiliary = 4105, SourceAnalog = 4106 } public class SignedMixerControl : MixerControl { private MixerInterop.MIXERCONTROLDETAILS_SIGNED signedDetails; public int Value { get { GetControlDetails(); return signedDetails.lValue; } set { signedDetails.lValue = value; mixerControlDetails.paDetails = Marshal.AllocHGlobal(Marshal.SizeOf((object)signedDetails)); Marshal.StructureToPtr((object)signedDetails, mixerControlDetails.paDetails, fDeleteOld: false); MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails"); Marshal.FreeHGlobal(mixerControlDetails.paDetails); } } public int MinValue => mixerControl.Bounds.minimum; public int MaxValue => mixerControl.Bounds.maximum; public double Percent { get { return 100.0 * (double)(Value - MinValue) / (double)(MaxValue - MinValue); } set { Value = (int)((double)MinValue + value / 100.0 * (double)(MaxValue - MinValue)); } } internal SignedMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { signedDetails = (MixerInterop.MIXERCONTROLDETAILS_SIGNED)Marshal.PtrToStructure(mixerControlDetails.paDetails, typeof(MixerInterop.MIXERCONTROLDETAILS_SIGNED)); } public override string ToString() { return $"{base.ToString()} {Percent}%"; } } public class UnsignedMixerControl : MixerControl { private MixerInterop.MIXERCONTROLDETAILS_UNSIGNED[] unsignedDetails; public uint Value { get { GetControlDetails(); return unsignedDetails[0].dwValue; } set { int num = Marshal.SizeOf((object)unsignedDetails[0]); mixerControlDetails.paDetails = Marshal.AllocHGlobal(num * nChannels); for (int i = 0; i < nChannels; i++) { unsignedDetails[i].dwValue = value; long num2 = mixerControlDetails.paDetails.ToInt64() + num * i; Marshal.StructureToPtr((object)unsignedDetails[i], (IntPtr)num2, fDeleteOld: false); } MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails"); Marshal.FreeHGlobal(mixerControlDetails.paDetails); } } public uint MinValue => (uint)mixerControl.Bounds.minimum; public uint MaxValue => (uint)mixerControl.Bounds.maximum; public double Percent { get { return 100.0 * (double)(Value - MinValue) / (double)(MaxValue - MinValue); } set { Value = (uint)((double)MinValue + value / 100.0 * (double)(MaxValue - MinValue)); } } internal UnsignedMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { unsignedDetails = new MixerInterop.MIXERCONTROLDETAILS_UNSIGNED[nChannels]; for (int i = 0; i < nChannels; i++) { unsignedDetails[i] = (MixerInterop.MIXERCONTROLDETAILS_UNSIGNED)Marshal.PtrToStructure(mixerControlDetails.paDetails, typeof(MixerInterop.MIXERCONTROLDETAILS_UNSIGNED)); } } public override string ToString() { return $"{base.ToString()} {Percent}%"; } } } namespace NAudio.Gui { public class Fader : Control { private int minimum; private int maximum; private float percent; private Orientation orientation; private Container components; private readonly int SliderHeight = 30; private readonly int SliderWidth = 15; private Rectangle sliderRectangle; private bool dragging; private int dragY; public int Minimum { get { return minimum; } set { minimum = value; } } public int Maximum { get { return maximum; } set { maximum = value; } } public int Value { get { return (int)(percent * (float)(maximum - minimum)) + minimum; } set { percent = (float)(value - minimum) / (float)(maximum - minimum); } } public Orientation Orientation { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return orientation; } set { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) orientation = value; } } public Fader() { InitializeComponent(); ((Control)this).SetStyle((ControlStyles)73730, true); } protected override void Dispose(bool disposing) { if (disposing && components != null) { components.Dispose(); } ((Control)this).Dispose(disposing); } private void DrawSlider(Graphics g) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown Brush val = (Brush)new SolidBrush(Color.White); Pen val2 = new Pen(Color.Black); sliderRectangle.X = (((Control)this).Width - SliderWidth) / 2; sliderRectangle.Width = SliderWidth; sliderRectangle.Y = (int)((float)(((Control)this).Height - SliderHeight) * percent); sliderRectangle.Height = SliderHeight; g.FillRectangle(val, sliderRectangle); g.DrawLine(val2, sliderRectangle.Left, sliderRectangle.Top + sliderRectangle.Height / 2, sliderRectangle.Right, sliderRectangle.Top + sliderRectangle.Height / 2); val.Dispose(); val2.Dispose(); } protected override void OnPaint(PaintEventArgs e) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Graphics graphics = e.Graphics; if ((int)Orientation == 1) { Brush val = (Brush)new SolidBrush(Color.Black); graphics.FillRectangle(val, ((Control)this).Width / 2, SliderHeight / 2, 2, ((Control)this).Height - SliderHeight); val.Dispose(); DrawSlider(graphics); } ((Control)this).OnPaint(e); } protected override void OnMouseDown(MouseEventArgs e) { if (sliderRectangle.Contains(e.X, e.Y)) { dragging = true; dragY = e.Y - sliderRectangle.Y; } ((Control)this).OnMouseDown(e); } protected override void OnMouseMove(MouseEventArgs e) { if (dragging) { int num = e.Y - dragY; if (num < 0) { percent = 0f; } else if (num > ((Control)this).Height - SliderHeight) { percent = 1f; } else { percent = (float)num / (float)(((Control)this).Height - SliderHeight); } ((Control)this).Invalidate(); } ((Control)this).OnMouseMove(e); } protected override void OnMouseUp(MouseEventArgs e) { dragging = false; ((Control)this).OnMouseUp(e); } private void InitializeComponent() { this.components = new System.ComponentModel.Container(); } } public class PanSlider : UserControl { private Container components; private float pan; public float Pan { get { return pan; } set { if (value < -1f) { value = -1f; } if (value > 1f) { value = 1f; } if (value != pan) { pan = value; if (this.PanChanged != null) { this.PanChanged(this, EventArgs.Empty); } ((Control)this).Invalidate(); } } } public event EventHandler PanChanged; public PanSlider() { InitializeComponent(); } protected override void Dispose(bool disposing) { if (disposing && components != null) { components.Dispose(); } ((ContainerControl)this).Dispose(disposing); } private void InitializeComponent() { ((Control)this).Name = "PanSlider"; ((Control)this).Size = new Size(104, 16); } protected override void OnPaint(PaintEventArgs pe) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown StringFormat val = new StringFormat(); val.LineAlignment = (StringAlignment)1; val.Alignment = (StringAlignment)1; string text; if ((double)pan == 0.0) { pe.Graphics.FillRectangle(Brushes.Orange, ((Control)this).Width / 2 - 1, 1, 3, ((Control)this).Height - 2); text = "C"; } else if (pan > 0f) { pe.Graphics.FillRectangle(Brushes.Orange, ((Control)this).Width / 2, 1, (int)((float)(((Control)this).Width / 2) * pan), ((Control)this).Height - 2); text = $"{pan * 100f:F0}%R"; } else { pe.Graphics.FillRectangle(Brushes.Orange, (int)((float)(((Control)this).Width / 2) * (pan + 1f)), 1, (int)((float)(((Control)this).Width / 2) * (0f - pan)), ((Control)this).Height - 2); text = $"{pan * -100f:F0}%L"; } pe.Graphics.DrawRectangle(Pens.Black, 0, 0, ((Control)this).Width - 1, ((Control)this).Height - 1); pe.Graphics.DrawString(text, ((Control)this).Font, Brushes.Black, (RectangleF)((Control)this).ClientRectangle, val); } protected override void OnMouseMove(MouseEventArgs e) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if ((int)e.Button == 1048576) { SetPanFromMouse(e.X); } ((Control)this).OnMouseMove(e); } protected override void OnMouseDown(MouseEventArgs e) { SetPanFromMouse(e.X); ((UserControl)this).OnMouseDown(e); } private void SetPanFromMouse(int x) { Pan = (float)x / (float)((Control)this).Width * 2f - 1f; } } public class Pot : UserControl { private double minimum; private double maximum = 1.0; private double value = 0.5; private int beginDragY; private double beginDragValue; private bool dragging; private IContainer components; public double Minimum { get { return minimum; } set { if (value >= maximum) { throw new ArgumentOutOfRangeException("Minimum must be less than maximum"); } minimum = value; if (Value < minimum) { Value = minimum; } } } public double Maximum { get { return maximum; } set { if (value <= minimum) { throw new ArgumentOutOfRangeException("Maximum must be greater than minimum"); } maximum = value; if (Value > maximum) { Value = maximum; } } } public double Value { get { return value; } set { SetValue(value, raiseEvents: false); } } public event EventHandler ValueChanged; public Pot() { ((Control)this).SetStyle((ControlStyles)73730, true); InitializeComponent(); } private void SetValue(double newValue, bool raiseEvents) { if (value != newValue) { value = newValue; if (raiseEvents && this.ValueChanged != null) { this.ValueChanged(this, EventArgs.Empty); } ((Control)this).Invalidate(); } } protected override void OnPaint(PaintEventArgs e) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown int num = Math.Min(((Control)this).Width - 4, ((Control)this).Height - 4); Pen val = new Pen(((Control)this).ForeColor, 3f); val.LineJoin = (LineJoin)2; GraphicsState val2 = e.Graphics.Save(); e.Graphics.TranslateTransform((float)(((Control)this).Width / 2), (float)(((Control)this).Height / 2)); e.Graphics.SmoothingMode = (SmoothingMode)4; e.Graphics.DrawArc(val, new Rectangle(num / -2, num / -2, num, num), 135f, 270f); double num2 = (value - minimum) / (maximum - minimum); double num3 = 135.0 + num2 * 270.0; double num4 = (double)num / 2.0 * Math.Cos(Math.PI * num3 / 180.0); double num5 = (double)num / 2.0 * Math.Sin(Math.PI * num3 / 180.0); e.Graphics.DrawLine(val, 0f, 0f, (float)num4, (float)num5); e.Graphics.Restore(val2); ((Control)this).OnPaint(e); } protected override void OnMouseDown(MouseEventArgs e) { dragging = true; beginDragY = e.Y; beginDragValue = value; ((UserControl)this).OnMouseDown(e); } protected override void OnMouseUp(MouseEventArgs e) { dragging = false; ((Control)this).OnMouseUp(e); } protected override void OnMouseMove(MouseEventArgs e) { if (dragging) { int num = beginDragY - e.Y; double num2 = (maximum - minimum) * ((double)num / 150.0); double num3 = beginDragValue + num2; if (num3 < minimum) { num3 = minimum; } if (num3 > maximum) { num3 = maximum; } SetValue(num3, raiseEvents: true); } ((Control)this).OnMouseMove(e); } protected override void Dispose(bool disposing) { if (disposing && components != null) { components.Dispose(); } ((ContainerControl)this).Dispose(disposing); } private void InitializeComponent() { ((Control)this).SuspendLayout(); ((ContainerControl)this).AutoScaleDimensions = new SizeF(6f, 13f); ((ContainerControl)this).AutoScaleMode = (AutoScaleMode)1; ((Control)this).Name = "Pot"; ((Control)this).Size = new Size(32, 32); ((Control)this).ResumeLayout(false); } } public class VolumeMeter : Control { private Brush foregroundBrush; private float amplitude; private IContainer components; [DefaultValue(-3.0)] public float Amplitude { get { return amplitude; } set { amplitude = value; ((Control)this).Invalidate(); } } [DefaultValue(-60.0)] public float MinDb { get; set; } [DefaultValue(18.0)] public float MaxDb { get; set; } [DefaultValue(/*Could not decode attribute arguments.*/)] public Orientation Orientation { get; set; } public VolumeMeter() { ((Control)this).SetStyle((ControlStyles)139266, true); MinDb = -60f; MaxDb = 18f; Amplitude = 0f; Orientation = (Orientation)1; InitializeComponent(); ((Control)this).OnForeColorChanged(EventArgs.Empty); } protected override void OnForeColorChanged(EventArgs e) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown foregroundBrush = (Brush)new SolidBrush(((Control)this).ForeColor); ((Control)this).OnForeColorChanged(e); } protected override void OnPaint(PaintEventArgs pe) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) pe.Graphics.DrawRectangle(Pens.Black, 0, 0, ((Control)this).Width - 1, ((Control)this).Height - 1); double num = 20.0 * Math.Log10(Amplitude); if (num < (double)MinDb) { num = MinDb; } if (num > (double)MaxDb) { num = MaxDb; } double num2 = (num - (double)MinDb) / (double)(MaxDb - MinDb); int num3 = ((Control)this).Width - 2; int num4 = ((Control)this).Height - 2; if ((int)Orientation == 0) { num3 = (int)((double)num3 * num2); pe.Graphics.FillRectangle(foregroundBrush, 1, 1, num3, num4); } else { num4 = (int)((double)num4 * num2); pe.Graphics.FillRectangle(foregroundBrush, 1, ((Control)this).Height - 1 - num4, num3, num4); } } protected override void Dispose(bool disposing) { if (disposing && components != null) { components.Dispose(); } ((Control)this).Dispose(disposing); } private void InitializeComponent() { this.components = new System.ComponentModel.Container(); } } public class VolumeSlider : UserControl { private Container components; private float volume = 1f; private float MinDb = -48f; [DefaultValue(1f)] public float Volume { get { return volume; } set { if (value < 0f) { value = 0f; } if (value > 1f) { value = 1f; } if (volume != value) { volume = value; if (this.VolumeChanged != null) { this.VolumeChanged(this, EventArgs.Empty); } ((Control)this).Invalidate(); } } } public event EventHandler VolumeChanged; public VolumeSlider() { InitializeComponent(); } protected override void Dispose(bool disposing) { if (disposing && components != null) { components.Dispose(); } ((ContainerControl)this).Dispose(disposing); } private void InitializeComponent() { ((Control)this).Name = "VolumeSlider"; ((Control)this).Size = new Size(96, 16); } protected override void OnPaint(PaintEventArgs pe) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown StringFormat val = new StringFormat(); val.LineAlignment = (StringAlignment)1; val.Alignment = (StringAlignment)1; pe.Graphics.DrawRectangle(Pens.Black, 0, 0, ((Control)this).Width - 1, ((Control)this).Height - 1); float num = 20f * (float)Math.Log10(Volume); float num2 = 1f - num / MinDb; pe.Graphics.FillRectangle(Brushes.LightGreen, 1, 1, (int)((float)(((Control)this).Width - 2) * num2), ((Control)this).Height - 2); string text = $"{num:F2} dB"; pe.Graphics.DrawString(text, ((Control)this).Font, Brushes.Black, (RectangleF)((Control)this).ClientRectangle, val); } protected override void OnMouseMove(MouseEventArgs e) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if ((int)e.Button == 1048576) { SetVolumeFromMouse(e.X); } ((Control)this).OnMouseMove(e); } protected override void OnMouseDown(MouseEventArgs e) { SetVolumeFromMouse(e.X); ((UserControl)this).OnMouseDown(e); } private void SetVolumeFromMouse(int x) { float num = (1f - (float)x / (float)((Control)this).Width) * MinDb; if (x <= 0) { Volume = 0f; } else { Volume = (float)Math.Pow(10.0, num / 20f); } } } public class WaveformPainter : Control { private Pen foregroundPen; private List<float> samples = new List<float>(1000); private int maxSamples; private int insertPos; private IContainer components; public WaveformPainter() { ((Control)this).SetStyle((ControlStyles)139266, true); InitializeComponent(); ((Control)this).OnForeColorChanged(EventArgs.Empty); ((Control)this).OnResize(EventArgs.Empty); } protected override void OnResize(EventArgs e) { maxSamples = ((Control)this).Width; ((Control)this).OnResize(e); } protected override void OnForeColorChanged(EventArgs e) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown foregroundPen = new Pen(((Control)this).ForeColor); ((Control)this).OnForeColorChanged(e); } public void AddMax(float maxSample) { if (maxSamples != 0) { if (samples.Count <= maxSamples) { samples.Add(maxSample); } else if (insertPos < maxSamples) { samples[insertPos] = maxSample; } insertPos++; insertPos %= maxSamples; ((Control)this).Invalidate(); } } protected override void OnPaint(PaintEventArgs pe) { ((Control)this).OnPaint(pe); for (int i = 0; i < ((Control)this).Width; i++) { float num = (float)((Control)this).Height * GetSample(i - ((Control)this).Width + insertPos); float num2 = ((float)((Control)this).Height - num) / 2f; pe.Graphics.DrawLine(foregroundPen, (float)i, num2, (float)i, num2 + num); } } private float GetSample(int index) { if (index < 0) { index += maxSamples; } if ((index >= 0) & (index < samples.Count)) { return samples[index]; } return 0f; } protected override void Dispose(bool disposing) { if (disposing && components != null) { components.Dispose(); } ((Control)this).Dispose(disposing); } private void InitializeComponent() { this.components = new System.ComponentModel.Container(); } } public class WaveViewer : UserControl { private Container components; private WaveStream waveStream; private int samplesPerPixel = 128; private long startPosition; private int bytesPerSample; public WaveStream WaveStream { get { return waveStream; } set { waveStream = value; if (waveStream != null) { bytesPerSample = waveStream.WaveFormat.BitsPerSample / 8 * waveStream.WaveFormat.Channels; } ((Control)this).Invalidate(); } } public int SamplesPerPixel { get { return samplesPerPixel; } set { samplesPerPixel = value; ((Control)this).Invalidate(); } } public long StartPosition { get { return startPosition; } set { startPosition = value; } } public WaveViewer() { InitializeComponent(); ((Control)this).DoubleBuffered = true; } protected override void Dispose(bool disposing) { if (disposing && components != null) { components.Dispose(); } ((ContainerControl)this).Dispose(disposing); } protected override void OnPaint(PaintEventArgs e) { if (waveStream != null) { waveStream.Position = 0L; byte[] array = new byte[samplesPerPixel * bytesPerSample]; waveStream.Position = startPosition + e.ClipRectangle.Left * bytesPerSample * samplesPerPixel; for (float num = e.ClipRectangle.X; num < (float)e.ClipRectangle.Right; num += 1f) { short num2 = 0; short num3 = 0; int num4 = waveStream.Read(array, 0, samplesPerPixel * bytesPerSample); if (num4 == 0) { break; } for (int i = 0; i < num4; i += 2) { short num5 = BitConverter.ToInt16(array, i); if (num5 < num2) { num2 = num5; } if (num5 > num3) { num3 = num5; } } float num6 = ((float)num2 - -32768f) / 65535f; float num7 = ((float)num3 - -32768f) / 65535f; e.Graphics.DrawLine(Pens.Black, num, (float)((Control)this).Height * num6, num, (float)((Control)this).Height * num7); } } ((Control)this).OnPaint(e); } private void InitializeComponent() { components = new Container(); } } } namespace NAudio.SoundFont { public class Generator { private GeneratorEnum generatorType; private ushort rawAmount; private Instrument instrument; private SampleHeader sampleHeader; public GeneratorEnum GeneratorType { get { return generatorType; } set { generatorType = value; } } public ushort UInt16Amount { get { return rawAmount; } set { rawAmount = value; } } public short Int16Amount { get { return (short)rawAmount; } set { rawAmount = (ushort)value; } } public byte LowByteAmount { get { return (byte)(rawAmount & 0xFFu); } set { rawAmount &= 65280; rawAmount += value; } } public byte HighByteAmount { get { return (byte)((rawAmount & 0xFF00) >> 8); } set { rawAmount &= 255; rawAmount += (ushort)(value << 8); } } public Instrument Instrument { get { return instrument; } set { instrument = value; } } public SampleHeader SampleHeader { get { return sampleHeader; } set { sampleHeader = value; } } public override string ToString() { if (generatorType == GeneratorEnum.Instrument) { return $"Generator Instrument {instrument.Name}"; } if (generatorType == GeneratorEnum.SampleID) { return $"Generator SampleID {sampleHeader}"; } return $"Generator {generatorType} {rawAmount}"; } } internal class GeneratorBuilder : StructureBuilder<Generator> { public override int Length => 4; public Generator[] Generators => data.ToArray(); public override Generator Read(BinaryReader br) { Generator generator = new Generator(); generator.GeneratorType = (GeneratorEnum)br.ReadUInt16(); generator.UInt16Amount = br.ReadUInt16(); data.Add(generator); return generator; } public override void Write(BinaryWriter bw, Generator o) { } public void Load(Instrument[] instruments) { Generator[] generators = Generators; foreach (Generator generator in generators) { if (generator.GeneratorType == GeneratorEnum.Instrument) { generator.Instrument = instruments[generator.UInt16Amount]; } } } public void Load(SampleHeader[] sampleHeaders) { Generator[] generators = Generators; foreach (Generator generator in generators) { if (generator.GeneratorType == GeneratorEnum.SampleID) { generator.SampleHeader = sampleHeaders[generator.UInt16Amount]; } } } } public enum GeneratorEnum { StartAddressOffset, EndAddressOffset, StartLoopAddressOffset, EndLoopAddressOffset, StartAddressCoarseOffset, ModulationLFOToPitch, VibratoLFOToPitch, ModulationEnvelopeToPitch, InitialFilterCutoffFrequency, InitialFilterQ, ModulationLFOToFilterCutoffFrequency, ModulationEnvelopeToFilterCutoffFrequency, EndAddressCoarseOffset, ModulationLFOToVolume, Unused1, ChorusEffectsSend, ReverbEffectsSend, Pan, Unused2, Unused3, Unused4, DelayModulationLFO, FrequencyModulationLFO, DelayVibratoLFO, FrequencyVibratoLFO, DelayModulationEnvelope, AttackModulationEnvelope, HoldModulationEnvelope, DecayModulationEnvelope, SustainModulationEnvelope, ReleaseModulationEnvelope, KeyNumberToModulationEnvelopeHold, KeyNumberToModulationEnvelopeDecay, DelayVolumeEnvelope, AttackVolumeEnvelope, HoldVolumeEnvelope, DecayVolumeEnvelope, SustainVolumeEnvelope, ReleaseVolumeEnvelope, KeyNumberToVolumeEnvelopeHold, KeyNumberToVolumeEnvelopeDecay, Instrument, Reserved1, KeyRange, VelocityRange, StartLoopAddressCoarseOffset, KeyNumber, Velocity, InitialAttenuation, Reserved2, EndLoopAddressCoarseOffset, CoarseTune, FineTune, SampleID, SampleModes, Reserved3, ScaleTuning, ExclusiveClass, OverridingRootKey, Unused5, UnusedEnd } public class InfoChunk { public SFVersion SoundFontVersion { get; } public string WaveTableSoundEngine { get; set; } public string BankName { get; set; } public string DataROM { get; set; } public string CreationDate { get; set; } public string Author { get; set; } public string TargetProduct { get; set; } public string Copyright { get; set; } public string Comments { get; set; } public string Tools { get; set; } public SFVersion ROMVersion { get; set; } internal InfoChunk(RiffChunk chunk) { bool flag = false; bool flag2 = false; if (chunk.ReadChunkID() != "INFO") { throw new InvalidDataException("Not an INFO chunk"); } RiffChunk nextSubChunk; while ((nextSubChunk = chunk.GetNextSubChunk()) != null) { switch (nextSubChunk.ChunkID) { case "ifil": flag = true; SoundFontVersion = nextSubChunk.GetDataAsStructure(new SFVersionBuilder()); break; case "isng": WaveTableSoundEngine = nextSubChunk.GetDataAsString(); break; case "INAM": flag2 = true; BankName = nextSubChunk.GetDataAsString(); break; case "irom": DataROM = nextSubChunk.GetDataAsString(); break; case "iver": ROMVersion = nextSubChunk.GetDataAsStructure(new SFVersionBuilder()); break; case "ICRD": CreationDate = nextSubChunk.GetDataAsString(); break; case "IENG": Author = nextSubChunk.GetDataAsString(); break; case "IPRD": TargetProduct = nextSubChunk.GetDataAsString(); break; case "ICOP": Copyright = nextSubChunk.GetDataAsString(); break; case "ICMT": Comments = nextSubChunk.GetDataAsString(); break; case "ISFT": Tools = nextSubChunk.GetDataAsString(); break; default: throw new InvalidDataException($"Unknown chunk type {nextSubChunk.ChunkID}"); } } if (!flag) { throw new InvalidDataException("Missing SoundFont version information"); } if (!flag2) { throw new InvalidDataException("Missing SoundFont name information"); } } public override string ToString() { return string.Format("Bank Name: {0}\r\nAuthor: {1}\r\nCopyright: {2}\r\nCreation Date: {3}\r\nTools: {4}\r\nComments: {5}\r\nSound Engine: {6}\r\nSoundFont Version: {7}\r\nTarget Product: {8}\r\nData ROM: {9}\r\nROM Version: {10}", BankName, Author, Copyright, CreationDate, Tools, "TODO-fix comments", WaveTableSoundEngine, SoundFontVersion, TargetProduct, DataROM, ROMVersion); } } public class Instrument { private string name; internal ushort startInstrumentZoneIndex; internal ushort endInstrumentZoneIndex; private Zone[] zones; public string Name { get { return name; } set { name = value; } } public Zone[] Zones { get { return zones; } set { zones = value; } } public override string ToString() { return name; } } internal class InstrumentBuilder : StructureBuilder<Instrument> { private Instrument lastInstrument; public override int Length => 22; public Instrument[] Instruments => data.ToArray(); public override Instrument Read(BinaryReader br) { Instrument instrument = new Instrument(); string text = Encoding.UTF8.GetString(br.ReadBytes(20), 0, 20); if (text.IndexOf('\0') >= 0) { text = text.Substring(0, text.IndexOf('\0')); } instrument.Name = text; instrument.startInstrumentZoneIndex = br.ReadUInt16(); if (lastInstrument != null) { lastInstrument.endInstrumentZoneIndex = (ushort)(instrument.startInstrumentZoneIndex - 1); } data.Add(instrument); lastInstrument = instrument; return instrument; } public override void Write(BinaryWriter bw, Instrument instrument) { } public void LoadZones(Zone[] zones) { for (int i = 0; i < data.Count - 1; i++) { Instrument instrument = data[i]; instrument.Zones = new Zone[instrument.endInstrumentZoneIndex - instrument.startInstrumentZoneIndex + 1]; Array.Copy(zones, instrument.startInstrumentZoneIndex, instrument.Zones, 0, instrument.Zones.Length); } data.RemoveAt(data.Count - 1); } } public enum TransformEnum { Linear } public class Modulator { private ModulatorType sourceModulationData; private GeneratorEnum destinationGenerator; private short amount; private ModulatorType sourceModulationAmount; private TransformEnum sourceTransform; public ModulatorType SourceModulationData { get { return sourceModulationData; } set { sourceModulationData = value; } } public GeneratorEnum DestinationGenerator { get { return destinationGenerator; } set { destinationGenerator = value; } } public short Amount { get { return amount; } set { amount = value; } } public ModulatorType SourceModulationAmount { get { return sourceModulationAmount; } set { sourceModulationAmount = value; } } public TransformEnum SourceTransform { get { return sourceTransform; } set { sourceTransform = value; } } public override string ToString() { return $"Modulator {sourceModulationData} {destinationGenerator} {amount} {sourceModulationAmount} {sourceTransform}"; } } internal class ModulatorBuilder : StructureBuilder<Modulator> { public override int Length => 10; public Modulator[] Modulators => data.ToArray(); public override Modulator Read(BinaryReader br) { Modulator modulator = new Modulator(); modulator.SourceModulationData = new ModulatorType(br.ReadUInt16()); modulator.DestinationGenerator = (GeneratorEnum)br.ReadUInt16(); modulator.Amount = br.ReadInt16(); modulator.SourceModulationAmount = new ModulatorType(br.ReadUInt16()); modulator.SourceTransform = (TransformEnum)br.ReadUInt16(); data.Add(modulator); return modulator; } public override void Write(BinaryWriter bw, Modulator o) { } } public enum ControllerSourceEnum { NoController = 0, NoteOnVelocity = 2, NoteOnKeyNumber = 3, PolyPressure = 10, ChannelPressure = 13, PitchWheel = 14, PitchWheelSensitivity = 16 } public enum SourceTypeEnum { Linear, Concave, Convex, Switch } public class ModulatorType { private bool polarity; private bool direction; private bool midiContinuousController; private ControllerSourceEnum controllerSource; private SourceTypeEnum sourceType; private ushort midiContinuousControllerNumber; internal ModulatorType(ushort raw) { polarity = (raw & 0x200) == 512; direction = (raw & 0x100) == 256; midiContinuousController = (raw & 0x80) == 128; sourceType = (SourceTypeEnum)((raw & 0xFC00) >> 10); controllerSource = (ControllerSourceEnum)(raw & 0x7F); midiContinuousControllerNumber = (ushort)(raw & 0x7Fu); } public override string ToString() { if (midiContinuousController) { return $"{sourceType} CC{midiContinuousControllerNumber}"; } return $"{sourceType} {controllerSource}"; } } public class Preset { private string name; private ushort patchNumber; private ushort bank; internal ushort startPresetZoneIndex; internal ushort endPresetZoneIndex; internal uint library; internal uint genre; internal uint morphology; private Zone[] zones; public string Name { get { return name; } set { name = value; } } public ushort PatchNumber { get { return patchNumber; } set { patchNumber = value; } } public ushort Bank { get { return bank; } set { bank = value; } } public Zone[] Zones { get { return zones; } set { zones = value; } } public override string ToString() { return $"{bank}-{patchNumber} {name}"; } } internal class PresetBuilder : StructureBuilder<Preset> { private Preset lastPreset; public override int Length => 38; public Preset[] Presets => data.ToArray(); public override Preset Read(BinaryReader br) { Preset preset = new Preset(); string text = Encoding.UTF8.GetString(br.ReadBytes(20), 0, 20); if (text.IndexOf('\0') >= 0) { text = text.Substring(0, text.IndexOf('\0')); } preset.Name = text; preset.PatchNumber = br.ReadUInt16(); preset.Bank = br.ReadUInt16(); preset.startPresetZoneIndex = br.ReadUInt16(); preset.library = br.ReadUInt32(); preset.genre = br.ReadUInt32(); preset.morphology = br.ReadUInt32(); if (lastPreset != null) { lastPreset.endPresetZoneIndex = (ushort)(preset.startPresetZoneIndex - 1); } data.Add(preset); lastPreset = preset; return preset; } public override void Write(BinaryWriter bw, Preset preset) { } public void LoadZones(Zone[] presetZones) { for (int i = 0; i < data.Count - 1; i++) { Preset preset = data[i]; preset.Zones = new Zone[preset.endPresetZoneIndex - preset.startPresetZoneIndex + 1]; Array.Copy(presetZones, preset.startPresetZoneIndex, preset.Zones, 0, preset.Zones.Length); } data.RemoveAt(data.Count - 1); } } public class PresetsChunk { private PresetBuilder presetHeaders = new PresetBuilder(); private ZoneBuilder presetZones = new ZoneBuilder(); private ModulatorBuilder presetZoneModulators = new ModulatorBuilder(); private GeneratorBuilder presetZoneGenerators = new GeneratorBuilder(); private InstrumentBuilder instruments = new InstrumentBuilder(); private ZoneBuilder instrumentZones = new ZoneBuilder(); private ModulatorBuilder instrumentZoneModulators = new ModulatorBuilder(); private GeneratorBuilder instrumentZoneGenerators = new GeneratorBuilder(); private SampleHeaderBuilder sampleHeaders = new SampleHeaderBuilder(); public Preset[] Presets => presetHeaders.Presets; public Instrument[] Instruments => instruments.Instruments; public SampleHeader[] SampleHeaders => sampleHeaders.SampleHeaders; internal PresetsChunk(RiffChunk chunk) { string text = chunk.ReadChunkID(); if (text != "pdta") { throw new InvalidDataException($"Not a presets data chunk ({text})"); } RiffChunk nextSubChunk; while ((nextSubChunk = chunk.GetNextSubChunk()) != null) { switch (nextSubChunk.ChunkID) { case "PHDR": case "phdr": nextSubChunk.GetDataAsStructureArray(presetHeaders); break; case "PBAG": case "pbag": nextSubChunk.GetDataAsStructureArray(presetZones); break; case "PMOD": case "pmod": nextSubChunk.GetDataAsStructureArray(presetZoneModulators); break; case "PGEN": case "pgen": nextSubChunk.GetDataAsStructureArray(presetZoneGenerators); break; case "INST": case "inst": nextSubChunk.GetDataAsStructureArray(instruments); break; case "IBAG": case "ibag": nextSubChunk.GetDataAsStructureArray(instrumentZones); break; case "IMOD": case "imod": nextSubChunk.GetDataAsStructureArray(instrumentZoneModulators); break; case "IGEN": case "igen": nextSubChunk.GetDataAsStructureArray(instrumentZoneGenerators); break; case "SHDR": case "shdr": nextSubChunk.GetDataAsStructureArray(sampleHeaders); break; default: throw new InvalidDataException($"Unknown chunk type {nextSubChunk.ChunkID}"); } } instrumentZoneGenerators.Load(sampleHeaders.SampleHeaders); instrumentZones.Load(instrumentZoneModulators.Modulators, instrumentZoneGenerators.Generators); instruments.LoadZones(instrumentZones.Zones); presetZoneGenerators.Load(instruments.Instruments); presetZones.Load(presetZoneModulators.Modulators, presetZoneGenerators.Generators); presetHeaders.LoadZones(presetZones.Zones); sampleHeaders.RemoveEOS(); } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("Preset Headers:\r\n"); Preset[] presets = presetHeaders.Presets; foreach (Preset arg in presets) { stringBuilder.AppendFormat("{0}\r\n", arg); } stringBuilder.Append("Instruments:\r\n"); Instrument[] array = instruments.Instruments; foreach (Instrument arg2 in array) { stringBuilder.AppendFormat("{0}\r\n", arg2); } return stringBuilder.ToString(); } } internal class RiffChunk { private string chunkID; private uint chunkSize; private long dataOffset; private BinaryReader riffFile; public string ChunkID { get { return chunkID; } set { if (value == null) { throw new ArgumentNullException("ChunkID may not be null"); } if (value.Length != 4) { throw new ArgumentException("ChunkID must be four characters"); } chunkID = value; } } public uint ChunkSize => chunkSize; public long DataOffset => dataOffset; public static RiffChunk GetTopLevelChunk(BinaryReader file) { RiffChunk riffChunk = new RiffChunk(file); riffChunk.ReadChunk(); return riffChunk; } private RiffChunk(BinaryReader file) { riffFile = file; chunkID = "????"; chunkSize = 0u; dataOffset = 0L; } public string ReadChunkID() { byte[] array = riffFile.ReadBytes(4); if (array.Length != 4) { throw new InvalidDataException("Couldn't read Chunk ID"); } return ByteEncoding.Instance.GetString(array, 0, array.Length); } private void ReadChunk() { chunkID = ReadChunkID(); chunkSize = riffFile.ReadUInt32(); dataOffset = riffFile.BaseStream.Position; } public RiffChunk GetNextSubChunk() { if (riffFile.BaseStream.Position + 8 < dataOffset + chunkSize) { RiffChunk riffChunk = new RiffChunk(riffFile); riffChunk.ReadChunk(); return riffChunk; } return null; } public byte[] GetData() { riffFile.BaseStream.Position = dataOffset; byte[] array = riffFile.ReadBytes((int)chunkSize); if (array.Length != chunkSize) { throw new InvalidDataException($"Couldn't read chunk's data Chunk: {this}, read {array.Length} bytes"); } return array; } public string GetDataAsString() { byte[] data = GetData(); if (data == null) { return null; } return ByteEncoding.Instance.GetString(data, 0, data.Length); } public T GetDataAsStructure<T>(StructureBuilder<T> s) { riffFile.BaseStream.Position = dataOffset; if (s.Length != chunkSize) { throw new InvalidDataException($"Chunk size is: {chunkSize} so can't read structure of: {s.Length}"); } return s.Read(riffFile); } public T[] GetDataAsStructureArray<T>(StructureBuilder<T> s) { riffFile.BaseStream.Position = dataOffset; if (chunkSize % s.Length != 0L) { throw new InvalidDataException($"Chunk size is: {chunkSize} not a multiple of structure size: {s.Length}"); } int num = (int)(chunkSize / s.Length); T[] array = new T[num]; for (int i = 0; i < num; i++) { array[i] = s.Read(riffFile); } return array; } public override string ToString() { return $"RiffChunk ID: {ChunkID} Size: {ChunkSize} Data Offset: {DataOffset}"; } } internal class SampleDataChunk { private byte[] sampleData; public byte[] SampleData => sampleData; public SampleDataChunk(RiffChunk chunk) { string text = chunk.ReadChunkID(); if (text != "sdta") { throw new InvalidDataException($"Not a sample data chunk ({text})"); } sampleData = chunk.GetData(); } } public class SampleHeader { public string SampleName; public uint Start; public uint End; public uint StartLoop; public uint EndLoop; public uint SampleRate; public byte OriginalPitch; public sbyte PitchCorrection; public ushort SampleLink; public SFSampleLink SFSampleLink; public override string ToString() { return SampleName; } } internal class SampleHeaderBuilder : StructureBuilder<SampleHeader> { public override int Length => 46; public SampleHeader[] SampleHeaders => data.ToArray(); public override SampleHeader Read(BinaryReader br) { SampleHeader sampleHeader = new SampleHeader(); byte[] array = br.ReadBytes(20); sampleHeader.SampleName = ByteEncoding.Instance.GetString(array, 0, array.Length); sampleHeader.Start = br.ReadUInt32(); sampleHeader.End = br.ReadUInt32(); sampleHeader.StartLoop = br.ReadUInt32(); sampleHeader.EndLoop = br.ReadUInt32(); sampleHeader.SampleRate = br.ReadUInt32(); sampleHeader.OriginalPitch = br.ReadByte(); sampleHeader.PitchCorrection = br.ReadSByte(); sampleHeader.SampleLink = br.ReadUInt16(); sampleHeader.SFSampleLink = (SFSampleLink)br.ReadUInt16(); data.Add(sampleHeader); return sampleHeader; } public override void Write(BinaryWriter bw, SampleHeader sampleHeader) { } internal void RemoveEOS() { data.RemoveAt(data.Count - 1); } } public enum SampleMode { NoLoop, LoopContinuously, ReservedNoLoop, LoopAndContinue } public enum SFSampleLink : ushort { MonoSample = 1, RightSample = 2, LeftSample = 4, LinkedSample = 8, RomMonoSample = 32769, RomRightSample = 32770, RomLeftSample = 32772, RomLinkedSample = 32776 } public class SFVersion { private short major; private short minor; public short Major { get { return major; } set { major = value; } } public short Minor { get { return minor; } set { minor = value; } } } internal class SFVersionBuilder : StructureBuilder<SFVersion> { public override int Length => 4; public override SFVersion Read(BinaryReader br) { SFVersion sFVersion = new SFVersion(); sFVersion.Major = br.ReadInt16(); sFVersion.Minor = br.ReadInt16(); data.Add(sFVersion); return sFVersion; } public override void Write(BinaryWriter bw, SFVersion v) { bw.Write(v.Major); bw.Write(v.Minor); } } public class SoundFont { private InfoChunk info; private PresetsChunk presetsChunk; private SampleDataChunk sampleData; public InfoChunk FileInfo => info; public Preset[] Presets => presetsChunk.Presets; public Instrument[] Instruments => presetsChunk.Instruments; public SampleHeader[] SampleHeaders => presetsChunk.SampleHeaders; public byte[] SampleData => sampleData.SampleData; public SoundFont(string fileName) : this(new FileStream(fileName, FileMode.Open, FileAccess.Read)) { } public SoundFont(Stream sfFile) { using (sfFile) { RiffChunk topLevelChunk = RiffChunk.GetTopLevelChunk(new BinaryReader(sfFile)); if (topLevelChunk.ChunkID == "RIFF") { string text = topLevelChunk.ReadChunkID(); if (text != "sfbk") { throw new InvalidDataException($"Not a SoundFont ({text})"); } RiffChunk nextSubChunk = topLevelChunk.GetNextSubChunk(); if (nextSubChunk.ChunkID == "LIST") { info = new InfoChunk(nextSubChunk); RiffChunk nextSubChunk2 = topLevelChunk.GetNextSubChunk(); sampleData = new SampleDataChunk(nextSubChunk2); nextSubChunk2 = topLevelChunk.GetNextSubChunk(); presetsChunk = new PresetsChunk(nextSubChunk2); return; } throw new InvalidDataException($"Not info list found ({nextSubChunk.ChunkID})"); } throw new InvalidDataException("Not a RIFF file"); } } public override string ToString() { return $"Info Chunk:\r\n{info}\r\nPresets Chunk:\r\n{presetsChunk}"; } } internal abstract class StructureBuilder<T> { protected List<T> data; public abstract int Length { get; } public T[] Data => data.ToArray(); public StructureBuilder() { Reset(); } public abstract T Read(BinaryReader br); public abstract void Write(BinaryWriter bw, T o); public void Reset() { data = new List<T>(); } } public class Zone { internal ushort generatorIndex; internal ushort modulatorIndex; internal ushort generatorCount; internal ushort modulatorCount; private Modulator[] modulators; private Generator[] generators; public Modulator[] Modulators { get { return modulators; } set { modulators = value; } } public Generator[] Generators { get { return generators; } set { generators = value; } } public override string ToString() { return $"Zone {generatorCount} Gens:{generatorIndex} {modulatorCount} Mods:{modulatorIndex}"; } } internal class ZoneBuilder : StructureBuilder<Zone> { private Zone lastZone; public Zone[] Zones => data.ToArray(); public override int Length => 4; public override Zone Read(BinaryReader br) { Zone zone = new Zone(); zone.generatorIndex = br.ReadUInt16(); zone.modulatorIndex = br.ReadUInt16(); if (lastZone != null) { lastZone.generatorCount = (ushort)(zone.generatorIndex - lastZone.generatorIndex); lastZone.modulatorCount = (ushort)(zone.modulatorIndex - lastZone.modulatorIndex); } data.Add(zone); lastZone = zone; return zone; } public override void Write(BinaryWriter bw, Zone zone) { } public void Load(Modulator[] modulators, Generator[] generators) { for (int i = 0; i < data.Count - 1; i++) { Zone zone = data[i]; zone.Generators = new Generator[zone.generatorCount]; Array.Copy(generators, zone.generatorIndex, zone.Generators, 0, zone.generatorCount); zone.Modulators = new Modulator[zone.modulatorCount]; Array.Copy(modulators, zone.modulatorIndex, zone.Modulators, 0, zone.modulatorCount); } data.RemoveAt(data.Count - 1); } } } namespace NAudio.Dmo { internal class AudioMediaSubtypes { public static readonly Guid MEDIASUBTYPE_PCM = new Guid("00000001-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_PCMAudioObsolete = new Guid("e436eb8a-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_MPEG1Packet = new Guid("e436eb80-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_MPEG1Payload = new Guid("e436eb81-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_MPEG2_AUDIO = new Guid("e06d802b-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid MEDIASUBTYPE_DVD_LPCM_AUDIO = new Guid("e06d8032-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid MEDIASUBTYPE_DRM_Audio = new Guid("00000009-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_IEEE_FLOAT = new Guid("00000003-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_DOLBY_AC3 = new Guid("e06d802c-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid MEDIASUBTYPE_DOLBY_AC3_SPDIF = new Guid("00000092-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_RAW_SPORT = new Guid("00000240-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_SPDIF_TAG_241h = new Guid("00000241-0000-0010-8000-00aa00389b71"); public static readonly Guid WMMEDIASUBTYPE_MP3 = new Guid("00000055-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_WAVE = new Guid("e436eb8b-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_AU = new Guid("e436eb8c-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_AIFF = new Guid("e436eb8d-524f-11ce-9f53-0020af0ba770"); public static readonly Guid[] AudioSubTypes = new Guid[13] { MEDIASUBTYPE_PCM, MEDIASUBTYPE_PCMAudioObsolete, MEDIASUBTYPE_MPEG1Packet, MEDIASUBTYPE_MPEG1Payload, MEDIASUBTYPE_MPEG2_AUDIO, MEDIASUBTYPE_DVD_LPCM_AUDIO, MEDIASUBTYPE_DRM_Audio, MEDIASUBTYPE_IEEE_FLOAT, MEDIASUBTYPE_DOLBY_AC3, MEDIASUBTYPE_DOLBY_AC3_SPDIF, MEDIASUBTYPE_RAW_SPORT, MEDIASUBTYPE_SPDIF_TAG_241h, WMMEDIASUBTYPE_MP3 }; public static readonly string[] AudioSubTypeNames = new string[13] { "PCM", "PCM Obsolete", "MPEG1Packet", "MPEG1Payload", "MPEG2_AUDIO", "DVD_LPCM_AUDIO", "DRM_Audio", "IEEE_FLOAT", "DOLBY_AC3", "DOLBY_AC3_SPDIF", "RAW_SPORT", "SPDIF_TAG_241h", "MP3" }; public static string GetAudioSubtypeName(Guid subType) { for (int i = 0; i < AudioSubTypes.Length; i++) { if (subType == AudioSubTypes[i]) { return AudioSubTypeNames[i]; } } return subType.ToString(); } } public class DmoDescriptor { public string Name { get; private set; } public Guid Clsid { get; private set; } public DmoDescriptor(string name, Guid clsid) { Name = name; Clsid = clsid; } } public class DmoEnumerator { public static IEnumerable<DmoDescriptor> GetAudioEffectNames() { return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_EFFECT); } public static IEnumerable<DmoDescriptor> GetAudioEncoderNames() { return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_ENCODER); } public static IEnumerable<DmoDescriptor> GetAudioDecoderNames() { return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_DECODER); } private static IEnumerable<DmoDescriptor> GetDmos(Guid category) { Marshal.ThrowExceptionForHR(DmoInterop.DMOEnum(ref category, DmoEnumFlags.None, 0, null, 0, null, out var enumDmo)); int itemsFetched; do { enumDmo.Next(1, out var clsid, out var name, out itemsFetched); if (itemsFetched == 1) { string name2 = Marshal.PtrToStringUni(name); Marshal.FreeCoTaskMem(name); yield return new DmoDescriptor(name2, clsid); } } while (itemsFetched > 0); } } [Flags] internal enum DmoEnumFlags { None = 0, DMO_ENUMF_INCLUDE_KEYED = 1 } internal static class DmoGuids { public static readonly Guid DMOCATEGORY_AUDIO_DECODER = new Guid("57f2db8b-e6bb-4513-9d43-dcd2a6593125"); public static readonly Guid DMOCATEGORY_AUDIO_ENCODER = new Guid("33D9A761-90C8-11d0-BD43-00A0C911CE86"); public static readonly Guid DMOCATEGORY_VIDEO_DECODER = new Guid("4a69b442-28be-4991-969c-b500adf5d8a8"); public static readonly Guid DMOCATEGORY_VIDEO_ENCODER = new Guid("33D9A760-90C8-11d0-BD43-00A0C911CE86"); public static readonly Guid DMOCATEGORY_AUDIO_EFFECT = new Guid("f3602b3f-0592-48df-a4cd-674721e7ebeb"); public static readonly Guid DMOCATEGORY_VIDEO_EFFECT = new Guid("d990ee14-776c-4723-be46-3da2f56f10b9"); public static readonly Guid DMOCATEGORY_AUDIO_CAPTURE_EFFECT = new Guid("f665aaba-3e09-4920-aa5f-219811148f09"); } internal static class DmoMediaTypeGuids { public static readonly Guid FORMAT_None = new Guid("0F6417D6-C318-11D0-A43F-00A0C9223196"); public static readonly Guid FORMAT_VideoInfo = new Guid("05589f80-c356-11ce-bf01-00aa0055595a"); public static readonly Guid FORMAT_VideoInfo2 = new Guid("F72A76A0-EB0A-11d0-ACE4-0000C0CC16BA"); public static readonly Guid FORMAT_WaveFormatEx = new Guid("05589f81-c356-11ce-bf01-00aa0055595a"); public static readonly Guid FORMAT_MPEGVideo = new Guid("05589f82-c356-11ce-bf01-00aa0055595a"); public static readonly Guid FORMAT_MPEGStreams = new Guid("05589f83-c356-11ce-bf01-00aa0055595a"); public static readonly Guid FORMAT_DvInfo = new Guid("05589f84-c356-11ce-bf01-00aa0055595a"); public static readonly Guid FORMAT_525WSS = new Guid("C7ECF04D-4582-4869-9ABB-BFB523B62EDF"); } internal enum DmoHResults { DMO_E_INVALIDSTREAMINDEX = -2147220991, DMO_E_INVALIDTYPE, DMO_E_TYPE_NOT_SET, DMO_E_NOTACCEPTING, DMO_E_TYPE_NOT_ACCEPTED, DMO_E_NO_MORE_ITEMS } internal static class DmoInterop { [DllImport("msdmo.dll")] public static extern int DMOEnum([In] ref Guid guidCategory, DmoEnumFlags flags, int inTypes, [In] DmoPartialMediaType[] inTypesArray, int outTypes, [In] DmoPartialMediaType[] outTypesArray, out IEnumDmo enumDmo); [DllImport("msdmo.dll")] public static extern int MoFreeMediaType([In] ref DmoMediaType mediaType); [DllImport("msdmo.dll")] public static extern int MoInitMediaType([In][Out] ref DmoMediaType mediaType, int formatBlockBytes); [DllImport("msdmo.dll")] public static extern int DMOGetName([In] ref Guid clsidDMO, [Out] StringBuilder name); } internal struct DmoPartialMediaType { private Guid type; private Guid subtype; public Guid Type { get { return type; } internal set { type = value; } } public Guid Subtype { get { return subtype; } internal set { subtype = value; } } } [ComImport] [SuppressUnmanagedCodeSecurity] [Guid("6d6cbb60-a223-44aa-842f-a2f06750be6d")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IMediaParamInfo { [PreserveSig] int GetParamCount(out int paramCount); [PreserveSig] int GetParamInfo(int paramIndex, ref MediaParamInfo paramInfo); [PreserveSig] int GetParamText(int paramIndex, out IntPtr paramText); [PreserveSig] int GetNumTimeFormats(out int numTimeFormats); [PreserveSig] int GetSupportedTimeFormat(int formatIndex, out Guid guidTimeFormat); [PreserveSig] int GetCurrentTimeFormat(out Guid guidTimeFormat, out int mediaTimeData); } [Guid("E7E9984F-F09F-4da4-903F-6E2E0EFE56B5")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IWMResamplerProps { int SetHalfFilterLength(int outputQuality); int SetUserChannelMtx([In] float[] channelConversionMatrix); } public class MediaBuffer : IMediaBuffer, IDisposable { private IntPtr buffer; private int length; private readonly int maxLength; public int Length { get { return length; } set { if (length > maxLength) { throw new ArgumentException("Cannot be greater than maximum buffer size"); } length = value; } } public MediaBuffer(int maxLength) { buffer = Marshal.AllocCoTaskMem(maxLength); this.maxLength = maxLength; } public void Dispose() { if (buffer != IntPtr.Zero) { Marshal.FreeCoTaskMem(buffer); buffer = IntPtr.Zero; GC.SuppressFinalize(this); } } ~MediaBuffer() { Dispose(); } int IMediaBuffer.SetLength(int length) { if (length > maxLength) { return -2147483645; } this.length = length; return 0; } int IMediaBuffer.GetMaxLength(out int maxLength) { maxLength = this.maxLength; return 0; } int IMediaBuffer.GetBufferAndLength(IntPtr bufferPointerPointer, IntPtr validDataLengthPointer) { if (bufferPointerPointer != IntPtr.Zero) { Marshal.WriteIntPtr(bufferPointerPointer, buffer); } if (validDataLengthPointer != IntPtr.Zero) { Marshal.WriteInt32(validDataLengthPointer, length); } return 0; } public void LoadData(byte[] data, int bytes) { Length = bytes; Marshal.Copy(data, 0, buffer, bytes); } public void RetrieveData(byte[] data, int offset) { Marshal.Copy(buffer, data, offset, Length); } } public class MediaObject : IDisposable { private IMediaObject mediaObject; private readonly int inputStreams; private readonly int outputStreams; public int InputStreamCount => inputStreams; public int OutputStreamCount => outputStreams; internal MediaObject(IMediaObject mediaObject) { this.mediaObject = mediaObject; mediaObject.GetStreamCount(out inputStreams, out outputStreams); } public DmoMediaType? GetInputType(int inputStream, int inputTypeIndex) { try { if (mediaObject.GetInputType(inputStream, inputTypeIndex, out var mediaType) == 0) { DmoInterop.MoFreeMediaType(ref mediaType); return mediaType; } } catch (COMException exception) { if (exception.GetHResult() != -2147220986) { throw; } } return null; } public DmoMediaType? GetOutputType(int outputStream, int outputTypeIndex) { try { if (mediaObject.GetOutputType(outputStream, outputTypeIndex, out var mediaType) == 0) { DmoInterop.MoFreeMediaType(ref mediaType); return mediaType; } } catch (COMException exception) { if (exception.GetHResult() != -2147220986) { throw; } } return null; } public DmoMediaType GetOutputCurrentType(int outputStreamIndex) { DmoMediaType mediaType; int outputCurrentType = mediaObject.GetOutputCurrentType(outputStreamIndex, out mediaType); switch (outputCurrentType) { case 0: DmoInterop.MoFreeMediaType(ref mediaType); return mediaType; case -2147220989: throw new InvalidOperationException("Media type was not set."); default: throw Marshal.GetExceptionForHR(outputCurrentType); } } public IEnumerable<DmoMediaType> GetInputTypes(int inputStreamIndex) { int typeIndex = 0; while (true) { DmoMediaType? inputType; DmoMediaType? mediaType = (inputType = GetInputType(inputStreamIndex, typeIndex)); inputType = inputType; if (inputType.HasValue) { yield return mediaType.Value; typeIndex++; continue; } break; } } public IEnumerable<DmoMediaType> GetOutputTypes(int outputStreamIndex) { int typeIndex = 0; while (true) { DmoMediaType? outputType; DmoMediaType? mediaType = (outputType = GetOutputType(outputStreamIndex, typeIndex)); outputType = outputType; if (outputType.HasValue) { yield return mediaType.Value; typeIndex++; continue; } break; } } public bool SupportsInputType(int inputStreamIndex, DmoMediaType mediaType) { return SetInputType(inputStreamIndex, mediaType, DmoSetTypeFlags.DMO_SET_TYPEF_TEST_ONLY); } private bool SetInputType(int inputStreamIndex, DmoMediaType mediaType, DmoSetTypeFlags flags) { switch (mediaObject.SetInputType(inputStreamIndex, ref mediaType, flags)) { case -2147220991: throw new ArgumentException("Invalid stream index"); default: _ = -2147220987; return false; case 0: return true; } } public void SetInputType(int inputStreamIndex, DmoMediaType mediaType) { if (!SetInputType(inputStreamIndex, mediaType, DmoSetTypeFlags.None)) { throw new ArgumentException("Media Type not supported"); } } public void SetInputWaveFormat(int inputStreamIndex, WaveFormat waveFormat) { DmoMediaType mediaType = CreateDmoMediaTypeForWaveFormat(waveFormat); bool num = SetInputType(inputStreamIndex, mediaType, DmoSetTypeFlags.None); DmoInterop.MoFreeMediaType(ref mediaType); if (!num) { throw new ArgumentException("Media Type not supported"); } } public bool SupportsInputWaveFormat(int inputStreamIndex, WaveFormat waveFormat) { DmoMediaType mediaType = CreateDmoMediaTypeForWaveFormat(waveFormat); bool result = SetInputType(inputStreamIndex, mediaType, DmoSetTypeFlags.DMO_SET_TYPEF_TEST_ONLY); DmoInterop.MoFreeMediaType(ref mediaType); return result; } private DmoMediaType CreateDmoMediaTypeForWaveFormat(WaveFormat waveFormat) { DmoMediaType mediaType = default(DmoMediaType); int formatBlockBytes = Marshal.SizeOf((object)waveFormat); DmoInterop.MoInitMediaType(ref mediaType, formatBlockBytes); mediaType.SetWaveFormat(waveFormat); return mediaType; } public bool SupportsOutputType(int outputStreamIndex, DmoMediaType mediaType) { return SetOutputType(outputStreamIndex, mediaType, DmoSetTypeFlags.DMO_SET_TYPEF_TEST_ONLY); } public bool SupportsOutputWaveFormat(int outputStreamIndex, WaveFormat waveFormat) { DmoMediaType mediaType = CreateDmoMediaTypeForWaveFormat(waveFormat); bool result = SetOutputType(outputStreamIndex, mediaType, DmoSetTypeFlags.DMO_SET_TYPEF_TEST_ONLY); DmoInterop.MoFreeMediaType(ref mediaType); return result; } private bool SetOutputType(int outputStreamIndex, DmoMediaType mediaType, DmoSetTypeFlags flags) { int num = mediaObject.SetOutputType(outputStreamIndex, ref mediaType, flags); return num switch { -2147220987 => false, 0 => true, _ => throw Marshal.GetExceptionForHR(num), }; } public void SetOutputType(int outputStreamIndex, DmoMediaType mediaType) { if (!SetOutputType(outputStreamIndex, mediaType, DmoSetTypeFlags.None)) { throw new ArgumentException("Media Type not supported"); } } public void SetOutputWaveFormat(int outputStreamIndex, WaveFormat waveFormat) { DmoMediaType mediaType = CreateDmoMediaTypeForWaveFormat(waveFormat); bool num = SetOutputType(outputStreamIndex, mediaType, DmoSetTypeFlags.None); DmoInterop.MoFreeMediaType(ref mediaType); if (!num) { throw new ArgumentException("Media Type not supported"); } } public MediaObjectSizeInfo GetInputSizeInfo(int inputStreamIndex) { Marshal.ThrowExceptionForHR(mediaObject.GetInputSizeInfo(inputStreamIndex, out var size, out var maxLookahead, out var alignment)); return new MediaObjectSizeInfo(size, maxLookahead, alignment); } public MediaObjectSizeInfo GetOutputSizeInfo(int outputStreamIndex) { Marshal.ThrowExceptionForHR(mediaObject.GetOutputSizeInfo(outputStreamIndex, out var size, out var alignment)); return new MediaObjectSizeInfo(size, 0, alignment); } public void ProcessInput(int inputStreamIndex, IMediaBuffer mediaBuffer, DmoInputDataBufferFlags flags, long timestamp, long duration) { Marshal.ThrowExceptionForHR(mediaObject.ProcessInput(inputStreamIndex, mediaBuffer, flags, timestamp, duration)); } public void ProcessOutput(DmoProcessOutputFlags flags, int outputBufferCount, DmoOutputDataBuffer[] outputBuffers) { Marshal.ThrowExceptionForHR(mediaObject.ProcessOutput(flags, outputBufferCount, outputBuffers, out var _)); } public void AllocateStreamingResources() { Marshal.ThrowExceptionForHR(mediaObject.AllocateStreamingResources()); } public void FreeStreamingResources() { Marshal.ThrowExceptionForHR(mediaObject.FreeStreamingResources()); } public long GetInputMaxLatency(int inputStreamIndex) { Marshal.ThrowExceptionForHR(mediaObject.GetInputMaxLatency(inputStreamIndex, out var referenceTimeMaxLatency)); return referenceTimeMaxLatency; } public void Flush() { Marshal.ThrowExceptionForHR(mediaObject.Flush()); } public void Discontinuity(int inputStreamIndex) { Marshal.ThrowExceptionForHR(mediaObject.Discontinuity(inputStreamIndex)); } public bool IsAcceptingData(int inputStreamIndex) { Marshal.ThrowExceptionForHR(mediaObject.GetInputStatus(inputStreamIndex, out var flags)); return (flags & DmoInputStatusFlags.DMO_INPUT_STATUSF_ACCEPT_DATA) == DmoInputStatusFlags.DMO_INPUT_STATUSF_ACCEPT_DATA; } public void Dispose() { if (mediaObject != null) { Marshal.ReleaseComObject(mediaObject); mediaObject = null; } } } public class MediaObjectSizeInfo { public int Size { get; private set; } public int MaxLookahead { get; } public int Alignment { get; } public MediaObjectSizeInfo(int size, int maxLookahead, int alignment) { Size = size; MaxLookahead = maxLookahead; Alignment = alignment; } public override string ToString() { return $"Size: {Size}, Alignment {Alignment}, MaxLookahead {MaxLookahead}"; } } internal struct MediaParamInfo { public MediaParamType mpType; public MediaParamCurveType mopCaps; public float mpdMinValue; public float mpdMaxValue; public float mpdNeutralValue; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szUnitText; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szLabel; } internal enum MediaParamType { Int, Float, Bool, Enum, Max } [Flags] internal enum MediaParamCurveType { MP_CURVE_JUMP = 1, MP_CURVE_LINEAR = 2, MP_CURVE_SQUARE = 4, MP_CURVE_INVSQUARE = 8, MP_CURVE_SINE = 0x10 } internal static class MediaTypes { public static readonly Guid MEDIATYPE_AnalogAudio = new Guid("0482DEE1-7817-11cf-8a03-00aa006ecb65"); public static readonly Guid MEDIATYPE_AnalogVideo = new Guid("0482DDE1-7817-11cf-8A03-00AA006ECB65"); public static readonly Guid MEDIATYPE_Audio = new Guid("73647561-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIATYPE_AUXLine21Data = new Guid("670AEA80-3A82-11d0-B79B-00AA003767A7"); public static readonly Guid MEDIATYPE_File = new Guid("656c6966-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIATYPE_Interleaved = new Guid("73766169-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIATYPE_Midi = new Guid("7364696D-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIATYPE_ScriptCommand = new Guid("73636d64-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIATYPE_Stream = new Guid("e436eb83-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIATYPE_Text = new Guid("73747874-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIATYPE_Timecode = new Guid("0482DEE3-7817-11cf-8a03-00aa006ecb65"); public static readonly Guid MEDIATYPE_Video = new Guid("73646976-0000-0010-8000-00AA00389B71"); public static readonly Guid[] MajorTypes = new Guid[12] { MEDIATYPE_AnalogAudio, MEDIATYPE_AnalogVideo, MEDIATYPE_Audio, MEDIATYPE_AUXLine21Data, MEDIATYPE_File, MEDIATYPE_Interleaved, MEDIATYPE_Midi, MEDIATYPE_ScriptCommand, MEDIATYPE_Stream, MEDIATYPE_Text, MEDIATYPE_Timecode, MEDIATYPE_Video }; public static readonly string[] MajorTypeNames = new string[12] { "Analog Audio", "Analog Video", "Audio", "AUXLine21Data", "File", "Interleaved", "Midi", "ScriptCommand", "Stream", "Text", "Timecode", "Video" }; public static string GetMediaTypeName(Guid majorType) { for (int i = 0; i < MajorTypes.Length; i++) { if (majorType == MajorTypes[i]) { return MajorTypeNames[i]; } } throw new ArgumentException("Major Type not found"); } } [ComImport] [Guid("bbeea841-0a63-4f52-a7ab-a9b3a84ed38a")] internal class WindowsMediaMp3DecoderComObject { } public class WindowsMediaMp3Decoder : IDisposable { private MediaObject mediaObject; private IPropertyStore propertyStoreInterface; private WindowsMediaMp3DecoderComObject mediaComObject; public MediaObject MediaObject => mediaObject; public WindowsMediaMp3Decoder() { mediaComObject = new WindowsMediaMp3DecoderComObject(); mediaObject = new MediaObject((IMediaObject)mediaComObject); propertyStoreInterface = (IPropertyStore)mediaComObject; } public void Dispose() { if (propertyStoreInterface != null) { Marshal.ReleaseComObject(propertyStoreInterface); propertyStoreInterface = null; } if (mediaObject != null) { mediaObject.Dispose(); mediaObject = null; } if (mediaComObject != null) { Marshal.ReleaseComObject(mediaComObject); mediaComObject = null; } } } [Flags] public enum DmoInputDataBufferFlags { None = 0, SyncPoint = 1, Time = 2, TimeLength = 4 } [Flags] internal enum DmoInputStatusFlags { None = 0, DMO_INPUT_STATUSF_ACCEPT_DATA = 1 } public struct DmoMediaType { private Guid majortype; private Guid subtype; private bool bFixedSizeSamples; private bool bTemporalCompression; private int lSampleSize; private Guid formattype; private IntPtr pUnk; private int cbFormat; private IntPtr pbFormat; public Guid MajorType => majortype; public string MajorTypeName => MediaTypes.GetMediaTypeName(majortype); public Guid SubType => subtype; public string SubTypeName { get { if (majortype == MediaTypes.MEDIATYPE_Audio) { return AudioMediaSubtypes.GetAudioSubtypeName(subtype); } return subtype.ToString(); } } public bool FixedSizeSamples => bFixedSizeSamples; public int SampleSize => lSampleSize; public Guid FormatType => formattype; public string FormatTypeName { get { if (formattype == DmoMediaTypeGuids.FORMAT_None) { return "None"; } if (formattype == Guid.Empty) { return "Null"; } if (formattype == DmoMediaTypeGuids.FORMAT_WaveFormatEx) { return "WaveFormatEx"; } return FormatType.ToString(); } } public WaveFormat GetWaveFormat() { if (formattype == DmoMediaTypeGuids.FORMAT_WaveFormatEx) { return WaveFormat.MarshalFromPtr(pbFormat); } throw new InvalidOperationException("Not a WaveFormat type"); } public void SetWaveFormat(WaveFormat waveFormat) { majortype = MediaTypes.MEDIATYPE_Audio; if (waveFormat is WaveFormatExtensible waveFormatExtensible) { subtype = waveFormatExtensible.SubFormat; } else { switch (waveFormat.Encoding) { case WaveFormatEncoding.Pcm: subtype = AudioMediaSubtypes.MEDIASUBTYPE_PCM; break; case WaveFormatEncoding.IeeeFloat: subtype = AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT; break; case WaveFormatEncoding.MpegLayer3: subtype = AudioMediaSubtypes.WMMEDIASUBTYPE_MP3; break; default: throw new ArgumentException($"Not a supported encoding {waveFormat.Encoding}"); } } bFixedSizeSamples = SubType == AudioMediaSubtypes.MEDIASUBTYPE_PCM || SubType == AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT; formattype = DmoMediaTypeGuids.FORMAT_WaveFormatEx; if (cbFormat < Marshal.SizeOf((object)waveFormat)) { throw new InvalidOperationException("Not enough memory assigned for a WaveFormat structure"); } Marshal.StructureToPtr((object)waveFormat, pbFormat, fDeleteOld: false); } } [StructLayout(LayoutKind.Sequential, Pack = 8)] public struct DmoOutputDataBuffer : IDisposable { [MarshalAs(UnmanagedType.Interface)] private IMediaBuffer pBuffer; private DmoOutputDataBufferFlags dwStatus; private long rtTimestamp; private long referenceTimeDuration; public IMediaBuffer MediaBuffer { get { return pBuffer; } internal set { pBuffer = value; } } public int Length => ((MediaBuffer)pBuffer).Length; public DmoOutputDataBufferFlags StatusFlags { get { return dwStatus; } internal set { dwStatus = value; } } public long Timestamp { get { return rtTimestamp; } internal set { rtTimestamp = value; } } public long Duration { get { return referenceTimeDuration; } internal set { referenceTimeDuration = value; } } public bool MoreDataAvailable => (StatusFlags & DmoOutputDataBufferFlags.Incomplete) == DmoOutputDataBufferFlags.Incomplete;
RiskOfMusic.dll
Decompiled 6 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; 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 BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using NAudio.Wave; using RoR2; using RoR2.ConVar; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.EventSystems; 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")] namespace UniversalCustomMusicManager; internal sealed class AudioPlayback : IDisposable { private sealed class TrackOutput : IDisposable { private readonly AudioFileReader _reader; private WaveOutEvent _player; private float _gain; private float _startGain; private float _targetGain; private float _fadeDuration; private float _fadeElapsed; private float _notPlayingElapsed; private bool _disposed; private bool _paused; private bool _hasEverPlayed; public volatile Exception Error; public string Path { get; private set; } public bool HasStarted { get; private set; } public bool Stopped { get; private set; } public bool HasEnded => Stopped; public bool IsPlaying { get { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 if (_player != null) { return (int)_player.PlaybackState == 1; } return false; } } public float Gain => _gain; public TrackOutput(string path, AudioFileReader reader) { Path = path; _reader = reader; } public void Initialize() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown _reader.Volume = 0f; _player = new WaveOutEvent(); _player.DesiredLatency = 100; _player.PlaybackStopped += OnPlaybackStopped; _player.Init((IWaveProvider)(object)_reader); } public void Play() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 _player.Play(); HasStarted = true; _paused = false; _hasEverPlayed = (int)_player.PlaybackState == 1; _notPlayingElapsed = 0f; } public void Pause() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 if (!HasStarted) { _paused = true; return; } _paused = true; _notPlayingElapsed = 0f; if ((int)_player.PlaybackState == 1) { _player.Pause(); } } public void Resume() { if (!HasStarted) { Play(); return; } _paused = false; _notPlayingElapsed = 0f; _player.Play(); } private void OnPlaybackStopped(object sender, StoppedEventArgs eventArgs) { if (!_disposed && eventArgs.Exception != null) { Error = eventArgs.Exception; } } public void SetGain(float target, float duration) { _startGain = _gain; _targetGain = Mathf.Clamp01(target); _fadeDuration = Mathf.Max(0f, duration); _fadeElapsed = 0f; if (_fadeDuration <= 0f) { _gain = _targetGain; } } public void Advance(float deltaTime) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Invalid comparison between Unknown and I4 float num = Mathf.Max(0f, deltaTime); if (_fadeDuration <= 0f) { _gain = _targetGain; } else { _fadeElapsed = Mathf.Min(_fadeDuration, _fadeElapsed + num); _gain = Mathf.Lerp(_startGain, _targetGain, _fadeElapsed / _fadeDuration); } if (!HasStarted || _paused || Stopped) { return; } if ((int)_player.PlaybackState == 1) { _hasEverPlayed = true; _notPlayingElapsed = 0f; return; } _notPlayingElapsed += num; if (!_hasEverPlayed && _notPlayingElapsed >= 2f) { Error = new InvalidOperationException("The audio device did not start playback within " + 2f + " seconds."); } else if (_hasEverPlayed && _notPlayingElapsed >= 0.25f) { Stopped = true; } } public void ApplyVolume(float masterVolume) { if (_reader != null) { _reader.Volume = Mathf.Clamp01(_gain * masterVolume); } } public void Dispose() { if (_disposed) { return; } _disposed = true; Stopped = true; if (_player != null) { _player.PlaybackStopped -= OnPlaybackStopped; try { _player.Stop(); } catch { } try { _player.Dispose(); } catch { } } try { ((Stream)(object)_reader).Dispose(); } catch { } } } private const float TrackFadeSeconds = 0.8f; private const float ResumeFadeSeconds = 0.25f; private const float StartupTimeoutSeconds = 2f; private readonly ManualLogSource _log; private readonly List<TrackOutput> _fadingOutputs = new List<TrackOutput>(); private TrackOutput _current; private float _musicVolume = 1f; private bool _paused; public string CurrentPath { get { if (_current != null) { return _current.Path; } return null; } } public bool IsPlaying { get { if (_current != null) { return _current.IsPlaying; } return false; } } public bool HasActiveTrack { get { if (_current != null) { return !_current.Stopped; } return false; } } public AudioPlayback(ManualLogSource log) { _log = log; } public bool TryPlay(string path, float musicVolume, bool paused, out string error) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown error = null; TrackOutput trackOutput = null; AudioFileReader val = null; try { val = new AudioFileReader(path); if (((WaveStream)val).TotalTime <= TimeSpan.Zero) { throw new InvalidDataException("The MP3 has no playable duration."); } trackOutput = new TrackOutput(path, val); val = null; trackOutput.Initialize(); if (paused) { trackOutput.Pause(); } else { trackOutput.Play(); } DisposeFadingOutputs(); if (_current != null) { _current.SetGain(0f, 0.8f); _fadingOutputs.Add(_current); } _current = trackOutput; _musicVolume = Mathf.Clamp01(musicVolume); _paused = paused; trackOutput.SetGain(paused ? 0f : 1f, paused ? 0f : 0.8f); trackOutput.ApplyVolume(_musicVolume); return true; } catch (Exception ex) { if (trackOutput != null) { DisposeOutput(trackOutput); } if (val != null) { try { ((Stream)(object)val).Dispose(); } catch { } } error = ex.Message; _log.LogWarning((object)("Could not start MP3 '" + Path.GetFileName(path) + "': " + ex)); return false; } } public void SetPaused(bool paused) { if (_paused == paused) { return; } _paused = paused; if (_current != null) { if (paused) { _current.SetGain(0f, 0f); _current.ApplyVolume(_musicVolume); PauseOutput(_current); } else { _current.SetGain(1f, 0.25f); _current.ApplyVolume(_musicVolume); ResumeOutput(_current); } } foreach (TrackOutput fadingOutput in _fadingOutputs) { if (paused) { PauseOutput(fadingOutput); } else { ResumeOutput(fadingOutput); } } } public bool Tick(float deltaTime, float musicVolume) { _musicVolume = Mathf.Clamp01(musicVolume); bool result = false; if (_current != null) { if (!_paused) { _current.Advance(deltaTime); } _current.ApplyVolume(_musicVolume); if (_current.Error != null) { _log.LogWarning((object)("MP3 playback stopped with an error: " + _current.Error)); DisposeOutput(_current); _current = null; result = true; } else if (!_paused && _current.HasEnded) { DisposeOutput(_current); _current = null; result = true; } } for (int num = _fadingOutputs.Count - 1; num >= 0; num--) { TrackOutput trackOutput = _fadingOutputs[num]; if (!_paused) { trackOutput.Advance(deltaTime); } trackOutput.ApplyVolume(_musicVolume); if (trackOutput.Gain <= 0.0001f || trackOutput.Error != null || trackOutput.HasEnded) { DisposeOutput(trackOutput); _fadingOutputs.RemoveAt(num); } } return result; } public void StopImmediate() { if (_current != null) { DisposeOutput(_current); _current = null; } DisposeFadingOutputs(); } public void Dispose() { StopImmediate(); } private void DisposeFadingOutputs() { foreach (TrackOutput fadingOutput in _fadingOutputs) { DisposeOutput(fadingOutput); } _fadingOutputs.Clear(); } private static void PauseOutput(TrackOutput output) { output.Pause(); } private static void ResumeOutput(TrackOutput output) { output.Resume(); } private static void DisposeOutput(TrackOutput output) { output?.Dispose(); } } internal static class Localizer { private static readonly string[] Keys = new string[28] { "music", "close", "search", "all", "favorites", "shuffle", "repeat", "nowPlaying", "previous", "next", "delete", "cancel", "confirm", "deletePrompt", "noTracks", "noFavorites", "noResults", "pressKey", "previousBinding", "nextBinding", "back", "deleted", "deleteFailed", "emptyPool", "clearSearch", "playTrack", "addFavorite", "removeFavorite" }; private static readonly Dictionary<string, string[]> Text = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase) { { "en", new string[28] { "Music", "Close", "Search", "All Tracks", "Favorites", "Shuffle", "Repeat Track", "Now Playing: {0}", "Previous Track", "Next Track", "Delete", "Cancel", "Confirm", "Delete the MP3 file '{0}' from the Music folder?", "No MP3 tracks found.", "No favorite tracks.", "No search results.", "Press a key, or Escape to cancel.", "Previous Track", "Next Track", "Back", "Track deleted.", "Could not delete the MP3: {0}", "No tracks are available in this list.", "Clear", "Play: {0}", "Add favorite", "Remove favorite" } }, { "ru", new string[28] { "Музыка", "Закрыть", "Поиск", "Все треки", "Избранное", "Случайно", "Повтор трека", "Сейчас играет: {0}", "Предыдущий трек", "Следующий трек", "Удалить", "Отмена", "Удалить", "Удалить MP3-файл «{0}» из папки Music?", "MP3-треки не найдены.", "Избранных треков нет.", "Ничего не найдено.", "Нажмите клавишу или Esc для отмены.", "Предыдущий трек", "Следующий трек", "Назад", "Трек удалён.", "Не удалось удалить MP3: {0}", "В этом списке нет доступных треков.", "Очистить", "Играть: {0}", "В избранное", "Убрать из избранного" } }, { "de", new string[28] { "Musik", "Schließen", "Suche", "Alle Titel", "Favoriten", "Zufall", "Titel wiederholen", "Läuft gerade: {0}", "Vorheriger Titel", "Nächster Titel", "Löschen", "Abbrechen", "Bestätigen", "MP3-Datei '{0}' aus dem Ordner Music löschen?", "Keine MP3-Titel gefunden.", "Keine Favoriten vorhanden.", "Keine Suchergebnisse.", "Taste drücken oder mit Escape abbrechen.", "Vorheriger Titel", "Nächster Titel", "Zurück", "Titel gelöscht.", "MP3 konnte nicht gelöscht werden: {0}", "In dieser Liste sind keine Titel verfügbar.", "Leeren", "Abspielen: {0}", "Zu Favoriten", "Aus Favoriten entfernen" } }, { "fr", new string[28] { "Musique", "Fermer", "Rechercher", "Tous les morceaux", "Favoris", "Aléatoire", "Répéter le morceau", "Lecture en cours : {0}", "Morceau précédent", "Morceau suivant", "Supprimer", "Annuler", "Confirmer", "Supprimer le fichier MP3 « {0} » du dossier Music ?", "Aucun morceau MP3 trouvé.", "Aucun favori.", "Aucun résultat.", "Appuyez sur une touche ou Échap pour annuler.", "Morceau précédent", "Morceau suivant", "Retour", "Morceau supprimé.", "Impossible de supprimer le MP3 : {0}", "Aucun morceau disponible dans cette liste.", "Effacer", "Lire : {0}", "Ajouter aux favoris", "Retirer des favoris" } }, { "it", new string[28] { "Musica", "Chiudi", "Cerca", "Tutti i brani", "Preferiti", "Casuale", "Ripeti brano", "In riproduzione: {0}", "Brano precedente", "Brano successivo", "Elimina", "Annulla", "Conferma", "Eliminare il file MP3 '{0}' dalla cartella Music?", "Nessun brano MP3 trovato.", "Nessun brano preferito.", "Nessun risultato.", "Premi un tasto o Esc per annullare.", "Brano precedente", "Brano successivo", "Indietro", "Brano eliminato.", "Impossibile eliminare l'MP3: {0}", "Nessun brano disponibile in questo elenco.", "Cancella", "Riproduci: {0}", "Aggiungi ai preferiti", "Rimuovi dai preferiti" } }, { "es", new string[28] { "Música", "Cerrar", "Buscar", "Todas las canciones", "Favoritas", "Aleatorio", "Repetir canción", "Reproduciendo: {0}", "Canción anterior", "Canción siguiente", "Eliminar", "Cancelar", "Confirmar", "¿Eliminar el archivo MP3 '{0}' de la carpeta Music?", "No se encontraron canciones MP3.", "No hay canciones favoritas.", "No hay resultados.", "Pulsa una tecla o Escape para cancelar.", "Canción anterior", "Canción siguiente", "Volver", "Canción eliminada.", "No se pudo eliminar el MP3: {0}", "No hay canciones disponibles en esta lista.", "Limpiar", "Reproducir: {0}", "Añadir a favoritas", "Quitar de favoritas" } }, { "pt", new string[28] { "Música", "Fechar", "Pesquisar", "Todas as faixas", "Favoritas", "Aleatório", "Repetir faixa", "Tocando agora: {0}", "Faixa anterior", "Próxima faixa", "Excluir", "Cancelar", "Confirmar", "Excluir o arquivo MP3 '{0}' da pasta Music?", "Nenhuma faixa MP3 encontrada.", "Nenhuma faixa favorita.", "Nenhum resultado.", "Pressione uma tecla ou Esc para cancelar.", "Faixa anterior", "Próxima faixa", "Voltar", "Faixa excluída.", "Não foi possível excluir o MP3: {0}", "Não há faixas disponíveis nesta lista.", "Limpar", "Reproduzir: {0}", "Adicionar aos favoritos", "Remover dos favoritos" } }, { "ja", new string[28] { "音楽", "閉じる", "検索", "すべての曲", "お気に入り", "シャッフル", "曲をリピート", "再生中: {0}", "前の曲", "次の曲", "削除", "キャンセル", "確定", "Music フォルダーから MP3 ファイル「{0}」を削除しますか?", "MP3 が見つかりません。", "お気に入りの曲はありません。", "検索結果はありません。", "キーを押すか Esc でキャンセルしてください。", "前の曲", "次の曲", "戻る", "曲を削除しました。", "MP3 を削除できませんでした: {0}", "このリストに再生できる曲はありません。", "クリア", "{0} を再生", "お気に入りに追加", "お気に入りから削除" } }, { "ko", new string[28] { "음악", "닫기", "검색", "모든 트랙", "즐겨찾기", "셔플", "트랙 반복", "재생 중: {0}", "이전 트랙", "다음 트랙", "삭제", "취소", "확인", "Music 폴더에서 MP3 파일 '{0}'을(를) 삭제할까요?", "MP3 트랙이 없습니다.", "즐겨찾기 트랙이 없습니다.", "검색 결과가 없습니다.", "키를 누르거나 Esc를 눌러 취소하세요.", "이전 트랙", "다음 트랙", "뒤로", "트랙을 삭제했습니다.", "MP3를 삭제할 수 없습니다: {0}", "이 목록에 재생할 트랙이 없습니다.", "지우기", "재생: {0}", "즐겨찾기 추가", "즐겨찾기에서 제거" } }, { "tr", new string[28] { "Müzik", "Kapat", "Ara", "Tüm Parçalar", "Favoriler", "Karışık", "Parçayı Tekrarla", "Şimdi Çalıyor: {0}", "Önceki Parça", "Sonraki Parça", "Sil", "İptal", "Onayla", "'{0}' MP3 dosyası Music klasöründen silinsin mi?", "MP3 parçası bulunamadı.", "Favori parça yok.", "Arama sonucu yok.", "Bir tuşa basın veya iptal için Esc'e basın.", "Önceki Parça", "Sonraki Parça", "Geri", "Parça silindi.", "MP3 silinemedi: {0}", "Bu listede kullanılabilir parça yok.", "Temizle", "Çal: {0}", "Favorilere ekle", "Favorilerden kaldır" } }, { "zh", new string[28] { "音乐", "关闭", "搜索", "全部曲目", "收藏", "随机播放", "单曲循环", "正在播放:{0}", "上一首", "下一首", "删除", "取消", "确认", "要从 Music 文件夹删除 MP3 文件“{0}”吗?", "未找到 MP3 曲目。", "没有收藏曲目。", "没有搜索结果。", "按任意键,或按 Esc 取消。", "上一首", "下一首", "返回", "曲目已删除。", "无法删除 MP3:{0}", "此列表中没有可播放的曲目。", "清除", "播放:{0}", "添加收藏", "取消收藏" } } }; public static string Get(string key) { int num = Array.IndexOf(Keys, key); if (num < 0) { return key; } if (!Text.TryGetValue(GetLanguageCode(), out var value)) { return Text["en"][num]; } return value[num]; } public static string Format(string key, params object[] arguments) { return string.Format(Get(key), arguments); } private static string GetLanguageCode() { string text = (Language.currentLanguageName ?? string.Empty).ToLowerInvariant(); if (text.StartsWith("ru")) { return "ru"; } if (text.StartsWith("de")) { return "de"; } if (text.StartsWith("fr")) { return "fr"; } if (text.StartsWith("it")) { return "it"; } if (text.StartsWith("es")) { return "es"; } if (text.StartsWith("pt")) { return "pt"; } if (text.StartsWith("ja")) { return "ja"; } if (text.StartsWith("ko")) { return "ko"; } if (text.StartsWith("tr")) { return "tr"; } if (text.StartsWith("zh")) { return "zh"; } return "en"; } } internal enum MusicIcon { Play, Star, Delete, Clear, Close, Shuffle, Repeat } internal static class MusicIcons { private const int TextureSize = 64; private static readonly Dictionary<MusicIcon, Sprite> Sprites = new Dictionary<MusicIcon, Sprite>(); public static Sprite Get(MusicIcon icon) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if (Sprites.TryGetValue(icon, out var value)) { return value; } Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); ((Object)val).name = "UCM_" + icon; ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = 0; for (int k = 0; k < 4; k++) { for (int l = 0; l < 4; l++) { float x = ((float)j + ((float)l + 0.5f) / 4f) / 64f * 2f - 1f; float y = ((float)i + ((float)k + 0.5f) / 4f) / 64f * 2f - 1f; if (Contains(icon, x, y)) { num++; } } } byte b = (byte)(num * 255 / 16); array[i * 64 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b); } } val.SetPixels32(array); val.Apply(false, true); value = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f); ((Object)value).name = "UCM_" + icon; Sprites.Add(icon, value); return value; } private static bool Contains(MusicIcon icon, float x, float y) { switch (icon) { case MusicIcon.Play: return InTriangle(x, y, -0.5f, -0.72f, -0.5f, 0.72f, 0.7f, 0f); case MusicIcon.Star: return InStar(x, y); case MusicIcon.Delete: if (!NearSegment(x, y, -0.38f, 0.25f, -0.28f, -0.56f, 0.075f) && !NearSegment(x, y, 0.38f, 0.25f, 0.28f, -0.56f, 0.075f) && !NearSegment(x, y, -0.28f, -0.56f, 0.28f, -0.56f, 0.075f) && !NearSegment(x, y, -0.52f, 0.34f, 0.52f, 0.34f, 0.075f) && !NearSegment(x, y, -0.2f, 0.53f, 0.2f, 0.53f, 0.075f) && !NearSegment(x, y, -0.2f, 0.53f, -0.2f, 0.43f, 0.075f)) { return NearSegment(x, y, 0.2f, 0.53f, 0.2f, 0.43f, 0.075f); } return true; case MusicIcon.Clear: case MusicIcon.Close: if (!NearSegment(x, y, -0.43f, -0.43f, 0.43f, 0.43f, 0.095f)) { return NearSegment(x, y, -0.43f, 0.43f, 0.43f, -0.43f, 0.095f); } return true; case MusicIcon.Shuffle: if (!NearSegment(x, y, -0.72f, 0.48f, -0.35f, 0.48f, 0.075f) && !NearSegment(x, y, -0.35f, 0.48f, 0.32f, -0.48f, 0.075f) && !NearSegment(x, y, 0.32f, -0.48f, 0.72f, -0.48f, 0.075f) && !NearSegment(x, y, -0.72f, -0.48f, -0.35f, -0.48f, 0.075f) && !NearSegment(x, y, -0.35f, -0.48f, 0.32f, 0.48f, 0.075f) && !NearSegment(x, y, 0.32f, 0.48f, 0.72f, 0.48f, 0.075f) && !InTriangle(x, y, 0.42f, -0.68f, 0.42f, -0.28f, 0.78f, -0.48f)) { return InTriangle(x, y, 0.42f, 0.28f, 0.42f, 0.68f, 0.78f, 0.48f); } return true; case MusicIcon.Repeat: { float num = Mathf.Sqrt(x * x + y * y); if (!(num > 0.44f) || !(num < 0.62f) || (y > 0.3f && x > -0.25f && x < 0.3f)) { return InTriangle(x, y, 0.05f, 0.34f, 0.43f, 0.72f, 0.48f, 0.24f); } return true; } default: return false; } } private static bool InCircle(float x, float y, float centerX, float centerY, float radius) { float num = x - centerX; float num2 = y - centerY; return num * num + num2 * num2 <= radius * radius; } private static bool InStar(float x, float y) { bool flag = false; float num = 0f; float num2 = 0.78f; for (int i = 1; i <= 10; i++) { float num3 = MathF.PI / 2f + (float)i * MathF.PI / 5f; float num4 = ((i % 2 == 0) ? 0.78f : 0.34f); float num5 = Mathf.Cos(num3) * num4; float num6 = Mathf.Sin(num3) * num4; if (num6 > y != num2 > y && x < (num - num5) * (y - num6) / (num2 - num6) + num5) { flag = !flag; } num = num5; num2 = num6; } return flag; } private static bool InTriangle(float x, float y, float ax, float ay, float bx, float by, float cx, float cy) { float num = (x - bx) * (ay - by) - (ax - bx) * (y - by); float num2 = (x - cx) * (by - cy) - (bx - cx) * (y - cy); float num3 = (x - ax) * (cy - ay) - (cx - ax) * (y - ay); bool flag = num < 0f || num2 < 0f || num3 < 0f; bool flag2 = num > 0f || num2 > 0f || num3 > 0f; return !(flag && flag2); } private static bool NearSegment(float x, float y, float ax, float ay, float bx, float by, float halfWidth) { float num = bx - ax; float num2 = by - ay; float num3 = num * num + num2 * num2; float num4 = Mathf.Clamp01(((x - ax) * num + (y - ay) * num2) / num3); float num5 = x - (ax + num4 * num); float num6 = y - (ay + num4 * num2); return num5 * num5 + num6 * num6 <= halfWidth * halfWidth; } } internal sealed class MusicTrack { public string FullPath { get; private set; } public string RelativePath { get; private set; } public string DisplayName { get; private set; } public string Id => RelativePath; public MusicTrack(string path) { FullPath = path; RelativePath = Path.GetFileName(path); DisplayName = Path.GetFileNameWithoutExtension(path); } } internal sealed class MusicLibrary { private static readonly StringComparer PathComparer = StringComparer.OrdinalIgnoreCase; private readonly ManualLogSource _log; private readonly ConfigEntry<bool> _shuffle; private readonly ConfigEntry<string> _savedFavorites; private readonly HashSet<string> _favorites = new HashSet<string>(PathComparer); private readonly List<MusicTrack> _tracks = new List<MusicTrack>(); public string RootPath { get; private set; } public bool FavoritesOnly { get; set; } public bool Shuffle { get { return _shuffle.Value; } set { _shuffle.Value = value; } } public IList<MusicTrack> Tracks => _tracks; public MusicLibrary(string rootPath, ConfigFile config, ManualLogSource log) { RootPath = Path.GetFullPath(rootPath); _log = log; _shuffle = config.Bind<bool>("Playback", "Shuffle", false, "Play tracks in random order."); _savedFavorites = config.Bind<string>("Tracks", "Favorites", string.Empty, "Saved favorite MP3 filenames."); LoadFavorites(_savedFavorites.Value); } public List<MusicTrack> GetActivePool() { return _tracks.Where((MusicTrack track) => !FavoritesOnly || _favorites.Contains(track.Id)).ToList(); } public bool IsFavorite(MusicTrack track) { if (track != null) { return _favorites.Contains(track.Id); } return false; } public bool Contains(string path) { return _tracks.Any((MusicTrack track) => PathComparer.Equals(track.FullPath, path)); } public MusicTrack FindById(string id) { return _tracks.FirstOrDefault((MusicTrack track) => PathComparer.Equals(track.Id, id)); } public void Rescan() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown Directory.CreateDirectory(RootPath); List<MusicTrack> list = new List<MusicTrack>(); string[] files = Directory.GetFiles(RootPath, "*", SearchOption.TopDirectoryOnly); foreach (string text in files) { if (!string.Equals(Path.GetExtension(text), ".mp3", StringComparison.OrdinalIgnoreCase)) { continue; } try { AudioFileReader val = new AudioFileReader(text); try { float[] array = new float[2048]; if (((WaveStream)val).TotalTime <= TimeSpan.Zero || val.Read(array, 0, array.Length) <= 0) { throw new InvalidDataException("The MP3 contains no readable audio frames."); } } finally { ((IDisposable)val)?.Dispose(); } list.Add(new MusicTrack(text)); } catch (Exception ex) { _log.LogWarning((object)("Skipping unreadable MP3 '" + Path.GetFileName(text) + "': " + ex.Message)); } } list.Sort(delegate(MusicTrack left, MusicTrack right) { int num = PathComparer.Compare(left.RelativePath, right.RelativePath); return (num == 0) ? StringComparer.Ordinal.Compare(left.RelativePath, right.RelativePath) : num; }); _tracks.Clear(); _tracks.AddRange(list); HashSet<string> available = new HashSet<string>(_tracks.Select((MusicTrack track) => track.Id), PathComparer); if (_favorites.RemoveWhere((string id) => !available.Contains(id)) > 0) { SaveFavorites(); } } public void ToggleFavorite(MusicTrack track) { if (track != null) { if (!_favorites.Add(track.Id)) { _favorites.Remove(track.Id); } SaveFavorites(); } } public bool DeleteFile(MusicTrack track, out string error) { error = null; if (track == null) { error = "Track no longer exists."; return false; } try { string value = Path.GetFullPath(RootPath).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar; string resolved = Path.GetFullPath(track.FullPath); if (!resolved.StartsWith(value, StringComparison.OrdinalIgnoreCase)) { error = "Resolved file path is outside the Music folder."; return false; } if (!File.Exists(resolved)) { error = "The MP3 file is missing."; return false; } File.Delete(resolved); _favorites.Remove(track.Id); SaveFavorites(); _tracks.RemoveAll((MusicTrack existing) => PathComparer.Equals(existing.FullPath, resolved)); return true; } catch (Exception ex) { error = ex.Message; return false; } } private void LoadFavorites(string serialized) { _favorites.Clear(); string[] array = (serialized ?? string.Empty).Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { try { _favorites.Add(Encoding.UTF8.GetString(Convert.FromBase64String(text.Trim()))); } catch (FormatException) { _log.LogWarning((object)"Ignoring an invalid saved favorite entry."); } } } private void SaveFavorites() { _savedFavorites.Value = string.Join("\n", from id in _favorites.OrderBy<string, string>((string id) => id, PathComparer) select Convert.ToBase64String(Encoding.UTF8.GetBytes(id))); } } internal sealed class MusicMenu : IDisposable { private readonly Plugin _plugin; private readonly ManualLogSource _log; private PauseScreenController _controller; private GameObject _musicButtonObject; private Button _musicButton; private GameObject _panelRoot; private GameObject _dialog; private RectTransform _trackContent; private TMP_InputField _search; private Button _clearSearchButton; private Button _shuffleButton; private Button _repeatButton; private Button _allTab; private Button _favoritesTab; private Button _previousBindingButton; private Button _nextBindingButton; private TMP_Text _titleLabel; private TMP_Text _nowPlayingLabel; private TMP_Text _statusLabel; private TMP_Text _emptyLabel; private string _searchValue = string.Empty; private bool _capturingPrevious; private bool _hasBindingCapture; private bool _mainPanelWasActive; private bool _pausePanelWasActive; private bool _gameMenuWasActive; private GameObject _previousSelectedObject; private bool _musicButtonWasActive; private readonly List<GameObject> _rootChildrenBeforeOpen = new List<GameObject>(); private readonly List<bool> _rootChildStatesBeforeOpen = new List<bool>(); private MusicTrack _pendingDelete; public bool CapturingKey => _hasBindingCapture; public bool SearchFocused { get { if ((Object)(object)_search != (Object)null) { return _search.isFocused; } return false; } } public MusicMenu(Plugin plugin, ManualLogSource log) { _plugin = plugin; _log = log; } public void Attach(PauseScreenController controller) { if (!((Object)(object)controller == (Object)null) && (!((Object)(object)controller == (Object)(object)_controller) || !((Object)(object)_musicButtonObject != (Object)null))) { if ((Object)(object)_controller != (Object)null) { Detach(_controller); } _controller = controller; CreatePauseMenuButton(); } } public void Detach(PauseScreenController controller) { if (!((Object)(object)controller == (Object)null) && !((Object)(object)controller != (Object)(object)_controller)) { _hasBindingCapture = false; if ((Object)(object)_panelRoot != (Object)null) { Object.Destroy((Object)(object)_panelRoot); } if ((Object)(object)_musicButtonObject != (Object)null) { Object.Destroy((Object)(object)_musicButtonObject); } _panelRoot = null; _musicButtonObject = null; _musicButton = null; _controller = null; ClearPanelReferences(); } } public void Open() { if ((Object)(object)_controller == (Object)null || (Object)(object)_controller.rootPanel == (Object)null) { return; } _plugin.RescanLibrary(); if ((Object)(object)_panelRoot == (Object)null) { try { BuildPanel(); } catch (Exception ex) { if ((Object)(object)_panelRoot != (Object)null) { Object.Destroy((Object)(object)_panelRoot); } _panelRoot = null; ClearPanelReferences(); _log.LogError((object)("Could not build the music menu: " + ex)); return; } } _pausePanelWasActive = (Object)(object)_controller.pausePanel != (Object)null && ((Component)_controller.pausePanel).gameObject.activeSelf; _gameMenuWasActive = (Object)(object)_controller.gameMenuPanel != (Object)null && ((Component)_controller.gameMenuPanel).gameObject.activeSelf; _mainPanelWasActive = (Object)(object)_controller.mainPanel != (Object)null && ((Component)_controller.mainPanel).gameObject.activeSelf; _previousSelectedObject = (((Object)(object)EventSystem.current == (Object)null) ? null : EventSystem.current.currentSelectedGameObject); _musicButtonWasActive = (Object)(object)_musicButtonObject != (Object)null && _musicButtonObject.activeSelf; _rootChildrenBeforeOpen.Clear(); _rootChildStatesBeforeOpen.Clear(); for (int i = 0; i < ((Transform)_controller.rootPanel).childCount; i++) { GameObject gameObject = ((Component)((Transform)_controller.rootPanel).GetChild(i)).gameObject; if (!((Object)(object)gameObject == (Object)(object)_panelRoot)) { _rootChildrenBeforeOpen.Add(gameObject); _rootChildStatesBeforeOpen.Add(gameObject.activeSelf); } } if ((Object)(object)_controller.pausePanel != (Object)null) { ((Component)_controller.pausePanel).gameObject.SetActive(false); } if ((Object)(object)_controller.gameMenuPanel != (Object)null) { ((Component)_controller.gameMenuPanel).gameObject.SetActive(false); } if ((Object)(object)_controller.mainPanel != (Object)null) { ((Component)_controller.mainPanel).gameObject.SetActive(false); } for (int j = 0; j < _rootChildrenBeforeOpen.Count; j++) { _rootChildrenBeforeOpen[j].SetActive(false); } if ((Object)(object)_musicButtonObject != (Object)null) { _musicButtonObject.SetActive(false); } if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } _searchValue = string.Empty; if ((Object)(object)_search != (Object)null) { _search.SetTextWithoutNotify(string.Empty); _search.ForceLabelUpdate(); } if ((Object)(object)_clearSearchButton != (Object)null) { ((Selectable)_clearSearchButton).interactable = false; } _panelRoot.SetActive(true); _panelRoot.transform.SetAsLastSibling(); RefreshControls(); RefreshTracks(); RefreshPlayback(); } public void Close() { _hasBindingCapture = false; if ((Object)(object)_panelRoot != (Object)null) { _panelRoot.SetActive(false); } if ((Object)(object)_controller == (Object)null) { return; } if ((Object)(object)_controller.pausePanel != (Object)null) { ((Component)_controller.pausePanel).gameObject.SetActive(_pausePanelWasActive); } if ((Object)(object)_controller.gameMenuPanel != (Object)null) { ((Component)_controller.gameMenuPanel).gameObject.SetActive(_gameMenuWasActive); } if ((Object)(object)_controller.mainPanel != (Object)null) { ((Component)_controller.mainPanel).gameObject.SetActive(_mainPanelWasActive); } for (int i = 0; i < _rootChildrenBeforeOpen.Count; i++) { if ((Object)(object)_rootChildrenBeforeOpen[i] != (Object)null) { _rootChildrenBeforeOpen[i].SetActive(_rootChildStatesBeforeOpen[i]); } } _rootChildrenBeforeOpen.Clear(); _rootChildStatesBeforeOpen.Clear(); if ((Object)(object)_musicButtonObject != (Object)null) { _musicButtonObject.SetActive(_musicButtonWasActive); } if ((Object)(object)EventSystem.current != (Object)null && (Object)(object)_previousSelectedObject != (Object)null && _previousSelectedObject.activeInHierarchy) { EventSystem.current.SetSelectedGameObject(_previousSelectedObject); } _previousSelectedObject = null; } public void TickInput() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_0055: 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 (_hasBindingCapture) { if (!Input.GetKeyDown((KeyCode)27)) { foreach (KeyCode value in Enum.GetValues(typeof(KeyCode))) { if ((int)value != 0 && (int)value < 323 && Input.GetKeyDown(value)) { _plugin.SetKeyBinding(_capturingPrevious, value); _hasBindingCapture = false; ShowStatus(string.Empty); break; } } return; } _hasBindingCapture = false; ShowStatus(string.Empty); } else if ((Object)(object)_panelRoot != (Object)null && _panelRoot.activeSelf && Input.GetKeyDown((KeyCode)27) && !SearchFocused && (Object)(object)_dialog == (Object)null) { Close(); } } public void RefreshControls() { if (!((Object)(object)_shuffleButton == (Object)null)) { SetNativeButtonSelected(_shuffleButton, _plugin.Library.Shuffle); SetNativeButtonSelected(_repeatButton, _plugin.RepeatTrack); UpdateTabColors(); RefreshBindings(); } } public void RefreshTracks() { if ((Object)(object)_trackContent == (Object)null) { return; } for (int num = ((Transform)_trackContent).childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Transform)_trackContent).GetChild(num)).gameObject); } string query = (((Object)(object)_search == (Object)null) ? _searchValue : _search.text) ?? string.Empty; IList<MusicTrack> tracks = _plugin.Library.Tracks; List<MusicTrack> list = (from track in tracks where !_plugin.Library.FavoritesOnly || _plugin.Library.IsFavorite(track) where query.Length == 0 || track.DisplayName.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0 || track.RelativePath.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0 select track).ToList(); if (list.Count == 0) { if ((Object)(object)_emptyLabel != (Object)null) { string key = ((tracks.Count == 0) ? "noTracks" : ((_plugin.Library.FavoritesOnly && tracks.All((MusicTrack track) => !_plugin.Library.IsFavorite(track))) ? "noFavorites" : ((query.Length > 0) ? "noResults" : "noFavorites"))); _emptyLabel.text = Localizer.Get(key); ((Component)_emptyLabel).gameObject.SetActive(true); } return; } if ((Object)(object)_emptyLabel != (Object)null) { ((Component)_emptyLabel).gameObject.SetActive(false); } foreach (MusicTrack item in list) { CreateTrackRow(item); } } public void RefreshPlayback() { if (!((Object)(object)_nowPlayingLabel == (Object)null)) { MusicTrack currentTrack = _plugin.CurrentTrack; _nowPlayingLabel.text = Localizer.Format("nowPlaying", (currentTrack == null) ? "-" : currentTrack.DisplayName); } } public void RefreshBindings() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_previousBindingButton != (Object)null) { SetButtonText(_previousBindingButton, ((object)_plugin.PreviousKey/*cast due to .constrained prefix*/).ToString()); } if ((Object)(object)_nextBindingButton != (Object)null) { SetButtonText(_nextBindingButton, ((object)_plugin.NextKey/*cast due to .constrained prefix*/).ToString()); } } public void RefreshLocalization() { if ((Object)(object)_controller == (Object)null) { return; } if ((Object)(object)_musicButton != (Object)null) { SetButtonText(_musicButton, Localizer.Get("music")); } if ((Object)(object)_panelRoot != (Object)null && _panelRoot.activeSelf) { string text = (((Object)(object)_search == (Object)null) ? _searchValue : _search.text); Object.Destroy((Object)(object)_panelRoot); _panelRoot = null; BuildPanel(); _searchValue = text; if ((Object)(object)_search != (Object)null) { _search.SetTextWithoutNotify(text); _search.ForceLabelUpdate(); } if ((Object)(object)_clearSearchButton != (Object)null) { ((Selectable)_clearSearchButton).interactable = !string.IsNullOrEmpty(text); } _panelRoot.SetActive(true); RefreshControls(); RefreshTracks(); RefreshPlayback(); } } public void BeginBinding(bool previous) { _capturingPrevious = previous; _hasBindingCapture = true; if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } ShowStatus(Localizer.Get("pressKey")); } public void ShowStatus(string message) { if ((Object)(object)_statusLabel != (Object)null) { _statusLabel.text = message ?? string.Empty; } } public void Dispose() { if ((Object)(object)_controller != (Object)null) { Detach(_controller); } } private void CreatePauseMenuButton() { //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected O, but got Unknown if ((Object)(object)_controller.exitGameButton != (Object)null && (Object)(object)_controller.exitGameButton.transform.parent != (Object)null) { GameObject exitGameButton = _controller.exitGameButton; _musicButtonObject = Object.Instantiate<GameObject>(exitGameButton, exitGameButton.transform.parent, false); ((Object)_musicButtonObject).name = "UCM_MusicMenuButton"; _musicButtonObject.transform.SetSiblingIndex(Mathf.Max(0, exitGameButton.transform.GetSiblingIndex() - 1)); LanguageTextMeshController[] componentsInChildren = _musicButtonObject.GetComponentsInChildren<LanguageTextMeshController>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } _musicButton = _musicButtonObject.GetComponentInChildren<Button>(true); if ((Object)(object)_musicButton != (Object)null) { ((UnityEventBase)_musicButton.onClick).RemoveAllListeners(); for (int j = 0; j < ((UnityEventBase)_musicButton.onClick).GetPersistentEventCount(); j++) { ((UnityEventBase)_musicButton.onClick).SetPersistentListenerState(j, (UnityEventCallState)0); } ((UnityEvent)_musicButton.onClick).AddListener(new UnityAction(Open)); SetButtonText(_musicButton, Localizer.Get("music")); return; } } if (!((Object)(object)_controller.mainPanel == (Object)null)) { _musicButtonObject = CreateFallbackButtonObject((Transform)(object)_controller.mainPanel, "UCM_MusicMenuButton", Localizer.Get("music"), new UnityAction(Open)); _musicButton = _musicButtonObject.GetComponent<Button>(); } } private void BuildPanel() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_019f: 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_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Expected O, but got Unknown //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Expected O, but got Unknown //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Expected O, but got Unknown //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Expected O, but got Unknown //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Expected O, but got Unknown //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Expected O, but got Unknown //IL_075f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("UCM_MusicMenu", new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent((Transform)(object)_controller.rootPanel, false); _panelRoot = val; Stretch(val.GetComponent<RectTransform>(), 0f, 0f, 0f, 0f); ((Graphic)val.GetComponent<Image>()).color = new Color(0.006f, 0.012f, 0.022f, 0.72f); ((Graphic)val.GetComponent<Image>()).raycastTarget = true; Button val2 = CreateNativeSurface(val.transform, "MusicPanel"); Transform transform = ((Component)val2).transform; Transform obj = ((transform is RectTransform) ? transform : null); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); ((RectTransform)obj).anchorMax = val3; ((RectTransform)obj).anchorMin = val3; ((RectTransform)obj).pivot = new Vector2(0.5f, 0.5f); Rect rect = _controller.rootPanel.rect; Vector2 size = ((Rect)(ref rect)).size; if (size.x <= 0f || size.y <= 0f) { ((Vector2)(ref size))..ctor((float)Screen.width, (float)Screen.height); } ((RectTransform)obj).sizeDelta = new Vector2(Mathf.Max(420f, Mathf.Min(1040f, size.x - 48f)), Mathf.Max(360f, Mathf.Min(860f, size.y - 48f))); ((RectTransform)obj).anchoredPosition = Vector2.zero; SetNativeSurfaceColor(val2, new Color(0.16f, 0.22f, 0.28f, 0.985f)); float x = ((RectTransform)obj).sizeDelta.x; float num = (x - 66f) * 0.5f; _titleLabel = CreateText(((Component)transform).transform, "Title", Localizer.Get("music"), 28f, (FontStyles)1, (TextAlignmentOptions)4097); SetTop(_titleLabel.rectTransform, 18f, 44f, 24f, 160f); CreateRule(((Component)transform).transform, "HeaderRule", 68f, 2f, 24f, 24f); Button val4 = CreateIconButton(((Component)transform).transform, "Close", MusicIcon.Close, new UnityAction(Close)); SetTopFixed(((Component)val4).GetComponent<RectTransform>(), 18f, 44f, x - 68f, 44f); AddTooltip(val4, Localizer.Get("close")); _search = CreateInputField(((Component)transform).transform, "SearchField", Localizer.Get("search")); SetTop(((Component)_search).GetComponent<RectTransform>(), 78f, 44f, 24f, 84f); _clearSearchButton = CreateIconButton(((Component)transform).transform, "ClearSearch", MusicIcon.Clear, new UnityAction(ClearSearch)); SetTopFixed(((Component)_clearSearchButton).GetComponent<RectTransform>(), 78f, 44f, x - 68f, 44f); AddTooltip(_clearSearchButton, Localizer.Get("clearSearch")); ((UnityEvent<string>)(object)_search.onValueChanged).AddListener((UnityAction<string>)delegate(string value) { _searchValue = value; _search.ForceLabelUpdate(); ((Selectable)_clearSearchButton).interactable = value.Length > 0; RefreshTracks(); }); ((Selectable)_clearSearchButton).interactable = false; _allTab = CreateButton(((Component)transform).transform, "AllTracksTab", Localizer.Get("all"), 19f, (UnityAction)delegate { SelectFavoritesOnly(favoritesOnly: false); }); _favoritesTab = CreateButton(((Component)transform).transform, "FavoritesTab", Localizer.Get("favorites"), 19f, (UnityAction)delegate { SelectFavoritesOnly(favoritesOnly: true); }); SetTop(((Component)_allTab).GetComponent<RectTransform>(), 136f, 44f, 24f, x * 0.5f + 4f); SetTop(((Component)_favoritesTab).GetComponent<RectTransform>(), 136f, 44f, x * 0.5f + 4f, 24f); _shuffleButton = CreateIconButton(((Component)transform).transform, "Shuffle", MusicIcon.Shuffle, (UnityAction)delegate { _plugin.SetShuffle(!_plugin.Library.Shuffle); }); _repeatButton = CreateIconButton(((Component)transform).transform, "Repeat", MusicIcon.Repeat, (UnityAction)delegate { _plugin.SetRepeat(!_plugin.RepeatTrack); }); SetTopFixed(((Component)_shuffleButton).GetComponent<RectTransform>(), 190f, 36f, x * 0.5f - 44f, 40f); SetTopFixed(((Component)_repeatButton).GetComponent<RectTransform>(), 190f, 36f, x * 0.5f + 4f, 40f); AddTooltip(_shuffleButton, Localizer.Get("shuffle")); AddTooltip(_repeatButton, Localizer.Get("repeat")); bool flag = x < 680f; CreateBindingLine(((Component)transform).transform, Localizer.Get("previousBinding"), previous: true, 238f, out _previousBindingButton); CreateBindingLine(((Component)transform).transform, Localizer.Get("nextBinding"), previous: false, flag ? 278f : 238f, out _nextBindingButton); TMP_Text obj2 = CreateText(((Component)transform).transform, "PreviousBindingLabel", Localizer.Get("previousBinding"), 17f, (FontStyles)0, (TextAlignmentOptions)4097); float width = (flag ? (x - 180f) : (num - 118f)); SetTopFixed(obj2.rectTransform, 238f, 36f, 24f, width); TMP_Text val5 = CreateText(((Component)transform).transform, "NextBindingLabel", Localizer.Get("nextBinding"), 17f, (FontStyles)0, (TextAlignmentOptions)4097); if (flag) { SetTopFixed(((Component)_previousBindingButton).GetComponent<RectTransform>(), 238f, 36f, x - 142f, 118f); SetTopFixed(((Component)_nextBindingButton).GetComponent<RectTransform>(), 278f, 36f, x - 142f, 118f); SetTopFixed(val5.rectTransform, 278f, 36f, 24f, width); } else { SetTopFixed(((Component)_previousBindingButton).GetComponent<RectTransform>(), 238f, 36f, 24f + num - 108f, 108f); SetTopFixed(((Component)_nextBindingButton).GetComponent<RectTransform>(), 238f, 36f, 46f + num * 2f - 108f, 108f); SetTopFixed(val5.rectTransform, 238f, 36f, 46f + num, width); } CreateTrackList(((Component)transform).transform, flag ? 324f : 284f); _nowPlayingLabel = CreateText(((Component)transform).transform, "NowPlaying", string.Empty, 18f, (FontStyles)1, (TextAlignmentOptions)4097); SetBottomStretch(_nowPlayingLabel.rectTransform, 68f, 30f, 24f, 24f); _statusLabel = CreateText(((Component)transform).transform, "Status", string.Empty, 15f, (FontStyles)0, (TextAlignmentOptions)4097); ((Graphic)_statusLabel).color = new Color(0.79f, 0.83f, 0.82f, 1f); SetBottomStretch(_statusLabel.rectTransform, 36f, 24f, 24f, 24f); _panelRoot.SetActive(false); } private void CreateTrackList(Transform panel, float top) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Expected O, but got Unknown //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: 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_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) Button obj = CreateNativeSurface(panel, "TrackListSurface"); Transform transform = ((Component)obj).transform; StretchVertical((RectTransform)(object)((transform is RectTransform) ? transform : null), top, 112f, 24f, 24f); SetNativeSurfaceColor(obj, new Color(0.26f, 0.36f, 0.43f, 1f)); GameObject val = new GameObject("TrackScroll", new Type[4] { typeof(RectTransform), typeof(ScrollRect), typeof(Image), typeof(Mask) }); val.transform.SetParent(panel, false); RectTransform component = val.GetComponent<RectTransform>(); StretchVertical(component, top, 112f, 24f, 24f); Image nativeButtonImage = GetNativeButtonImage(); Image component2 = val.GetComponent<Image>(); if ((Object)(object)nativeButtonImage != (Object)null) { component2.sprite = nativeButtonImage.sprite; component2.type = nativeButtonImage.type; component2.pixelsPerUnitMultiplier = nativeButtonImage.pixelsPerUnitMultiplier; } ((Graphic)component2).color = new Color(0.45f, 0.58f, 0.68f, 1f); val.GetComponent<Mask>().showMaskGraphic = false; GameObject val2 = new GameObject("TrackRows", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter) }); val2.transform.SetParent(val.transform, false); _trackContent = val2.GetComponent<RectTransform>(); _trackContent.anchorMin = new Vector2(0f, 1f); _trackContent.anchorMax = new Vector2(1f, 1f); _trackContent.pivot = new Vector2(0.5f, 1f); _trackContent.anchoredPosition = Vector2.zero; _trackContent.sizeDelta = new Vector2(0f, 0f); VerticalLayoutGroup component3 = val2.GetComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component3).spacing = 2f; ((LayoutGroup)component3).padding = new RectOffset(5, 5, 5, 5); ((HorizontalOrVerticalLayoutGroup)component3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component3).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component3).childForceExpandWidth = true; val2.GetComponent<ContentSizeFitter>().verticalFit = (FitMode)2; _emptyLabel = CreateText(val.transform, "EmptyMessage", string.Empty, 18f, (FontStyles)2, (TextAlignmentOptions)514); Stretch(_emptyLabel.rectTransform, 24f, 24f, 24f, 24f); ScrollRect component4 = val.GetComponent<ScrollRect>(); component4.content = _trackContent; component4.viewport = component; component4.horizontal = false; component4.vertical = true; component4.movementType = (MovementType)2; component4.scrollSensitivity = 32f; } private void CreateTrackRow(MusicTrack track) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Expected O, but got Unknown //IL_0238: 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_0272: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Expected O, but got Unknown //IL_02d4: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("TrackRow", new Type[3] { typeof(RectTransform), typeof(LayoutElement), typeof(HorizontalLayoutGroup) }); val.transform.SetParent((Transform)(object)_trackContent, false); LayoutElement component = val.GetComponent<LayoutElement>(); component.preferredHeight = 56f; component.minHeight = 48f; HorizontalLayoutGroup component2 = val.GetComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component2).spacing = 4f; ((LayoutGroup)component2).padding = new RectOffset(0, 0, 2, 2); ((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false; Button val2 = CreateButton(val.transform, "PlayTrack", track.DisplayName, 18f, (UnityAction)delegate { _plugin.SelectTrack(track); }); LayoutElement orAddLayoutElement = GetOrAddLayoutElement(((Component)val2).gameObject); orAddLayoutElement.flexibleWidth = 1f; orAddLayoutElement.minWidth = 64f; orAddLayoutElement.preferredHeight = 52f; TMP_Text obj = FindText(((Component)val2).gameObject); obj.alignment = (TextAlignmentOptions)4097; obj.margin = new Vector4(36f, 0f, 8f, 0f); AddButtonIcon(val2, MusicIcon.Play, new Color(0.9f, 0.95f, 1f, 1f), 19f, leftAligned: true); AddTooltip(val2, Localizer.Format("playTrack", track.DisplayName)); bool flag = _plugin.Library.IsFavorite(track); Button val3 = CreateIconButton(val.transform, "Favorite", MusicIcon.Star, (UnityAction)delegate { _plugin.ToggleFavorite(track); }); LayoutElement orAddLayoutElement2 = GetOrAddLayoutElement(((Component)val3).gameObject); orAddLayoutElement2.preferredWidth = 48f; orAddLayoutElement2.minWidth = 44f; orAddLayoutElement2.preferredHeight = 52f; ((Graphic)((Component)((Component)val3).transform.Find("Icon")).GetComponent<Image>()).color = (flag ? new Color(0.98f, 0.78f, 0.32f, 1f) : new Color(0.87f, 0.91f, 0.95f, 1f)); AddTooltip(val3, Localizer.Get(flag ? "removeFavorite" : "addFavorite")); Button val4 = CreateIconButton(val.transform, "Delete", MusicIcon.Delete, (UnityAction)delegate { ShowDeleteConfirmation(track); }); LayoutElement orAddLayoutElement3 = GetOrAddLayoutElement(((Component)val4).gameObject); orAddLayoutElement3.preferredWidth = 48f; orAddLayoutElement3.minWidth = 44f; orAddLayoutElement3.preferredHeight = 52f; ((Graphic)((Component)((Component)val4).transform.Find("Icon")).GetComponent<Image>()).color = new Color(0.95f, 0.68f, 0.69f, 1f); AddTooltip(val4, Localizer.Get("delete")); } private void CreateBindingLine(Transform panel, string label, bool previous, float top, out Button button) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown button = CreateButton(panel, previous ? "PreviousBinding" : "NextBinding", "", 15f, (UnityAction)delegate { BeginBinding(previous); }); } private void ShowDeleteConfirmation(MusicTrack track) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_00a2: 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: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Expected O, but got Unknown if ((Object)(object)_dialog != (Object)null) { Object.Destroy((Object)(object)_dialog); } _pendingDelete = track; GameObject val = new GameObject("DeleteConfirmation", new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(_panelRoot.transform, false); _dialog = val; Stretch(val.GetComponent<RectTransform>(), 0f, 0f, 0f, 0f); ((Graphic)val.GetComponent<Image>()).color = new Color(0.008f, 0.015f, 0.025f, 0.78f); Button obj = CreateNativeSurface(val.transform, "ConfirmationPanel"); Transform transform = ((Component)obj).transform; Transform obj2 = ((transform is RectTransform) ? transform : null); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); ((RectTransform)obj2).anchorMax = val2; ((RectTransform)obj2).anchorMin = val2; ((RectTransform)obj2).sizeDelta = new Vector2(540f, 220f); SetNativeSurfaceColor(obj, new Color(0.5f, 0.64f, 0.74f, 1f)); TMP_Text obj3 = CreateText(((Component)transform).transform, "DeleteMessage", Localizer.Format("deletePrompt", track.DisplayName + ".mp3"), 19f, (FontStyles)0, (TextAlignmentOptions)514); obj3.enableWordWrapping = true; SetTop(obj3.rectTransform, 28f, 100f, 28f, 28f); Button val3 = CreateButton(((Component)transform).transform, "ConfirmDelete", Localizer.Get("confirm"), 17f, new UnityAction(ConfirmDelete)); Button obj4 = CreateButton(((Component)transform).transform, "CancelDelete", Localizer.Get("cancel"), 17f, new UnityAction(CancelDelete)); SetBottomLeft(((Component)val3).GetComponent<RectTransform>(), 24f, 42f, 24f, 270f); SetBottomRight(((Component)obj4).GetComponent<RectTransform>(), 24f, 42f, 24f, 270f); } private void ConfirmDelete() { MusicTrack pendingDelete = _pendingDelete; string error; bool flag = _plugin.DeleteTrack(pendingDelete, out error); CloseDeleteConfirmation(); ShowStatus(flag ? Localizer.Get("deleted") : Localizer.Format("deleteFailed", error ?? string.Empty)); RefreshTracks(); RefreshPlayback(); } private void CancelDelete() { CloseDeleteConfirmation(); } private void CloseDeleteConfirmation() { if ((Object)(object)_dialog != (Object)null) { Object.Destroy((Object)(object)_dialog); } _dialog = null; _pendingDelete = null; } private void UpdateTabColors() { if (!((Object)(object)_allTab == (Object)null) && !((Object)(object)_favoritesTab == (Object)null)) { SetNativeButtonSelected(_allTab, !_plugin.Library.FavoritesOnly); SetNativeButtonSelected(_favoritesTab, _plugin.Library.FavoritesOnly); } } private void SelectFavoritesOnly(bool favoritesOnly) { if ((Object)(object)_search != (Object)null && _search.isFocused) { _search.DeactivateInputField(false); } Button val = (favoritesOnly ? _favoritesTab : _allTab); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject(((Object)(object)val == (Object)null) ? null : ((Component)val).gameObject); } _plugin.SetFavoritesOnly(favoritesOnly); } private GameObject CreateFallbackButtonObject(Transform parent, string name, string text, UnityAction action) { Button val = CreateFallbackButton(parent, name, text, 18f, action); LayoutElement val2 = ((Component)val).GetComponent<LayoutElement>(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val).gameObject.AddComponent<LayoutElement>(); } val2.preferredHeight = 42f; return ((Component)val).gameObject; } private Button CreateButton(Transform parent, string name, string text, float fontSize, UnityAction action) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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) Image nativeButtonImage = GetNativeButtonImage(); if ((Object)(object)nativeButtonImage == (Object)null) { return CreateFallbackButton(parent, name, text, fontSize, action); } GameObject val = new GameObject(name, new Type[4] { typeof(RectTransform), typeof(Image), typeof(Button), typeof(LayoutElement) }); val.transform.SetParent(parent, false); Image component = val.GetComponent<Image>(); CopyImageStyle(nativeButtonImage, component); Button component2 = val.GetComponent<Button>(); ((Selectable)component2).targetGraphic = (Graphic)(object)component; ((Selectable)component2).transition = (Transition)(((Object)(object)_musicButton == (Object)null) ? 1 : ((int)((Selectable)_musicButton).transition)); ((Selectable)component2).colors = (((Object)(object)_musicButton == (Object)null) ? ColorBlock.defaultColorBlock : ((Selectable)_musicButton).colors); Navigation navigation = ((Selectable)component2).navigation; ((Navigation)(ref navigation)).mode = (Mode)3; ((Selectable)component2).navigation = navigation; if (action != null) { ((UnityEvent)component2.onClick).AddListener(action); } TMP_Text obj = CreateText(val.transform, "Label", text, fontSize, (FontStyles)0, (TextAlignmentOptions)514); Stretch(obj.rectTransform, 4f, 4f, 8f, 8f); ((Graphic)obj).raycastTarget = false; obj.enableAutoSizing = true; obj.fontSizeMin = Mathf.Max(10f, fontSize - 5f); obj.fontSizeMax = fontSize; val.GetComponent<LayoutElement>().minHeight = 32f; return component2; } private Button CreateFallbackButton(Transform parent, string name, string text, float fontSize, UnityAction action) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00df: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[4] { typeof(RectTransform), typeof(Image), typeof(Button), typeof(LayoutElement) }); val.transform.SetParent(parent, false); Image component = val.GetComponent<Image>(); ((Graphic)component).color = new Color(0.31f, 0.46f, 0.59f, 1f); Outline obj = val.AddComponent<Outline>(); ((Shadow)obj).effectColor = new Color(0.73f, 0.83f, 0.91f, 0.6f); ((Shadow)obj).effectDistance = new Vector2(1f, -1f); Button component2 = val.GetComponent<Button>(); ((Selectable)component2).targetGraphic = (Graphic)(object)component; ((Selectable)component2).transition = (Transition)1; ColorBlock colors = ((Selectable)component2).colors; ((ColorBlock)(ref colors)).normalColor = new Color(0.31f, 0.46f, 0.59f, 1f); ((ColorBlock)(ref colors)).highlightedColor = new Color(0.43f, 0.59f, 0.71f, 1f); ((ColorBlock)(ref colors)).pressedColor = new Color(0.2f, 0.32f, 0.43f, 1f); ((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).highlightedColor; ((Selectable)component2).colors = colors; if (action != null) { ((UnityEvent)component2.onClick).AddListener(action); } TMP_Text obj2 = CreateText(val.transform, "Label", text, fontSize, (FontStyles)0, (TextAlignmentOptions)514); Stretch(obj2.rectTransform, 4f, 4f, 8f, 8f); ((Graphic)obj2).raycastTarget = false; obj2.enableAutoSizing = true; obj2.fontSizeMin = Mathf.Max(10f, fontSize - 5f); obj2.fontSizeMax = fontSize; val.GetComponent<LayoutElement>().minHeight = 32f; return component2; } private Button CreateNativeSurface(Transform parent, string name) { Button val = CreateButton(parent, name, string.Empty, 16f, null); ((Selectable)val).interactable = false; ((Behaviour)val).enabled = false; ((Component)FindText(((Component)val).gameObject)).gameObject.SetActive(false); Image buttonImage = GetButtonImage(val); if ((Object)(object)buttonImage != (Object)null) { ((Graphic)buttonImage).raycastTarget = false; } return val; } private static void SetNativeSurfaceColor(Button surface, Color color) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) Image buttonImage = GetButtonImage(surface); if ((Object)(object)buttonImage != (Object)null) { ((Graphic)buttonImage).color = color; } } private Image GetNativeButtonImage() { if ((Object)(object)_musicButton == (Object)null) { return null; } return GetButtonImage(_musicButton); } private static Image GetButtonImage(Button button) { if ((Object)(object)button == (Object)null) { return null; } Graphic targetGraphic = ((Selectable)button).targetGraphic; Image val = (Image)(object)((targetGraphic is Image) ? targetGraphic : null); if ((Object)(object)val != (Object)null) { return val; } val = ((Component)button).GetComponent<Image>(); if (!((Object)(object)val != (Object)null)) { return ((Component)button).GetComponentInChildren<Image>(true); } return val; } private static LayoutElement GetOrAddLayoutElement(GameObject gameObject) { LayoutElement component = gameObject.GetComponent<LayoutElement>(); if (!((Object)(object)component != (Object)null)) { return gameObject.AddComponent<LayoutElement>(); } return component; } private Button CreateIconButton(Transform parent, string name, MusicIcon icon, UnityAction action) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) Button val = CreateButton(parent, name, string.Empty, 16f, action); ((Component)FindText(((Component)val).gameObject)).gameObject.SetActive(false); AddButtonIcon(val, icon, new Color(0.9f, 0.94f, 0.98f, 1f), 21f, leftAligned: false); return val; } private static void AddButtonIcon(Button button, MusicIcon icon, Color color, float size, bool leftAligned) { //IL_0025: 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_003c: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_0095: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00dd: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Icon", new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(((Component)button).transform, false); RectTransform component = val.GetComponent<RectTransform>(); Vector2 anchorMin = (component.anchorMax = (leftAligned ? new Vector2(0f, 0.5f) : new Vector2(0.5f, 0.5f))); component.anchorMin = anchorMin; component.pivot = (leftAligned ? new Vector2(0f, 0.5f) : new Vector2(0.5f, 0.5f)); component.anchoredPosition = (Vector2)(leftAligned ? new Vector2(12f, 0f) : Vector2.zero); component.sizeDelta = new Vector2(size, size); Image component2 = val.GetComponent<Image>(); component2.sprite = MusicIcons.Get(icon); ((Graphic)component2).color = color; ((Graphic)component2).raycastTarget = false; } private void AddTooltip(Button button, string text) { //IL_003b: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0078: Expected O, but got Unknown EventTrigger val = ((Component)button).GetComponent<EventTrigger>(); if ((Object)(object)val == (Object)null) { val = ((Component)button).gameObject.AddComponent<EventTrigger>(); } val.triggers.Clear(); Entry val2 = new Entry { eventID = (EventTriggerType)0 }; ((UnityEvent<BaseEventData>)(object)val2.callback).AddListener((UnityAction<BaseEventData>)delegate { ShowStatus(text); }); val.triggers.Add(val2); Entry val3 = new Entry { eventID = (EventTriggerType)1 }; ((UnityEvent<BaseEventData>)(object)val3.callback).AddListener((UnityAction<BaseEventData>)delegate { if ((Object)(object)_statusLabel != (Object)null && _statusLabel.text == text) { ShowStatus(string.Empty); } }); val.triggers.Add(val3); } private void SetNativeButtonSelected(Button button, bool selected) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)button == (Object)null) { return; } Image buttonImage = GetButtonImage(button); if ((Object)(object)_musicButton != (Object)null) { Transform val = ((Component)button).transform.Find("Icon"); if ((Object)(object)val != (Object)null) { Image component = ((Component)val).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = (selected ? new Color(0.75f, 0.83f, 0.66f, 1f) : new Color(0.9f, 0.94f, 0.98f, 1f)); } return; } ColorBlock colors = ((Selectable)_musicButton).colors; ColorBlock colors2 = ((Selectable)button).colors; Color selectedColor = (((ColorBlock)(ref colors2)).normalColor = (selected ? ((ColorBlock)(ref colors)).highlightedColor : ((ColorBlock)(ref colors)).normalColor)); ((ColorBlock)(ref colors2)).selectedColor = selectedColor; ((ColorBlock)(ref colors2)).highlightedColor = ((ColorBlock)(ref colors)).highlightedColor; ((ColorBlock)(ref colors2)).pressedColor = ((ColorBlock)(ref colors)).pressedColor; ((ColorBlock)(ref colors2)).disabledColor = ((ColorBlock)(ref colors)).disabledColor; ((Selectable)button).colors = colors2; } else if ((Object)(object)buttonImage != (Object)null) { ((Graphic)buttonImage).color = (selected ? new Color(0.75f, 0.83f, 0.66f, 1f) : new Color(0.31f, 0.46f, 0.59f, 1f)); } } private static void CopyImageStyle(Image source, Image target) { //IL_000e: 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) target.sprite = source.sprite; target.type = source.type; target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; ((Graphic)target).material = ((Graphic)source).material; target.preserveAspect = source.preserveAspect; target.useSpriteMesh = source.useSpriteMesh; ((MaskableGraphic)target).maskable = ((MaskableGraphic)source).maskable; ((Graphic)target).color = ((Graphic)source).color; } private static void CreateRule(Transform parent, string name, float top, float height, float left, float right) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_005d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(parent, false); SetTop(val.GetComponent<RectTransform>(), top, height, left, right); ((Graphic)val.GetComponent<Image>()).color = new Color(0.48f, 0.63f, 0.75f, 0.65f); } private TMP_InputField CreateInputField(Transform parent, string name, string placeholderText) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0088: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0141: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Expected O, but got Unknown //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Expected O, but got Unknown //IL_0165: 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) GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(parent, false); val.SetActive(false); Image component = val.GetComponent<Image>(); ((Graphic)component).raycastTarget = true; Image nativeButtonImage = GetNativeButtonImage(); if ((Object)(object)nativeButtonImage != (Object)null) { CopyImageStyle(nativeButtonImage, component); ((Graphic)component).color = Color.white; } else { ((Graphic)component).color = new Color(0.12f, 0.18f, 0.24f, 1f); Outline obj = val.AddComponent<Outline>(); ((Shadow)obj).effectColor = new Color(0.64f, 0.77f, 0.86f, 0.8f); ((Shadow)obj).effectDistance = new Vector2(1f, -1f); } TMP_InputField input = val.AddComponent<TMP_InputField>(); input.lineType = (LineType)0; input.contentType = (ContentType)0; input.characterLimit = 128; input.caretColor = Color.white; input.customCaretColor = true; ((Selectable)input).targetGraphic = (Graphic)(object)component; input.selectionColor = new Color(0.3f, 0.54f, 0.49f, 0.6f); if ((Object)(object)_musicButton != (Object)null) { ((Selectable)input).transition = ((Selectable)_musicButton).transition; ((Selectable)input).colors = ((Selectable)_musicButton).colors; } GameObject val2 = new GameObject("TextArea", new Type[2] { typeof(RectTransform), typeof(RectMask2D) }); val2.transform.SetParent(val.transform, false); RectTransform component2 = val2.GetComponent<RectTransform>(); Stretch(component2, 4f, 3f, 4f, 3f); TMP_Text val3 = CreateText((Transform)(object)component2, "Text", string.Empty, 19f, (FontStyles)0, (TextAlignmentOptions)4097); ConfigureText(val3, string.Empty, 19f, (FontStyles)0, (TextAlignmentOptions)4097); Stretch(val3.rectTransform, 2f, 2f, 8f, 2f); val3.enableWordWrapping = false; ((Graphic)val3).color = Color.white; val3.overflowMode = (TextOverflowModes)1; input.textComponent = val3; input.textViewport = component2; TMP_Text placeholder = CreateText((Transform)(object)component2, "Placeholder", placeholderText, 19f, (FontStyles)2, (TextAlignmentOptions)4097); ((Graphic)placeholder).color = new Color(0.78f, 0.84f, 0.87f, 1f); Stretch(placeholder.rectTransform, 2f, 2f, 8f, 2f); placeholder.enableWordWrapping = false; input.placeholder = (Graphic)(object)placeholder; EventTrigger obj2 = val.AddComponent<EventTrigger>(); Entry val4 = new Entry { eventID = (EventTriggerType)9 }; ((UnityEvent<BaseEventData>)(object)val4.callback).AddListener((UnityAction<BaseEventData>)delegate { ((Component)placeholder).gameObject.SetActive(false); }); obj2.triggers.Add(val4); Entry val5 = new Entry { eventID = (EventTriggerType)10 }; ((UnityEvent<BaseEventData>)(object)val5.callback).AddListener((UnityAction<BaseEventData>)delegate { ((Component)placeholder).gameObject.SetActive(string.IsNullOrEmpty(input.text)); }); obj2.triggers.Add(val5); val.SetActive(true); return input; } private TMP_Text CreateText(Transform parent, string name, string text, float size, FontStyles style, TextAlignmentOptions alignment) { //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_00f0: Unknown result type (might be due to invalid IL or missing references) TMP_Text val = null; if ((Object)(object)_musicButtonObject != (Object)null) { GameObject val2 = Object.Instantiate<GameObject>(_musicButtonObject, parent, false); LanguageTextMeshController[] componentsInChildren = val2.GetComponentsInChildren<LanguageTextMeshController>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } Button componentInChildren = val2.GetComponentInChildren<Button>(true); if ((Object)(object)componentInChildren != (Object)null) { ((UnityEventBase)componentInChildren.onClick).RemoveAllListeners(); for (int j = 0; j < ((UnityEventBase)componentInChildren.onClick).GetPersistentEventCount(); j++) { ((UnityEventBase)componentInChildren.onClick).SetPersistentListenerState(j, (UnityEventCallState)0); } ((Selectable)componentInChildren).interactable = false; } TMP_Text componentInChildren2 = val2.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren2 != (Object)null) { componentInChildren2.transform.SetParent(parent, false); val = componentInChildren2; Object.Destroy((Object)(object)val2); } else { Object.Destroy((Object)(object)val2); } } if ((Object)(object)val == (Object)null) { GameObject val3 = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val3.transform.SetParent(parent, false); val = (TMP_Text)(object)val3.GetComponent<TextMeshProUGUI>(); } ((Object)((Component)val).gameObject).name = name; ConfigureText(val, text, size, style, alignment); return val; } private static void ConfigureText(TMP_Text label, string text, float size, FontStyles style, TextAlignmentOptions alignment) { //IL_0028: 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) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)label.font == (Object)null) { label.font = TMP_Settings.defaultFontAsset; } label.text = text; label.fontSize = size; label.fontStyle = style; ((Graphic)label).color = new Color(0.92f, 0.94f, 0.93f, 1f); label.alignment = alignment; label.enableWordWrapping = false; label.overflowMode = (TextOverflowModes)1; label.enableAutoSizing = true; label.fontSizeMin = Mathf.Max(10f, size - 5f); label.fontSizeMax = size; ((Graphic)label).raycastTarget = false; } private TMP_Text FindText(GameObject gameObject) { TMP_Text componentInChildren = gameObject.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { return componentInChildren; } return CreateText(gameObject.transform, "Label", string.Empty, 16f, (FontStyles)0, (TextAlignmentOptions)514); } private void SetButtonText(Button button, string text) { if (!((Object)(object)button == (Object)null)) { TMP_Text val = FindText(((Component)button).gameObject); val.text = text; ((Component)val).gameObject.SetActive(!string.IsNullOrEmpty(text)); val.enableWordWrapping = false; val.overflowMode = (TextOverflowModes)1; val.enableAutoSizing = true; val.fontSizeMin = Mathf.Max(10f, val.fontSize - 5f); val.fontSizeMax = val.fontSize; } } private static void Stretch(RectTransform rect, float left, float bottom, float right, float top) { //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_0029: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = new Vector2(left, bottom); rect.offsetMax = new Vector2(0f - right, 0f - top); } private static void StretchVertical(RectTransform rect, float top, float bottom, float left, float right) { //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_0029: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = new Vector2(left, bottom); rect.offsetMax = new Vector2(0f - right, 0f - top); } private static void SetTop(RectTransform rect, float top, float height, float left, float right) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0055: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = new Vector2(0f, 1f); rect.anchorMax = new Vector2(1f, 1f); rect.pivot = new Vector2(0.5f, 1f); rect.offsetMin = new Vector2(left, 0f - top - height); rect.offsetMax = new Vector2(0f - right, 0f - top); } private static void SetTopRight(RectTransform rect, float top, float size, float right) { //IL_0013: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(1f, 1f); rect.anchorMax = val; rect.anchorMin = val; rect.pivot = new Vector2(1f, 1f); rect.anchoredPosition = new Vector2(0f - right, 0f - top); rect.sizeDelta = new Vector2(size, size); } private void ClearSearch() { _searchValue = string.Empty; if ((Object)(object)_search != (Object)null) { _search.SetTextWithoutNotify(string.Empty); _search.ForceLabelUpdate(); } if ((Object)(object)_clearSearchButton != (Object)null) { ((Selectable)_clearSearchButton).interactable = false; } RefreshTracks(); } private static void SetTopFixed(RectTransform rect, float top, float height, float left, float width) { //IL_0013: 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_002a: 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_0046: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rect.anchorMax = val; rect.anchorMin = val; rect.pivot = new Vector2(0f, 1f); rect.anchoredPosition = new Vector2(left, 0f - top); rect.sizeDelta = new Vector2(width, height); } private static void SetBottomStretch(RectTransform rect, float bottom, float height, float left, float right) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0049: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = new Vector2(1f, 0f); rect.pivot = new Vector2(0.5f, 0f); rect.offsetMin = new Vector2(left, bottom); rect.offsetMax = new Vector2(0f - right, bottom + height); } private static void SetBottomLeft(RectTransform rect, float left, float height, float bottom, float width) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0030: Unknown result type (might be due to invalid IL or missing references) Vector2 anchorMin = (rect.anchorMax = Vector2.zero); rect.anchorMin = anchorMin; rect.pivot = Vector2.zero; rect.anchoredPosition = new Vector2(left, bottom); rect.sizeDelta = new Vector2(width, height); } private static void SetBottomRight(RectTransform rect, float right, float height, float bottom, float width) { //IL_0013: 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_002a: 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_0046: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(1f, 0f); rect.anchorMax = val; rect.anchorMin = val; rect.pivot = new Vector2(1f, 0f); rect.anchoredPosition = new Vector2(0f - right, bottom); rect.sizeDelta = new Vector2(width, height); } private void ClearPanelReferences() { _dialog = null; _trackContent = null; _search = null; _clearSearchButton = null; _shuffleButton = null; _repeatButton = null; _allTab = null; _favoritesTab = null; _previousBindingButton = null; _nextBindingButton = null; _titleLabel = null; _nowPlayingLabel = null; _statusLabel = null; _emptyLabel = null; _pendingDelete = null; } } internal sealed class NotificationToast { private const float FadeInSeconds = 0.5f; private const float VisibleSeconds = 10f; private const float FadeOutSeconds = 1f; private readonly GameObject _root; private readonly CanvasGroup _group; private readonly TMP_Text _label; private string _trackName; private float _elapsed; public NotificationToast() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_013f: 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_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) _root = new GameObject("UCM_TrackNotification", new Type[3] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler) }); Object.DontDestroyOnLoad((Object)(object)_root); Canvas component = _root.GetComponent<Canvas>(); component.renderMode = (RenderMode)0; component.sortingOrder = 32700; CanvasScaler component2 = _root.GetComponent<CanvasScaler>(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1920f, 1080f); component2.matchWidthOrHeight = 0.5f; _group = _root.AddComponent<CanvasGroup>(); GameObject val = new GameObject("TrackName", new Type[3] { typeof(RectTransform), typeof(TextMeshProUGUI), typeof(Shadow) }); val.transform.SetParent(_root.transform, false); RectTransform component3 = val.GetComponent<RectTransform>(); component3.anchorMin = (component3.anchorMax = Vector2.zero); component3.pivot = Vector2.zero; component3.anchoredPosition = new Vector2(78f, 10f); component3.sizeDelta = new Vector2(760f, 32f); _label = (TMP_Text)(object)val.GetComponent<TextMeshProUGUI>(); _label.font = TMP_Settings.defaultFontAsset; _label.fontSize = 18f; ((Graphic)_label).color = Color.white; _label.alignment = (TextAlignmentOptions)4097; _label.enableWordWrapping = false; _label.overflowMode = (TextOverflowModes)1; _label.enableAutoSizing = true; _label.fontSizeMin = 13f; _label.fontSizeMax = 18f; ((Graphic)_label).raycastTarget = false; Shadow component4 = val.GetComponent<Shadow>(); component4.effectColor = new Color(0f, 0f, 0f, 0.95f); component4.effectDistance = new Vector2(1.5f, -1.5f); _group.alpha = 0f; _root.SetActive(false); } public void Show(string trackName) { _trackName = trackName; _elapsed = 0f; _label.text = Localizer.Format("nowPlaying", trackName); _group.alpha = 0f; _root.SetActive(true); } public void RefreshLanguage() { if (_root.activeSelf && _trackName != null) { _label.text = Localizer.Format("nowPlaying", _trackName); } } public void Tick(float unscaledDeltaTime) { if (_root.activeSelf) { _elapsed += Mathf.Max(0f, unscaledDeltaTime); if (_elapsed < 0.5f) { _group.alpha = _elapsed / 0.5f; return; } if (_elapsed < 10.5f) { _group.alpha = 1f; return; } if (_elapsed < 11.5f) { _group.alpha = 1f - (_elapsed - 0.5f - 10f) / 1f; return; } _group.alpha = 0f; _root.SetActive(false); } } public void Dispose() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } } } [BepInPlugin("com.universalcmm.ror2", "Risk of Music", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.universalcmm.ror2"; public const string PluginName = "Risk of Music"; public const string PluginVersion = "1.0.0"; private static Plugin _instance; private readonly List<string> _shuffleHistory = new List<string>(); private readonly Random _random = new Random(); private ConfigEntry<KeyCode> _previousKey; private ConfigEntry<KeyCode> _nextKey; private ConfigEntry<float> _maximumPlaybackVolume; private ConfigEntry<bool> _repeatTrackSetting; private Harmony _harmony; private MusicLibrary _library; private AudioPlayback _playback; private NotificationToast _toast; private MusicMenu _menu; private MusicTrack _currentTrack; private Run _sessionRun; private bool _inRunScene; private bool _vanillaTrackStopped; private bool _paused; private bool _repeatTrack; private bool _volumeReadWarningLogged; private int _historyPosition = -1; private float _volumePollTimer; private float _effectiveMusicVolume; internal static Plugin Instance => _instance; internal MusicLibrary Library => _library; internal MusicTrack CurrentTrack => _currentTrack; internal bool RepeatTrack => _repeatTrack; internal KeyCode PreviousKey => _previousKey.Value; internal KeyCode NextKey => _nextKey.Value; internal bool ShouldSuppressVanillaMusic { get { if (_inRunScene && _playback != null) { return _playback.HasActiveTrack; } return false; } } private void Awake() { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Expected O, but got Unknown if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } _instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); _previousKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "PreviousTrack", (KeyCode)122, "Key to play the previous track."); _nextKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "NextTrack", (KeyCode)120, "Key to play the next track."); _maximumPlaybackVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Playback", "MaximumVolume", 0.2f, new ConfigDescription("Maximum custom music level relative to full-scale audio. Lower this for recording or streaming.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); if (Mathf.Approximately(_maximumPlaybackVolume.Value, 0.35f)) { _maximumPlaybackVolume.Value = 0.2f; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Reduced the previous default MaximumVolume to 0.2 for recording-safe headroom."); } _repeatTrackSetting = ((BaseUnityPlugin)this).Config.Bind<bool>("Playback", "Repeat", false, "Repeat the current custom music track."); _repeatTrack = _repeatTrackSetting.Value; _effectiveMusicVolume = GetSafePlaybackVolume(ReadGameMusicVolume()); string text = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (string.IsNullOrEmpty(text)) { text = Path.Combine(Paths.PluginPath, "RiskOfMusic"); } string text2 = Path.Combine(text, "Music"); Directory.CreateDirectory(text2); _library = new MusicLibrary(text2, ((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); _playback = new AudioPlayback(((BaseUnityPlugin)this).Logger); _toast = new NotificationToast(); try { _library.Rescan(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Could not scan the Music folder: " + ex)); } _harmony = new Harmony("com.universalcmm.ror2"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); Run.onRunStartGlobal += OnRunStarted; Run.onRunDestroyGlobal += OnRunDestroyed; SceneCatalog.onMostRecentSceneDefChanged += OnSceneChanged; PauseManager.onPauseStartGlobal = (Action)Delegate.Combine(PauseManager.onPauseStartGlobal, new Action(OnPauseStarted)); PauseManager.onPauseEndGlobal = (Action)Delegate.Combine(PauseManager.onPauseEndGlobal, new Action(OnPauseEnded)); Language.onCurrentLanguageChanged += OnLanguageChanged; _paused = PauseManager.isPaused || Time.timeScale == 0f; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Risk of Music loaded. Musi