Decompiled source of ModAudio v2.2.1
plugins/Marioalexsan.ModAudio.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Marioalexsan.ModAudio.SoftDependencies; using Microsoft.CodeAnalysis; using NAudio.Wave; using NVorbis; using Newtonsoft.Json; using Newtonsoft.Json.Schema; using Newtonsoft.Json.Serialization; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Events; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("UnityEngine.AudioModule")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Marioalexsan.ModAudio")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("2.2.1.0")] [assembly: AssemblyInformationalVersion("2.2.1+6f4dbb5df69bcc99947b875e45f2286892b94c03")] [assembly: AssemblyProduct("ModAudio")] [assembly: AssemblyTitle("Marioalexsan.ModAudio")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.2.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NAudio.Wave { public class Mp3FileReader : Mp3FileReaderBase { [CompilerGenerated] private static class <>O { public static FrameDecompressorBuilder <0>__CreateAcmFrameDecompressor; } public Mp3FileReader(string mp3FileName) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown FileStream fileStream = File.OpenRead(mp3FileName); object obj = <>O.<0>__CreateAcmFrameDecompressor; if (obj == null) { FrameDecompressorBuilder val = CreateAcmFrameDecompressor; <>O.<0>__CreateAcmFrameDecompressor = val; obj = (object)val; } ((Mp3FileReaderBase)this)..ctor((Stream)fileStream, (FrameDecompressorBuilder)obj, true); } public Mp3FileReader(Stream inputStream) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown object obj = <>O.<0>__CreateAcmFrameDecompressor; if (obj == null) { FrameDecompressorBuilder val = CreateAcmFrameDecompressor; <>O.<0>__CreateAcmFrameDecompressor = val; obj = (object)val; } ((Mp3FileReaderBase)this)..ctor(inputStream, (FrameDecompressorBuilder)obj, false); } public static IMp3FrameDecompressor CreateAcmFrameDecompressor(WaveFormat mp3Format) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown return (IMp3FrameDecompressor)new AcmMp3FrameDecompressor(mp3Format); } } } namespace Marioalexsan.ModAudio { public static class AudioClipLoader { public interface IAudioStream : IDisposable { int TotalFrames { get; } int ChannelsPerFrame { get; } int Frequency { get; } void OnAudioRead(float[] samples); void OnAudioSetPosition(int newPosition); } private class OggStream : IAudioStream, IDisposable { private readonly VorbisReader _reader = new VorbisReader(stream, true); public float VolumeModifier = 1f; public int TotalFrames => (int)_reader.TotalSamples; public int ChannelsPerFrame => _reader.Channels; public int Frequency => _reader.SampleRate; public OggStream(Stream stream) { }//IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown public void OnAudioRead(float[] samples) { _reader.ReadSamples((Span<float>)samples); OptimizedMethods.MultiplyFloatArray(samples, VolumeModifier); } public void OnAudioSetPosition(int newPosition) { _reader.SamplePosition = newPosition; } public void Dispose() { _reader.Dispose(); } } private class WavStream : IAudioStream, IDisposable { private readonly WaveFileReader _reader; private readonly ISampleProvider _provider; public float VolumeModifier = 1f; public int TotalFrames => (int)_reader.SampleCount; public int ChannelsPerFrame => ((WaveStream)_reader).WaveFormat.Channels; public int Frequency => ((WaveStream)_reader).WaveFormat.SampleRate; public WavStream(Stream stream) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown _reader = new WaveFileReader(stream); _provider = WaveExtensionMethods.ToSampleProvider((IWaveProvider)(object)_reader); } public void OnAudioRead(float[] samples) { _provider.Read(samples, 0, samples.Length); OptimizedMethods.MultiplyFloatArray(samples, VolumeModifier); } public void OnAudioSetPosition(int newPosition) { ((Stream)(object)_reader).Position = newPosition * ((WaveStream)_reader).BlockAlign; } public void Dispose() { ((Stream)(object)_reader).Dispose(); } } private class Mp3Stream : IAudioStream, IDisposable { private readonly Mp3FileReader _reader; private readonly ISampleProvider _provider; public float VolumeModifier = 1f; public int TotalFrames => (int)(((Stream)(object)_reader).Length * 8 / ChannelsPerFrame / ((WaveStream)_reader).WaveFormat.BitsPerSample); public int ChannelsPerFrame => ((WaveStream)_reader).WaveFormat.Channels; public int Frequency => ((WaveStream)_reader).WaveFormat.SampleRate; public Mp3Stream(Stream stream) { _reader = new Mp3FileReader(stream); _provider = WaveExtensionMethods.ToSampleProvider((IWaveProvider)(object)_reader); } public void OnAudioRead(float[] samples) { _provider.Read(samples, 0, samples.Length); OptimizedMethods.MultiplyFloatArray(samples, VolumeModifier); } public void OnAudioSetPosition(int newPosition) { ((Stream)(object)_reader).Position = newPosition * ((WaveStream)_reader).BlockAlign; } public void Dispose() { ((Stream)(object)_reader).Dispose(); } } public static readonly string[] SupportedLoadExtensions = new string[7] { ".aiff", ".aif", ".mp3", ".ogg", ".wav", ".aac", ".alac" }; public static readonly string[] SupportedStreamExtensions = new string[3] { ".wav", ".ogg", ".mp3" }; public static readonly string[] SupportedExtensions; public static AudioClip LoadFromFile(string clipName, string path, float volumeModifier) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(new Uri(path ?? ""), (AudioType)0); try { audioClip.SendWebRequest(); while (!audioClip.isDone) { Thread.Yield(); } if ((int)audioClip.result != 1) { throw new Exception("Request for audio clip " + path + " failed."); } DownloadHandlerAudioClip val = (DownloadHandlerAudioClip)audioClip.downloadHandler; AudioClip audioClip2 = val.audioClip; ((Object)audioClip2).name = clipName; float[] array = new float[audioClip2.samples * audioClip2.channels]; audioClip2.GetData(array, 0); OptimizedMethods.MultiplyFloatArray(array, volumeModifier); audioClip2.SetData(array, 0); ((DownloadHandler)val).Dispose(); return audioClip2; } finally { ((IDisposable)audioClip)?.Dispose(); } } public static AudioClip StreamFromFile(string clipName, string path, float volumeModifier, out IAudioStream openedStream) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00ba: Expected O, but got Unknown IAudioStream audioStream = null; if (path.EndsWith(".ogg")) { audioStream = new OggStream(File.OpenRead(path)) { VolumeModifier = volumeModifier }; } if (path.EndsWith(".mp3")) { audioStream = new Mp3Stream(File.OpenRead(path)) { VolumeModifier = volumeModifier }; } if (path.EndsWith(".wav")) { audioStream = new WavStream(File.OpenRead(path)) { VolumeModifier = volumeModifier }; } if (audioStream == null) { throw new NotImplementedException("The given file format isn't supported for streaming."); } openedStream = audioStream; int totalFrames = audioStream.TotalFrames; int channelsPerFrame = audioStream.ChannelsPerFrame; int frequency = audioStream.Frequency; IAudioStream audioStream2 = audioStream; PCMReaderCallback val = audioStream2.OnAudioRead; IAudioStream audioStream3 = audioStream; return AudioClip.Create(clipName, totalFrames, channelsPerFrame, frequency, true, val, new PCMSetPositionCallback(audioStream3.OnAudioSetPosition)); } static AudioClipLoader() { string[] supportedStreamExtensions = SupportedStreamExtensions; string[] supportedLoadExtensions = SupportedLoadExtensions; int num = 0; string[] array = new string[supportedStreamExtensions.Length + supportedLoadExtensions.Length]; ReadOnlySpan<string> readOnlySpan = new ReadOnlySpan<string>(supportedStreamExtensions); readOnlySpan.CopyTo(new Span<string>(array).Slice(num, readOnlySpan.Length)); num += readOnlySpan.Length; ReadOnlySpan<string> readOnlySpan2 = new ReadOnlySpan<string>(supportedLoadExtensions); readOnlySpan2.CopyTo(new Span<string>(array).Slice(num, readOnlySpan2.Length)); num += readOnlySpan2.Length; SupportedExtensions = array; } } internal static class AudioEngine { private struct SourceState { public AudioClip Clip; public float Volume; public float Pitch; public AudioClip AppliedClip; public float AppliedVolume; public float AppliedPitch; public bool DisableRouting; public bool IsOneShotSource; public bool IsOverlay; public bool JustRouted; public bool JustUsedDefaultClip; public bool WasStoppedOrDisabled; public AudioSource OneShotOrigin; } private static readonly Random RNG = new Random(); private static readonly Stopwatch Watch = new Stopwatch(); private static readonly Dictionary<AudioSource, SourceState> TrackedSources = new Dictionary<AudioSource, SourceState>(); private static readonly HashSet<AudioSource> TrackedPlayOnAwakeSources = new HashSet<AudioSource>(); private static AudioClip _emptyClip; public static List<AudioPack> AudioPacks { get; } = new List<AudioPack>(); public static IEnumerable<AudioPack> EnabledPacks => AudioPacks.Where((AudioPack x) => x.Enabled); private static AudioClip EmptyClip { get { if ((Object)(object)_emptyClip == (Object)null) { _emptyClip = AudioClip.Create("___nothing___", 16384, 1, 44100, false); _emptyClip.SetData(new float[16384], 0); } return _emptyClip; } } private static bool IsValidTarget(AudioSource source, AudioPackConfig.Route route) { AudioClip clip = TrackedSources[source].Clip; string text = ((clip != null) ? ((Object)clip).name : null); bool flag = false; if (text != null) { for (int i = 0; i < route.OriginalClips.Count; i++) { if (route.OriginalClips[i] == text) { flag = true; break; } } } if (!flag) { return false; } if (route.FilterBySources.Count > 0) { string name = ((Object)source).name; bool flag2 = false; for (int j = 0; j < route.FilterBySources.Count; j++) { if (route.FilterBySources[j] == name) { flag2 = true; break; } } if (!flag2) { return false; } } if (route.FilterByObject.Count > 0) { Transform val = ((Component)source).transform; bool flag3 = false; while ((Object)(object)val != (Object)null) { string name2 = ((Object)((Component)val).gameObject).name; for (int k = 0; k < route.FilterByObject.Count; k++) { if (route.FilterByObject[k] == name2) { flag3 = true; break; } } val = val.parent; } if (!flag3) { return false; } } return true; } public static void HardReload() { Reload(hardReload: true); } public static void SoftReload() { Reload(hardReload: false); } private static void Reload(bool hardReload) { Watch.Restart(); try { Logging.LogInfo("Reloading engine..."); CleanupSources(); if (hardReload) { OptimizedMethods.CachedForeach(TrackedSources, delegate(in KeyValuePair<AudioSource, SourceState> source) { KeyValuePair<AudioSource, SourceState> keyValuePair = source; if (keyValuePair.Value.IsOneShotSource) { Dictionary<AudioSource, SourceState> trackedSources = TrackedSources; keyValuePair = source; trackedSources.Remove(keyValuePair.Key); keyValuePair = source; Object.Destroy((Object)(object)keyValuePair.Key); } }); } Dictionary<AudioSource, bool> dictionary = new Dictionary<AudioSource, bool>(); AudioSource[] array = Object.FindObjectsOfType<AudioSource>(true); foreach (AudioSource val in array) { dictionary[val] = val.isPlaying; if (dictionary[val]) { val.Stop(); } } foreach (KeyValuePair<AudioSource, SourceState> trackedSource in TrackedSources) { if ((Object)(object)trackedSource.Key != (Object)null) { trackedSource.Key.clip = trackedSource.Value.Clip; trackedSource.Key.volume = trackedSource.Value.Volume; trackedSource.Key.pitch = trackedSource.Value.Pitch; } } TrackedSources.Clear(); if (hardReload) { Logging.LogInfo("Reloading audio packs..."); foreach (AudioPack audioPack in AudioPacks) { foreach (AudioClipLoader.IAudioStream openStream in audioPack.OpenStreams) { openStream.Dispose(); } } AudioPacks.Clear(); AudioPacks.AddRange(AudioPackLoader.LoadAudioPacks()); ModAudio.Plugin.InitializePackConfiguration(); } Logging.LogInfo("Preloading audio data..."); foreach (AudioPack audioPack2 in AudioPacks) { if (audioPack2.Enabled && audioPack2.PendingClipsToLoad.Count > 0) { string[] array2 = audioPack2.PendingClipsToLoad.Keys.ToArray(); string[] array3 = array2; foreach (string name in array3) { audioPack2.TryGetReadyClip(name, out var _); } Logging.LogInfo($"{audioPack2.Config.Id} - {array2.Length} clips preloaded."); } } Logging.LogInfo("Audio data preloaded."); AudioSource[] array4 = Object.FindObjectsOfType<AudioSource>(true); foreach (AudioSource val2 in array4) { if (dictionary[val2]) { val2.Play(); } } Logging.LogInfo("Done with reload!"); } catch (Exception ex) { Logging.LogError("ModAudio crashed in Reload! Please report this error to the mod developer:"); Logging.LogError(ex.ToString()); } Watch.Stop(); Logging.LogInfo($"Reload took {Watch.ElapsedMilliseconds} milliseconds."); } public static void Update() { try { AudioSource[] array = Object.FindObjectsOfType<AudioSource>(true); foreach (AudioSource val in array) { if (val.playOnAwake) { if (!TrackedPlayOnAwakeSources.Contains(val) && ((Behaviour)val).isActiveAndEnabled && val.isPlaying) { AudioPlayed(val); } else if (TrackedPlayOnAwakeSources.Contains(val) && !((Behaviour)val).isActiveAndEnabled && !val.isPlaying) { AudioStopped(val, stopOneShots: false); } } } CleanupSources(); } catch (Exception ex) { Logging.LogError("ModAudio crashed in Update! Please report this error to the mod developer:"); Logging.LogError(ex.ToString()); } } private static void CleanupSources() { OptimizedMethods.CachedForeach(TrackedPlayOnAwakeSources, delegate(in AudioSource source) { if ((Object)(object)source == (Object)null) { TrackedPlayOnAwakeSources.Remove(source); } }); OptimizedMethods.CachedForeach(TrackedSources, delegate(in KeyValuePair<AudioSource, SourceState> source) { KeyValuePair<AudioSource, SourceState> keyValuePair = source; if ((Object)(object)keyValuePair.Key == (Object)null) { Dictionary<AudioSource, SourceState> trackedSources = TrackedSources; keyValuePair = source; trackedSources.Remove(keyValuePair.Key); } else { keyValuePair = source; if (keyValuePair.Value.IsOneShotSource) { keyValuePair = source; if (!keyValuePair.Key.isPlaying) { Dictionary<AudioSource, SourceState> trackedSources2 = TrackedSources; keyValuePair = source; trackedSources2.Remove(keyValuePair.Key); keyValuePair = source; AudioStopped(keyValuePair.Key, stopOneShots: false); keyValuePair = source; Object.Destroy((Object)(object)keyValuePair.Key); } } } }); } private static void TrackSource(AudioSource source) { if (!TrackedSources.ContainsKey(source)) { TrackedSources.Add(source, new SourceState { AppliedClip = source.clip, Clip = source.clip, Pitch = source.pitch, Volume = source.volume, AppliedPitch = source.pitch, AppliedVolume = source.volume }); } } private static AudioSource CreateOneShotFromSource(AudioSource source) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = ((Component)source).gameObject; int num = 3; do { ParticleSystem component = gameObject.GetComponent<ParticleSystem>(); if ((Object)(object)component == (Object)null || (Object)(object)gameObject.transform.parent == (Object)null) { break; } gameObject = ((Component)gameObject.transform.parent).gameObject; } while (num-- > 0); AudioSource val = gameObject.AddComponent<AudioSource>(); val.volume = source.volume; val.pitch = source.pitch; val.clip = source.clip; val.outputAudioMixerGroup = source.outputAudioMixerGroup; val.loop = false; val.ignoreListenerVolume = source.ignoreListenerVolume; val.ignoreListenerPause = source.ignoreListenerPause; val.velocityUpdateMode = source.velocityUpdateMode; val.panStereo = source.panStereo; val.spatialBlend = source.spatialBlend; val.spatialize = source.spatialize; val.spatializePostEffects = source.spatializePostEffects; val.reverbZoneMix = source.reverbZoneMix; val.bypassEffects = source.bypassEffects; val.bypassListenerEffects = source.bypassListenerEffects; val.bypassReverbZones = source.bypassReverbZones; val.dopplerLevel = source.dopplerLevel; val.spread = source.spread; val.priority = source.priority; val.mute = source.mute; val.minDistance = source.minDistance; val.maxDistance = source.maxDistance; val.rolloffMode = source.rolloffMode; val.playOnAwake = false; val.SetCustomCurve((AudioSourceCurveType)0, source.GetCustomCurve((AudioSourceCurveType)0)); val.SetCustomCurve((AudioSourceCurveType)2, source.GetCustomCurve((AudioSourceCurveType)2)); val.SetCustomCurve((AudioSourceCurveType)1, source.GetCustomCurve((AudioSourceCurveType)1)); val.SetCustomCurve((AudioSourceCurveType)3, source.GetCustomCurve((AudioSourceCurveType)3)); TrackSource(val); Dictionary<AudioSource, SourceState> trackedSources = TrackedSources; SourceState value = TrackedSources[val]; value.IsOneShotSource = true; value.OneShotOrigin = source; trackedSources[val] = value; return val; } public static bool OneShotClipPlayed(AudioClip clip, AudioSource source, float volumeScale) { try { AudioSource val = CreateOneShotFromSource(source); val.volume *= volumeScale; val.clip = clip; Dictionary<AudioSource, SourceState> trackedSources = TrackedSources; SourceState value = TrackedSources[val]; value.Clip = clip; value.AppliedClip = val.clip; value.Volume = val.volume; value.AppliedVolume = val.volume; trackedSources[val] = value; val.Play(); return false; } catch (Exception ex) { Logging.LogError("ModAudio crashed in OneShotClipPlayed! Please report this error to the mod developer:"); Logging.LogError(ex.ToString()); Logging.LogError("AudioSource that caused the crash:"); Logging.LogError(" name = " + (((source != null) ? ((Object)source).name : null) ?? "(null)")); object obj; if (source == null) { obj = null; } else { AudioClip clip2 = source.clip; obj = ((clip2 != null) ? ((Object)clip2).name : null); } if (obj == null) { obj = "(null)"; } Logging.LogError(" clip = " + (string?)obj); Logging.LogError("AudioClip that caused the crash:"); Logging.LogError(" name = " + (((clip != null) ? ((Object)clip).name : null) ?? "(null)")); Logging.LogError(string.Format("Parameter {0} was: {1}", "volumeScale", volumeScale)); return true; } } private static void LogAudio(AudioSource source) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) float num = float.MinValue; if (ModAudio.Plugin.UseMaxDistanceForLogging.Value && Object.op_Implicit((Object)(object)Player._mainPlayer)) { num = Vector3.Distance(((Component)Player._mainPlayer).transform.position, ((Component)source).transform.position); if (num > ModAudio.Plugin.MaxDistanceForLogging.Value) { return; } } AudioMixerGroup outputAudioMixerGroup = source.outputAudioMixerGroup; string text = ((outputAudioMixerGroup == null) ? null : ((Object)outputAudioMixerGroup).name?.ToLower()) ?? "(null)"; if ((ModAudio.Plugin.LogAmbience.Value || !(text == "ambience")) && (ModAudio.Plugin.LogGame.Value || !(text == "game")) && (ModAudio.Plugin.LogGUI.Value || !(text == "gui")) && (ModAudio.Plugin.LogMusic.Value || !(text == "music")) && (ModAudio.Plugin.LogVoice.Value || !(text == "voice"))) { AudioClip clip = TrackedSources[source].Clip; string text2 = ((clip != null) ? ((Object)clip).name : null) ?? "(null)"; AudioClip clip2 = source.clip; string text3 = ((clip2 != null) ? ((Object)clip2).name : null) ?? "(null)"; bool flag = (Object)(object)TrackedSources[source].Clip != (Object)(object)source.clip; if (TrackedSources[source].JustUsedDefaultClip) { flag = true; text3 = "___default___"; } float volume = TrackedSources[source].Volume; float appliedVolume = TrackedSources[source].AppliedVolume; float pitch = TrackedSources[source].Pitch; float appliedPitch = TrackedSources[source].AppliedPitch; string text4 = (flag ? (text2 + " > " + text3) : text2); string text5 = ((volume != appliedVolume) ? $"{volume:F2} > {appliedVolume:F2}" : $"{volume:F2}"); string text6 = ((pitch != appliedPitch) ? $"{pitch:F2} > {appliedPitch:F2}" : $"{pitch:F2}"); string text7 = "Clip " + text4 + " Src " + ((Object)source).name + " Vol " + text5 + " Pit " + text6 + " Grp " + text; if (num != float.MinValue) { text7 += $" Dst {num:F2}"; } if (TrackedSources[source].IsOverlay) { text7 += " overlay"; } if (TrackedSources[source].IsOneShotSource) { text7 += " oneshot"; } Logging.LogInfo(text7, ModAudio.Plugin.LogAudioPlayed); } } public static bool AudioPlayed(AudioSource source) { try { TrackSource(source); if (source.playOnAwake) { TrackedPlayOnAwakeSources.Add(source); } bool isPlaying = source.isPlaying; if (!Route(source)) { LogAudio(source); return true; } Dictionary<AudioSource, SourceState> trackedSources = TrackedSources; SourceState value = TrackedSources[source]; value.JustRouted = false; value.WasStoppedOrDisabled = false; trackedSources[source] = value; bool flag = isPlaying && !source.isPlaying; if (flag) { source.Play(); } else { LogAudio(source); } return !flag; } catch (Exception ex) { Logging.LogError("ModAudio crashed in AudioPlayed! Please report this error to the mod developer:"); Logging.LogError(ex.ToString()); Logging.LogError("AudioSource that caused the crash:"); Logging.LogError(" name = " + (((source != null) ? ((Object)source).name : null) ?? "(null)")); object obj; if (source == null) { obj = null; } else { AudioClip clip = source.clip; obj = ((clip != null) ? ((Object)clip).name : null); } if (obj == null) { obj = "(null)"; } Logging.LogError(" clip = " + (string?)obj); return true; } } public static bool AudioStopped(AudioSource source, bool stopOneShots) { try { TrackSource(source); if (source.playOnAwake) { TrackedPlayOnAwakeSources.Remove(source); } if (stopOneShots) { OptimizedMethods.CachedForeach(TrackedSources, in source, delegate(in KeyValuePair<AudioSource, SourceState> trackedSource, in AudioSource stoppedSource) { KeyValuePair<AudioSource, SourceState> keyValuePair = trackedSource; if (keyValuePair.Value.IsOneShotSource) { keyValuePair = trackedSource; if ((Object)(object)keyValuePair.Value.OneShotOrigin == (Object)(object)stoppedSource) { keyValuePair = trackedSource; if ((Object)(object)keyValuePair.Key != (Object)null) { keyValuePair = trackedSource; if (keyValuePair.Key.isPlaying) { keyValuePair = trackedSource; keyValuePair.Key.Stop(); } } } } }); } Dictionary<AudioSource, SourceState> trackedSources = TrackedSources; AudioSource key = source; SourceState value = TrackedSources[source]; value.WasStoppedOrDisabled = true; trackedSources[key] = value; return true; } catch (Exception ex) { Logging.LogError("ModAudio crashed in AudioStopped! Please report this error to the mod developer:"); Logging.LogError(ex.ToString()); Logging.LogError("AudioSource that caused the crash:"); Logging.LogError(" name = " + (((source != null) ? ((Object)source).name : null) ?? "(null)")); object obj; if (source == null) { obj = null; } else { AudioClip clip = source.clip; obj = ((clip != null) ? ((Object)clip).name : null); } if (obj == null) { obj = "(null)"; } Logging.LogError(" clip = " + (string?)obj); Logging.LogError(string.Format("Parameter {0} was: {1}", "stopOneShots", stopOneShots)); return true; } } private static bool Route(AudioSource source) { SourceState sourceState = TrackedSources[source]; SourceState value; if ((Object)(object)source.clip != (Object)(object)sourceState.AppliedClip) { Dictionary<AudioSource, SourceState> trackedSources = TrackedSources; value = TrackedSources[source]; value.Clip = source.clip; value.AppliedClip = source.clip; trackedSources[source] = value; if ((double)Math.Abs(source.volume - sourceState.AppliedVolume) >= 0.005) { Dictionary<AudioSource, SourceState> trackedSources2 = TrackedSources; value = TrackedSources[source]; value.Volume = source.volume; value.AppliedVolume = source.volume; trackedSources2[source] = value; } else { source.volume = sourceState.Volume; } if ((double)Math.Abs(source.pitch - sourceState.AppliedPitch) >= 0.005) { Dictionary<AudioSource, SourceState> trackedSources3 = TrackedSources; value = TrackedSources[source]; value.Pitch = source.pitch; value.AppliedPitch = source.pitch; trackedSources3[source] = value; } else { source.pitch = sourceState.Pitch; } } if (sourceState.JustRouted || sourceState.DisableRouting) { return false; } Dictionary<AudioSource, SourceState> trackedSources4 = TrackedSources; value = TrackedSources[source]; value.JustRouted = true; value.JustUsedDefaultClip = false; trackedSources4[source] = value; List<(AudioPack, AudioPackConfig.Route)> list = new List<(AudioPack, AudioPackConfig.Route)>(); foreach (AudioPack enabledPack in EnabledPacks) { foreach (AudioPackConfig.Route route in enabledPack.Config.Routes) { if (IsValidTarget(source, route)) { list.Add((enabledPack, route)); } } } (AudioPack, AudioPackConfig.Route) tuple = (null, null); if (list.Count > 0) { tuple = SelectRandomWeighted(list); if (tuple.Item2.RelativeReplacementEffects) { source.volume = sourceState.Volume * tuple.Item2.Volume; source.pitch = sourceState.Pitch * tuple.Item2.Pitch; } else { source.volume = tuple.Item2.Volume; source.pitch = tuple.Item2.Pitch; } Dictionary<AudioSource, SourceState> trackedSources5 = TrackedSources; value = TrackedSources[source]; value.AppliedPitch = source.pitch; value.AppliedVolume = source.volume; trackedSources5[source] = value; if (tuple.Item2.ReplacementClips.Count > 0) { AudioPackConfig.Route.ClipSelection clipSelection = SelectRandomWeighted(tuple.Item2.ReplacementClips); AudioClip clip; if (clipSelection.Name == "___default___") { clip = TrackedSources[source].Clip; Dictionary<AudioSource, SourceState> trackedSources6 = TrackedSources; value = TrackedSources[source]; value.JustUsedDefaultClip = true; trackedSources6[source] = value; } else if (clipSelection.Name == "___nothing___") { clip = EmptyClip; } else { tuple.Item1.TryGetReadyClip(clipSelection.Name, out clip); } if ((Object)(object)clip != (Object)null) { source.volume *= clipSelection.Volume; source.pitch *= clipSelection.Pitch; Dictionary<AudioSource, SourceState> trackedSources7 = TrackedSources; value = TrackedSources[source]; value.AppliedClip = clip; value.JustRouted = true; value.AppliedPitch = source.pitch; value.AppliedVolume = source.volume; trackedSources7[source] = value; if ((Object)(object)source.clip != (Object)(object)clip && source.isPlaying) { source.Stop(); } source.clip = clip; } else { Logging.LogWarning(Texts.AudioClipNotFound(clipSelection.Name)); } } } List<(AudioPack, AudioPackConfig.Route)> list2 = new List<(AudioPack, AudioPackConfig.Route)>(); foreach (AudioPack enabledPack2 in EnabledPacks) { foreach (AudioPackConfig.Route route2 in enabledPack2.Config.Routes) { if ((!route2.OverlaysIgnoreRestarts || TrackedSources[source].WasStoppedOrDisabled || !source.isPlaying) && route2.OverlayClips.Count > 0 && IsValidTarget(source, route2) && (!route2.LinkOverlayAndReplacement || tuple.Item2 == route2)) { list2.Add((enabledPack2, route2)); } } } if (list2.Count > 0 && !TrackedSources[source].IsOverlay) { foreach (var item3 in list2) { AudioPack item = item3.Item1; AudioPackConfig.Route item2 = item3.Item2; AudioPackConfig.Route.ClipSelection clipSelection2 = SelectRandomWeighted(item2.OverlayClips); if (clipSelection2.Name == "___nothing___") { continue; } if (item.TryGetReadyClip(clipSelection2.Name, out var clip2)) { AudioSource val = CreateOneShotFromSource(source); val.clip = clip2; if (item2.RelativeOverlayEffects) { val.volume = sourceState.Volume * clipSelection2.Volume; val.pitch = sourceState.Pitch * clipSelection2.Pitch; } else { val.volume = clipSelection2.Volume; val.pitch = clipSelection2.Pitch; } Dictionary<AudioSource, SourceState> trackedSources8 = TrackedSources; value = TrackedSources[val]; value.Pitch = val.pitch; value.Volume = val.volume; value.AppliedPitch = val.pitch; value.AppliedVolume = val.volume; value.Clip = val.clip; value.AppliedClip = val.clip; value.IsOverlay = true; value.DisableRouting = true; trackedSources8[val] = value; val.Play(); } else { Logging.LogWarning(Texts.AudioClipNotFound(clipSelection2.Name)); } } } return true; } private static (AudioPack Pack, AudioPackConfig.Route Route) SelectRandomWeighted(List<(AudioPack Pack, AudioPackConfig.Route Route)> routes) { double num = 0.0; for (int i = 0; i < routes.Count; i++) { num += (double)routes[i].Route.ReplacementWeight; } int num2 = -1; double num3 = RNG.NextDouble() * num; do { num2++; num3 -= (double)routes[num2].Route.ReplacementWeight; } while (num3 >= 0.0); return routes[num2]; } private static AudioPackConfig.Route.ClipSelection SelectRandomWeighted(List<AudioPackConfig.Route.ClipSelection> selections) { double num = 0.0; for (int i = 0; i < selections.Count; i++) { num += (double)selections[i].Weight; } int num2 = -1; double num3 = RNG.NextDouble() * num; do { num2++; num3 -= (double)selections[num2].Weight; } while (num3 >= 0.0); return selections[num2]; } } public class AudioPack { public string PackPath { get; set; } = "???"; public bool Enabled { get; set; } = false; public bool OverrideModeEnabled { get; set; } = false; public AudioPackConfig Config { get; set; } = new AudioPackConfig(); public List<AudioClipLoader.IAudioStream> OpenStreams { get; } = new List<AudioClipLoader.IAudioStream>(); public Dictionary<string, AudioClip> ReadyClips { get; } = new Dictionary<string, AudioClip>(); public Dictionary<string, Func<AudioClip>> PendingClipsToLoad { get; } = new Dictionary<string, Func<AudioClip>>(); public Dictionary<string, Func<AudioClip>> PendingClipsToStream { get; } = new Dictionary<string, Func<AudioClip>>(); public bool IsUserPack() { return PackPath.StartsWith(ModAudio.Plugin.ModAudioConfigFolder) || PackPath.StartsWith(ModAudio.Plugin.ModAudioPluginFolder); } public bool TryGetReadyClip(string name, out AudioClip clip) { if (ReadyClips.TryGetValue(name, out clip)) { return true; } if (PendingClipsToStream.TryGetValue(name, out var value)) { PendingClipsToStream.Remove(name); AudioClip val2 = (ReadyClips[name] = value()); clip = val2; return true; } if (PendingClipsToLoad.TryGetValue(name, out var value2)) { PendingClipsToLoad.Remove(name); AudioClip val2 = (ReadyClips[name] = value2()); clip = val2; return true; } clip = null; return false; } } public class AudioPackConfig { public class Settings { [JsonProperty(/*Could not decode attribute arguments.*/)] public bool AutoloadReplacementClips { get; set; } = true; } public class AudioClipData { [JsonProperty(/*Could not decode attribute arguments.*/)] public string Name { get; set; } = ""; [JsonProperty(/*Could not decode attribute arguments.*/)] public string Path { get; set; } = ""; [JsonProperty(/*Could not decode attribute arguments.*/)] public float Volume { get; set; } = 1f; [JsonProperty(/*Could not decode attribute arguments.*/)] public bool IgnoreClipExtension { get; set; } = false; } public class Route { public class ClipSelection { [JsonProperty(/*Could not decode attribute arguments.*/)] public string Name { get; set; } = ""; [JsonProperty(/*Could not decode attribute arguments.*/)] public float Weight { get; set; } = 1f; [JsonProperty(/*Could not decode attribute arguments.*/)] public float Volume { get; set; } = 1f; [JsonProperty(/*Could not decode attribute arguments.*/)] public float Pitch { get; set; } = 1f; } [JsonProperty(/*Could not decode attribute arguments.*/)] public bool LinkOverlayAndReplacement { get; set; } = true; [JsonProperty(/*Could not decode attribute arguments.*/)] public bool RelativeReplacementEffects { get; set; } = true; [JsonProperty(/*Could not decode attribute arguments.*/)] public bool RelativeOverlayEffects { get; set; } = false; [JsonProperty(/*Could not decode attribute arguments.*/)] public bool OverlaysIgnoreRestarts { get; set; } = false; [JsonProperty(/*Could not decode attribute arguments.*/)] public List<string> OriginalClips { get; set; } = new List<string>(); [JsonProperty(/*Could not decode attribute arguments.*/)] public List<ClipSelection> ReplacementClips { get; set; } = new List<ClipSelection>(); [JsonProperty(/*Could not decode attribute arguments.*/)] public List<ClipSelection> OverlayClips { get; set; } = new List<ClipSelection>(); [JsonProperty(/*Could not decode attribute arguments.*/)] public List<string> FilterBySources { get; set; } = new List<string>(); [JsonProperty(/*Could not decode attribute arguments.*/)] public List<string> FilterByObject { get; set; } = new List<string>(); [JsonProperty(/*Could not decode attribute arguments.*/)] public float ReplacementWeight { get; set; } = 1f; [JsonProperty(/*Could not decode attribute arguments.*/)] public float Volume { get; set; } = 1f; [JsonProperty(/*Could not decode attribute arguments.*/)] public float Pitch { get; set; } = 1f; } [JsonProperty(/*Could not decode attribute arguments.*/)] public string Id { get; set; } = ""; [JsonProperty(/*Could not decode attribute arguments.*/)] public string DisplayName { get; set; } = ""; [JsonProperty(/*Could not decode attribute arguments.*/)] public Settings AudioPackSettings { get; set; } = new Settings(); [JsonProperty(/*Could not decode attribute arguments.*/)] public List<AudioClipData> CustomClips { get; set; } = new List<AudioClipData>(); [JsonProperty(/*Could not decode attribute arguments.*/)] public List<Route> Routes { get; set; } = new List<Route>(); public static AudioPackConfig ReadJSON(Stream stream) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown List<string> warnings = new List<string>(); StreamReader streamReader = new StreamReader(stream); AudioPackConfig result = JsonConvert.DeserializeObject<AudioPackConfig>(streamReader.ReadToEnd(), new JsonSerializerSettings { MissingMemberHandling = (MissingMemberHandling)1, Error = delegate(object obj, ErrorEventArgs e) { Exception error = e.ErrorContext.Error; JsonException val = (JsonException)(object)((error is JsonException) ? error : null); if (val != null && ((Exception)(object)val).Message.Contains("Could not find member")) { warnings.Add(((Exception)(object)val).Message); e.ErrorContext.Handled = true; } } }); foreach (string item in warnings) { Logging.LogWarning(item); } return result; } public static AudioPackConfig ConvertFromRoutes(RouteConfig routeConfig) { AudioPackConfig audioPackConfig = new AudioPackConfig { CustomClips = (from x in (from x in routeConfig.Routes.SelectMany((Route x) => x.ReplacementClips.Concat(x.OverlayClips)) select x.Name into x where x != "___default___" && x != "___nothing___" select x).Distinct() select new AudioClipData { Name = x, Path = x, IgnoreClipExtension = true, Volume = (routeConfig.ClipVolumes.ContainsKey(x) ? routeConfig.ClipVolumes[x] : 1f) }).ToList(), Routes = routeConfig.Routes, Id = routeConfig.Id, DisplayName = routeConfig.DisplayName }; foreach (KeyValuePair<string, float> clipVolume in routeConfig.ClipVolumes) { if (!audioPackConfig.CustomClips.Any((AudioClipData x) => x.Name == clipVolume.Key)) { Logging.LogWarning("Couldn't find clip " + clipVolume.Key + " to set volume for."); } } return audioPackConfig; } public static string GenerateSchema() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return ((object)new JsonSchemaGenerator().Generate(typeof(AudioPackConfig))).ToString(); } } public static class AudioPackLoader { public const float OneMB = 1048576f; public const string AudioPackConfigName = "modaudio.config.json"; public const string RoutesConfigName = "__routes.txt"; public const int FileSizeLimitForLoading = 1048576; public static string ReplaceRootPath(string path) { return Path.GetFullPath(path).Replace(Paths.PluginPath + "/", "plugin://").Replace(Paths.PluginPath + "\\", "plugin://") .Replace(Paths.ConfigPath + "/", "config://") .Replace(Paths.ConfigPath + "\\", "config://"); } private static bool IsNormalizedId(string id) { return !id.Contains("\\"); } private static string NormalizeId(string id) { return id.Replace("\\", "/"); } private static string ConvertPathToId(string path) { return NormalizeId(ReplaceRootPath(path)); } private static string ConvertPathToDisplayName(string path) { string text = Path.GetFullPath(path).Replace(Paths.PluginPath + "/", "").Replace(Paths.PluginPath + "\\", "") .Replace(Paths.ConfigPath + "/", "") .Replace(Paths.ConfigPath + "\\", "") .Replace("\\", "/"); int num = text.IndexOf('/'); return (num == -1) ? text : text.Substring(0, num); } public static List<AudioPack> LoadAudioPacks() { List<AudioPack> list = new List<AudioPack>(); string[] directories = Directory.GetDirectories(Paths.ConfigPath); string[] directories2 = Directory.GetDirectories(Paths.PluginPath); List<string> list2 = new List<string>(directories.Length + directories2.Length); list2.AddRange(directories); list2.AddRange(directories2); List<string> list3 = list2; foreach (string item in list3) { LoadAudioPacksFromRoot(list, item); } foreach (AudioPack item2 in list) { FinalizePack(item2); Logging.LogInfo(Texts.PackLoaded(item2), ModAudio.Plugin.LogPackLoading); } return list; } private static void FinalizePack(AudioPack pack) { foreach (AudioPackConfig.Route route in pack.Config.Routes) { float num = Mathf.Clamp(route.ReplacementWeight, 0.001f, 1000f); if (num != route.ReplacementWeight) { Logging.LogWarning(Texts.WeightClamped(num, pack)); } route.ReplacementWeight = num; foreach (AudioPackConfig.Route.ClipSelection replacementClip in route.ReplacementClips) { num = Mathf.Clamp(replacementClip.Weight, 0.001f, 1000f); if (num != replacementClip.Weight) { Logging.LogWarning(Texts.WeightClamped(num, pack)); } replacementClip.Weight = num; } foreach (AudioPackConfig.Route.ClipSelection overlayClip in route.OverlayClips) { num = Mathf.Clamp(overlayClip.Weight, 0.001f, 1000f); if (num != overlayClip.Weight) { Logging.LogWarning(Texts.WeightClamped(num, pack)); } overlayClip.Weight = num; } } } private static void LoadAudioPacksFromRoot(List<AudioPack> packs, string rootPath) { Queue<string> queue = new Queue<string>(); queue.Enqueue(rootPath); while (queue.Count > 0) { string text = queue.Dequeue(); string[] directories = Directory.GetDirectories(text); foreach (string item in directories) { queue.Enqueue(item); } string path = Path.Combine(text, "modaudio.config.json"); if (File.Exists(path)) { AudioPack audioPack = LoadAudioPack(packs, path); if (audioPack != null) { packs.Add(audioPack); } continue; } string path2 = Path.Combine(text, "__routes.txt"); if (File.Exists(path2)) { AudioPack audioPack2 = LoadLegacyAudioPack(packs, path2); if (audioPack2 != null) { packs.Add(audioPack2); } } else if ((text == rootPath || text == Path.Combine(rootPath, "audio")) && Directory.GetFiles(text).Any((string x) => VanillaClipNames.IsKnownClip(Path.GetFileNameWithoutExtension(x)))) { AudioPack audioPack3 = LoadLegacyAudioPack(packs, path2); if (audioPack3 != null) { packs.Add(audioPack3); } } } } private static AudioPack LoadAudioPack(List<AudioPack> existingPacks, string path) { Logging.LogInfo(Texts.LoadingPack(path), ModAudio.Plugin.LogPackLoading); using FileStream stream = File.OpenRead(path); AudioPackConfig config; try { config = AudioPackConfig.ReadJSON(stream); } catch (Exception ex) { Logging.LogWarning("Failed to read audio pack config for " + ReplaceRootPath(path) + "."); Logging.LogWarning(ex.ToString()); return null; } AudioPack pack = new AudioPack { Config = config, PackPath = path }; if (string.IsNullOrEmpty(pack.Config.Id)) { pack.Config.Id = ConvertPathToId(pack.PackPath); } else if (!IsNormalizedId(pack.Config.Id)) { Logging.LogWarning(Texts.InvalidPackId(pack.PackPath, pack.Config.Id)); return null; } if (string.IsNullOrEmpty(pack.Config.DisplayName)) { pack.Config.DisplayName = ConvertPathToDisplayName(pack.PackPath); } if (existingPacks.Any((AudioPack x) => x.Config.Id == pack.Config.Id)) { Logging.LogWarning(Texts.DuplicatePackId(pack.PackPath, pack.Config.Id)); return null; } string fullPath = Path.GetFullPath(Path.GetDirectoryName(path)); LoadCustomClips(fullPath, pack, extensionless: false); if (pack.Config.AudioPackSettings.AutoloadReplacementClips) { Logging.LogInfo(Texts.AutoloadingClips(path), ModAudio.Plugin.LogPackLoading); AutoLoadReplacementClipsFromPath(path, pack); } return pack; } private static AudioPack LoadLegacyAudioPack(List<AudioPack> existingPacks, string path) { Logging.LogInfo(Texts.LoadingPack(path), ModAudio.Plugin.LogPackLoading); string id = NormalizeId(ReplaceRootPath(path)); if (existingPacks.Any((AudioPack x) => x.Config.Id == id)) { Logging.LogWarning(Texts.DuplicatePackId(path, id)); return null; } AudioPack audioPack = new AudioPack { PackPath = path, Config = { AudioPackSettings = { AutoloadReplacementClips = true } } }; if (File.Exists(path)) { RouteConfig routeConfig = RouteConfig.ReadTextFormat(path); audioPack.Config = AudioPackConfig.ConvertFromRoutes(routeConfig); } if (string.IsNullOrWhiteSpace(audioPack.Config.DisplayName)) { audioPack.Config.DisplayName = ConvertPathToDisplayName(path); } if (string.IsNullOrWhiteSpace(audioPack.Config.Id)) { audioPack.Config.Id = ConvertPathToId(path); } string fullPath = Path.GetFullPath(Path.GetDirectoryName(path)); LoadCustomClips(fullPath, audioPack, extensionless: true); AutoLoadReplacementClipsFromPath(path, audioPack); return audioPack; } private static void LoadCustomClips(string rootPath, AudioPack pack, bool extensionless) { foreach (AudioPackConfig.AudioClipData clipData in pack.Config.CustomClips) { if (pack.ReadyClips.Any((KeyValuePair<string, AudioClip> x) => ((Object)x.Value).name == clipData.Name)) { Logging.LogWarning(Texts.DuplicateClipId(clipData.Path, clipData.Name)); continue; } string clipPath = Path.GetFullPath(Path.Combine(rootPath, clipData.Path)); if (!clipPath.StartsWith(rootPath)) { Logging.LogWarning(Texts.InvalidPackPath(clipData.Path, clipData.Name)); continue; } if (clipData.IgnoreClipExtension) { string[] supportedStreamExtensions = AudioClipLoader.SupportedStreamExtensions; foreach (string text in supportedStreamExtensions) { if (File.Exists(clipPath + text)) { clipPath += text; break; } } } if (!AudioClipLoader.SupportedExtensions.Any(clipPath.EndsWith)) { Logging.LogWarning(Texts.UnsupportedAudioFile(clipData.Path, clipData.Name)); continue; } long length = new FileInfo(clipPath).Length; bool flag = length >= 1048576; if (flag && !AudioClipLoader.SupportedStreamExtensions.Any(clipPath.EndsWith)) { Logging.LogWarning(Texts.AudioCannotBeStreamed(clipPath, length)); flag = false; } try { Logging.LogInfo(Texts.LoadingClip(clipPath, clipData.Name, flag), ModAudio.Plugin.LogPackLoading); if (flag) { pack.PendingClipsToStream[clipData.Name] = delegate { AudioClipLoader.IAudioStream openedStream; AudioClip result = AudioClipLoader.StreamFromFile(clipData.Name, clipPath, clipData.Volume, out openedStream); pack.OpenStreams.Add(openedStream); return result; }; } else { pack.PendingClipsToLoad[clipData.Name] = () => AudioClipLoader.LoadFromFile(clipData.Name, clipPath, clipData.Volume); } } catch (Exception arg) { Logging.LogWarning("Failed to load " + clipData.Name + " from " + ReplaceRootPath(clipPath) + "!"); Logging.LogWarning($"Exception: {arg}"); } } } private static void AutoLoadReplacementClipsFromPath(string path, AudioPack pack) { List<string> list = new List<string>(); string[] files = Directory.GetFiles(Path.GetDirectoryName(path)); foreach (string file in files) { if (!AudioClipLoader.SupportedExtensions.Any(file.EndsWith) || !VanillaClipNames.IsKnownClip(Path.GetFileNameWithoutExtension(path))) { continue; } long length = new FileInfo(file).Length; bool flag = length >= 1048576; if (flag && !AudioClipLoader.SupportedStreamExtensions.Any(file.EndsWith)) { Logging.LogWarning(Texts.AudioCannotBeStreamed(file, length)); flag = false; } string name = Path.GetFileNameWithoutExtension(file); if (pack.ReadyClips.ContainsKey(name)) { Logging.LogWarning(Texts.DuplicateClipSkipped(file, name)); continue; } list.Add(name); try { Logging.LogInfo(Texts.LoadingClip(name, file, flag), ModAudio.Plugin.LogPackLoading); if (flag) { pack.PendingClipsToStream[name] = delegate { AudioClipLoader.IAudioStream openedStream; AudioClip result = AudioClipLoader.StreamFromFile(name, file, 1f, out openedStream); pack.OpenStreams.Add(openedStream); return result; }; } else { pack.PendingClipsToLoad[name] = () => AudioClipLoader.LoadFromFile(name, file, 1f); } } catch (Exception arg) { Logging.LogWarning("Failed to load " + name + " from " + ReplaceRootPath(file) + "!"); Logging.LogWarning($"Exception: {arg}"); } } foreach (string item in list) { pack.Config.Routes.Add(new AudioPackConfig.Route { OriginalClips = new List<string>(1) { item }, ReplacementClips = new List<AudioPackConfig.Route.ClipSelection>(1) { new AudioPackConfig.Route.ClipSelection { Name = item } } }); } } } internal static class Logging { private static ManualLogSource InternalLogger => ModAudio.Plugin.Logger; public static void LogFatal(object data, ConfigEntry<bool> toggle = null) { Log(data, (LogLevel)1, toggle); } public static void LogError(object data, ConfigEntry<bool> toggle = null) { Log(data, (LogLevel)2, toggle); } public static void LogWarning(object data, ConfigEntry<bool> toggle = null) { Log(data, (LogLevel)4, toggle); } public static void LogMessage(object data, ConfigEntry<bool> toggle = null) { Log(data, (LogLevel)8, toggle); } public static void LogInfo(object data, ConfigEntry<bool> toggle = null) { Log(data, (LogLevel)16, toggle); } public static void LogDebug(object data, ConfigEntry<bool> toggle = null) { Log(data, (LogLevel)32, toggle); } private static void Log(object data, LogLevel level = 16, ConfigEntry<bool> toggle = null) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (toggle == null || toggle.Value) { ManualLogSource internalLogger = InternalLogger; if (internalLogger != null) { internalLogger.Log(level, data); } } } } [BepInPlugin("Marioalexsan.ModAudio", "ModAudio", "2.2.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ModAudio : BaseUnityPlugin { public const float MinWeight = 0.001f; public const float MaxWeight = 1000f; public const float DefaultWeight = 1f; public const string DefaultClipIdentifier = "___default___"; private Harmony _harmony; private bool _reloadRequired = true; public static ModAudio Plugin { get; private set; } internal ManualLogSource Logger { get; private set; } public string ModAudioConfigFolder => Path.Combine(Paths.ConfigPath, "Marioalexsan.ModAudio_UserAudioPack"); public string ModAudioPluginFolder => Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); public ConfigEntry<bool> LogPackLoading { get; private set; } public ConfigEntry<bool> LogAudioPlayed { get; private set; } public ConfigEntry<bool> UseMaxDistanceForLogging { get; private set; } public ConfigEntry<float> MaxDistanceForLogging { get; private set; } public ConfigEntry<bool> LogAmbience { get; private set; } public ConfigEntry<bool> LogGame { get; private set; } public ConfigEntry<bool> LogGUI { get; private set; } public ConfigEntry<bool> LogMusic { get; private set; } public ConfigEntry<bool> LogVoice { get; private set; } public Dictionary<string, ConfigEntry<bool>> AudioPackEnabled { get; } = new Dictionary<string, ConfigEntry<bool>>(); public Dictionary<string, GameObject> AudioPackEnabledObjects { get; } = new Dictionary<string, GameObject>(); public GameObject AudioPackEnabledRoot { get; set; } private void SetupBaseAudioPack() { if (!Directory.Exists(ModAudioConfigFolder)) { Directory.CreateDirectory(ModAudioConfigFolder); } VanillaClipNames.GenerateReferenceFile(Path.Combine(ModAudioConfigFolder, "clip_names.txt")); File.WriteAllText(Path.Combine(ModAudioConfigFolder, "schema_modaudio.config.json"), AudioPackConfig.GenerateSchema()); } private void Awake() { Plugin = this; Logger = ((BaseUnityPlugin)this).Logger; _harmony = Harmony.CreateAndPatchAll(typeof(ModAudio).Assembly, "Marioalexsan.ModAudio"); SetupBaseAudioPack(); InitializeConfiguration(); } private void InitializeConfiguration() { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown LogPackLoading = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogPackLoading", true, "True to enable logging when loading audio packs, false to disable it."); LogAudioPlayed = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogAudioPlayed", false, "True to enable console logging for audio played, false to disable it."); UseMaxDistanceForLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "UseMaxDistanceForLogging", false, "True to log audio played only if it's within a certain range of the player, false to log all sounds."); MaxDistanceForLogging = ((BaseUnityPlugin)this).Config.Bind<float>("Logging", "MaxDistanceForLogging", 32f, new ConfigDescription("The max distance in units from the player where audio will be logged (for reference, 12 units ~ Angela Flux's height).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(32f, 2048f), Array.Empty<object>())); LogAmbience = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogAmbience", true, "True to log audio that's part of the ambience group, false to skip it."); LogGame = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogGame", true, "True to log audio that's part of the game group, false to skip it."); LogGUI = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogGUI", true, "True to log audio that's part of the GUI group, false to skip it."); LogMusic = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogMusic", true, "True to log audio that's part of the music group, false to skip it."); LogVoice = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogVoice", true, "True to log audio that's part of the voice group, false to skip it."); if (!EasySettings.IsAvailable) { return; } EasySettings.OnApplySettings.AddListener((UnityAction)delegate { try { ((BaseUnityPlugin)this).Config.Save(); bool flag = false; foreach (AudioPack audioPack in AudioEngine.AudioPacks) { ConfigEntry<bool> value; bool flag2 = !AudioPackEnabled.TryGetValue(audioPack.Config.Id, out value) || value.Value; if (flag2 != audioPack.Enabled) { Logger.LogInfo((object)("Pack " + audioPack.Config.Id + " is now " + (flag2 ? "enabled" : "disabled"))); flag = true; } audioPack.Enabled = flag2; } if (flag) { AudioEngine.SoftReload(); } } catch (Exception ex) { Logging.LogError("ModAudio crashed in OnApplySettings! Please report this error to the mod developer:"); Logging.LogError(ex.ToString()); } }); EasySettings.OnInitialized.AddListener((UnityAction)delegate { EasySettings.AddHeader("ModAudio"); EasySettings.AddToggle("Log audio pack loading", LogPackLoading); EasySettings.AddToggle("Log audio played", LogAudioPlayed); EasySettings.AddToggle("Limit audio logged by distance", UseMaxDistanceForLogging); EasySettings.AddAdvancedSlider("Max log distance", MaxDistanceForLogging, wholeNumbers: true); EasySettings.AddToggle("Log ambience audio", LogAmbience); EasySettings.AddToggle("Log game audio", LogGame); EasySettings.AddToggle("Log GUI audio", LogGUI); EasySettings.AddToggle("Log music audio", LogMusic); EasySettings.AddToggle("Log voice audio", LogVoice); }); } internal void InitializePackConfiguration() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)AudioPackEnabledRoot) && EasySettings.IsAvailable) { EasySettings.AddHeader("ModAudio audio packs"); EasySettings.AddButton("Open custom audio pack folder", (UnityAction)delegate { SetupBaseAudioPack(); Application.OpenURL(new Uri(ModAudioConfigFolder ?? "").AbsoluteUri); }); AudioPackEnabledRoot = EasySettings.AddButton("Reload audio packs", (UnityAction)delegate { _reloadRequired = true; }); } foreach (AudioPack audioPack in AudioEngine.AudioPacks) { if (!AudioPackEnabled.TryGetValue(audioPack.Config.Id, out var value)) { ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("EnabledAudioPacks", audioPack.Config.Id, true, Texts.EnablePackDescription(audioPack.Config.DisplayName)); AudioPackEnabled[audioPack.Config.Id] = val; if (EasySettings.IsAvailable && !AudioPackEnabledObjects.ContainsKey(audioPack.Config.Id)) { AudioPackEnabledObjects[audioPack.Config.Id] = EasySettings.AddToggle(audioPack.Config.DisplayName, val); } audioPack.Enabled = val.Value; } else { audioPack.Enabled = value.Value; } } if (!EasySettings.IsAvailable) { return; } int num = AudioPackEnabledRoot.transform.GetSiblingIndex() + 1; foreach (KeyValuePair<string, GameObject> item in AudioPackEnabledObjects.OrderBy((KeyValuePair<string, GameObject> x) => x.Key)) { item.Value.transform.SetSiblingIndex(num++); } foreach (KeyValuePair<string, GameObject> config in AudioPackEnabledObjects) { config.Value.SetActive(AudioEngine.AudioPacks.Any((AudioPack x) => x.Config.Id == config.Key)); } } private void CheckForObsoleteStuff() { string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); string path = Path.Combine(directoryName, "audio"); bool flag = false; if (Directory.GetFiles(directoryName).Any(IsAudioPackFile)) { flag = true; } if (Directory.Exists(path) && Directory.GetFiles(path).Any(IsAudioPackFile)) { flag = true; } if (flag) { Logger.LogWarning((object)"There is an audio pack under ModAudio's plugin folder!"); Logger.LogWarning((object)"Please use the folder from BepInEx/config for your custom packs instead of the plugin folder."); Logger.LogWarning((object)"When using r2modman, the plugin folder might be deleted mercilessly when you update or uninstall your mod, which will delete your custom audio."); } static bool IsAudioPackFile(string name) { return Path.GetFileName(name) == "modaudio.config.json" || Path.GetFileName(name) == "__routes.txt" || AudioClipLoader.SupportedLoadExtensions.Contains<string>(Path.GetExtension(name)); } } private void Update() { try { if (_reloadRequired) { _reloadRequired = false; CheckForObsoleteStuff(); AudioEngine.HardReload(); } AudioEngine.Update(); } catch (Exception ex) { Logging.LogError("ModAudio crashed in Update! Please report this error to the mod developer:"); Logging.LogError(ex.ToString()); } } } internal static class OptimizedMethods { public delegate void CachedForeachAction<T>(in T value); public delegate void CachedForeachAction<T, V>(in T value, in V context); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void MultiplyFloatArray(float[] data, float factor) { fixed (float* ptr = data) { float* ptr2 = ptr; for (float* ptr3 = ptr + data.Length; ptr2 != ptr3; ptr2++) { *ptr2 *= factor; } } } public static void CachedForeach<T>(ICollection<T> enumerable, CachedForeachAction<T> action) { T[] array = ArrayPool<T>.Shared.Rent(enumerable.Count); int num = 0; foreach (T item in enumerable) { array[num++] = item; } for (int i = 0; i < num; i++) { action(in array[i]); } ArrayPool<T>.Shared.Return(array); } public static void CachedForeach<T, V>(ICollection<T> enumerable, in V context, CachedForeachAction<T, V> action) { T[] array = ArrayPool<T>.Shared.Rent(enumerable.Count); int num = 0; foreach (T item in enumerable) { array[num++] = item; } for (int i = 0; i < num; i++) { action(in array[i], in context); } ArrayPool<T>.Shared.Return(array); } } public class RouteConfig { private static readonly char[] ReplacementSeparator = new char[1] { '=' }; private static readonly char[] OverlaySeparator = new char[1] { '@' }; private static readonly char[] EffectSeparator = new char[1] { '~' }; private static readonly char[] RouteSeparators; private static readonly char[] FieldSeparator; private static readonly char[] ListSeparator; public Dictionary<string, float> ClipVolumes { get; set; } = new Dictionary<string, float>(); public List<AudioPackConfig.Route> Routes { get; set; } = new List<AudioPackConfig.Route>(); public string Id { get; set; } = ""; public string DisplayName { get; set; } = ""; public static RouteConfig ReadTextFormat(string path) { using StreamReader streamReader = new StreamReader(File.OpenRead(path)); Dictionary<string, float> dictionary = new Dictionary<string, float>(); List<AudioPackConfig.Route> list = new List<AudioPackConfig.Route>(); string id = ""; string displayName = ""; int num = -1; string text; while ((text = streamReader.ReadLine()) != null) { num++; if (text.Trim() == "" || text.Trim().StartsWith("#")) { continue; } if (text.Trim().StartsWith("%")) { if (text.Trim().StartsWith("%id ")) { id = text.Trim().Substring("%id ".Length); } else if (text.Trim().StartsWith("%displayname ")) { displayName = text.Trim().Substring("%displayname ".Length); } else if (text.Trim().StartsWith("%customclipvolume ")) { string[] array = text.Trim().Substring("%customclipvolume ".Length).Split(new char[1] { '=' }); if (array.Length != 2) { Logging.LogWarning($"Line {num}: Expected %customclipvolume clipName = volume."); } if (array[0].Trim() == "") { Logging.LogWarning($"Line {num}: Expected a clip name."); } if (!float.TryParse(array[1], out var result)) { Logging.LogWarning($"Line {num}: Volume is not a number."); } dictionary[array[0].Trim()] = result; } else { Logging.LogWarning($"Line {num}: Unrecognized attribute {text.Trim().Substring(1)}."); } continue; } if (text.Contains("/") || (text.IndexOfAny(EffectSeparator) == -1 && text.IndexOfAny(OverlaySeparator) == -1 && text.IndexOfAny(FieldSeparator) == -1 && text.IndexOfAny(ListSeparator) == -1)) { string[] array2 = text.Split(ReplacementSeparator, 3); if (array2.Length != 2) { Logging.LogWarning($"Line {num}: Encountered a malformed route (expected key = value), skipping it."); continue; } string[] array3 = array2[1].Split(new char[1] { '/' }, 3); if (array3.Length > 2) { Logging.LogWarning($"Line {num}: Too many values defined for a route (expected at most 2), skipping it."); continue; } string text2 = array2[0].Trim(); string text3 = array3[0].Trim(); float result2 = 1f; if (text2.Trim() == "" || text3.Trim() == "") { Logging.LogWarning($"Line {num}: Either clip name or replacement was empty for a route, skipping it."); continue; } if (array3.Length > 1 && !float.TryParse(array3[1], out result2)) { Logging.LogWarning($"Line {num}: Couldn't parse random weight {array3[1]} for {text2} => {text3}, defaulting to {1f}."); } list.Add(new AudioPackConfig.Route { OriginalClips = new List<string>(1) { text2 }, ReplacementClips = new List<AudioPackConfig.Route.ClipSelection>(1) { new AudioPackConfig.Route.ClipSelection { Name = text3, Weight = result2 } } }); continue; } string[] array4 = text.Split(RouteSeparators, 5, StringSplitOptions.None); int num2 = -1; int num3 = -1; int num4 = -1; int num5 = -1; int num6 = -1; int num7 = -1; if (array4.Length > 5 || array4.Length == 1) { Logging.LogWarning($"Line {num}: Encountered a malformed route (expected source = replacement @ overlay ~ modifier), skipping it."); continue; } int num8 = text.IndexOfAny(RouteSeparators, 0); int num9 = 1; if (num8 == -1) { Logging.LogWarning($"Line {num}: Encountered a malformed route (expected source = replacement @ overlay ~ effect), skipping it."); continue; } bool flag = false; while (num8 != -1) { if (text[num8] == ReplacementSeparator[0]) { if (num2 != -1 || num3 != -1 || num4 != -1) { flag = true; break; } num2 = num8; num5 = num9++; } else if (text[num8] == OverlaySeparator[0]) { if (num3 != -1) { flag = true; break; } num3 = num8; num6 = num9++; } else if (text[num8] == EffectSeparator[0]) { if (num4 != -1) { flag = true; break; } num4 = num8; num7 = num9++; } num8 = text.IndexOfAny(RouteSeparators, num8 + 1); } if (flag) { Logging.LogWarning($"Line {num}: Encountered a malformed route (expected source = replacement @ overlay ~ effect), skipping it."); continue; } AudioPackConfig.Route route = new AudioPackConfig.Route(); bool flag2 = num3 < num4; List<string> list2 = (from x in array4[0].Trim().Split(ListSeparator, StringSplitOptions.RemoveEmptyEntries) select x.Trim()).ToList(); List<string> list3 = ((num5 == -1) ? new List<string>() : (from x in array4[num5].Trim().Split(ListSeparator, StringSplitOptions.RemoveEmptyEntries) select x.Trim()).ToList()); List<string> list4 = ((num6 == -1) ? new List<string>() : (from x in array4[num6].Split(ListSeparator, StringSplitOptions.RemoveEmptyEntries) select x.Trim()).ToList()); List<string> list5 = ((num7 == -1) ? new List<string>() : (from x in array4[num7].Split(ListSeparator, StringSplitOptions.RemoveEmptyEntries) select x.Trim()).ToList()); for (int i = 0; i < list2.Count; i++) { if (list2[i] == "") { Logging.LogWarning($"Line {num}: empty clip, ignoring it."); list2.RemoveAt(i--); } } if (list2.Count == 0) { Logging.LogWarning($"Line {num}: Expected at least one source clip, skipping route."); continue; } route.OriginalClips = list2; for (int j = 0; j < list3.Count; j++) { string[] array5 = (from x in list3[j].Split(FieldSeparator) select x.Trim()).ToArray(); if (array5.Length > 4) { Logging.LogWarning($"Line {num}: Too many values defined for a target clip (expected at most 4), skipping it."); continue; } string text4 = array5[0]; if (text4 == "") { Logging.LogWarning($"Line {num}: empty clip, ignoring it."); list3.RemoveAt(j--); } float result3 = 1f; float result4 = 1f; float result5 = 1f; if (array5.Length > 1 && !float.TryParse(array5[1], out result3)) { Logging.LogWarning($"Line {num}: Couldn't parse random weight {array5[1]} for {text4}, defaulting to {1f}."); } if (array5.Length > 2 && !float.TryParse(array5[2], out result4)) { Logging.LogWarning($"Line {num}: Couldn't parse volume {array5[2]} for {text4}, defaulting to 1."); } if (array5.Length > 3 && !float.TryParse(array5[3], out result5)) { Logging.LogWarning($"Line {num}: Couldn't parse pitch {array5[3]} for {text4}, defaulting to 1."); } route.ReplacementClips.Add(new AudioPackConfig.Route.ClipSelection { Name = text4, Weight = result3, Volume = result4, Pitch = result5 }); } list.Add(route); for (int k = 0; k < list4.Count; k++) { string[] array6 = (from x in list4[k].Split(FieldSeparator) select x.Trim()).ToArray(); if (array6.Length > 4) { Logging.LogWarning($"Line {num}: Too many values defined for a target clip (expected at most 4), skipping it."); continue; } string text5 = array6[0]; if (text5 == "") { ModAudio plugin = ModAudio.Plugin; if (plugin != null) { ManualLogSource logger = plugin.Logger; if (logger != null) { logger.LogWarning((object)$"Line {num}: empty clip, ignoring it."); } } list4.RemoveAt(k--); } float result6 = 1f; float result7 = 1f; float result8 = 1f; if (array6.Length > 1 && !float.TryParse(array6[1], out result6)) { Logging.LogWarning($"Line {num}: Couldn't parse random weight {array6[1]} for {text5}, defaulting to {1f}."); } if (array6.Length > 2 && !float.TryParse(array6[2], out result7)) { Logging.LogWarning($"Line {num}: Couldn't parse volume {array6[2]} for {text5}, defaulting to 1."); } if (array6.Length > 3 && !float.TryParse(array6[3], out result8)) { Logging.LogWarning($"Line {num}: Couldn't parse pitch {array6[3]} for {text5}, defaulting to 1."); } route.OverlayClips.Add(new AudioPackConfig.Route.ClipSelection { Name = text5, Weight = result6, Volume = result7, Pitch = result8 }); } for (int l = 0; l < list5.Count; l++) { string[] array7 = (from x in list5[l].Split(FieldSeparator) select x.Trim()).ToArray(); switch (array7[0]) { case "weight": { float result10; if (array7.Length != 2) { Logging.LogWarning($"Line {num}: Expected a value for replacement weight."); } else if (!float.TryParse(array7[1], out result10)) { Logging.LogWarning($"Line {num}: Couldn't parse replacement weight {array7[1]}."); } else { route.ReplacementWeight = result10; } break; } case "volume": { float result12; if (array7.Length != 2) { Logging.LogWarning($"Line {num}: Expected a value for volume."); } else if (!float.TryParse(array7[1], out result12)) { Logging.LogWarning($"Line {num}: Couldn't parse volume {array7[1]}."); } else { route.Volume = result12; } break; } case "pitch": { float result11; if (array7.Length != 2) { Logging.LogWarning($"Line {num}: Expected a value for pitch."); } else if (!float.TryParse(array7[1], out result11)) { Logging.LogWarning($"Line {num}: Couldn't parse pitch {array7[1]}."); } else { route.Pitch = result11; } break; } case "overlays_ignore_restarts": { bool result9; if (array7.Length != 2) { Logging.LogWarning($"Line {num}: Expected a value for overlays_ignore_restarts."); } else if (!bool.TryParse(array7[1], out result9)) { Logging.LogWarning($"Line {num}: Couldn't parse {array7[1]} boolean for overlays_ignore_restarts."); } else { route.OverlaysIgnoreRestarts = result9; } break; } default: Logging.LogWarning($"Line {num}: Unrecognized route effect / setting {array7[0]}."); break; } } } return new RouteConfig { ClipVolumes = dictionary, Id = id, DisplayName = displayName, Routes = list }; } static RouteConfig() { char[] replacementSeparator = ReplacementSeparator; char[] overlaySeparator = OverlaySeparator; char[] effectSeparator = EffectSeparator; int num = 0; char[] array = new char[replacementSeparator.Length + overlaySeparator.Length + effectSeparator.Length]; ReadOnlySpan<char> readOnlySpan = new ReadOnlySpan<char>(replacementSeparator); readOnlySpan.CopyTo(new Span<char>(array).Slice(num, readOnlySpan.Length)); num += readOnlySpan.Length; ReadOnlySpan<char> readOnlySpan2 = new ReadOnlySpan<char>(overlaySeparator); readOnlySpan2.CopyTo(new Span<char>(array).Slice(num, readOnlySpan2.Length)); num += readOnlySpan2.Length; ReadOnlySpan<char> readOnlySpan3 = new ReadOnlySpan<char>(effectSeparator); readOnlySpan3.CopyTo(new Span<char>(array).Slice(num, readOnlySpan3.Length)); num += readOnlySpan3.Length; RouteSeparators = array; FieldSeparator = new char[1] { ':' }; ListSeparator = new char[1] { '|' }; } } public static class Texts { public const string LogAudioLoadingTitle = "Log audio pack loading"; public const string LogAudioLoadingDescription = "True to enable logging when loading audio packs, false to disable it."; public const string LogAudioPlayedTitle = "Log audio played"; public const string LogAudioPlayedDescription = "True to enable console logging for audio played, false to disable it."; public const string UseMaxDistanceForLoggingTitle = "Limit audio logged by distance"; public const string UseMaxDistanceForLoggingDescription = "True to log audio played only if it's within a certain range of the player, false to log all sounds."; public const string MaxDistanceForLoggingTitle = "Max log distance"; public const string MaxDistanceForLoggingDescription = "The max distance in units from the player where audio will be logged (for reference, 12 units ~ Angela Flux's height)."; public const string LogAmbienceTitle = "Log ambience audio"; public const string LogAmbienceDescription = "True to log audio that's part of the ambience group, false to skip it."; public const string LogGameTitle = "Log game audio"; public const string LogGameDescription = "True to log audio that's part of the game group, false to skip it."; public const string LogGUITitle = "Log GUI audio"; public const string LogGUIDescription = "True to log audio that's part of the GUI group, false to skip it."; public const string LogMusicTitle = "Log music audio"; public const string LogMusicDescription = "True to log audio that's part of the music group, false to skip it."; public const string LogVoiceTitle = "Log voice audio"; public const string LogVoiceDescription = "True to log audio that's part of the voice group, false to skip it."; public const string ReloadTitle = "Reload audio packs"; public const string OpenCustomAudioPackTitle = "Open custom audio pack folder"; public static string WeightClamped(float weight, AudioPack pack) { return $"Pack {pack.Config.Id} has a weight {weight} that is outside the [{0.001f}, {1000f}] range and will be clamped."; } public static string EnablePackDescription(string displayName) { return "Set to true to enable " + displayName + ", false to disable it."; } public static string InvalidPackId(string path, string id) { return "Refusing to load pack " + id + " from " + path + ", its ID contains invalid characters."; } public static string DuplicatePackId(string path, string id) { return "Refusing to load pack " + id + " from " + path + ", an audio pack with that ID already exists."; } public static string DuplicateClipId(string path, string id) { return "Refusing to load clip " + id + " from " + path + ", a clip with that name was already loaded."; } public static string InvalidPackPath(string path, string id) { return "Refusing to load clip " + id + " from " + path + ", its path was outside of audio pack."; } public static string UnsupportedAudioFile(string file, string id) { return "File " + file + " from clip " + id + " is not a supported audio format."; } public static string DuplicateClipSkipped(string file, string id) { return "Audio file " + file + " was not loaded, clip " + id + " was already loaded previously."; } public static string AutoloadingClips(string path) { return "Autoloading replacement clips from " + AudioPackLoader.ReplaceRootPath(path); } public static string LoadingPack(string path) { return "Loading pack from " + AudioPackLoader.ReplaceRootPath(path); } public static string PackLoaded(AudioPack pack) { return $"Loaded pack {pack.Config.Id} with {pack.Config.Routes.Count} routes, {pack.PendingClipsToStream.Count} clips to streams and {pack.PendingClipsToLoad.Count} clips to load"; } public static string LoadingClip(string path, string name, bool useStreaming) { return (useStreaming ? "Streaming" : "Loading") + " clip " + name + " from " + AudioPackLoader.ReplaceRootPath(path); } public static string AudioCannotBeStreamed(string path, long fileSize) { return "Audio file " + path + " is above the size threshold for streaming" + $" ({(float)fileSize / 1048576f}MB >= {1f}MB)," + " but it cannot be streamed using the current audio format. Please try using one of the following supported formats: " + string.Join(", ", AudioClipLoader.SupportedStreamExtensions) + "."; } public static string AudioClipNotFound(string name) { return "Couldn't get clip " + name + " to play for audio event!"; } } public static class VanillaClipNames { private struct Metadata { public AudioGroup AudioGroup; public string Description; public Metadata(AudioGroup audioGroup, string description) { AudioGroup = audioGroup; Description = description; } } private enum AudioGroup { Unknown, Ambience, Game, GUI, Master, Music, Voice } private static readonly string[] AllClipNames; private static readonly HashSet<string> ClipNamesHashed; public const int TotalClips = 482; public const string Absorb = "_absorb"; public const string Acre_Bolt = "acre_bolt"; public const string AmbBla = "_ambBla"; public const string AmbCave01 = "_ambCave01"; public const string AmbCave02 = "_ambCave02"; public const string AmbCoast = "_ambCoast"; public const string AmbCricket01 = "_ambCricket01"; public const string AmbCuckoo = "_ambCuckoo"; public const string AmbFire01 = "_ambFire01"; public const string AmbFrst01 = "_ambFrst01"; public const string AmbFrst02 = "_ambFrst02"; public const string AmbFrst03 = "_ambFrst03"; public const string AmbGlyph01 = "_ambGlyph01"; public const string AmbGlyph02 = "_ambGlyph02"; public const string AmbGlyph03 = "_ambGlyph03"; public const string AmbGuest01 = "_ambGuest01"; public const string AmbOutside01 = "_ambOutside01"; public const string AmbOutside02 = "_ambOutside02"; public const string AmbRiver01 = "_ambRiver01"; public const string AmbUnderwater = "_ambUnderwater"; public const string AmbWat_Cave = "_ambWat_cave"; public const string AmbWater01 = "_ambWater01"; public const string AmbWater02 = "_ambWater02"; public const string AmbWaterfall01 = "_ambWaterfall01"; public const string AmbWatfall = "_ambWatfall"; public const string AmbWind01 = "_ambWind01"; public const string AmbWind02 = "_ambWind02"; public const string AmbWind02_0 = "_ambWind02_0"; public const string AmbWind03 = "_ambWind03"; public const string AmbWind04 = "_ambWind04"; public const string AmbWind05 = "_ambWind05"; public const string AmbWind06 = "_ambWind06"; public const string AmbWind07 = "_ambWind07"; public const string AmbWindChime01 = "_ambWindChime01"; public const string Amb_Jungle00 = "_amb_jungle00"; public const string Amb_Jungle01 = "_amb_jungle01"; public const string Amb_Jungle02 = "_amb_jungle02"; public const string Amb_Rain01 = "_amb_rain01"; public const string Angela_Aura = "angela_aura"; public const string AtlyssSet_Catacomb_Action5 = "_atlyssSet_catacomb_action5"; public const string AtlyssSet_Catacomb_Amb3 = "_atlyssSet_catacomb_amb3"; public const string AtlyssSet_Track01 = "_atlyssSet_track01"; public const string AttackClick = "attackClick"; public const string AttackMiss = "_attackMiss"; public const string AttributeGlyph = "_attributeGlyph"; public const string BeamStatue_BeamLoop = "_beamStatue_beamLoop"; public const string BeamStatue_ProneLoop = "_beamStatue_proneLoop"; public const string BellSwing01 = "_bellSwing01"; public const string BellSwing02 = "_bellSwing02"; public const string BellSwing03 = "_bellSwing03"; public const string BellSwing04 = "_bellSwing04"; public const string BladeTrap_Init = "_bladeTrap_init"; public const string BladeTrap_SpinLoop = "_bladeTrap_spinLoop"; public const string BladeTrap_SpinLoop2 = "_bladeTrap_spinLoop2"; public const string BlockBreak = "_blockBreak"; public const string BlockHit = "_blockHit"; public const string BobbyVox01 = "bobbyVox01"; public const string BobbyVox02 = "bobbyVox02"; public const string BobbyVox03 = "bobbyVox03"; public const string BobbyVox04 = "bobbyVox04"; public const string BobbyVox05 = "bobbyVox05"; public const string BobbyVox06 = "bobbyVox06"; public const string BobbyVox07 = "bobbyVox07"; public const string BombBiggenEX = "bombBiggenEX"; public const string BombHitChar = "bombHitChar"; public const string BombKick = "bombKick"; public const string Book_Handled_1 = "book handled 1"; public const string Bow_Fire01 = "bow_fire01"; public const string Bow_TakeOut = "bow_takeOut"; public const string Break01 = "_break01"; public const string BreakBox01 = "_breakBox01"; public const string Buff_Resolute = "buff_resolute"; public const string BuyItem = "_buyItem"; public const string ByrdleTalk01 = "_byrdleTalk01"; public const string ByrdleTalk02 = "_byrdleTalk02"; public const string ByrdleTalk03 = "_byrdleTalk03"; public const string ByrdleTalk04 = "_byrdleTalk04"; public const string Cannonbug_BeginMove = "cannonbug_beginMove"; public const string Cannonbug_CannonShot = "cannonbug_cannonShot"; public const string Cannonbug_ChargeShot = "cannonbug_chargeShot"; public const string Cannonbug_FrontalAttack = "cannonbug_frontalAttack"; public const string Cannonbug_Spin = "cannonbug_spin"; public const string Carbuncle_Death = "_carbuncle_death"; public const string Carbuncle_Hurt00 = "_carbuncle_hurt00"; public const string CastChannelShadow = "castChannelShadow"; public const string CastChannelShadow2 = "castChannelShadow2"; public const string CastEarth = "_castEarth"; public const string CastLoop_00 = "_castLoop_00"; public const string CastLoop_01 = "_castLoop_01"; public const string CastMysticSpell = "_castMysticSpell"; public const string CastWater = "_castWater"; public const string Cast_00 = "_cast_00"; public const string Cast_01 = "_cast_01"; public const string Cast_02 = "_cast_02"; public const string Cast_03 = "_cast_03"; public const string Cast_04 = "_cast_04"; public const string Cast_05 = "_cast_05"; public const string Cast_06 = "_cast_06"; public const string Cast_07 = "_cast_07"; public const string Cast_FlameBurst = "cast_flameBurst"; public const string Cast_Holy = "_cast_holy"; public const string Cast_Octane = "cast_octane"; public const string ChangTalk01 = "_changTalk01"; public const string ChangTalk02 = "_changTalk02"; public const string ChangTalk03 = "_changTalk03"; public const string ChangTalk04 = "_changTalk04"; public const string ChannelEarthSpell = "_channelEarthSpell"; public const string ChannelMysticSpell = "_channelMysticSpell"; public const string ChestOpen = "chestOpen"; public const string Chime02 = "_chime02"; public const string Chime03 = "_chime03"; public const string Chime04 = "_chime04"; public const string Clap01 = "_clap01"; public const string ClearSkill = "_clearSkill"; public const string CloseShop = "_closeShop"; public const string Coin01 = "_coin01"; public const string CoinSell = "_coinSell"; public const string Collide01 = "_collide01"; public const string ConsumableHeal = "consumableHeal"; public const string Cop_Turretcharge = "cop_turretcharge"; public const string CreepAggroNotif = "_creepAggroNotif"; public const string CreepSfx_SlimeAtk1 = "_creepSfx_slimeAtk1"; public const string CreepSfx_SlimeAtk2 = "_creepSfx_slimeAtk2"; public const string CreepSfx_SlimeAtk3 = "_creepSfx_slimeAtk3"; public const string CreepSfx_SlimeDeath = "_creepSfx_slimeDeath"; public const string CreepSfx_SlimeHit = "_creepSfx_slimeHit"; public const string CreepSfx_SlimeHurt = "_creepSfx_slimeHurt"; public const string CreepSpawn = "_creepSpawn"; public const string Crit = "_crit"; public const string CrossExplodeSfx01 = "_crossExplodeSfx01"; public const string CrossLoopSfx01 = "_crossLoopSfx01"; public const string CurrencyTally = "_currencyTally"; public const string Debuff_Bleed = "debuff_bleed"; public const string Debuff_Freeze = "debuff_freeze"; public const string Debuff_Freeze_Old1 = "debuff_freeze-old1"; public const string Debuff_Poison = "debuff_poison"; public const string DungeonFloorSwitch_Pressed = "_dungeonFloorSwitch_pressed"; public const string DungeonFloorSwitch_Unpressed = "_dungeonFloorSwitch_unpressed"; public const string DungeonLock_Open = "_dungeonLock_open"; public const string Effect_Demon01 = "_effect_demon01"; public const string Electric01 = "_electric01"; public const string EnemyPreAttack = "enemyPreAttack"; public const string Enemyalert = "enemyalert"; public const string Enok_Vox01 = "_enok_vox01"; public const string Enok_Vox02 = "_enok_vox02"; public const string Enok_Vox03 = "_enok_vox03"; public const string Enok_Vox04 = "_enok_vox04"; public const string Enok_Vox05 = "_enok_vox05"; public const string Enok_Vox06 = "_enok_vox06"; public const string Enok_Vox07 = "_enok_vox07"; public const string Enok_Vox08 = "_enok_vox08"; public const string Equip01 = "_equip01"; public const string Equip02 = "_equip02"; public const string ExpPickup_F = "expPickup_f"; public const string Expression_Surprise = "_expression_surprise"; public const string Fanfale3 = "fanfale3"; public const string Fanfale4 = "fanfale4"; public const string Fistcuffs_Swing01 = "_fistcuffs_swing01"; public const string Fistcuffs_Swing02 = "_fistcuffs_swing02"; public const string Fistcuffs_Swing03 = "_fistcuffs_swing03"; public const string Fistcuffs_Swing04 = "_fistcuffs_swing04"; public const string Fistcuffs_Swing05 = "_fistcuffs_swing05"; public const string FloatSkull_Attack01 = "_floatSkull_attack01"; public const string FloatSkull_Attack02 = "_floatSkull_attack02"; public const string FloatSkull_Death = "_floatSkull_death"; public const string FloatSkull_Hurt = "_floatSkull_hurt"; public const string FluxSpear01 = "_fluxSpear01"; public const string Focus = "focus"; public const string Focusoff = "focusoff"; public const string FootStep_Basic = "footStep_basic"; public const string FootStep_Grass = "footStep_grass"; public const string FootStep_Grass02 = "footStep_grass02"; public const string FootStep_Stone = "footStep_stone"; public const string FootStep_Water = "footStep_water"; public const string FootStep_Wood = "footStep_wood"; public const string FootstepGrass02 = "_footstepGrass02"; public const string GeistLaugh = "_geistLaugh"; public const string GeistLaugh02 = "_geistLaugh02"; public const string Geist_Attack01 = "_geist_attack01"; public const string Geist_Attack02 = "_geist_attack02"; public const string Geist_Death = "_geist_death"; public const string Geist_Hurt = "_geist_hurt"; public const string GetClassSfx = "_getClassSfx"; public const string Gib = "_gib"; public const string GlassBreak = "glassBreak"; public const string GlassBreak2 = "glassBreak2"; public const string Golem_Death01 = "_golem_death01"; public const string Golem_Hurt01 = "_golem_hurt01"; public const string Golem_Hurt02 = "_golem_hurt02"; public const string Guard_Block = "guard_block"; public const string Hampter_Defend = "hampter_defend"; public const string Hampter_Login = "hampter_login"; public const string HealConsumable = "_healConsumable"; public const string HeavyInit01 = "_heavyInit01"; public const string HeavyInit02 = "_heavyInit02"; public const string HeavyInit03 = "_heavyInit03"; public const string HeavySheath = "_heavySheath"; public const string Homerun_Hit = "_homerun_hit"; public const string ImbueSkillSfx = "_imbueSkillSfx"; public const string ImpTalk01 = "_impTalk01"; public const string ImpTalk02 = "_impTalk02"; public const string ImpTalk03 = "_impTalk03"; public const string ImpTalk04 = "_impTalk04"; public const string ImpTalk05 = "_impTalk05"; public const string ImpTalk06 = "_impTalk06"; public const string IntroNoise_00 = "_introNoise_00"; public const string IntroNoise_01 = "_introNoise_01"; public const string IntroNoise_02 = "_introNoise_02"; public const string ItemDrop_Rare = "_itemDrop_rare"; public const string ItemEntryPlace01 = "_itemEntryPlace01"; public const string ItemEntryPlace02 = "_itemEntryPlace02"; public const string ItemObject_Pickup = "itemObject_pickup"; public const string ItemObject_Spawn = "itemObject_spawn"; public const string KinggolemDeath_00 = "_kinggolemDeath_00"; public const string KuboldTalk01 = "_kuboldTalk01"; public const string KuboldTalk02 = "_kuboldTalk02"; public const string KuboldTalk03 = "_kuboldTalk03"; public const string KuboldTalk04 = "_kuboldTalk04"; public const string KuboldTalk05 = "_kuboldTalk05"; public const string Land_Grass01 = "land_grass01"; public const string Land_Stone01 = "land_stone01"; public const string Land_Water = "land_water"; public const string Land_Wood = "land_wood"; public const string LargeFootstep01 = "_largeFootstep01"; public const string LedgeGrab = "_ledgeGrab"; public const string Levelup = "levelup"; public const string LeverSfx01 = "_leverSfx01"; public const string LexiconBell = "_lexiconBell"; public const string LexiconClose = "_lexiconClose"; public const string LexiconOpen = "_lexiconOpen"; public const string LightSheath = "_lightSheath"; public const string Lockon = "lockon"; public const string Lockout = "lockout"; public const string LowHealthPulse01 = "_lowHealthPulse01"; public const string LowHealthWarning = "_lowHealthWarning"; public const string LungePower = "_lungePower"; public const string MediumSheath = "_mediumSheath"; public const string MeeleSkillCharge = "_meeleSkillCharge"; public const string Mekboar_ChargeAtk01 = "_mekboar_chargeAtk01"; public const string Mekboar_ChargeAtk02 = "_mekboar_chargeAtk02"; public const string Mekboar_ChargeAtk03 = "_mekboar_chargeAtk03"; public const string Mekboar_Death = "_mekboar_death"; public const string Mekboar_Hurt = "_mekboar_hurt"; public const string MeleeSkillLoop = "_meleeSkillLoop"; public const string Melee_Swipe = "melee_swipe"; public const string MouthEnemy_Death01 = "mouthEnemy_death01"; public const string MouthEnemy_Hurt01 = "mouthEnemy_hurt01"; public const string MouthEnemy_Hurt02 = "mouthEnemy_hurt02"; public const string MouthEnemy_Vomit01 = "mouthEnemy_vomit01"; public const string MouthEnemy_Vomit02 = "mouthEnemy_vomit02"; public const string Mover_MetalGateClose = "_mover_metalGateClose"; public const string Mover_MetalGateLoop = "_mover_metalGateLoop"; public const string Mover_MetalGateOpen = "_mover_metalGateOpen"; public const string Mu_AmbCrispr = "_mu_ambCrispr"; public const string Mu_Botany = "_mu_botany"; public const string Mu_Cahoots = "_mu_cahoots"; public const string Mu_Calp = "_mu_calp"; public const string Mu_Cane = "_mu_cane"; public const string Mu_Discover01 = "_mu_discover01"; public const string Mu_Discover02 = "_mu_discover02"; public const string Mu_Discover03 = "_mu_discover03"; public const string Mu_Discover04 = "_mu_discover04"; public const string Mu_Discover05 = "_mu_discover05"; public const string Mu_Ecka = "_mu_ecka"; public const string Mu_Flyby = "_mu_flyby"; public const string Mu_Haven = "_mu_haven"; public const string Mu_Hell01 = "_mu_hell01"; public const string Mu_Hell02 = "_mu_hell02"; public const string Mu_Laid = "_mu_laid"; public const string Mu_Lethargy = "_mu_lethargy"; public const string Mu_NouCove = "mu_nouCove"; public const string Mu_Photo = "_mu_photo"; public const string Mu_Sailex = "_mu_sailex"; public const string Mu_Select1 = "mu_select1"; public const string Mu_Selee = "_mu_selee"; public const string Mu_SnatchNight = "_mu_snatchNight"; public const string Mu_Snatchsprings = "mu_snatchsprings"; public const string Mu_Tex01 = "_mu_tex01"; public const string Mu_Wasp = "_mu_wasp"; public const string Mu_Wonton = "_mu_wonton"; public const string Mu_Wonton5 = "_mu_wonton5"; public const string Music_Whisper = "music_whisper"; public const string NovaSkill_Init01 = "_novaSkill_init01"; public const string NovaSkill_Init02 = "_novaSkill_init02"; public const string OpenShop = "_openShop"; public const string Option = "option"; public const string PartyInviteSfx = "_partyInviteSfx"; public const string Party_Init01 = "_party_init01"; public const string Party_Join = "_party_join"; public const string Pickup01 = "_pickup01"; public const string Pickup02 = "_pickup02"; public const string PlayerPort = "_playerPort"; public const string Player_Dash = "player_dash"; public const string Player_InitDeath = "_player_initDeath"; public const string Player_InitDeath2 = "_player_initDeath2"; public const string Player_Jiggle2 = "player_jiggle2"; public const string Player_Jump = "player_jump"; public const string PolearmSwing01 = "_polearmSwing01"; public const string PolearmSwing02 = "_polearmSwing02"; public const string PolearmSwing03 = "_polearmSwing03"; public const string PolearmTakeOut01 = "_polearmTakeOut01"; public const string PoonBounce = "_poonBounce"; public const string PoonBounce02 = "_poonBounce02"; public const string PoonTalk01 = "_poonTalk01"; public const string PoonTalk02 = "_poonTalk02"; public const string PoonTalk03 = "_poonTalk03"; public const string PoonTalk04 = "_poonTalk04"; public const string PoonTalk05 = "_poonTalk05"; public const string PoonTalk06 = "_poonTalk06"; public const string Port = "port"; public const string PortalGlyph = "_portalGlyph"; public const string PortalInteract = "_portalInteract"; public const string PrismSkill_Init01 = "_prismSkill_init01"; public const string PrismSkill_Loop01 = "_prismSkill_loop01"; public const string Pushblock_Loop = "_pushblock_loop"; public const string Pushblock_Stop = "_pushblock_stop"; public const string PvpFlagInit = "_pvpFlagInit"; public const string QuestAbandon = "_questAbandon"; public const string QuestAccept = "_questAccept"; public const string QuestProgressTick = "_questProgressTick"; public const string QuestTurnIn = "_questTurnIn"; public const string RageSfx01 = "_rageSfx01"; public const string Railgun_Lv3 = "railgun_lv3"; public const string ResShrineLoop = "_resShrineLoop"; public const string Rock_Impact = "rock_impact"; public const string RoosterDaySfx01 = "_roosterDaySfx01"; public const string RopeClimb = "_ropeClimb"; public const string SallyVox01 = "_sallyVox01"; public const string SallyVox02 = "_sallyVox02"; public const string SallyVox03 = "_sallyVox03"; public const string SallyVox04 = "_sallyVox04"; public const string SallyVox05 = "_sallyVox05"; public const string SallyVox06 = "_sallyVox06"; public const string SallyVox07 = "_sallyVox07"; public const string Sally_Sweep = "_sally_sweep"; public const string Satch_Explodelv2 = "satch_explodelv2"; public const string ScepterCharge = "_scepterCharge"; public const string ScepterChargeWeak = "_scepterChargeWeak"; public const string ScepterProjectileBurst = "scepterProjectileBurst"; public const string SeedPickup = "seedPickup"; public const string Seekr_Equip = "seekr_equip"; public const string SkillSet = "_skillSet"; public const string SkritVox_00 = "_skritVox_00"; public const string SkritVox_01 = "_skritVox_01"; public const string SkritVox_02 = "_skritVox_02"; public const string SkritVox_03 = "_skritVox_03"; public const string Slap = "_slap"; public const string SlimeDiva_AttackAoeSwing = "_slimeDiva_attackAoeSwing"; public const string SlimeDiva_ChargeTitGun = "_slimeDiva_chargeTitGun"; public const string SlimeDiva_Death = "_slimeDiva_death"; public const string SlimeDiva_FloatMoveLoop = "_slimeDiva_floatMoveLoop"; public const string SlimeDiva_Hurt01 = "_slimeDiva_hurt01"; public const string SlimeDiva_Laugh01 = "_slimeDiva_laugh01"; public const string SlimeDiva_Laugh02 = "_slimeDiva_laugh02"; public const string SlimeDiva_Moan01 = "_slimeDiva_moan01"; public const string SlimeDiva_SlimeOrb_Bounce = "_slimeDiva_slimeOrb_bounce"; public const string SlimeDiva_SlimeOrb_Explode = "_slimeDiva_slimeOrb_explode"; public const string SlimeDiva_TitBullet = "_slimeDiva_titBullet"; public const string SmallClap = "_smallClap"; public const string Snd_GrubdogBite = "snd_grubdogBite"; public const string Snd_GrubdogConsume = "snd_grubdogConsume"; public const string Snd_SummonAngel = "snd_summonAngel"; public
plugins/NAudio.Core.dll
Decompiled a month ago
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.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using NAudio.Dmo; using NAudio.Dsp; using NAudio.FileFormats.Wav; using NAudio.Utils; using NAudio.Wave; using NAudio.Wave.SampleProviders; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Mark Heath")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("© Mark Heath 2023")] [assembly: AssemblyFileVersion("2.2.1.0")] [assembly: AssemblyInformationalVersion("2.2.1")] [assembly: AssemblyProduct("NAudio.Core")] [assembly: AssemblyTitle("NAudio.Core")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.2.1.0")] [module: UnverifiableCode] namespace NAudio { public enum Manufacturers { Microsoft = 1, Creative = 2, Mediavision = 3, Fujitsu = 4, Artisoft = 20, TurtleBeach = 21, Ibm = 22, Vocaltec = 23, Roland = 24, DspSolutions = 25, Nec = 26, Ati = 27, Wanglabs = 28, Tandy = 29, Voyetra = 30, Antex = 31, IclPS = 32, Intel = 33, Gravis = 34, Val = 35, Interactive = 36, Yamaha = 37, Everex = 38, Echo = 39, Sierra = 40, Cat = 41, Apps = 42, DspGroup = 43, Melabs = 44, ComputerFriends = 45, Ess = 46, Audiofile = 47, Motorola = 48, Canopus = 49, Epson = 50, Truevision = 51, Aztech = 52, Videologic = 53, Scalacs = 54, Korg = 55, Apt = 56, Ics = 57, Iteratedsys = 58, Metheus = 59, Logitech = 60, Winnov = 61, Ncr = 62, Exan = 63, Ast = 64, Willowpond = 65, Sonicfoundry = 66, Vitec = 67, Moscom = 68, Siliconsoft = 69, Supermac = 73, Audiopt = 74, Speechcomp = 76, Ahead = 77, Dolby = 78, Oki = 79, Auravision = 80, Olivetti = 81, Iomagic = 82, Matsushita = 83, Controlres = 84, Xebec = 85, Newmedia = 86, Nms = 87, Lyrrus = 88, Compusic = 89, Opti = 90, Adlacc = 91, Compaq = 92, Dialogic = 93, Insoft = 94, Mptus = 95, Weitek = 96, LernoutAndHauspie = 97, Qciar = 98, Apple = 99, Digital = 100, Motu = 101, Workbit = 102, Ositech = 103, Miro = 104, Cirruslogic = 105, Isolution = 106, Horizons = 107, Concepts = 108, Vtg = 109, Radius = 110, Rockwell = 111, Xyz = 112, Opcode = 113, Voxware = 114, NorthernTelecom = 115, Apicom = 116, Grande = 117, Addx = 118, Wildcat = 119, Rhetorex = 120, Brooktree = 121, Ensoniq = 125, Fast = 126, Nvidia = 127, Oksori = 128, Diacoustics = 129, Gulbransen = 130, KayElemetrics = 131, Crystal = 132, SplashStudios = 133, Quarterdeck = 134, Tdk = 135, DigitalAudioLabs = 136, Seersys = 137, Picturetel = 138, AttMicroelectronics = 139, Osprey = 140, Mediatrix = 141, Soundesigns = 142, Aldigital = 143, SpectrumSignalProcessing = 144, Ecs = 145, Amd = 146, Coredynamics = 147, Canam = 148, Softsound = 149, Norris = 150, Ddd = 151, Euphonics = 152, Precept = 153, CrystalNet = 154, Chromatic = 155, Voiceinfo = 156, Viennasys = 157, Connectix = 158, Gadgetlabs = 159, Frontier = 160, Viona = 161, Casio = 162, Diamondmm = 163, S3 = 164, FraunhoferIis = 172 } public class MmException : Exception { public MmResult Result { get; } public string Function { get; } public MmException(MmResult result, string function) : base(ErrorMessage(result, function)) { Result = result; Function = function; } private static string ErrorMessage(MmResult result, string function) { return $"{result} calling {function}"; } public static void Try(MmResult result, string function) { if (result != 0) { throw new MmException(result, function); } } } public enum MmResult { NoError = 0, UnspecifiedError = 1, BadDeviceId = 2, NotEnabled = 3, AlreadyAllocated = 4, InvalidHandle = 5, NoDriver = 6, MemoryAllocationError = 7, NotSupported = 8, BadErrorNumber = 9, InvalidFlag = 10, InvalidParameter = 11, HandleBusy = 12, InvalidAlias = 13, BadRegistryDatabase = 14, RegistryKeyNotFound = 15, RegistryReadError = 16, RegistryWriteError = 17, RegistryDeleteError = 18, RegistryValueNotFound = 19, NoDriverCallback = 20, MoreData = 21, WaveBadFormat = 32, WaveStillPlaying = 33, WaveHeaderUnprepared = 34, WaveSync = 35, AcmNotPossible = 512, AcmBusy = 513, AcmHeaderUnprepared = 514, AcmCancelled = 515, MixerInvalidLine = 1024, MixerInvalidControl = 1025, MixerInvalidValue = 1026 } } namespace NAudio.CoreAudioApi { public enum CaptureState { Stopped, Starting, Capturing, Stopping } } namespace NAudio.Dmo { public class AudioMediaSubtypes { public static readonly Guid MEDIASUBTYPE_PCM = new Guid("00000001-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_PCMAudioObsolete = new Guid("e436eb8a-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_MPEG1Packet = new Guid("e436eb80-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_MPEG1Payload = new Guid("e436eb81-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_MPEG2_AUDIO = new Guid("e06d802b-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid MEDIASUBTYPE_DVD_LPCM_AUDIO = new Guid("e06d8032-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid MEDIASUBTYPE_DRM_Audio = new Guid("00000009-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_IEEE_FLOAT = new Guid("00000003-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_DOLBY_AC3 = new Guid("e06d802c-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid MEDIASUBTYPE_DOLBY_AC3_SPDIF = new Guid("00000092-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_RAW_SPORT = new Guid("00000240-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_SPDIF_TAG_241h = new Guid("00000241-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_I420 = new Guid("30323449-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_IYUV = new Guid("56555949-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_RGB1 = new Guid("e436eb78-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_RGB24 = new Guid("e436eb7d-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_RGB32 = new Guid("e436eb7e-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_RGB4 = new Guid("e436eb79-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_RGB555 = new Guid("e436eb7c-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_RGB565 = new Guid("e436eb7b-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_RGB8 = new Guid("e436eb7a-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_UYVY = new Guid("59565955-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_VIDEOIMAGE = new Guid("1d4a45f2-e5f6-4b44-8388-f0ae5c0e0c37"); public static readonly Guid MEDIASUBTYPE_YUY2 = new Guid("32595559-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_YV12 = new Guid("31313259-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_YVU9 = new Guid("39555659-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_YVYU = new Guid("55595659-0000-0010-8000-00AA00389B71"); public static readonly Guid WMFORMAT_MPEG2Video = new Guid("e06d80e3-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid WMFORMAT_Script = new Guid("5C8510F2-DEBE-4ca7-BBA5-F07A104F8DFF"); public static readonly Guid WMFORMAT_VideoInfo = new Guid("05589f80-c356-11ce-bf01-00aa0055595a"); public static readonly Guid WMFORMAT_WaveFormatEx = new Guid("05589f81-c356-11ce-bf01-00aa0055595a"); public static readonly Guid WMFORMAT_WebStream = new Guid("da1e6b13-8359-4050-b398-388e965bf00c"); public static readonly Guid WMMEDIASUBTYPE_ACELPnet = new Guid("00000130-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_Base = new Guid("00000000-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_DRM = new Guid("00000009-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_MP3 = new Guid("00000055-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_MP43 = new Guid("3334504D-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_MP4S = new Guid("5334504D-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_M4S2 = new Guid("3253344D-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_P422 = new Guid("32323450-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_MPEG2_VIDEO = new Guid("e06d8026-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid WMMEDIASUBTYPE_MSS1 = new Guid("3153534D-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_MSS2 = new Guid("3253534D-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_PCM = new Guid("00000001-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WebStream = new Guid("776257d4-c627-41cb-8f81-7ac7ff1c40cc"); public static readonly Guid WMMEDIASUBTYPE_WMAudio_Lossless = new Guid("00000163-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMAudioV2 = new Guid("00000161-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMAudioV7 = new Guid("00000161-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMAudioV8 = new Guid("00000161-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMAudioV9 = new Guid("00000162-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMSP1 = new Guid("0000000A-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMV1 = new Guid("31564D57-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMV2 = new Guid("32564D57-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMV3 = new Guid("33564D57-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMVA = new Guid("41564D57-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMVP = new Guid("50564D57-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WVP2 = new Guid("32505657-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIATYPE_Audio = new Guid("73647561-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIATYPE_FileTransfer = new Guid("D9E47579-930E-4427-ADFC-AD80F290E470"); public static readonly Guid WMMEDIATYPE_Image = new Guid("34A50FD8-8AA5-4386-81FE-A0EFE0488E31"); public static readonly Guid WMMEDIATYPE_Script = new Guid("73636d64-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIATYPE_Text = new Guid("9BBA1EA7-5AB2-4829-BA57-0940209BCF3E"); public static readonly Guid WMMEDIATYPE_Video = new Guid("73646976-0000-0010-8000-00AA00389B71"); public static readonly Guid WMSCRIPTTYPE_TwoStrings = new Guid("82f38a70-c29f-11d1-97ad-00a0c95ea850"); public static readonly Guid MEDIASUBTYPE_WAVE = new Guid("e436eb8b-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_AU = new Guid("e436eb8c-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_AIFF = new Guid("e436eb8d-524f-11ce-9f53-0020af0ba770"); public static readonly Guid[] AudioSubTypes = new Guid[13] { MEDIASUBTYPE_PCM, MEDIASUBTYPE_PCMAudioObsolete, MEDIASUBTYPE_MPEG1Packet, MEDIASUBTYPE_MPEG1Payload, MEDIASUBTYPE_MPEG2_AUDIO, MEDIASUBTYPE_DVD_LPCM_AUDIO, MEDIASUBTYPE_DRM_Audio, MEDIASUBTYPE_IEEE_FLOAT, MEDIASUBTYPE_DOLBY_AC3, MEDIASUBTYPE_DOLBY_AC3_SPDIF, MEDIASUBTYPE_RAW_SPORT, MEDIASUBTYPE_SPDIF_TAG_241h, WMMEDIASUBTYPE_MP3 }; public static readonly string[] AudioSubTypeNames = new string[13] { "PCM", "PCM Obsolete", "MPEG1Packet", "MPEG1Payload", "MPEG2_AUDIO", "DVD_LPCM_AUDIO", "DRM_Audio", "IEEE_FLOAT", "DOLBY_AC3", "DOLBY_AC3_SPDIF", "RAW_SPORT", "SPDIF_TAG_241h", "MP3" }; public static string GetAudioSubtypeName(Guid subType) { for (int i = 0; i < AudioSubTypes.Length; i++) { if (subType == AudioSubTypes[i]) { return AudioSubTypeNames[i]; } } return subType.ToString(); } } } namespace NAudio.Utils { public static class BufferHelpers { public static byte[] Ensure(byte[] buffer, int bytesRequired) { if (buffer == null || buffer.Length < bytesRequired) { buffer = new byte[bytesRequired]; } return buffer; } public static float[] Ensure(float[] buffer, int samplesRequired) { if (buffer == null || buffer.Length < samplesRequired) { buffer = new float[samplesRequired]; } return buffer; } } public static class ByteArrayExtensions { public static bool IsEntirelyNull(byte[] buffer) { for (int i = 0; i < buffer.Length; i++) { if (buffer[i] != 0) { return false; } } return true; } public static string DescribeAsHex(byte[] buffer, string separator, int bytesPerLine) { StringBuilder stringBuilder = new StringBuilder(); int num = 0; foreach (byte b in buffer) { stringBuilder.AppendFormat("{0:X2}{1}", b, separator); if (++num % bytesPerLine == 0) { stringBuilder.Append("\r\n"); } } stringBuilder.Append("\r\n"); return stringBuilder.ToString(); } public static string DecodeAsString(byte[] buffer, int offset, int length, Encoding encoding) { for (int i = 0; i < length; i++) { if (buffer[offset + i] == 0) { length = i; } } return encoding.GetString(buffer, offset, length); } public static byte[] Concat(params byte[][] byteArrays) { int num = 0; byte[][] array = byteArrays; foreach (byte[] array2 in array) { num += array2.Length; } if (num <= 0) { return new byte[0]; } byte[] array3 = new byte[num]; int num2 = 0; array = byteArrays; foreach (byte[] array4 in array) { Array.Copy(array4, 0, array3, num2, array4.Length); num2 += array4.Length; } return array3; } } public class ByteEncoding : Encoding { public static readonly ByteEncoding Instance = new ByteEncoding(); private ByteEncoding() { } public override int GetByteCount(char[] chars, int index, int count) { return count; } public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { for (int i = 0; i < charCount; i++) { bytes[byteIndex + i] = (byte)chars[charIndex + i]; } return charCount; } public override int GetCharCount(byte[] bytes, int index, int count) { for (int i = 0; i < count; i++) { if (bytes[index + i] == 0) { return i; } } return count; } public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { for (int i = 0; i < byteCount; i++) { byte b = bytes[byteIndex + i]; if (b == 0) { return i; } chars[charIndex + i] = (char)b; } return byteCount; } public override int GetMaxCharCount(int byteCount) { return byteCount; } public override int GetMaxByteCount(int charCount) { return charCount; } } public class ChunkIdentifier { public static int ChunkIdentifierToInt32(string s) { if (s.Length != 4) { throw new ArgumentException("Must be a four character string"); } byte[] bytes = Encoding.UTF8.GetBytes(s); if (bytes.Length != 4) { throw new ArgumentException("Must encode to exactly four bytes"); } return BitConverter.ToInt32(bytes, 0); } } public class CircularBuffer { private readonly byte[] buffer; private readonly object lockObject; private int writePosition; private int readPosition; private int byteCount; public int MaxLength => buffer.Length; public int Count { get { lock (lockObject) { return byteCount; } } } public CircularBuffer(int size) { buffer = new byte[size]; lockObject = new object(); } public int Write(byte[] data, int offset, int count) { lock (lockObject) { int num = 0; if (count > buffer.Length - byteCount) { count = buffer.Length - byteCount; } int num2 = Math.Min(buffer.Length - writePosition, count); Array.Copy(data, offset, buffer, writePosition, num2); writePosition += num2; writePosition %= buffer.Length; num += num2; if (num < count) { Array.Copy(data, offset + num, buffer, writePosition, count - num); writePosition += count - num; num = count; } byteCount += num; return num; } } public int Read(byte[] data, int offset, int count) { lock (lockObject) { if (count > byteCount) { count = byteCount; } int num = 0; int num2 = Math.Min(buffer.Length - readPosition, count); Array.Copy(buffer, readPosition, data, offset, num2); num += num2; readPosition += num2; readPosition %= buffer.Length; if (num < count) { Array.Copy(buffer, readPosition, data, offset + num, count - num); readPosition += count - num; num = count; } byteCount -= num; return num; } } public void Reset() { lock (lockObject) { ResetInner(); } } private void ResetInner() { byteCount = 0; readPosition = 0; writePosition = 0; } public void Advance(int count) { lock (lockObject) { if (count >= byteCount) { ResetInner(); return; } byteCount -= count; readPosition += count; readPosition %= MaxLength; } } } public class Decibels { private const double LOG_2_DB = 8.685889638065037; private const double DB_2_LOG = 0.11512925464970228; public static double LinearToDecibels(double lin) { return Math.Log(lin) * 8.685889638065037; } public static double DecibelsToLinear(double dB) { return Math.Exp(dB * 0.11512925464970228); } } [AttributeUsage(AttributeTargets.Field)] public class FieldDescriptionAttribute : Attribute { public string Description { get; } public FieldDescriptionAttribute(string description) { Description = description; } public override string ToString() { return Description; } } public static class FieldDescriptionHelper { public static string Describe(Type t, Guid guid) { FieldInfo[] fields = t.GetFields(BindingFlags.Static | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (!fieldInfo.IsPublic || !fieldInfo.IsStatic || !(fieldInfo.FieldType == typeof(Guid)) || !((Guid)fieldInfo.GetValue(null) == guid)) { continue; } object[] customAttributes = fieldInfo.GetCustomAttributes(inherit: false); for (int j = 0; j < customAttributes.Length; j++) { if (customAttributes[j] is FieldDescriptionAttribute fieldDescriptionAttribute) { return fieldDescriptionAttribute.Description; } } return fieldInfo.Name; } return guid.ToString(); } } public static class HResult { public const int S_OK = 0; public const int S_FALSE = 1; public const int E_INVALIDARG = -2147483645; private const int FACILITY_AAF = 18; private const int FACILITY_ACS = 20; private const int FACILITY_BACKGROUNDCOPY = 32; private const int FACILITY_CERT = 11; private const int FACILITY_COMPLUS = 17; private const int FACILITY_CONFIGURATION = 33; private const int FACILITY_CONTROL = 10; private const int FACILITY_DISPATCH = 2; private const int FACILITY_DPLAY = 21; private const int FACILITY_HTTP = 25; private const int FACILITY_INTERNET = 12; private const int FACILITY_ITF = 4; private const int FACILITY_MEDIASERVER = 13; private const int FACILITY_MSMQ = 14; private const int FACILITY_NULL = 0; private const int FACILITY_RPC = 1; private const int FACILITY_SCARD = 16; private const int FACILITY_SECURITY = 9; private const int FACILITY_SETUPAPI = 15; private const int FACILITY_SSPI = 9; private const int FACILITY_STORAGE = 3; private const int FACILITY_SXS = 23; private const int FACILITY_UMI = 22; private const int FACILITY_URT = 19; private const int FACILITY_WIN32 = 7; private const int FACILITY_WINDOWS = 8; private const int FACILITY_WINDOWS_CE = 24; public static int MAKE_HRESULT(int sev, int fac, int code) { return (sev << 31) | (fac << 16) | code; } public static int GetHResult(this COMException exception) { return exception.ErrorCode; } } public static class IEEE { private static double UnsignedToFloat(ulong u) { return (double)(long)(u - int.MaxValue - 1) + 2147483648.0; } private static double ldexp(double x, int exp) { return x * Math.Pow(2.0, exp); } private static double frexp(double x, out int exp) { exp = (int)Math.Floor(Math.Log(x) / Math.Log(2.0)) + 1; return 1.0 - (Math.Pow(2.0, exp) - x) / Math.Pow(2.0, exp); } private static ulong FloatToUnsigned(double f) { return (ulong)((long)(f - 2147483648.0) + int.MaxValue + 1); } public static byte[] ConvertToIeeeExtended(double num) { int num2; if (num < 0.0) { num2 = 32768; num *= -1.0; } else { num2 = 0; } ulong num4; ulong num5; int num3; if (num == 0.0) { num3 = 0; num4 = 0uL; num5 = 0uL; } else { double num6 = frexp(num, out num3); if (num3 > 16384 || !(num6 < 1.0)) { num3 = num2 | 0x7FFF; num4 = 0uL; num5 = 0uL; } else { num3 += 16382; if (num3 < 0) { num6 = ldexp(num6, num3); num3 = 0; } num3 |= num2; num6 = ldexp(num6, 32); double num7 = Math.Floor(num6); num4 = FloatToUnsigned(num7); num6 = ldexp(num6 - num7, 32); num7 = Math.Floor(num6); num5 = FloatToUnsigned(num7); } } return new byte[10] { (byte)(num3 >> 8), (byte)num3, (byte)(num4 >> 24), (byte)(num4 >> 16), (byte)(num4 >> 8), (byte)num4, (byte)(num5 >> 24), (byte)(num5 >> 16), (byte)(num5 >> 8), (byte)num5 }; } public static double ConvertFromIeeeExtended(byte[] bytes) { if (bytes.Length != 10) { throw new Exception("Incorrect length for IEEE extended."); } int num = ((bytes[0] & 0x7F) << 8) | bytes[1]; uint num2 = (uint)((bytes[2] << 24) | (bytes[3] << 16) | (bytes[4] << 8) | bytes[5]); uint num3 = (uint)((bytes[6] << 24) | (bytes[7] << 16) | (bytes[8] << 8) | bytes[9]); double num4; if (num == 0 && num2 == 0 && num3 == 0) { num4 = 0.0; } else if (num == 32767) { num4 = double.NaN; } else { num -= 16383; num4 = ldexp(UnsignedToFloat(num2), num -= 31); num4 += ldexp(UnsignedToFloat(num3), num -= 32); } if ((bytes[0] & 0x80) == 128) { return 0.0 - num4; } return num4; } } public class IgnoreDisposeStream : Stream { public Stream SourceStream { get; private set; } public bool IgnoreDispose { get; set; } public override bool CanRead => SourceStream.CanRead; public override bool CanSeek => SourceStream.CanSeek; public override bool CanWrite => SourceStream.CanWrite; public override long Length => SourceStream.Length; public override long Position { get { return SourceStream.Position; } set { SourceStream.Position = value; } } public IgnoreDisposeStream(Stream sourceStream) { SourceStream = sourceStream; IgnoreDispose = true; } public override void Flush() { SourceStream.Flush(); } public override int Read(byte[] buffer, int offset, int count) { return SourceStream.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { return SourceStream.Seek(offset, origin); } public override void SetLength(long value) { SourceStream.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { SourceStream.Write(buffer, offset, count); } protected override void Dispose(bool disposing) { if (!IgnoreDispose) { SourceStream.Dispose(); SourceStream = null; } } } public static class NativeMethods { [DllImport("kernel32.dll")] public static extern IntPtr LoadLibrary(string dllToLoad); [DllImport("kernel32.dll")] public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); [DllImport("kernel32.dll")] public static extern bool FreeLibrary(IntPtr hModule); } public static class WavePositionExtensions { public static TimeSpan GetPositionTimeSpan(this IWavePosition @this) { return TimeSpan.FromMilliseconds((double)(@this.GetPosition() / (@this.OutputWaveFormat.Channels * @this.OutputWaveFormat.BitsPerSample / 8)) * 1000.0 / (double)@this.OutputWaveFormat.SampleRate); } } } namespace NAudio.FileFormats.Wav { public class WaveFileChunkReader { private WaveFormat waveFormat; private long dataChunkPosition; private long dataChunkLength; private List<RiffChunk> riffChunks; private readonly bool strictMode; private bool isRf64; private readonly bool storeAllChunks; private long riffSize; public WaveFormat WaveFormat => waveFormat; public long DataChunkPosition => dataChunkPosition; public long DataChunkLength => dataChunkLength; public List<RiffChunk> RiffChunks => riffChunks; public WaveFileChunkReader() { storeAllChunks = true; strictMode = false; } public void ReadWaveHeader(Stream stream) { dataChunkPosition = -1L; waveFormat = null; riffChunks = new List<RiffChunk>(); dataChunkLength = 0L; BinaryReader binaryReader = new BinaryReader(stream); ReadRiffHeader(binaryReader); riffSize = binaryReader.ReadUInt32(); if (binaryReader.ReadInt32() != ChunkIdentifier.ChunkIdentifierToInt32("WAVE")) { throw new FormatException("Not a WAVE file - no WAVE header"); } if (isRf64) { ReadDs64Chunk(binaryReader); } int num = ChunkIdentifier.ChunkIdentifierToInt32("data"); int num2 = ChunkIdentifier.ChunkIdentifierToInt32("fmt "); long num3 = Math.Min(riffSize + 8, stream.Length); while (stream.Position <= num3 - 8) { int num4 = binaryReader.ReadInt32(); uint num5 = binaryReader.ReadUInt32(); if (num4 == num) { dataChunkPosition = stream.Position; if (!isRf64) { dataChunkLength = num5; } stream.Position += num5; } else if (num4 == num2) { if (num5 > int.MaxValue) { throw new InvalidDataException($"Format chunk length must be between 0 and {int.MaxValue}."); } waveFormat = WaveFormat.FromFormatChunk(binaryReader, (int)num5); } else { if (num5 > stream.Length - stream.Position) { if (!strictMode) { } break; } if (storeAllChunks) { if (num5 > int.MaxValue) { throw new InvalidDataException($"RiffChunk chunk length must be between 0 and {int.MaxValue}."); } riffChunks.Add(GetRiffChunk(stream, num4, (int)num5)); } stream.Position += num5; } if (num5 % 2 != 0 && binaryReader.PeekChar() == 0) { stream.Position++; } } if (waveFormat == null) { throw new FormatException("Invalid WAV file - No fmt chunk found"); } if (dataChunkPosition == -1) { throw new FormatException("Invalid WAV file - No data chunk found"); } } private void ReadDs64Chunk(BinaryReader reader) { int num = ChunkIdentifier.ChunkIdentifierToInt32("ds64"); if (reader.ReadInt32() != num) { throw new FormatException("Invalid RF64 WAV file - No ds64 chunk found"); } int num2 = reader.ReadInt32(); riffSize = reader.ReadInt64(); dataChunkLength = reader.ReadInt64(); reader.ReadInt64(); reader.ReadBytes(num2 - 24); } private static RiffChunk GetRiffChunk(Stream stream, int chunkIdentifier, int chunkLength) { return new RiffChunk(chunkIdentifier, chunkLength, stream.Position); } private void ReadRiffHeader(BinaryReader br) { int num = br.ReadInt32(); if (num == ChunkIdentifier.ChunkIdentifierToInt32("RF64")) { isRf64 = true; } else if (num != ChunkIdentifier.ChunkIdentifierToInt32("RIFF")) { throw new FormatException("Not a WAVE file - no RIFF header"); } } } } namespace NAudio.SoundFont { public class Generator { public GeneratorEnum GeneratorType { get; set; } public ushort UInt16Amount { get; set; } public short Int16Amount { get { return (short)UInt16Amount; } set { UInt16Amount = (ushort)value; } } public byte LowByteAmount { get { return (byte)(UInt16Amount & 0xFFu); } set { UInt16Amount &= 65280; UInt16Amount += value; } } public byte HighByteAmount { get { return (byte)((UInt16Amount & 0xFF00) >> 8); } set { UInt16Amount &= 255; UInt16Amount += (ushort)(value << 8); } } public Instrument Instrument { get; set; } public SampleHeader SampleHeader { get; set; } public override string ToString() { if (GeneratorType == GeneratorEnum.Instrument) { return "Generator Instrument " + Instrument.Name; } if (GeneratorType == GeneratorEnum.SampleID) { return $"Generator SampleID {SampleHeader}"; } return $"Generator {GeneratorType} {UInt16Amount}"; } } internal class GeneratorBuilder : StructureBuilder<Generator> { public override int Length => 4; public Generator[] Generators => data.ToArray(); public override Generator Read(BinaryReader br) { Generator generator = new Generator(); generator.GeneratorType = (GeneratorEnum)br.ReadUInt16(); generator.UInt16Amount = br.ReadUInt16(); data.Add(generator); return generator; } public override void Write(BinaryWriter bw, Generator o) { } public void Load(Instrument[] instruments) { Generator[] generators = Generators; foreach (Generator generator in generators) { if (generator.GeneratorType == GeneratorEnum.Instrument) { generator.Instrument = instruments[generator.UInt16Amount]; } } } public void Load(SampleHeader[] sampleHeaders) { Generator[] generators = Generators; foreach (Generator generator in generators) { if (generator.GeneratorType == GeneratorEnum.SampleID) { generator.SampleHeader = sampleHeaders[generator.UInt16Amount]; } } } } public enum GeneratorEnum { StartAddressOffset, EndAddressOffset, StartLoopAddressOffset, EndLoopAddressOffset, StartAddressCoarseOffset, ModulationLFOToPitch, VibratoLFOToPitch, ModulationEnvelopeToPitch, InitialFilterCutoffFrequency, InitialFilterQ, ModulationLFOToFilterCutoffFrequency, ModulationEnvelopeToFilterCutoffFrequency, EndAddressCoarseOffset, ModulationLFOToVolume, Unused1, ChorusEffectsSend, ReverbEffectsSend, Pan, Unused2, Unused3, Unused4, DelayModulationLFO, FrequencyModulationLFO, DelayVibratoLFO, FrequencyVibratoLFO, DelayModulationEnvelope, AttackModulationEnvelope, HoldModulationEnvelope, DecayModulationEnvelope, SustainModulationEnvelope, ReleaseModulationEnvelope, KeyNumberToModulationEnvelopeHold, KeyNumberToModulationEnvelopeDecay, DelayVolumeEnvelope, AttackVolumeEnvelope, HoldVolumeEnvelope, DecayVolumeEnvelope, SustainVolumeEnvelope, ReleaseVolumeEnvelope, KeyNumberToVolumeEnvelopeHold, KeyNumberToVolumeEnvelopeDecay, Instrument, Reserved1, KeyRange, VelocityRange, StartLoopAddressCoarseOffset, KeyNumber, Velocity, InitialAttenuation, Reserved2, EndLoopAddressCoarseOffset, CoarseTune, FineTune, SampleID, SampleModes, Reserved3, ScaleTuning, ExclusiveClass, OverridingRootKey, Unused5, UnusedEnd } public class InfoChunk { public SFVersion SoundFontVersion { get; } public string WaveTableSoundEngine { get; set; } public string BankName { get; set; } public string DataROM { get; set; } public string CreationDate { get; set; } public string Author { get; set; } public string TargetProduct { get; set; } public string Copyright { get; set; } public string Comments { get; set; } public string Tools { get; set; } public SFVersion ROMVersion { get; set; } internal InfoChunk(RiffChunk chunk) { bool flag = false; bool flag2 = false; if (chunk.ReadChunkID() != "INFO") { throw new InvalidDataException("Not an INFO chunk"); } RiffChunk nextSubChunk; while ((nextSubChunk = chunk.GetNextSubChunk()) != null) { switch (nextSubChunk.ChunkID) { case "ifil": flag = true; SoundFontVersion = nextSubChunk.GetDataAsStructure(new SFVersionBuilder()); break; case "isng": WaveTableSoundEngine = nextSubChunk.GetDataAsString(); break; case "INAM": flag2 = true; BankName = nextSubChunk.GetDataAsString(); break; case "irom": DataROM = nextSubChunk.GetDataAsString(); break; case "iver": ROMVersion = nextSubChunk.GetDataAsStructure(new SFVersionBuilder()); break; case "ICRD": CreationDate = nextSubChunk.GetDataAsString(); break; case "IENG": Author = nextSubChunk.GetDataAsString(); break; case "IPRD": TargetProduct = nextSubChunk.GetDataAsString(); break; case "ICOP": Copyright = nextSubChunk.GetDataAsString(); break; case "ICMT": Comments = nextSubChunk.GetDataAsString(); break; case "ISFT": Tools = nextSubChunk.GetDataAsString(); break; default: throw new InvalidDataException("Unknown chunk type " + nextSubChunk.ChunkID); } } if (!flag) { throw new InvalidDataException("Missing SoundFont version information"); } if (!flag2) { throw new InvalidDataException("Missing SoundFont name information"); } } public override string ToString() { return string.Format("Bank Name: {0}\r\nAuthor: {1}\r\nCopyright: {2}\r\nCreation Date: {3}\r\nTools: {4}\r\nComments: {5}\r\nSound Engine: {6}\r\nSoundFont Version: {7}\r\nTarget Product: {8}\r\nData ROM: {9}\r\nROM Version: {10}", BankName, Author, Copyright, CreationDate, Tools, "TODO-fix comments", WaveTableSoundEngine, SoundFontVersion, TargetProduct, DataROM, ROMVersion); } } public class Instrument { internal ushort startInstrumentZoneIndex; internal ushort endInstrumentZoneIndex; public string Name { get; set; } public Zone[] Zones { get; set; } public override string ToString() { return Name; } } internal class InstrumentBuilder : StructureBuilder<Instrument> { private Instrument lastInstrument; public override int Length => 22; public Instrument[] Instruments => data.ToArray(); public override Instrument Read(BinaryReader br) { Instrument instrument = new Instrument(); string text = Encoding.UTF8.GetString(br.ReadBytes(20), 0, 20); if (text.IndexOf('\0') >= 0) { text = text.Substring(0, text.IndexOf('\0')); } instrument.Name = text; instrument.startInstrumentZoneIndex = br.ReadUInt16(); if (lastInstrument != null) { lastInstrument.endInstrumentZoneIndex = (ushort)(instrument.startInstrumentZoneIndex - 1); } data.Add(instrument); lastInstrument = instrument; return instrument; } public override void Write(BinaryWriter bw, Instrument instrument) { } public void LoadZones(Zone[] zones) { for (int i = 0; i < data.Count - 1; i++) { Instrument instrument = data[i]; instrument.Zones = new Zone[instrument.endInstrumentZoneIndex - instrument.startInstrumentZoneIndex + 1]; Array.Copy(zones, instrument.startInstrumentZoneIndex, instrument.Zones, 0, instrument.Zones.Length); } data.RemoveAt(data.Count - 1); } } public enum TransformEnum { Linear } public class Modulator { public ModulatorType SourceModulationData { get; set; } public GeneratorEnum DestinationGenerator { get; set; } public short Amount { get; set; } public ModulatorType SourceModulationAmount { get; set; } public TransformEnum SourceTransform { get; set; } public override string ToString() { return $"Modulator {SourceModulationData} {DestinationGenerator} {Amount} {SourceModulationAmount} {SourceTransform}"; } } internal class ModulatorBuilder : StructureBuilder<Modulator> { public override int Length => 10; public Modulator[] Modulators => data.ToArray(); public override Modulator Read(BinaryReader br) { Modulator modulator = new Modulator(); modulator.SourceModulationData = new ModulatorType(br.ReadUInt16()); modulator.DestinationGenerator = (GeneratorEnum)br.ReadUInt16(); modulator.Amount = br.ReadInt16(); modulator.SourceModulationAmount = new ModulatorType(br.ReadUInt16()); modulator.SourceTransform = (TransformEnum)br.ReadUInt16(); data.Add(modulator); return modulator; } public override void Write(BinaryWriter bw, Modulator o) { } } public enum ControllerSourceEnum { NoController = 0, NoteOnVelocity = 2, NoteOnKeyNumber = 3, PolyPressure = 10, ChannelPressure = 13, PitchWheel = 14, PitchWheelSensitivity = 16 } public enum SourceTypeEnum { Linear, Concave, Convex, Switch } public class ModulatorType { private bool polarity; private bool direction; private bool midiContinuousController; private ControllerSourceEnum controllerSource; private SourceTypeEnum sourceType; private ushort midiContinuousControllerNumber; internal ModulatorType(ushort raw) { polarity = (raw & 0x200) == 512; direction = (raw & 0x100) == 256; midiContinuousController = (raw & 0x80) == 128; sourceType = (SourceTypeEnum)((raw & 0xFC00) >> 10); controllerSource = (ControllerSourceEnum)(raw & 0x7F); midiContinuousControllerNumber = (ushort)(raw & 0x7Fu); } public override string ToString() { if (midiContinuousController) { return $"{sourceType} CC{midiContinuousControllerNumber}"; } return $"{sourceType} {controllerSource}"; } } public class Preset { internal ushort startPresetZoneIndex; internal ushort endPresetZoneIndex; internal uint library; internal uint genre; internal uint morphology; public string Name { get; set; } public ushort PatchNumber { get; set; } public ushort Bank { get; set; } public Zone[] Zones { get; set; } public override string ToString() { return $"{Bank}-{PatchNumber} {Name}"; } } internal class PresetBuilder : StructureBuilder<Preset> { private Preset lastPreset; public override int Length => 38; public Preset[] Presets => data.ToArray(); public override Preset Read(BinaryReader br) { Preset preset = new Preset(); string text = Encoding.UTF8.GetString(br.ReadBytes(20), 0, 20); if (text.IndexOf('\0') >= 0) { text = text.Substring(0, text.IndexOf('\0')); } preset.Name = text; preset.PatchNumber = br.ReadUInt16(); preset.Bank = br.ReadUInt16(); preset.startPresetZoneIndex = br.ReadUInt16(); preset.library = br.ReadUInt32(); preset.genre = br.ReadUInt32(); preset.morphology = br.ReadUInt32(); if (lastPreset != null) { lastPreset.endPresetZoneIndex = (ushort)(preset.startPresetZoneIndex - 1); } data.Add(preset); lastPreset = preset; return preset; } public override void Write(BinaryWriter bw, Preset preset) { } public void LoadZones(Zone[] presetZones) { for (int i = 0; i < data.Count - 1; i++) { Preset preset = data[i]; preset.Zones = new Zone[preset.endPresetZoneIndex - preset.startPresetZoneIndex + 1]; Array.Copy(presetZones, preset.startPresetZoneIndex, preset.Zones, 0, preset.Zones.Length); } data.RemoveAt(data.Count - 1); } } public class PresetsChunk { private PresetBuilder presetHeaders = new PresetBuilder(); private ZoneBuilder presetZones = new ZoneBuilder(); private ModulatorBuilder presetZoneModulators = new ModulatorBuilder(); private GeneratorBuilder presetZoneGenerators = new GeneratorBuilder(); private InstrumentBuilder instruments = new InstrumentBuilder(); private ZoneBuilder instrumentZones = new ZoneBuilder(); private ModulatorBuilder instrumentZoneModulators = new ModulatorBuilder(); private GeneratorBuilder instrumentZoneGenerators = new GeneratorBuilder(); private SampleHeaderBuilder sampleHeaders = new SampleHeaderBuilder(); public Preset[] Presets => presetHeaders.Presets; public Instrument[] Instruments => instruments.Instruments; public SampleHeader[] SampleHeaders => sampleHeaders.SampleHeaders; internal PresetsChunk(RiffChunk chunk) { string text = chunk.ReadChunkID(); if (text != "pdta") { throw new InvalidDataException($"Not a presets data chunk ({text})"); } RiffChunk nextSubChunk; while ((nextSubChunk = chunk.GetNextSubChunk()) != null) { switch (nextSubChunk.ChunkID) { case "phdr": case "PHDR": nextSubChunk.GetDataAsStructureArray(presetHeaders); break; case "pbag": case "PBAG": nextSubChunk.GetDataAsStructureArray(presetZones); break; case "pmod": case "PMOD": nextSubChunk.GetDataAsStructureArray(presetZoneModulators); break; case "pgen": case "PGEN": nextSubChunk.GetDataAsStructureArray(presetZoneGenerators); break; case "inst": case "INST": nextSubChunk.GetDataAsStructureArray(instruments); break; case "ibag": case "IBAG": nextSubChunk.GetDataAsStructureArray(instrumentZones); break; case "imod": case "IMOD": nextSubChunk.GetDataAsStructureArray(instrumentZoneModulators); break; case "igen": case "IGEN": nextSubChunk.GetDataAsStructureArray(instrumentZoneGenerators); break; case "shdr": case "SHDR": nextSubChunk.GetDataAsStructureArray(sampleHeaders); break; default: throw new InvalidDataException($"Unknown chunk type {nextSubChunk.ChunkID}"); } } instrumentZoneGenerators.Load(sampleHeaders.SampleHeaders); instrumentZones.Load(instrumentZoneModulators.Modulators, instrumentZoneGenerators.Generators); instruments.LoadZones(instrumentZones.Zones); presetZoneGenerators.Load(instruments.Instruments); presetZones.Load(presetZoneModulators.Modulators, presetZoneGenerators.Generators); presetHeaders.LoadZones(presetZones.Zones); sampleHeaders.RemoveEOS(); } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("Preset Headers:\r\n"); Preset[] presets = presetHeaders.Presets; foreach (Preset arg in presets) { stringBuilder.AppendFormat("{0}\r\n", arg); } stringBuilder.Append("Instruments:\r\n"); Instrument[] array = instruments.Instruments; foreach (Instrument arg2 in array) { stringBuilder.AppendFormat("{0}\r\n", arg2); } return stringBuilder.ToString(); } } internal class RiffChunk { private string chunkID; private BinaryReader riffFile; public string ChunkID { get { return chunkID; } set { if (value == null) { throw new ArgumentNullException("ChunkID may not be null"); } if (value.Length != 4) { throw new ArgumentException("ChunkID must be four characters"); } chunkID = value; } } public uint ChunkSize { get; private set; } public long DataOffset { get; private set; } public static RiffChunk GetTopLevelChunk(BinaryReader file) { RiffChunk riffChunk = new RiffChunk(file); riffChunk.ReadChunk(); return riffChunk; } private RiffChunk(BinaryReader file) { riffFile = file; chunkID = "????"; ChunkSize = 0u; DataOffset = 0L; } public string ReadChunkID() { byte[] array = riffFile.ReadBytes(4); if (array.Length != 4) { throw new InvalidDataException("Couldn't read Chunk ID"); } return ByteEncoding.Instance.GetString(array, 0, array.Length); } private void ReadChunk() { chunkID = ReadChunkID(); ChunkSize = riffFile.ReadUInt32(); DataOffset = riffFile.BaseStream.Position; } public RiffChunk GetNextSubChunk() { if (riffFile.BaseStream.Position + 8 < DataOffset + ChunkSize) { RiffChunk riffChunk = new RiffChunk(riffFile); riffChunk.ReadChunk(); return riffChunk; } return null; } public byte[] GetData() { riffFile.BaseStream.Position = DataOffset; byte[] array = riffFile.ReadBytes((int)ChunkSize); if (array.Length != ChunkSize) { throw new InvalidDataException($"Couldn't read chunk's data Chunk: {this}, read {array.Length} bytes"); } return array; } public string GetDataAsString() { byte[] data = GetData(); if (data == null) { return null; } return ByteEncoding.Instance.GetString(data, 0, data.Length); } public T GetDataAsStructure<T>(StructureBuilder<T> s) { riffFile.BaseStream.Position = DataOffset; if (s.Length != ChunkSize) { throw new InvalidDataException($"Chunk size is: {ChunkSize} so can't read structure of: {s.Length}"); } return s.Read(riffFile); } public T[] GetDataAsStructureArray<T>(StructureBuilder<T> s) { riffFile.BaseStream.Position = DataOffset; if (ChunkSize % s.Length != 0L) { throw new InvalidDataException($"Chunk size is: {ChunkSize} not a multiple of structure size: {s.Length}"); } int num = (int)(ChunkSize / s.Length); T[] array = new T[num]; for (int i = 0; i < num; i++) { array[i] = s.Read(riffFile); } return array; } public override string ToString() { return $"RiffChunk ID: {ChunkID} Size: {ChunkSize} Data Offset: {DataOffset}"; } } internal class SampleDataChunk { public byte[] SampleData { get; private set; } public SampleDataChunk(RiffChunk chunk) { string text = chunk.ReadChunkID(); if (text != "sdta") { throw new InvalidDataException("Not a sample data chunk (" + text + ")"); } SampleData = chunk.GetData(); } } public class SampleHeader { public string SampleName; public uint Start; public uint End; public uint StartLoop; public uint EndLoop; public uint SampleRate; public byte OriginalPitch; public sbyte PitchCorrection; public ushort SampleLink; public SFSampleLink SFSampleLink; public override string ToString() { return SampleName; } } internal class SampleHeaderBuilder : StructureBuilder<SampleHeader> { public override int Length => 46; public SampleHeader[] SampleHeaders => data.ToArray(); public override SampleHeader Read(BinaryReader br) { SampleHeader sampleHeader = new SampleHeader(); byte[] array = br.ReadBytes(20); sampleHeader.SampleName = ByteEncoding.Instance.GetString(array, 0, array.Length); sampleHeader.Start = br.ReadUInt32(); sampleHeader.End = br.ReadUInt32(); sampleHeader.StartLoop = br.ReadUInt32(); sampleHeader.EndLoop = br.ReadUInt32(); sampleHeader.SampleRate = br.ReadUInt32(); sampleHeader.OriginalPitch = br.ReadByte(); sampleHeader.PitchCorrection = br.ReadSByte(); sampleHeader.SampleLink = br.ReadUInt16(); sampleHeader.SFSampleLink = (SFSampleLink)br.ReadUInt16(); data.Add(sampleHeader); return sampleHeader; } public override void Write(BinaryWriter bw, SampleHeader sampleHeader) { } internal void RemoveEOS() { data.RemoveAt(data.Count - 1); } } public enum SampleMode { NoLoop, LoopContinuously, ReservedNoLoop, LoopAndContinue } public enum SFSampleLink : ushort { MonoSample = 1, RightSample = 2, LeftSample = 4, LinkedSample = 8, RomMonoSample = 32769, RomRightSample = 32770, RomLeftSample = 32772, RomLinkedSample = 32776 } public class SFVersion { public short Major { get; set; } public short Minor { get; set; } } internal class SFVersionBuilder : StructureBuilder<SFVersion> { public override int Length => 4; public override SFVersion Read(BinaryReader br) { SFVersion sFVersion = new SFVersion(); sFVersion.Major = br.ReadInt16(); sFVersion.Minor = br.ReadInt16(); data.Add(sFVersion); return sFVersion; } public override void Write(BinaryWriter bw, SFVersion v) { bw.Write(v.Major); bw.Write(v.Minor); } } public class SoundFont { private InfoChunk info; private PresetsChunk presetsChunk; private SampleDataChunk sampleData; public InfoChunk FileInfo => info; public Preset[] Presets => presetsChunk.Presets; public Instrument[] Instruments => presetsChunk.Instruments; public SampleHeader[] SampleHeaders => presetsChunk.SampleHeaders; public byte[] SampleData => sampleData.SampleData; public SoundFont(string fileName) : this(new FileStream(fileName, FileMode.Open, FileAccess.Read)) { } public SoundFont(Stream sfFile) { using (sfFile) { RiffChunk topLevelChunk = RiffChunk.GetTopLevelChunk(new BinaryReader(sfFile)); if (topLevelChunk.ChunkID == "RIFF") { string text = topLevelChunk.ReadChunkID(); if (text != "sfbk") { throw new InvalidDataException($"Not a SoundFont ({text})"); } RiffChunk nextSubChunk = topLevelChunk.GetNextSubChunk(); if (nextSubChunk.ChunkID == "LIST") { info = new InfoChunk(nextSubChunk); RiffChunk nextSubChunk2 = topLevelChunk.GetNextSubChunk(); sampleData = new SampleDataChunk(nextSubChunk2); nextSubChunk2 = topLevelChunk.GetNextSubChunk(); presetsChunk = new PresetsChunk(nextSubChunk2); return; } throw new InvalidDataException($"Not info list found ({nextSubChunk.ChunkID})"); } throw new InvalidDataException("Not a RIFF file"); } } public override string ToString() { return $"Info Chunk:\r\n{info}\r\nPresets Chunk:\r\n{presetsChunk}"; } } internal abstract class StructureBuilder<T> { protected List<T> data; public abstract int Length { get; } public T[] Data => data.ToArray(); public StructureBuilder() { Reset(); } public abstract T Read(BinaryReader br); public abstract void Write(BinaryWriter bw, T o); public void Reset() { data = new List<T>(); } } public class Zone { internal ushort generatorIndex; internal ushort modulatorIndex; internal ushort generatorCount; internal ushort modulatorCount; public Modulator[] Modulators { get; set; } public Generator[] Generators { get; set; } public override string ToString() { return $"Zone {generatorCount} Gens:{generatorIndex} {modulatorCount} Mods:{modulatorIndex}"; } } internal class ZoneBuilder : StructureBuilder<Zone> { private Zone lastZone; public Zone[] Zones => data.ToArray(); public override int Length => 4; public override Zone Read(BinaryReader br) { Zone zone = new Zone(); zone.generatorIndex = br.ReadUInt16(); zone.modulatorIndex = br.ReadUInt16(); if (lastZone != null) { lastZone.generatorCount = (ushort)(zone.generatorIndex - lastZone.generatorIndex); lastZone.modulatorCount = (ushort)(zone.modulatorIndex - lastZone.modulatorIndex); } data.Add(zone); lastZone = zone; return zone; } public override void Write(BinaryWriter bw, Zone zone) { } public void Load(Modulator[] modulators, Generator[] generators) { for (int i = 0; i < data.Count - 1; i++) { Zone zone = data[i]; zone.Generators = new Generator[zone.generatorCount]; Array.Copy(generators, zone.generatorIndex, zone.Generators, 0, zone.generatorCount); zone.Modulators = new Modulator[zone.modulatorCount]; Array.Copy(modulators, zone.modulatorIndex, zone.Modulators, 0, zone.modulatorCount); } data.RemoveAt(data.Count - 1); } } } namespace NAudio.Wave { public enum ChannelMode { Stereo, JointStereo, DualChannel, Mono } public class Id3v2Tag { private long tagStartPosition; private long tagEndPosition; private byte[] rawData; public byte[] RawData => rawData; public static Id3v2Tag ReadTag(Stream input) { try { return new Id3v2Tag(input); } catch (FormatException) { return null; } } public static Id3v2Tag Create(IEnumerable<KeyValuePair<string, string>> tags) { return ReadTag(CreateId3v2TagStream(tags)); } private static byte[] FrameSizeToBytes(int n) { byte[] bytes = BitConverter.GetBytes(n); Array.Reverse((Array)bytes); return bytes; } private static byte[] CreateId3v2Frame(string key, string value) { if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } if (string.IsNullOrEmpty(value)) { throw new ArgumentNullException("value"); } if (key.Length != 4) { throw new ArgumentOutOfRangeException("key", "key " + key + " must be 4 characters long"); } byte[] array = new byte[2] { 255, 254 }; byte[] array2 = new byte[3]; byte[] array3 = new byte[2]; byte[] array4 = ((!(key == "COMM")) ? ByteArrayExtensions.Concat(new byte[1] { 1 }, array, Encoding.Unicode.GetBytes(value)) : ByteArrayExtensions.Concat(new byte[1] { 1 }, array2, array3, array, Encoding.Unicode.GetBytes(value))); return ByteArrayExtensions.Concat(Encoding.UTF8.GetBytes(key), FrameSizeToBytes(array4.Length), new byte[2], array4); } private static byte[] GetId3TagHeaderSize(int size) { byte[] array = new byte[4]; for (int num = array.Length - 1; num >= 0; num--) { array[num] = (byte)(size % 128); size /= 128; } return array; } private static byte[] CreateId3v2TagHeader(IEnumerable<byte[]> frames) { int num = 0; foreach (byte[] frame in frames) { num += frame.Length; } return ByteArrayExtensions.Concat(Encoding.UTF8.GetBytes("ID3"), new byte[2] { 3, 0 }, new byte[1], GetId3TagHeaderSize(num)); } private static Stream CreateId3v2TagStream(IEnumerable<KeyValuePair<string, string>> tags) { List<byte[]> list = new List<byte[]>(); foreach (KeyValuePair<string, string> tag in tags) { list.Add(CreateId3v2Frame(tag.Key, tag.Value)); } byte[] array = CreateId3v2TagHeader(list); MemoryStream memoryStream = new MemoryStream(); memoryStream.Write(array, 0, array.Length); foreach (byte[] item in list) { memoryStream.Write(item, 0, item.Length); } memoryStream.Position = 0L; return memoryStream; } private Id3v2Tag(Stream input) { tagStartPosition = input.Position; BinaryReader binaryReader = new BinaryReader(input); byte[] array = binaryReader.ReadBytes(10); if (array.Length >= 3 && array[0] == 73 && array[1] == 68 && array[2] == 51) { if ((array[5] & 0x40) == 64) { byte[] array2 = binaryReader.ReadBytes(4); _ = array2[0] * 2097152 + array2[1] * 16384 + array2[2] * 128; _ = array2[3]; } int num = array[6] * 2097152; num += array[7] * 16384; num += array[8] * 128; num += array[9]; binaryReader.ReadBytes(num); if ((array[5] & 0x10) == 16) { binaryReader.ReadBytes(10); } tagEndPosition = input.Position; input.Position = tagStartPosition; rawData = binaryReader.ReadBytes((int)(tagEndPosition - tagStartPosition)); return; } input.Position = tagStartPosition; throw new FormatException("Not an ID3v2 tag"); } } public interface IMp3FrameDecompressor : IDisposable { WaveFormat OutputFormat { get; } int DecompressFrame(Mp3Frame frame, byte[] dest, int destOffset); void Reset(); } public class Mp3Frame { private static readonly int[,,] bitRates = new int[2, 3, 15] { { { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } }, { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 }, { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 } } }; private static readonly int[,] samplesPerFrame = new int[2, 3] { { 384, 1152, 1152 }, { 384, 1152, 576 } }; private static readonly int[] sampleRatesVersion1 = new int[3] { 44100, 48000, 32000 }; private static readonly int[] sampleRatesVersion2 = new int[3] { 22050, 24000, 16000 }; private static readonly int[] sampleRatesVersion25 = new int[3] { 11025, 12000, 8000 }; private const int MaxFrameLength = 16384; public int SampleRate { get; private set; } public int FrameLength { get; private set; } public int BitRate { get; private set; } public byte[] RawData { get; private set; } public MpegVersion MpegVersion { get; private set; } public MpegLayer MpegLayer { get; private set; } public ChannelMode ChannelMode { get; private set; } public int SampleCount { get; private set; } public int ChannelExtension { get; private set; } public int BitRateIndex { get; private set; } public bool Copyright { get; private set; } public bool CrcPresent { get; private set; } public long FileOffset { get; private set; } public static Mp3Frame LoadFromStream(Stream input) { return LoadFromStream(input, readData: true); } public static Mp3Frame LoadFromStream(Stream input, bool readData) { Mp3Frame mp3Frame = new Mp3Frame(); mp3Frame.FileOffset = input.Position; byte[] array = new byte[4]; if (input.Read(array, 0, array.Length) < array.Length) { return null; } while (!IsValidHeader(array, mp3Frame)) { array[0] = array[1]; array[1] = array[2]; array[2] = array[3]; if (input.Read(array, 3, 1) < 1) { return null; } mp3Frame.FileOffset++; } int num = mp3Frame.FrameLength - 4; if (readData) { mp3Frame.RawData = new byte[mp3Frame.FrameLength]; Array.Copy(array, mp3Frame.RawData, 4); if (input.Read(mp3Frame.RawData, 4, num) < num) { throw new EndOfStreamException("Unexpected end of stream before frame complete"); } } else { input.Position += num; } return mp3Frame; } private Mp3Frame() { } private static bool IsValidHeader(byte[] headerBytes, Mp3Frame frame) { if (headerBytes[0] == byte.MaxValue && (headerBytes[1] & 0xE0) == 224) { frame.MpegVersion = (MpegVersion)((headerBytes[1] & 0x18) >> 3); if (frame.MpegVersion == MpegVersion.Reserved) { return false; } frame.MpegLayer = (MpegLayer)((headerBytes[1] & 6) >> 1); if (frame.MpegLayer == MpegLayer.Reserved) { return false; } int num = ((frame.MpegLayer != MpegLayer.Layer1) ? ((frame.MpegLayer == MpegLayer.Layer2) ? 1 : 2) : 0); frame.CrcPresent = (headerBytes[1] & 1) == 0; frame.BitRateIndex = (headerBytes[2] & 0xF0) >> 4; if (frame.BitRateIndex == 15) { return false; } int num2 = ((frame.MpegVersion != MpegVersion.Version1) ? 1 : 0); frame.BitRate = bitRates[num2, num, frame.BitRateIndex] * 1000; if (frame.BitRate == 0) { return false; } int num3 = (headerBytes[2] & 0xC) >> 2; if (num3 == 3) { return false; } if (frame.MpegVersion == MpegVersion.Version1) { frame.SampleRate = sampleRatesVersion1[num3]; } else if (frame.MpegVersion == MpegVersion.Version2) { frame.SampleRate = sampleRatesVersion2[num3]; } else { frame.SampleRate = sampleRatesVersion25[num3]; } bool flag = (headerBytes[2] & 2) == 2; _ = headerBytes[2]; frame.ChannelMode = (ChannelMode)((headerBytes[3] & 0xC0) >> 6); frame.ChannelExtension = (headerBytes[3] & 0x30) >> 4; if (frame.ChannelExtension != 0 && frame.ChannelMode != ChannelMode.JointStereo) { return false; } frame.Copyright = (headerBytes[3] & 8) == 8; _ = headerBytes[3]; _ = headerBytes[3]; int num4 = (flag ? 1 : 0); frame.SampleCount = samplesPerFrame[num2, num]; int num5 = frame.SampleCount / 8; if (frame.MpegLayer == MpegLayer.Layer1) { frame.FrameLength = (num5 * frame.BitRate / frame.SampleRate + num4) * 4; } else { frame.FrameLength = num5 * frame.BitRate / frame.SampleRate + num4; } if (frame.FrameLength > 16384) { return false; } return true; } return false; } } public enum MpegLayer { Reserved, Layer3, Layer2, Layer1 } public enum MpegVersion { Version25, Reserved, Version2, Version1 } public class XingHeader { [Flags] private enum XingHeaderOptions { Frames = 1, Bytes = 2, Toc = 4, VbrScale = 8 } private static int[] sr_table = new int[4] { 44100, 48000, 32000, 99999 }; private int vbrScale = -1; private int startOffset; private int endOffset; private int tocOffset = -1; private int framesOffset = -1; private int bytesOffset = -1; private Mp3Frame frame; public int Frames { get { if (framesOffset == -1) { return -1; } return ReadBigEndian(frame.RawData, framesOffset); } set { if (framesOffset == -1) { throw new InvalidOperationException("Frames flag is not set"); } WriteBigEndian(frame.RawData, framesOffset, value); } } public int Bytes { get { if (bytesOffset == -1) { return -1; } return ReadBigEndian(frame.RawData, bytesOffset); } set { if (framesOffset == -1) { throw new InvalidOperationException("Bytes flag is not set"); } WriteBigEndian(frame.RawData, bytesOffset, value); } } public int VbrScale => vbrScale; public Mp3Frame Mp3Frame => frame; private static int ReadBigEndian(byte[] buffer, int offset) { return (((((buffer[offset] << 8) | buffer[offset + 1]) << 8) | buffer[offset + 2]) << 8) | buffer[offset + 3]; } private void WriteBigEndian(byte[] buffer, int offset, int value) { byte[] bytes = BitConverter.GetBytes(value); for (int i = 0; i < 4; i++) { buffer[offset + 3 - i] = bytes[i]; } } public static XingHeader LoadXingHeader(Mp3Frame frame) { XingHeader xingHeader = new XingHeader(); xingHeader.frame = frame; int num = 0; if (frame.MpegVersion == MpegVersion.Version1) { num = ((frame.ChannelMode == ChannelMode.Mono) ? 21 : 36); } else { if (frame.MpegVersion != MpegVersion.Version2) { return null; } num = ((frame.ChannelMode == ChannelMode.Mono) ? 13 : 21); } if (frame.RawData[num] == 88 && frame.RawData[num + 1] == 105 && frame.RawData[num + 2] == 110 && frame.RawData[num + 3] == 103) { xingHeader.startOffset = num; num += 4; } else { if (frame.RawData[num] != 73 || frame.RawData[num + 1] != 110 || frame.RawData[num + 2] != 102 || frame.RawData[num + 3] != 111) { return null; } xingHeader.startOffset = num; num += 4; } int num2 = ReadBigEndian(frame.RawData, num); num += 4; if (((uint)num2 & (true ? 1u : 0u)) != 0) { xingHeader.framesOffset = num; num += 4; } if (((uint)num2 & 2u) != 0) { xingHeader.bytesOffset = num; num += 4; } if (((uint)num2 & 4u) != 0) { xingHeader.tocOffset = num; num += 100; } if (((uint)num2 & 8u) != 0) { xingHeader.vbrScale = ReadBigEndian(frame.RawData, num); num += 4; } xingHeader.endOffset = num; return xingHeader; } private XingHeader() { } } public static class WaveExtensionMethods { public static ISampleProvider ToSampleProvider(this IWaveProvider waveProvider) { return SampleProviderConverters.ConvertWaveProviderIntoSampleProvider(waveProvider); } public static void Init(this IWavePlayer wavePlayer, ISampleProvider sampleProvider, bool convertTo16Bit = false) { IWaveProvider waveProvider2; if (!convertTo16Bit) { IWaveProvider waveProvider = new SampleToWaveProvider(sampleProvider); waveProvider2 = waveProvider; } else { IWaveProvider waveProvider = new SampleToWaveProvider16(sampleProvider); waveProvider2 = waveProvider; } IWaveProvider waveProvider3 = waveProvider2; wavePlayer.Init(waveProvider3); } public static WaveFormat AsStandardWaveFormat(this WaveFormat waveFormat) { if (!(waveFormat is WaveFormatExtensible waveFormatExtensible)) { return waveFormat; } return waveFormatExtensible.ToStandardWaveFormat(); } public static IWaveProvider ToWaveProvider(this ISampleProvider sampleProvider) { return new SampleToWaveProvider(sampleProvider); } public static IWaveProvider ToWaveProvider16(this ISampleProvider sampleProvider) { return new SampleToWaveProvider16(sampleProvider); } public static ISampleProvider FollowedBy(this ISampleProvider sampleProvider, ISampleProvider next) { return new ConcatenatingSampleProvider(new ISampleProvider[2] { sampleProvider, next }); } public static ISampleProvider FollowedBy(this ISampleProvider sampleProvider, TimeSpan silenceDuration, ISampleProvider next) { OffsetSampleProvider offsetSampleProvider = new OffsetSampleProvider(sampleProvider) { LeadOut = silenceDuration }; return new ConcatenatingSampleProvider(new ISampleProvider[2] { offsetSampleProvider, next }); } public static ISampleProvider Skip(this ISampleProvider sampleProvider, TimeSpan skipDuration) { return new OffsetSampleProvider(sampleProvider) { SkipOver = skipDuration }; } public static ISampleProvider Take(this ISampleProvider sampleProvider, TimeSpan takeDuration) { return new OffsetSampleProvider(sampleProvider) { Take = takeDuration }; } public static ISampleProvider ToMono(this ISampleProvider sourceProvider, float leftVol = 0.5f, float rightVol = 0.5f) { if (sourceProvider.WaveFormat.Channels == 1) { return sourceProvider; } return new StereoToMonoSampleProvider(sourceProvider) { LeftVolume = leftVol, RightVolume = rightVol }; } public static ISampleProvider ToStereo(this ISampleProvider sourceProvider, float leftVol = 1f, float rightVol = 1f) { if (sourceProvider.WaveFormat.Channels == 2) { return sourceProvider; } return new MonoToStereoSampleProvider(sourceProvider) { LeftVolume = leftVol, RightVolume = rightVol }; } } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class AdpcmWaveFormat : WaveFormat { private short samplesPerBlock; private short numCoeff; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] private short[] coefficients; public int SamplesPerBlock => samplesPerBlock; public int NumCoefficients => numCoeff; public short[] Coefficients => coefficients; private AdpcmWaveFormat() : this(8000, 1) { } public AdpcmWaveFormat(int sampleRate, int channels) : base(sampleRate, 0, channels) { waveFormatTag = WaveFormatEncoding.Adpcm; extraSize = 32; switch (base.sampleRate) { case 8000: case 11025: blockAlign = 256; break; case 22050: blockAlign = 512; break; default: blockAlign = 1024; break; } bitsPerSample = 4; samplesPerBlock = (short)((blockAlign - 7 * channels) * 8 / (bitsPerSample * channels) + 2); averageBytesPerSecond = base.SampleRate * blockAlign / samplesPerBlock; numCoeff = 7; coefficients = new short[14] { 256, 0, 512, -256, 0, 0, 192, 64, 240, 0, 460, -208, 392, -232 }; } public override void Serialize(BinaryWriter writer) { base.Serialize(writer); writer.Write(samplesPerBlock); writer.Write(numCoeff); short[] array = coefficients; foreach (short value in array) { writer.Write(value); } } public override string ToString() { return $"Microsoft ADPCM {base.SampleRate} Hz {channels} channels {bitsPerSample} bits per sample {samplesPerBlock} samples per block"; } } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class Gsm610WaveFormat : WaveFormat { private readonly short samplesPerBlock; public short SamplesPerBlock => samplesPerBlock; public Gsm610WaveFormat() { waveFormatTag = WaveFormatEncoding.Gsm610; channels = 1; averageBytesPerSecond = 1625; bitsPerSample = 0; blockAlign = 65; sampleRate = 8000; extraSize = 2; samplesPerBlock = 320; } public override void Serialize(BinaryWriter writer) { base.Serialize(writer); writer.Write(samplesPerBlock); } } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class ImaAdpcmWaveFormat : WaveFormat { private short samplesPerBlock; private ImaAdpcmWaveFormat() { } public ImaAdpcmWaveFormat(int sampleRate, int channels, int bitsPerSample) { waveFormatTag = WaveFormatEncoding.DviAdpcm; base.sampleRate = sampleRate; base.channels = (short)channels; base.bitsPerSample = (short)bitsPerSample; extraSize = 2; blockAlign = 0; averageBytesPerSecond = 0; samplesPerBlock = 0; } } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class Mp3WaveFormat : WaveFormat { public Mp3WaveFormatId id; public Mp3WaveFormatFlags flags; public ushort blockSize; public ushort framesPerBlock; public ushort codecDelay; private const short Mp3WaveFormatExtraBytes = 12; public Mp3WaveFormat(int sampleRate, int channels, int blockSize, int bitRate) { waveFormatTag = WaveFormatEncoding.MpegLayer3; base.channels = (short)channels; averageBytesPerSecond = bitRate / 8; bitsPerSample = 0; blockAlign = 1; base.sampleRate = sampleRate; extraSize = 12; id = Mp3WaveFormatId.Mpeg; flags = Mp3WaveFormatFlags.PaddingIso; this.blockSize = (ushort)blockSize; framesPerBlock = 1; codecDelay = 0; } } [Flags] public enum Mp3WaveFormatFlags { PaddingIso = 0, PaddingOn = 1, PaddingOff = 2 } public enum Mp3WaveFormatId : ushort { Unknown, Mpeg, ConstantFrameSize } [StructLayout(LayoutKind.Sequential, Pack = 2)] internal class OggWaveFormat : WaveFormat { public uint dwVorbisACMVersion; public uint dwLibVorbisVersion; } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class TrueSpeechWaveFormat : WaveFormat { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] private short[] unknown; public TrueSpeechWaveFormat() { waveFormatTag = WaveFormatEncoding.DspGroupTrueSpeech; channels = 1; averageBytesPerSecond = 1067; bitsPerSample = 1; blockAlign = 32; sampleRate = 8000; extraSize = 32; unknown = new short[16]; unknown[0] = 1; unknown[1] = 240; } public override void Serialize(BinaryWriter writer) { base.Serialize(writer); short[] array = unknown; foreach (short value in array) { writer.Write(value); } } } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class WaveFormat { protected WaveFormatEncoding waveFormatTag; protected short channels; protected int sampleRate; protected int averageBytesPerSecond; protected short blockAlign; protected short bitsPerSample; protected short extraSize; public WaveFormatEncoding Encoding => waveFormatTag; public int Channels => channels; public int SampleRate => sampleRate; public int AverageBytesPerSecond => averageBytesPerSecond; public virtual int BlockAlign => blockAlign; public int BitsPerSample => bitsPerSample; public int ExtraSize => extraSize; public WaveFormat() : this(44100, 16, 2) { } public WaveFormat(int sampleRate, int channels) : this(sampleRate, 16, channels) { } public int ConvertLatencyToByteSize(int milliseconds) { int num = (int)((double)AverageBytesPerSecond / 1000.0 * (double)milliseconds); if (num % BlockAlign != 0) { num = num + BlockAlign - num % BlockAlign; } return num; } public static WaveFormat CreateCustomFormat(WaveFormatEncoding tag, int sampleRate, int channels, int averageBytesPerSecond, int blockAlign, int bitsPerSample) { return new WaveFormat { waveFormatTag = tag, channels = (short)channels, sampleRate = sampleRate, averageBytesPerSecond = averageBytesPerSecond, blockAlign = (short)blockAlign, bitsPerSample = (short)bitsPerSample, extraSize = 0 }; } public static WaveFormat CreateALawFormat(int sampleRate, int channels) { return CreateCustomFormat(WaveFormatEncoding.ALaw, sampleRate, channels, sampleRate * channels, channels, 8); } public static WaveFormat CreateMuLawFormat(int sampleRate, int channels) { return CreateCustomFormat(WaveFormatEncoding.MuLaw, sampleRate, channels, sampleRate * channels, channels, 8); } public WaveFormat(int rate, int bits, int channels) { if (channels < 1) { throw new ArgumentOutOfRangeException("channels", "Channels must be 1 or greater"); } waveFormatTag = WaveFormatEncoding.Pcm; this.channels = (short)channels; sampleRate = rate; bitsPerSample = (short)bits; extraSize = 0; blockAlign = (short)(channels * (bits / 8)); averageBytesPerSecond = sampleRate * blockAlign; } public static WaveFormat CreateIeeeFloatWaveFormat(int sampleRate, int channels) { WaveFormat waveFormat = new WaveFormat(); waveFormat.waveFormatTag = WaveFormatEncoding.IeeeFloat; waveFormat.channels = (short)channels; waveFormat.bitsPerSample = 32; waveFormat.sampleRate = sampleRate; waveFormat.blockAlign = (short)(4 * channels); waveFormat.averageBytesPerSecond = sampleRate * waveFormat.blockAlign; waveFormat.extraSize = 0; return waveFormat; } public static WaveFormat MarshalFromPtr(IntPtr pointer) { WaveFormat waveFormat = Marshal.PtrToStructure<WaveFormat>(pointer); switch (waveFormat.Encoding) { case WaveFormatEncoding.Pcm: waveFormat.extraSize = 0; break; case WaveFormatEncoding.Extensible: waveFormat = Marshal.PtrToStructure<WaveFormatExtensible>(pointer); break; case WaveFormatEncoding.Adpcm: waveFormat = Marshal.PtrToStructure<AdpcmWaveFormat>(pointer); break; case WaveFormatEncoding.Gsm610: waveFormat = Marshal.PtrToStructure<Gsm610WaveFormat>(pointer); break; default: if (waveFormat.ExtraSize > 0) { waveFormat = Marshal.PtrToStructure<WaveFormatExtraData>(pointer); } break; } return waveFormat; } public static IntPtr MarshalToPtr(WaveFormat format) { IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(format)); Marshal.StructureToPtr(format, intPtr, fDeleteOld: false); return intPtr; } public static WaveFormat FromFormatChunk(BinaryReader br, int formatChunkLength) { WaveFormatExtraData waveFormatExtraData = new WaveFormatExtraData(); waveFormatExtraData.ReadWaveFormat(br, formatChunkLength); waveFormatExtraData.ReadExtraData(br); return waveFormatExtraData; } private void ReadWaveFormat(BinaryReader br, int formatChunkLength) { if (formatChunkLength < 16) { throw new InvalidDataException("Invalid WaveFormat Structure"); } waveFormatTag = (WaveFormatEncoding)br.ReadUInt16(); channels = br.ReadInt16(); sampleRate = br.ReadInt32(); averageBytesPerSecond = br.ReadInt32(); blockAlign = br.ReadInt16(); bitsPerSample = br.ReadInt16(); if (formatChunkLength > 16) { extraSize = br.ReadInt16(); if (extraSize != formatChunkLength - 18) { extraSize = (short)(formatChunkLength - 18); } } } public WaveFormat(BinaryReader br) { int formatChunkLength = br.ReadInt32(); ReadWaveFormat(br, formatChunkLength); } public override string ToString() { switch (waveFormatTag) { case WaveFormatEncoding.Pcm: case WaveFormatEncoding.Extensible: return $"{bitsPerSample} bit PCM: {sampleRate}Hz {channels} channels"; case WaveFormatEncoding.IeeeFloat: return $"{bitsPerSample} bit IEEFloat: {sampleRate}Hz {channels} channels"; default: return waveFormatTag.ToString(); } } public override bool Equals(object obj) { if (obj is WaveFormat waveFormat) { if (waveFormatTag == waveFormat.waveFormatTag && channels == waveFormat.channels && sampleRate == waveFormat.sampleRate && averageBytesPerSecond == waveFormat.averageBytesPerSecond && blockAlign == waveFormat.blockAlign) { return bitsPerSample == waveFormat.bitsPerSample; } return false; } return false; } public override int GetHashCode() { return (int)waveFormatTag ^ (int)channels ^ sampleRate ^ averageBytesPerSecond ^ blockAlign ^ bitsPerSample; } public virtual void Serialize(BinaryWriter writer) { writer.Write(18 + extraSize); writer.Write((short)Encoding); writer.Write((short)Channels); writer.Write(SampleRate); writer.Write(AverageBytesPerSecond); writer.Write((short)BlockAlign); writer.Write((short)BitsPerSample); writer.Write(extraSize); } } public sealed class WaveFormatCustomMarshaler : ICustomMarshaler { private static WaveFormatCustomMarshaler marshaler; public static ICustomMarshaler GetInstance(string cookie) { if (marshaler == null) { marshaler = new WaveFormatCustomMarshaler(); } return marshaler; } public void CleanUpManagedData(object ManagedObj) { } public void CleanUpNativeData(IntPtr pNativeData) { Marshal.FreeHGlobal(pNativeData); } public int GetNativeDataSize() { throw new NotImplementedException(); } public IntPtr MarshalManagedToNative(object ManagedObj) { return WaveFormat.MarshalToPtr((WaveFormat)ManagedObj); } public object MarshalNativeToManaged(IntPtr pNativeData) { return WaveFormat.MarshalFromPtr(pNativeData); } } public enum WaveFormatEncoding : ushort { Unknown = 0, Pcm = 1, Adpcm = 2, IeeeFloat = 3, Vselp = 4, IbmCvsd = 5, ALaw = 6, MuLaw = 7, Dts = 8, Drm = 9, WmaVoice9 = 10, OkiAdpcm = 16, DviAdpcm = 17, ImaAdpcm = 17, MediaspaceAdpcm = 18, SierraAdpcm = 19, G723Adpcm = 20, DigiStd = 21, DigiFix = 22, DialogicOkiAdpcm = 23, MediaVisionAdpcm = 24, CUCodec = 25, YamahaAdpcm = 32, SonarC = 33, DspGroupTrueSpeech = 34, EchoSpeechCorporation1 = 35, AudioFileAf36 = 36, Aptx = 37, AudioFileAf10 = 38, Prosody1612 = 39, Lrc = 40, DolbyAc2 = 48, Gsm610 = 49, MsnAudio = 50, AntexAdpcme = 51, ControlResVqlpc = 52, DigiReal = 53, DigiAdpcm = 54, ControlResCr10 = 55, WAVE_FORMAT_NMS_VBXADPCM = 56, WAVE_FORMAT_CS_IMAADPCM = 57, WAVE_FORMAT_ECHOSC3 = 58, WAVE_FORMAT_ROCKWELL_ADPCM = 59, WAVE_FORMAT_ROCKWELL_DIGITALK = 60, WAVE_FORMAT_XEBEC = 61, WAVE_FORMAT_G721_ADPCM = 64, WAVE_FORMAT_G728_CELP = 65, WAVE_FORMAT_MSG723 = 66, Mpeg = 80, WAVE_FORMAT_RT24 = 82, WAVE_FORMAT_PAC = 83, MpegLayer3 = 85, WAVE_FORMAT_LUCENT_G723 = 89, WAVE_FORMAT_CIRRUS = 96, WAVE_FORMAT_ESPCM = 97, WAVE_FORMAT_VOXWARE = 98, WAVE_FORMAT_CANOPUS_ATRAC = 99, WAVE_FORMAT_G726_ADPCM = 100, WAVE_FORMAT_G722_ADPCM = 101, WAVE_FORMAT_DSAT_DISPLAY = 103, WAVE_FORMAT_VOXWARE_BYTE_ALIGNED = 105, WAVE_FORMAT_VOXWARE_AC8 = 112, WAVE_FORMAT_VOXWARE_AC10 = 113, WAVE_FORMAT_VOXWARE_AC16 = 114, WAVE_FORMAT_VOXWARE_AC20 = 115, WAVE_FORMAT_VOXWARE_RT24 = 116, WAVE_FORMAT_VOXWARE_RT29 = 117, WAVE_FORMAT_VOXWARE_RT29HW = 118, WAVE_FORMAT_VOXWARE_VR12 = 119, WAVE_FORMAT_VOXWARE_VR18 = 120, WAVE_FORMAT_VOXWARE_TQ40 = 121, WAVE_FORMAT_SOFTSOUND = 128, WAVE_FORMAT_VOXWARE_TQ60 = 129, WAVE_FORMAT_MSRT24 = 130, WAVE_FORMAT_G729A = 131, WAVE_FORMAT_MVI_MVI2 = 132, WAVE_FORMAT_DF_G726 = 133, WAVE_FORMAT_DF_GSM610 = 134, WAVE_FORMAT_ISIAUDIO = 136, WAVE_FORMAT_ONLIVE = 137, WAVE_FORMAT_SBC24 = 145, WAVE_FORMAT_DOLBY_AC3_SPDIF = 146, WAVE_FORMAT_MEDIASONIC_G723 = 147, WAVE_FORMAT_PROSODY_8KBPS = 148, WAVE_FORMAT_ZYXEL_ADPCM = 151, WAVE_FORMAT_PHILIPS_LPCBB = 152, WAVE_FORMAT_PACKED = 153, WAVE_FORMAT_MALDEN_PHONYTALK = 160, Gsm = 161, G729 = 162, G723 = 163, Acelp = 164, RawAac = 255, WAVE_FORMAT_RHETOREX_ADPCM = 256, WAVE_FORMAT_IRAT = 257, WAVE_FORMAT_VIVO_G723 = 273, WAVE_FORMAT_VIVO_SIREN = 274, WAVE_FORMAT_DIGITAL_G723 = 291, WAVE_FORMAT_SANYO_LD_ADPCM = 293, WAVE_FORMAT_SIPROLAB_ACEPLNET = 304, WAVE_FORMAT_SIPROLAB_ACELP4800 = 305, WAVE_FORMAT_SIPROLAB_ACELP8V3 = 306, WAVE_FORMAT_SIPROLAB_G729 = 307, WAVE_FORMAT_SIPROLAB_G729A = 308, WAVE_FORMAT_SIPROLAB_KELVIN = 309, WAVE_FORMAT_G726ADPCM = 320, WAVE_FORMAT_QUALCOMM_PUREVOICE = 336, WAVE_FORMAT_QUALCOMM_HALFRATE = 337, WAVE_FORMAT_TUBGSM = 341, WAVE_FORMAT_MSAUDIO1 = 352, WindowsMediaAudio = 353, WindowsMediaAudioProfessional = 354, WindowsMediaAudioLosseless = 355, WindowsMediaAudioSpdif = 356, WAVE_FORMAT_UNISYS_NAP_ADPCM = 368, WAVE_FORMAT_UNISYS_NAP_ULAW = 369, WAVE_FORMAT_UNISYS_NAP_ALAW = 370, WAVE_FORMAT_UNISYS_NAP_16K = 371, WAVE_FORMAT_CREATIVE_ADPCM = 512, WAVE_FORMAT_CREATIVE_FASTSPEECH8 = 514, WAVE_FORMAT_CREATIVE_FASTSPEECH10 = 515, WAVE_FORMAT_UHER_ADPCM = 528, WAVE_FORMAT_QUARTERDECK = 544, WAVE_FORMAT_ILINK_VC = 560, WAVE_FORMAT_RAW_SPORT = 576, WAVE_FORMAT_ESST_AC3 = 577, WAVE_FORMAT_IPI_HSX = 592, WAVE_FORMAT_IPI_RPELP = 593, WAVE_FORMAT_CS2 = 608, WAVE_FORMAT_SONY_SCX = 624, WAVE_FORMAT_FM_TOWNS_SND = 768, WAVE_FORMAT_BTV_DIGITAL = 1024, WAVE_FORMAT_QDESIGN_MUSIC = 1104, WAVE_FORMAT_VME_VMPCM = 1664, WAVE_FORMAT_TPC = 1665, WAVE_FORMAT_OLIGSM = 4096, WAVE_FORMAT_OLIADPCM = 4097, WAVE_FORMAT_OLICELP = 4098, WAVE_FORMAT_OLISBC = 4099, WAVE_FORMAT_OLIOPR = 4100, WAVE_FORMAT_LH_CODEC = 4352, WAVE_FORMAT_NORRIS = 5120, WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS = 5376, MPEG_ADTS_AAC = 5632, MPEG_RAW_AAC = 5633, MPEG_LOAS = 5634, NOKIA_MPEG_ADTS_AAC = 5640, NOKIA_MPEG_RAW_AAC = 5641, VODAFONE_MPEG_ADTS_AAC = 5642, VODAFONE_MPEG_RAW_AAC = 5643, MPEG_HEAAC = 5648, WAVE_FORMAT_DVM = 8192, Vorbis1 = 26447, Vorbis2 = 26448, Vorbis3 = 26449, Vorbis1P = 26479, Vorbis2P = 26480, Vorbis3P = 26481, Extensible = 65534, WAVE_FORMAT_DEVELOPMENT = ushort.MaxValue } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class WaveFormatExtensible : WaveFormat { private short wValidBitsPerSample; private int dwChannelMask; private Guid subFormat; public Guid SubFormat => subFormat; private WaveFormatExtensible() { } public WaveFormatExtensible(int rate, int bits, int channels) : base(rate, bits, channels) { waveFormatTag = WaveFormatEncoding.Extensible; extraSize = 22; wValidBitsPerSample = (short)bits; for (int i = 0; i < channels; i++) { dwChannelMask |= 1 << i; } if (bits == 32) { subFormat = AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT; } else { subFormat = AudioMediaSubtypes.MEDIASUBTYPE_PCM; } } public WaveFormat ToStandardWaveFormat() { if (subFormat == AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT && bitsPerSample == 32) { return WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channels); } if (subFormat == AudioMediaSubtypes.MEDIASUBTYPE_PCM) { return new WaveFormat(sampleRate, bitsPerSample, channels); } return this; } public override void Serialize(BinaryWriter writer) { base.Serialize(writer); writer.Write(wValidBitsPerSample); writer.Write(dwChannelMask); byte[] array = subFormat.ToByteArray(); writer.Write(array, 0, array.Length); } public override string ToString() { return "WAVE_FORMAT_EXTENSIBLE " + AudioMediaSubtypes.GetAudioSubtypeName(subFormat) + " " + $"{base.SampleRate}Hz {base.Channels} channels {base.BitsPerSample} bit"; } } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class WaveFormatExtraData : WaveFormat { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)] private byte[] extraData = new byte[100]; public byte[] ExtraData => extraData; internal WaveFormatExtraData() { } public WaveFormatExtraData(BinaryReader reader) : base(reader) { ReadExtraData(reader); } internal void ReadExtraData(BinaryReader reader) { if (extraSize > 0) { reader.Read(extraData, 0, extraSize); } } public override void Serialize(BinaryWriter writer) { base.Serialize(writer); if (extraSize > 0) { writer.Write(extraData, 0, extraSize); } } } public interface IWaveIn : IDisposable { WaveFormat WaveFormat { get; set; } event EventHandler<WaveInEventArgs> DataAvailable; event EventHandler<StoppedEventArgs> RecordingStopped; void StartRecording(); void StopRecording(); } public class WaveInEventArgs : EventArgs { private byte[] buffer; private int bytes; public byte[] Buffer => buffer; public int BytesRecorded => bytes; public WaveInEventArgs(byte[] buffer, int bytes) { this.buffer = buffer; this.bytes = bytes; } } public class AiffFileWriter : Stream { private Stream outStream; private BinaryWriter writer; private long dataSizePos; private long commSampleCountPos; private long dataChunkSize = 8L; private WaveFormat format; private string filename; private byte[] value24 = new byte[3]; public string Filename => filename; public override long Length => dataChunkSize; public WaveFormat WaveFormat => format; public override bool CanRead => false; public override bool CanWrite => true; public override bool CanSeek => false; public override long Position { get { return dataChunkSize; } set { throw new InvalidOperationException("Repositioning an AiffFileWriter is not supported"); } } public static void CreateAiffFile(string filename, WaveStream sourceProvider) { using AiffFileWriter aiffFileWriter = new AiffFileWriter(filename, sourceProvider.WaveFormat); byte[] array = new byte[16384]; while (sourceProvider.Position < sourceProvider.Length) { int count = Math.Min((int)(sourceProvider.Length - sourceProvider.Position), array.Length); int num = sourceProvider.Read(array, 0, count); if (num == 0) { break; } aiffFileWriter.Write(array, 0, num); } } public AiffFileWriter(Stream outStream, WaveFormat format) { this.outStream = outStream; this.format = format; writer = new BinaryWriter(outStream, Encoding.UTF8); writer.Write(Encoding.UTF8.GetBytes("FORM")); writer.Write(0); writer.Write(Encoding.UTF8.GetBytes("AIFF")); CreateCommChunk(); WriteSsndChunkHeader(); } public AiffFileWriter(string filename, WaveFormat format) : this(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read), format) { this.filename = filename; } private void WriteSsndChunkHeader() { writer.Write(Encoding.UTF8.GetBytes("SSND")); dataSizePos = outStream.Position; writer.Write(0); writer.Write(0); writer.Write(SwapEndian(format.BlockAlign)); } private byte[] SwapEndian(short n) { return new byte[2] { (byte)(n >> 8), (byte)((uint)n & 0xFFu) }; } private byte[] SwapEndian(int n) { return new byte[4] { (byte)((uint)(n >> 24) & 0xFFu), (byte)((uint)(n >> 16) & 0xFFu), (byte)((uint)(n >> 8) & 0xFFu), (byte)((uint)n & 0xFFu) }; } private void CreateCommChunk() { writer.Write(Encoding.UTF8.GetBytes("COMM")); writer.Write(SwapEndian(18)); writer.Write(SwapEndian((short)format.Channels)); commSampleCountPos = outStream.Position; writer.Write(0); writer.Write(SwapEndian((short)format.BitsPerSample)); writer.Write(IEEE.ConvertToIeeeExtended(format.SampleRate)); } public override int Read(byte[] buffer, int offset, int count) { throw new InvalidOperationException("Cannot read from an AiffFileWriter"); } public override long Seek(long offset, SeekOrigin origin) { throw new InvalidOperationException("Cannot seek within an AiffFileWriter"); } public override void SetLength(long value) { throw new InvalidOperationException("Cannot set length of an AiffFileWriter"); } public override void Write(byte[] data, int offset, int count) { byte[] array = new byte[data.Length]; int num = format.BitsPerSample / 8; for (int i = 0; i < data.Length; i++) { int num2 = (int)Math.Floor((double)i / (double)num) * num + (num - i % num - 1); array[i] = data[num2]; } outStream.Write(array, offset, count); dataChunkSize += count; } public void WriteSample(float sample) { if (WaveFormat.BitsPerSample == 16) { writer.Write(SwapEndian((short)(32767f * sample))); dataChunkSize += 2L; } else if (WaveFormat.BitsPerSample == 24) { byte[] bytes = BitConverter.GetBytes((int)(2.1474836E+09f * sample)); value24[2] = bytes[1]; value24[1] = bytes[2]; value24[0] = bytes[3]; writer.Write(value24); dataChunkSize += 3L; } else { if (WaveFormat.BitsPerSample != 32 || WaveFormat.Encoding != WaveFormatEncoding.Extensible) { throw new InvalidOperationException("Only 16, 24 or 32 bit PCM or IEEE float audio data supported"); } writer.Write(SwapEndian(65535 * (int)sample)); dataChunkSize += 4L; } } public void WriteSamples(float[] samples, int offset, int count) { for (int i = 0; i < count; i++) { WriteSample(samples[offset + i]); } } public void WriteSamples(short[] samples, int offset, int count) { if (WaveFormat.BitsPerSample == 16) { for (int i = 0; i < count; i++) { writer.Write(SwapEndian(samples[i + offset])); } dataChunkSize += count * 2; } else if (WaveFormat.BitsPerSample == 24) { for (int j = 0; j < count; j++) { byte[] bytes = BitConverter.GetBytes(65535 * samples[j + offset]); value24[2] = bytes[1]; value24[1] = bytes[2]; value24[0] = bytes[3]; writer.Write(value24); } dataChunkSize += count * 3; } else { if (WaveFormat.BitsPerSample != 32 || WaveFormat.Encoding != WaveFormatEncoding.Extensible) { throw new InvalidOperationException("Only 16, 24 or 32 bit PCM audio data supported"); } for (int k = 0; k < count; k++) { writer.Write(SwapEndian(65535 * samples[k + offset])); } dataChunkSize += count * 4; } } public override void Flush() { writer.Flush(); } protected override void Dispose(bool disposing) { if (disposing && outStream != null) { try { UpdateHeader(writer); } finally { outStream.Dispose(); outStream = null; } } } protected virtual void UpdateHeader(BinaryWriter writer) { Flush(); writer.Seek(4, SeekOrigin.Begin); writer.Write(SwapEndian((int)(outStream.Length - 8))); UpdateCommChunk(writer); UpdateSsndChunk(writer); } private void UpdateCommChunk(BinaryWriter writer) { writer.Seek((int)commSampleCountPos, SeekOrigin.Begin); writer.Write(SwapEndian((int)(dataChunkSize * 8 / format.BitsPerSample / format.Channels))); } private void UpdateSsndChunk(BinaryWriter writer) { writer.Seek((int)dataSizePos, SeekOrigin.Begin); writer.Write(SwapEndian((int)dataChunkSize)); } ~AiffFileWriter() { Dispose(disposing: false); } } public class BextChunkInfo { public string Description { get; set; } public string Originator { get; set; } public string OriginatorReference { get; set; } public DateTime OriginationDateTime { get; set; } public string OriginationDate => OriginationDateTime.ToString("yyyy-MM-dd"); public string OriginationTime => OriginationDateTime.ToString("HH:mm:ss"); public long TimeReference { get; set; } public ushort Version => 1; public string UniqueMaterialIdentifier { get; set; } public byte[] Reserved { get; } public string CodingHistory { get; set; } public BextChunkInfo() { Reserved = new byte[190]; } } public class BwfWriter : IDisposable { private readonly WaveFormat format; private readonly BinaryWriter writer; private readonly long dataChunkSizePosition; private long dataLength; private bool isDisposed; public BwfWriter(string filename, WaveFormat format, BextChunkInfo bextChunkInfo) { this.format = format; writer = new BinaryWriter(File.OpenWrite(filename)); writer.Write(Encoding.UTF8.GetBytes("RIFF")); writer.Write(0); writer.Write(Encoding.UTF8.GetBytes("WAVE")); writer.Write(Encoding.UTF8.GetBytes("JUNK")); writer.Write(28); writer.Write(0L); writer.Write(0L); writer.Write(0L); writer.Write(0); writer.Write(Encoding.UTF8.GetBytes("bext")); byte[] bytes = Encoding.ASCII.GetBytes(bextChunkInfo.CodingHistory ?? ""); int num = 602 + bytes.Length; if (num % 2 != 0) { num++; } writer.Write(num); _ = writer.BaseStream.Position; writer.Write(GetAsBytes(bextChunkInfo.Description, 256)); writer.Write(GetAsBytes(bextChunkInfo.Originator, 32)); writer.Write(GetAsBytes(bextChunkInfo.OriginatorReference, 32)); writer.Write(GetAsBytes(bextChunkInfo.OriginationDate, 10)); writer.Write(GetAsBytes(bextChunkInfo.OriginationTime, 8)); writer.Write(bextChunkInfo.TimeReference); writer.Write(bextChunkInfo.Version); writer.Write(GetAsBytes(bextChunkInfo.UniqueMaterialIdentifier, 64)); writer.Write(bextChunkInfo.Reserved); writer.Write(bytes); if (bytes.Length % 2 != 0) { writer.Write((byte)0); } writer.Write(Encoding.UTF8.GetBytes("fmt ")); format.Serialize(writer); writer.Write(Encoding.UTF8.GetBytes("data")); dataChunkSizePosition = writer.BaseStream.Position; writer.Write(-1); } public void Write(byte[] buffer, int offset, int count) { if (isDisposed) { throw new ObjectDisposedException("This BWF Writer already disposed"); } writer.Write(buffer, offset, count); dataLength += count; } public void Flush() { if (isDisposed) { throw new ObjectDisposedException("This BWF Writer already disposed"); } writer.Flush(); FixUpChunkSizes(restorePosition: true); } private void FixUpChunkSizes(bool restorePosition) { long position = writer.BaseStream.Position; bool num = dataLength > int.MaxValue; long num2 = writer.BaseStream.Length - 8; if (num) { int num3 = format.BitsPerSample / 8 * format.Channels; writer.BaseStream.Position = 0L; writer.Write(Encoding.UTF8.GetBytes("RF64")); writer.Write(-1); writer.BaseStream.Position += 4L; writer.Write(Encoding.UTF8.GetBytes("ds64")); writer.BaseStream.Position += 4L; writer.Write(num2); writer.Write(dataLength); writer.Write(dataLength / num3); } else { writer.BaseStream.Position = 4L; writer.Write((uint)num2); writer.BaseStream.Position = dataChunkSizePosition; writer.Write((uint)dataLength); } if (restorePosition) { writer.BaseStream.Position = position; } } public void Dispose() { if (!isDisposed) { FixUpChunkSizes(restorePosition: false); writer.Dispose(); isDisposed = true; } } private static byte[] GetAsBytes(string message, int byteSize) { byte[] array = new byte[byteSize]; byte[] bytes = Encoding.ASCII.GetBytes(message ?? ""); Array.Copy(bytes, array, Math.Min(bytes.Length, byteSize)); return array; } } public class CueWaveFileWriter : WaveFileWriter { private CueList cues; public CueWaveFileWriter(string fileName, WaveFormat waveFormat) : base(fileName, waveFormat) { } public void AddCue(int position, string label) { if (cues == null) { cues = new CueList(); } cues.Add(new Cue(position, label)); } private void WriteCues(BinaryWriter w) { if (cues != null) { int count = cues.GetRiffChunks().Length; w.Seek(0, SeekOrigin.End); if (w.BaseStream.Length % 2 == 1) { w.Write((byte)0); } w.Write(cues.GetRiffChunks(), 0, count); w.Seek(4, SeekOrigin.Begin); w.Write((int)(w.BaseStream.Length - 8)); } } protected override void UpdateHeader(BinaryWriter writer) { base.UpdateHeader(writer); WriteCues(writer); } } public class DirectSoundOut : IWavePlayer, IDisposable { [StructLayout(LayoutKind.Sequential, Pack = 2)] internal class BufferDescription { public int dwSize; [MarshalAs(UnmanagedType.U4)] public DirectSoundBufferCaps dwFlags; public uint dwBufferBytes; public int dwReserved; public IntPtr lpwfxFormat; public Guid guidAlgo; } [StructLayout(LayoutKind.Sequential, Pack = 2)] internal class BufferCaps { public int dwSize; public int dwFlags; public int dwBufferBytes; public int dwUnlockTransferRate; public int dwPlayCpuOverhead; } internal enum DirectSoundCooperativeLevel : uint { DSSCL_NORMAL = 1u, DSSCL_PRIORITY, DSSCL_EXCLUSIVE, DSSCL_WRITEPRIMARY } [Flags] internal enum DirectSoundPlayFlags : uint { DSBPLAY_LOOPING = 1u, DSBPLAY_LOCHARDWARE = 2u, DSBPLAY_LOCSOFTWARE = 4u, DSBPLAY_TERMINATEBY_TIME = 8u, DSBPLAY_TERMINATEBY_DISTANCE = 0x10u, DSBPLAY_TERMINATEBY_PRIORITY = 0x20u } internal enum DirectSoundBufferLockFlag : uint { None, FromWriteCursor, EntireBuffer } [Flags] internal enum DirectSoundBufferStatus : uint { DSBSTATUS_PLAYING = 1u, DSBSTATUS_BUFFERLOST = 2u, DSBSTATUS_LOOPING = 4u, DSBSTATUS_LOCHARDWARE = 8u, DSBSTATUS_LOCSOFTWARE = 0x10u, DSBSTATUS_TERMINATED = 0x20u } [Flags] internal enum DirectSoundBufferCaps : uint { DSBCAPS_PRIMARYBUFFER = 1u, DSBCAPS_STATIC = 2u, DSBCAPS_LOCHARDWARE = 4u, DSBCAPS_LOCSOFTWARE = 8u, DSBCAPS_CTRL3D = 0x10u, DSBCAPS_CTRLFREQUENCY = 0x20u, DSBCAPS_CTRLPAN = 0x40u, DSBCAPS_CTRLVOLUME = 0x80u, DSBCAPS_CTRLPOSITIONNOTIFY = 0x100u, DSBCAPS_CTRLFX = 0x200u, DSBCAPS_STICKYFOCUS = 0x4000u, DSBCAPS_GLOBALFOCUS = 0x8000u, DSBCAPS_GETCURRENTPOSITION2 = 0x10000u, DSBCAPS_MUTE3DATMAXDISTANCE = 0x20000u, DSBCAPS_LOCDEFER = 0x40000u } internal struct DirectSoundBufferPositionNotify { public uint dwOffset; public IntPtr hEventNotify; } [ComImport] [Guid("279AFA83-4981-11CE-A521-0020AF0BE560")] [SuppressUnmanagedCodeSecurity] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IDirectSound { void CreateSoundBuffer([In] BufferDescription desc, [MarshalAs(UnmanagedType.Interface)] out object dsDSoundBuffer, IntPtr pUnkOuter); void GetCaps(IntPtr caps); void DuplicateSoundBuffer([In][MarshalAs(UnmanagedType.Interface)] IDirectSoundBuffer bufferOriginal, [In][MarshalAs(UnmanagedType.Interface)] IDirectSoundBuffer bufferDuplicate); void SetCooperativeLevel(IntPtr HWND, [In][MarshalAs(UnmanagedType.U4)] DirectSoundCooperativeLevel dwLevel); void Compact(); void GetSpeakerConfig(IntPtr pdwSpeakerConfig); void SetSpeakerConfig(uint pdwSpeakerConfig); void Initialize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guid); } [ComImport] [Guid("279AFA85-4981-11CE-A521-0020AF0BE560")] [SuppressUnmanagedCodeSecurity] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IDirectSoundBuffer { void GetCaps([MarshalAs(UnmanagedType.LPStruct)] BufferCaps pBufferCaps); void GetCurrentPosition(out uint currentPlayCursor, out uint currentWriteCursor); void GetFormat(); [return: MarshalAs(UnmanagedType.I4)] int GetVolume(); void GetPan(out uint pan); [return: MarshalAs(UnmanagedType.I4)] int GetFrequency(); [return: MarshalAs(UnmanagedType.U4)] DirectSoundBufferStatus GetStatus(); void Initialize([In][MarshalAs(UnmanagedType.Interface)] IDirectSound directSound, [In] BufferDescription desc); void Lock(int dwOffset, uint dwBytes, out IntPtr audioPtr1, out int audioBytes1, out IntPtr audioPtr2, out int audioBytes2, [MarshalAs(UnmanagedType.U4)] DirectSoundBufferLockFlag dwFlags); void Play(uint dwReserved1, uint dwPriority, [In][MarshalAs(UnmanagedType.U4)] DirectSoundPlayFlags dwFlags); void SetCurrentPosition(uint dwNewPosition); void SetFormat([In] WaveFormat pcfxFormat); void SetVolume(int volume); void SetPan(uint pan); void SetFrequency(uint frequency); void Stop(); void Unlock(IntPtr pvAudioPtr1, int dwAudioBytes1, IntPtr pvAudioPtr2, int dwAudioBytes2); void Restore(); } [ComImport] [Guid("b0210783-89cd-11d0-af08-00a0c925cd16")] [SuppressUnmanagedCodeSecurity] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IDirectSoundNotify { void SetNotificationPositions(uint dwPositionNotifies, [In][MarshalAs(UnmanagedType.LPArray)] DirectSoundBufferPositionNotify[] pcPositionNotifies); } private delegate bool DSEnumCallback(IntPtr lpGuid, IntPtr lpcstrDescription, IntPtr lpcstrModule, IntPtr lpContext); private PlaybackState playbackState; private WaveFormat waveFormat; private int samplesTotalSize; private int samplesFrameSize; private int nextSamplesWriteIndex; private int desiredLatency; private Guid device; private byte[] samples; private IWaveProvider waveStream; private IDirectSound directSound; private IDirectSoundBuffer primarySoundBuffer; private IDirectSoundBuffer sec
plugins/NAudio.WinMM.dll
Decompiled a month agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Threading; using Microsoft.Win32; using NAudio.CoreAudioApi; using NAudio.Mixer; using NAudio.Utils; using NAudio.Wave.Compression; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("NAudio.WinMM")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("© Mark Heath 2023")] [assembly: AssemblyFileVersion("2.2.1.0")] [assembly: AssemblyInformationalVersion("2.2.1")] [assembly: AssemblyProduct("NAudio.WinMM")] [assembly: AssemblyTitle("NAudio.WinMM")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")] [assembly: AssemblyVersion("2.2.1.0")] namespace NAudio.Mixer { public class BooleanMixerControl : MixerControl { private MixerInterop.MIXERCONTROLDETAILS_BOOLEAN boolDetails; public bool Value { get { GetControlDetails(); return boolDetails.fValue == 1; } set { //IL_0055: Unknown result type (might be due to invalid IL or missing references) boolDetails.fValue = (value ? 1 : 0); mixerControlDetails.paDetails = Marshal.AllocHGlobal(Marshal.SizeOf(boolDetails)); Marshal.StructureToPtr(boolDetails, mixerControlDetails.paDetails, fDeleteOld: false); MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails"); Marshal.FreeHGlobal(mixerControlDetails.paDetails); } } internal BooleanMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { boolDetails = Marshal.PtrToStructure<MixerInterop.MIXERCONTROLDETAILS_BOOLEAN>(pDetails); } } public class CustomMixerControl : MixerControl { internal CustomMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { } } public class ListTextMixerControl : MixerControl { internal ListTextMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { } } public class Mixer { private MixerInterop.MIXERCAPS caps; private IntPtr mixerHandle; private MixerFlags mixerHandleType; public static int NumberOfDevices => MixerInterop.mixerGetNumDevs(); public int DestinationCount => (int)caps.cDestinations; public string Name => caps.szPname; public Manufacturers Manufacturer => (Manufacturers)caps.wMid; public int ProductID => caps.wPid; public IEnumerable<MixerLine> Destinations { get { for (int destination = 0; destination < DestinationCount; destination++) { yield return GetDestination(destination); } } } public static IEnumerable<Mixer> Mixers { get { for (int device = 0; device < NumberOfDevices; device++) { yield return new Mixer(device); } } } public Mixer(int mixerIndex) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (mixerIndex < 0 || mixerIndex >= NumberOfDevices) { throw new ArgumentOutOfRangeException("mixerID"); } caps = default(MixerInterop.MIXERCAPS); MmException.Try(MixerInterop.mixerGetDevCaps((IntPtr)mixerIndex, ref caps, Marshal.SizeOf(caps)), "mixerGetDevCaps"); mixerHandle = (IntPtr)mixerIndex; mixerHandleType = MixerFlags.Mixer; } public MixerLine GetDestination(int destinationIndex) { if (destinationIndex < 0 || destinationIndex >= DestinationCount) { throw new ArgumentOutOfRangeException("destinationIndex"); } return new MixerLine(mixerHandle, destinationIndex, mixerHandleType); } } public abstract class MixerControl { internal MixerInterop.MIXERCONTROL mixerControl; internal MixerInterop.MIXERCONTROLDETAILS mixerControlDetails; protected IntPtr mixerHandle; protected int nChannels; protected MixerFlags mixerHandleType; public string Name => mixerControl.szName; public MixerControlType ControlType => mixerControl.dwControlType; public bool IsBoolean => IsControlBoolean(mixerControl.dwControlType); public bool IsListText => IsControlListText(mixerControl.dwControlType); public bool IsSigned => IsControlSigned(mixerControl.dwControlType); public bool IsUnsigned => IsControlUnsigned(mixerControl.dwControlType); public bool IsCustom => IsControlCustom(mixerControl.dwControlType); public static IList<MixerControl> GetMixerControls(IntPtr mixerHandle, MixerLine mixerLine, MixerFlags mixerHandleType) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) List<MixerControl> list = new List<MixerControl>(); if (mixerLine.ControlsCount > 0) { int num = Marshal.SizeOf<MixerInterop.MIXERCONTROL>(); MixerInterop.MIXERLINECONTROLS mixerLineControls = default(MixerInterop.MIXERLINECONTROLS); IntPtr intPtr = Marshal.AllocHGlobal(num * mixerLine.ControlsCount); mixerLineControls.cbStruct = Marshal.SizeOf(mixerLineControls); mixerLineControls.dwLineID = mixerLine.LineId; mixerLineControls.cControls = mixerLine.ControlsCount; mixerLineControls.pamxctrl = intPtr; mixerLineControls.cbmxctrl = Marshal.SizeOf<MixerInterop.MIXERCONTROL>(); try { MmResult val = MixerInterop.mixerGetLineControls(mixerHandle, ref mixerLineControls, MixerFlags.Mixer | mixerHandleType); if ((int)val != 0) { throw new MmException(val, "mixerGetLineControls"); } for (int i = 0; i < mixerLineControls.cControls; i++) { MixerInterop.MIXERCONTROL mIXERCONTROL = Marshal.PtrToStructure<MixerInterop.MIXERCONTROL>((IntPtr)(intPtr.ToInt64() + num * i)); MixerControl item = GetMixerControl(mixerHandle, mixerLine.LineId, mIXERCONTROL.dwControlID, mixerLine.Channels, mixerHandleType); list.Add(item); } } finally { Marshal.FreeHGlobal(intPtr); } } return list; } public static MixerControl GetMixerControl(IntPtr mixerHandle, int nLineId, int controlId, int nChannels, MixerFlags mixerFlags) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) MixerInterop.MIXERLINECONTROLS mixerLineControls = default(MixerInterop.MIXERLINECONTROLS); MixerInterop.MIXERCONTROL structure = default(MixerInterop.MIXERCONTROL); IntPtr intPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(structure)); mixerLineControls.cbStruct = Marshal.SizeOf(mixerLineControls); mixerLineControls.cControls = 1; mixerLineControls.dwControlID = controlId; mixerLineControls.cbmxctrl = Marshal.SizeOf(structure); mixerLineControls.pamxctrl = intPtr; mixerLineControls.dwLineID = nLineId; MmResult val = MixerInterop.mixerGetLineControls(mixerHandle, ref mixerLineControls, MixerFlags.ListText | mixerFlags); if ((int)val != 0) { Marshal.FreeCoTaskMem(intPtr); throw new MmException(val, "mixerGetLineControls"); } structure = Marshal.PtrToStructure<MixerInterop.MIXERCONTROL>(mixerLineControls.pamxctrl); Marshal.FreeCoTaskMem(intPtr); if (IsControlBoolean(structure.dwControlType)) { return new BooleanMixerControl(structure, mixerHandle, mixerFlags, nChannels); } if (IsControlSigned(structure.dwControlType)) { return new SignedMixerControl(structure, mixerHandle, mixerFlags, nChannels); } if (IsControlUnsigned(structure.dwControlType)) { return new UnsignedMixerControl(structure, mixerHandle, mixerFlags, nChannels); } if (IsControlListText(structure.dwControlType)) { return new ListTextMixerControl(structure, mixerHandle, mixerFlags, nChannels); } if (IsControlCustom(structure.dwControlType)) { return new CustomMixerControl(structure, mixerHandle, mixerFlags, nChannels); } throw new InvalidOperationException($"Unknown mixer control type {structure.dwControlType}"); } protected void GetControlDetails() { //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) mixerControlDetails.cbStruct = Marshal.SizeOf(mixerControlDetails); mixerControlDetails.dwControlID = mixerControl.dwControlID; if (IsCustom) { mixerControlDetails.cChannels = 0; } else if ((mixerControl.fdwControl & (true ? 1u : 0u)) != 0) { mixerControlDetails.cChannels = 1; } else { mixerControlDetails.cChannels = nChannels; } if ((mixerControl.fdwControl & 2u) != 0) { mixerControlDetails.hwndOwner = (IntPtr)mixerControl.cMultipleItems; } else if (IsCustom) { mixerControlDetails.hwndOwner = IntPtr.Zero; } else { mixerControlDetails.hwndOwner = IntPtr.Zero; } if (IsBoolean) { mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_BOOLEAN>(); } else if (IsListText) { mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_LISTTEXT>(); } else if (IsSigned) { mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_SIGNED>(); } else if (IsUnsigned) { mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_UNSIGNED>(); } else { mixerControlDetails.cbDetails = mixerControl.Metrics.customData; } int num = mixerControlDetails.cbDetails * mixerControlDetails.cChannels; if ((mixerControl.fdwControl & 2u) != 0) { num *= (int)mixerControl.cMultipleItems; } IntPtr intPtr = Marshal.AllocCoTaskMem(num); mixerControlDetails.paDetails = intPtr; MmResult val = MixerInterop.mixerGetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType); if ((int)val == 0) { GetDetails(mixerControlDetails.paDetails); } Marshal.FreeCoTaskMem(intPtr); if ((int)val != 0) { throw new MmException(val, "mixerGetControlDetails"); } } protected abstract void GetDetails(IntPtr pDetails); private static bool IsControlBoolean(MixerControlType controlType) { switch (controlType) { case MixerControlType.BooleanMeter: case MixerControlType.Boolean: case MixerControlType.OnOff: case MixerControlType.Mute: case MixerControlType.Mono: case MixerControlType.Loudness: case MixerControlType.StereoEnhance: case MixerControlType.Button: case MixerControlType.SingleSelect: case MixerControlType.Mux: case MixerControlType.MultipleSelect: case MixerControlType.Mixer: return true; default: return false; } } private static bool IsControlListText(MixerControlType controlType) { if (controlType == MixerControlType.Equalizer || (uint)(controlType - 1879113728) <= 1u || (uint)(controlType - 1895890944) <= 1u) { return true; } return false; } private static bool IsControlSigned(MixerControlType controlType) { switch (controlType) { case MixerControlType.SignedMeter: case MixerControlType.PeakMeter: case MixerControlType.Signed: case MixerControlType.Decibels: case MixerControlType.Slider: case MixerControlType.Pan: case MixerControlType.QSoundPan: return true; default: return false; } } private static bool IsControlUnsigned(MixerControlType controlType) { switch (controlType) { case MixerControlType.UnsignedMeter: case MixerControlType.Unsigned: case MixerControlType.Percent: case MixerControlType.Fader: case MixerControlType.Volume: case MixerControlType.Bass: case MixerControlType.Treble: case MixerControlType.Equalizer: case MixerControlType.MicroTime: case MixerControlType.MilliTime: return true; default: return false; } } private static bool IsControlCustom(MixerControlType controlType) { return controlType == MixerControlType.Custom; } public override string ToString() { return $"{Name} {ControlType}"; } } [Flags] internal enum MixerControlClass { Custom = 0, Meter = 0x10000000, Switch = 0x20000000, Number = 0x30000000, Slider = 0x40000000, Fader = 0x50000000, Time = 0x60000000, List = 0x70000000, Mask = 0x70000000 } [Flags] internal enum MixerControlSubclass { SwitchBoolean = 0, SwitchButton = 0x1000000, MeterPolled = 0, TimeMicrosecs = 0, TimeMillisecs = 0x1000000, ListSingle = 0, ListMultiple = 0x1000000, Mask = 0xF000000 } [Flags] internal enum MixerControlUnits { Custom = 0, Boolean = 0x10000, Signed = 0x20000, Unsigned = 0x30000, Decibels = 0x40000, Percent = 0x50000, Mask = 0xFF0000 } public enum MixerControlType { Custom = 0, BooleanMeter = 268500992, SignedMeter = 268566528, PeakMeter = 268566529, UnsignedMeter = 268632064, Boolean = 536936448, OnOff = 536936449, Mute = 536936450, Mono = 536936451, Loudness = 536936452, StereoEnhance = 536936453, Button = 553713664, Decibels = 805568512, Signed = 805437440, Unsigned = 805502976, Percent = 805634048, Slider = 1073872896, Pan = 1073872897, QSoundPan = 1073872898, Fader = 1342373888, Volume = 1342373889, Bass = 1342373890, Treble = 1342373891, Equalizer = 1342373892, SingleSelect = 1879113728, Mux = 1879113729, MultipleSelect = 1895890944, Mixer = 1895890945, MicroTime = 1610809344, MilliTime = 1627586560 } [Flags] public enum MixerFlags { Handle = int.MinValue, Mixer = 0, MixerHandle = int.MinValue, WaveOut = 0x10000000, WaveOutHandle = -1879048192, WaveIn = 0x20000000, WaveInHandle = -1610612736, MidiOut = 0x30000000, MidiOutHandle = -1342177280, MidiIn = 0x40000000, MidiInHandle = -1073741824, Aux = 0x50000000, Value = 0, ListText = 1, QueryMask = 0xF, All = 0, OneById = 1, OneByType = 2, GetLineInfoOfDestination = 0, GetLineInfoOfSource = 1, GetLineInfoOfLineId = 2, GetLineInfoOfComponentType = 3, GetLineInfoOfTargetType = 4, GetLineInfoOfQueryMask = 0xF } internal class MixerInterop { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)] public struct MIXERCONTROLDETAILS { public int cbStruct; public int dwControlID; public int cChannels; public IntPtr hwndOwner; public int cbDetails; public IntPtr paDetails; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERCAPS { public ushort wMid; public ushort wPid; public uint vDriverVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szPname; public uint fdwSupport; public uint cDestinations; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERLINECONTROLS { public int cbStruct; public int dwLineID; public int dwControlID; public int cControls; public int cbmxctrl; public IntPtr pamxctrl; } [Flags] public enum MIXERLINE_LINEF { MIXERLINE_LINEF_ACTIVE = 1, MIXERLINE_LINEF_DISCONNECTED = 0x8000, MIXERLINE_LINEF_SOURCE = int.MinValue } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERLINE { public int cbStruct; public int dwDestination; public int dwSource; public int dwLineID; public MIXERLINE_LINEF fdwLine; public IntPtr dwUser; public MixerLineComponentType dwComponentType; public int cChannels; public int cConnections; public int cControls; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string szShortName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string szName; public uint dwType; public uint dwDeviceID; public ushort wMid; public ushort wPid; public uint vDriverVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szPname; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct Bounds { public int minimum; public int maximum; public int reserved2; public int reserved3; public int reserved4; public int reserved5; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct Metrics { public int step; public int customData; public int reserved2; public int reserved3; public int reserved4; public int reserved5; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERCONTROL { public uint cbStruct; public int dwControlID; public MixerControlType dwControlType; public uint fdwControl; public uint cMultipleItems; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string szShortName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string szName; public Bounds Bounds; public Metrics Metrics; } public struct MIXERCONTROLDETAILS_BOOLEAN { public int fValue; } public struct MIXERCONTROLDETAILS_SIGNED { public int lValue; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERCONTROLDETAILS_LISTTEXT { public uint dwParam1; public uint dwParam2; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string szName; } public struct MIXERCONTROLDETAILS_UNSIGNED { public uint dwValue; } public const uint MIXERCONTROL_CONTROLF_UNIFORM = 1u; public const uint MIXERCONTROL_CONTROLF_MULTIPLE = 2u; public const uint MIXERCONTROL_CONTROLF_DISABLED = 2147483648u; public const int MAXPNAMELEN = 32; public const int MIXER_SHORT_NAME_CHARS = 16; public const int MIXER_LONG_NAME_CHARS = 64; [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern int mixerGetNumDevs(); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerOpen(out IntPtr hMixer, int uMxId, IntPtr dwCallback, IntPtr dwInstance, MixerFlags dwOpenFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerClose(IntPtr hMixer); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetControlDetails(IntPtr hMixer, ref MIXERCONTROLDETAILS mixerControlDetails, MixerFlags dwDetailsFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetDevCaps(IntPtr nMixerID, ref MIXERCAPS mixerCaps, int mixerCapsSize); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetID(IntPtr hMixer, out int mixerID, MixerFlags dwMixerIDFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetLineControls(IntPtr hMixer, ref MIXERLINECONTROLS mixerLineControls, MixerFlags dwControlFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetLineInfo(IntPtr hMixer, ref MIXERLINE mixerLine, MixerFlags dwInfoFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerMessage(IntPtr hMixer, uint nMessage, IntPtr dwParam1, IntPtr dwParam2); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerSetControlDetails(IntPtr hMixer, ref MIXERCONTROLDETAILS mixerControlDetails, MixerFlags dwDetailsFlags); } public class MixerLine { private MixerInterop.MIXERLINE mixerLine; private IntPtr mixerHandle; private MixerFlags mixerHandleType; public string Name => mixerLine.szName; public string ShortName => mixerLine.szShortName; public int LineId => mixerLine.dwLineID; public MixerLineComponentType ComponentType => mixerLine.dwComponentType; public string TypeDescription => mixerLine.dwComponentType switch { MixerLineComponentType.DestinationUndefined => "Undefined Destination", MixerLineComponentType.DestinationDigital => "Digital Destination", MixerLineComponentType.DestinationLine => "Line Level Destination", MixerLineComponentType.DestinationMonitor => "Monitor Destination", MixerLineComponentType.DestinationSpeakers => "Speakers Destination", MixerLineComponentType.DestinationHeadphones => "Headphones Destination", MixerLineComponentType.DestinationTelephone => "Telephone Destination", MixerLineComponentType.DestinationWaveIn => "Wave Input Destination", MixerLineComponentType.DestinationVoiceIn => "Voice Recognition Destination", MixerLineComponentType.SourceUndefined => "Undefined Source", MixerLineComponentType.SourceDigital => "Digital Source", MixerLineComponentType.SourceLine => "Line Level Source", MixerLineComponentType.SourceMicrophone => "Microphone Source", MixerLineComponentType.SourceSynthesizer => "Synthesizer Source", MixerLineComponentType.SourceCompactDisc => "Compact Disk Source", MixerLineComponentType.SourceTelephone => "Telephone Source", MixerLineComponentType.SourcePcSpeaker => "PC Speaker Source", MixerLineComponentType.SourceWaveOut => "Wave Out Source", MixerLineComponentType.SourceAuxiliary => "Auxiliary Source", MixerLineComponentType.SourceAnalog => "Analog Source", _ => "Invalid Component Type", }; public int Channels => mixerLine.cChannels; public int SourceCount => mixerLine.cConnections; public int ControlsCount => mixerLine.cControls; public bool IsActive => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_ACTIVE) != 0; public bool IsDisconnected => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_DISCONNECTED) != 0; public bool IsSource => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_SOURCE) != 0; public IEnumerable<MixerControl> Controls => MixerControl.GetMixerControls(mixerHandle, this, mixerHandleType); public IEnumerable<MixerLine> Sources { get { for (int source = 0; source < SourceCount; source++) { yield return GetSource(source); } } } public string TargetName => mixerLine.szPname; public MixerLine(IntPtr mixerHandle, int destinationIndex, MixerFlags mixerHandleType) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) this.mixerHandle = mixerHandle; this.mixerHandleType = mixerHandleType; mixerLine = default(MixerInterop.MIXERLINE); mixerLine.cbStruct = Marshal.SizeOf(mixerLine); mixerLine.dwDestination = destinationIndex; MmException.Try(MixerInterop.mixerGetLineInfo(mixerHandle, ref mixerLine, mixerHandleType | MixerFlags.Mixer), "mixerGetLineInfo"); } public MixerLine(IntPtr mixerHandle, int destinationIndex, int sourceIndex, MixerFlags mixerHandleType) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) this.mixerHandle = mixerHandle; this.mixerHandleType = mixerHandleType; mixerLine = default(MixerInterop.MIXERLINE); mixerLine.cbStruct = Marshal.SizeOf(mixerLine); mixerLine.dwDestination = destinationIndex; mixerLine.dwSource = sourceIndex; MmException.Try(MixerInterop.mixerGetLineInfo(mixerHandle, ref mixerLine, mixerHandleType | MixerFlags.ListText), "mixerGetLineInfo"); } public static int GetMixerIdForWaveIn(int waveInDevice) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) int mixerID = -1; MmException.Try(MixerInterop.mixerGetID((IntPtr)waveInDevice, out mixerID, MixerFlags.WaveIn), "mixerGetID"); return mixerID; } public MixerLine GetSource(int sourceIndex) { if (sourceIndex < 0 || sourceIndex >= SourceCount) { throw new ArgumentOutOfRangeException("sourceIndex"); } return new MixerLine(mixerHandle, mixerLine.dwDestination, sourceIndex, mixerHandleType); } public override string ToString() { return $"{Name} {TypeDescription} ({ControlsCount} controls, ID={mixerLine.dwLineID})"; } } public enum MixerLineComponentType { DestinationUndefined = 0, DestinationDigital = 1, DestinationLine = 2, DestinationMonitor = 3, DestinationSpeakers = 4, DestinationHeadphones = 5, DestinationTelephone = 6, DestinationWaveIn = 7, DestinationVoiceIn = 8, SourceUndefined = 4096, SourceDigital = 4097, SourceLine = 4098, SourceMicrophone = 4099, SourceSynthesizer = 4100, SourceCompactDisc = 4101, SourceTelephone = 4102, SourcePcSpeaker = 4103, SourceWaveOut = 4104, SourceAuxiliary = 4105, SourceAnalog = 4106 } public class SignedMixerControl : MixerControl { private MixerInterop.MIXERCONTROLDETAILS_SIGNED signedDetails; public int Value { get { GetControlDetails(); return signedDetails.lValue; } set { //IL_0052: Unknown result type (might be due to invalid IL or missing references) signedDetails.lValue = value; mixerControlDetails.paDetails = Marshal.AllocHGlobal(Marshal.SizeOf(signedDetails)); Marshal.StructureToPtr(signedDetails, mixerControlDetails.paDetails, fDeleteOld: false); MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails"); Marshal.FreeHGlobal(mixerControlDetails.paDetails); } } public int MinValue => mixerControl.Bounds.minimum; public int MaxValue => mixerControl.Bounds.maximum; public double Percent { get { return 100.0 * (double)(Value - MinValue) / (double)(MaxValue - MinValue); } set { Value = (int)((double)MinValue + value / 100.0 * (double)(MaxValue - MinValue)); } } internal SignedMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { signedDetails = Marshal.PtrToStructure<MixerInterop.MIXERCONTROLDETAILS_SIGNED>(mixerControlDetails.paDetails); } public override string ToString() { return $"{base.ToString()} {Percent}%"; } } public class UnsignedMixerControl : MixerControl { private MixerInterop.MIXERCONTROLDETAILS_UNSIGNED[] unsignedDetails; public uint Value { get { GetControlDetails(); return unsignedDetails[0].dwValue; } set { //IL_008f: Unknown result type (might be due to invalid IL or missing references) int num = Marshal.SizeOf(unsignedDetails[0]); mixerControlDetails.paDetails = Marshal.AllocHGlobal(num * nChannels); for (int i = 0; i < nChannels; i++) { unsignedDetails[i].dwValue = value; long num2 = mixerControlDetails.paDetails.ToInt64() + num * i; Marshal.StructureToPtr(unsignedDetails[i], (IntPtr)num2, fDeleteOld: false); } MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails"); Marshal.FreeHGlobal(mixerControlDetails.paDetails); } } public uint MinValue => (uint)mixerControl.Bounds.minimum; public uint MaxValue => (uint)mixerControl.Bounds.maximum; public double Percent { get { return 100.0 * (double)(Value - MinValue) / (double)(MaxValue - MinValue); } set { Value = (uint)((double)MinValue + value / 100.0 * (double)(MaxValue - MinValue)); } } internal UnsignedMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { unsignedDetails = new MixerInterop.MIXERCONTROLDETAILS_UNSIGNED[nChannels]; for (int i = 0; i < nChannels; i++) { unsignedDetails[i] = Marshal.PtrToStructure<MixerInterop.MIXERCONTROLDETAILS_UNSIGNED>(mixerControlDetails.paDetails); } } public override string ToString() { return $"{base.ToString()} {Percent}%"; } } } namespace NAudio.Wave { internal enum AcmMetrics { CountDrivers = 1, CountCodecs = 2, CountConverters = 3, CountFilters = 4, CountDisabled = 5, CountHardware = 6, CountLocalDrivers = 20, CountLocalCodecs = 21, CountLocalConverters = 22, CountLocalFilters = 23, CountLocalDisabled = 24, HardwareWaveInput = 30, HardwareWaveOutput = 31, MaxSizeFormat = 50, MaxSizeFilter = 51, DriverSupport = 100, DriverPriority = 101 } [Flags] internal enum AcmStreamConvertFlags { BlockAlign = 4, Start = 0x10, End = 0x20 } [StructLayout(LayoutKind.Explicit)] public struct MmTime { public const int TIME_MS = 1; public const int TIME_SAMPLES = 2; public const int TIME_BYTES = 4; [FieldOffset(0)] public uint wType; [FieldOffset(4)] public uint ms; [FieldOffset(4)] public uint sample; [FieldOffset(4)] public uint cb; [FieldOffset(4)] public uint ticks; [FieldOffset(4)] public byte smpteHour; [FieldOffset(5)] public byte smpteMin; [FieldOffset(6)] public byte smpteSec; [FieldOffset(7)] public byte smpteFrame; [FieldOffset(8)] public byte smpteFps; [FieldOffset(9)] public byte smpteDummy; [FieldOffset(10)] public byte smptePad0; [FieldOffset(11)] public byte smptePad1; [FieldOffset(4)] public uint midiSongPtrPos; } public enum WaveCallbackStrategy { FunctionCallback, NewWindow, ExistingWindow, Event } [StructLayout(LayoutKind.Sequential)] public sealed class WaveHeader { public IntPtr dataBuffer; public int bufferLength; public int bytesRecorded; public IntPtr userData; public WaveHeaderFlags flags; public int loops; public IntPtr next; public IntPtr reserved; } [Flags] public enum WaveHeaderFlags { BeginLoop = 4, Done = 1, EndLoop = 8, InQueue = 0x10, Prepared = 2 } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct WaveInCapabilities { private short manufacturerId; private short productId; private int driverVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] private string productName; private SupportedWaveFormat supportedFormats; private short channels; private short reserved; private Guid manufacturerGuid; private Guid productGuid; private Guid nameGuid; private const int MaxProductNameLength = 32; public int Channels => channels; public string ProductName => productName; public Guid NameGuid => nameGuid; public Guid ProductGuid => productGuid; public Guid ManufacturerGuid => manufacturerGuid; public bool SupportsWaveFormat(SupportedWaveFormat waveFormat) { return (supportedFormats & waveFormat) == waveFormat; } } public static class WaveCapabilitiesHelpers { public static readonly Guid MicrosoftDefaultManufacturerId = new Guid("d5a47fa8-6d98-11d1-a21a-00a0c9223196"); public static readonly Guid DefaultWaveOutGuid = new Guid("E36DC310-6D9A-11D1-A21A-00A0C9223196"); public static readonly Guid DefaultWaveInGuid = new Guid("E36DC311-6D9A-11D1-A21A-00A0C9223196"); public static string GetNameFromGuid(Guid guid) { string result = null; using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Control\\MediaCategories")) { using RegistryKey registryKey2 = registryKey.OpenSubKey(guid.ToString("B")); if (registryKey2 != null) { result = registryKey2.GetValue("Name") as string; } } return result; } } public class WaveInterop { [Flags] public enum WaveInOutOpenFlags { CallbackNull = 0, CallbackFunction = 0x30000, CallbackEvent = 0x50000, CallbackWindow = 0x10000, CallbackThread = 0x20000 } public enum WaveMessage { WaveInOpen = 958, WaveInClose = 959, WaveInData = 960, WaveOutClose = 956, WaveOutDone = 957, WaveOutOpen = 955 } public delegate void WaveCallback(IntPtr hWaveOut, WaveMessage message, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved); [DllImport("winmm.dll")] public static extern int mmioStringToFOURCC([MarshalAs(UnmanagedType.LPStr)] string s, int flags); [DllImport("winmm.dll")] public static extern int waveOutGetNumDevs(); [DllImport("winmm.dll")] public static extern MmResult waveOutPrepareHeader(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize); [DllImport("winmm.dll")] public static extern MmResult waveOutUnprepareHeader(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize); [DllImport("winmm.dll")] public static extern MmResult waveOutWrite(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize); [DllImport("winmm.dll")] public static extern MmResult waveOutOpen(out IntPtr hWaveOut, IntPtr uDeviceID, WaveFormat lpFormat, WaveCallback dwCallback, IntPtr dwInstance, WaveInOutOpenFlags dwFlags); [DllImport("winmm.dll", EntryPoint = "waveOutOpen")] public static extern MmResult waveOutOpenWindow(out IntPtr hWaveOut, IntPtr uDeviceID, WaveFormat lpFormat, IntPtr callbackWindowHandle, IntPtr dwInstance, WaveInOutOpenFlags dwFlags); [DllImport("winmm.dll")] public static extern MmResult waveOutReset(IntPtr hWaveOut); [DllImport("winmm.dll")] public static extern MmResult waveOutClose(IntPtr hWaveOut); [DllImport("winmm.dll")] public static extern MmResult waveOutPause(IntPtr hWaveOut); [DllImport("winmm.dll")] public static extern MmResult waveOutRestart(IntPtr hWaveOut); [DllImport("winmm.dll")] public static extern MmResult waveOutGetPosition(IntPtr hWaveOut, ref MmTime mmTime, int uSize); [DllImport("winmm.dll")] public static extern MmResult waveOutSetVolume(IntPtr hWaveOut, int dwVolume); [DllImport("winmm.dll")] public static extern MmResult waveOutGetVolume(IntPtr hWaveOut, out int dwVolume); [DllImport("winmm.dll", CharSet = CharSet.Auto)] public static extern MmResult waveOutGetDevCaps(IntPtr deviceID, out WaveOutCapabilities waveOutCaps, int waveOutCapsSize); [DllImport("winmm.dll")] public static extern int waveInGetNumDevs(); [DllImport("winmm.dll", CharSet = CharSet.Auto)] public static extern MmResult waveInGetDevCaps(IntPtr deviceID, out WaveInCapabilities waveInCaps, int waveInCapsSize); [DllImport("winmm.dll")] public static extern MmResult waveInAddBuffer(IntPtr hWaveIn, WaveHeader pwh, int cbwh); [DllImport("winmm.dll")] public static extern MmResult waveInClose(IntPtr hWaveIn); [DllImport("winmm.dll")] public static extern MmResult waveInOpen(out IntPtr hWaveIn, IntPtr uDeviceID, WaveFormat lpFormat, WaveCallback dwCallback, IntPtr dwInstance, WaveInOutOpenFlags dwFlags); [DllImport("winmm.dll", EntryPoint = "waveInOpen")] public static extern MmResult waveInOpenWindow(out IntPtr hWaveIn, IntPtr uDeviceID, WaveFormat lpFormat, IntPtr callbackWindowHandle, IntPtr dwInstance, WaveInOutOpenFlags dwFlags); [DllImport("winmm.dll")] public static extern MmResult waveInPrepareHeader(IntPtr hWaveIn, WaveHeader lpWaveInHdr, int uSize); [DllImport("winmm.dll")] public static extern MmResult waveInUnprepareHeader(IntPtr hWaveIn, WaveHeader lpWaveInHdr, int uSize); [DllImport("winmm.dll")] public static extern MmResult waveInReset(IntPtr hWaveIn); [DllImport("winmm.dll")] public static extern MmResult waveInStart(IntPtr hWaveIn); [DllImport("winmm.dll")] public static extern MmResult waveInStop(IntPtr hWaveIn); [DllImport("winmm.dll")] public static extern MmResult waveInGetPosition(IntPtr hWaveIn, out MmTime mmTime, int uSize); } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct WaveOutCapabilities { private short manufacturerId; private short productId; private int driverVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] private string productName; private SupportedWaveFormat supportedFormats; private short channels; private short reserved; private WaveOutSupport support; private Guid manufacturerGuid; private Guid productGuid; private Guid nameGuid; private const int MaxProductNameLength = 32; public int Channels => channels; public bool SupportsPlaybackRateControl => (support & WaveOutSupport.PlaybackRate) == WaveOutSupport.PlaybackRate; public string ProductName => productName; public Guid NameGuid => nameGuid; public Guid ProductGuid => productGuid; public Guid ManufacturerGuid => manufacturerGuid; public bool SupportsWaveFormat(SupportedWaveFormat waveFormat) { return (supportedFormats & waveFormat) == waveFormat; } } [Flags] public enum SupportedWaveFormat { WAVE_FORMAT_1M08 = 1, WAVE_FORMAT_1S08 = 2, WAVE_FORMAT_1M16 = 4, WAVE_FORMAT_1S16 = 8, WAVE_FORMAT_2M08 = 0x10, WAVE_FORMAT_2S08 = 0x20, WAVE_FORMAT_2M16 = 0x40, WAVE_FORMAT_2S16 = 0x80, WAVE_FORMAT_4M08 = 0x100, WAVE_FORMAT_4S08 = 0x200, WAVE_FORMAT_4M16 = 0x400, WAVE_FORMAT_4S16 = 0x800, WAVE_FORMAT_44M08 = 0x100, WAVE_FORMAT_44S08 = 0x200, WAVE_FORMAT_44M16 = 0x400, WAVE_FORMAT_44S16 = 0x800, WAVE_FORMAT_48M08 = 0x1000, WAVE_FORMAT_48S08 = 0x2000, WAVE_FORMAT_48M16 = 0x4000, WAVE_FORMAT_48S16 = 0x8000, WAVE_FORMAT_96M08 = 0x10000, WAVE_FORMAT_96S08 = 0x20000, WAVE_FORMAT_96M16 = 0x40000, WAVE_FORMAT_96S16 = 0x80000 } [Flags] internal enum WaveOutSupport { Pitch = 1, PlaybackRate = 2, Volume = 4, LRVolume = 8, Sync = 0x10, SampleAccurate = 0x20 } public class AcmMp3FrameDecompressor : IMp3FrameDecompressor, IDisposable { private readonly AcmStream conversionStream; private readonly WaveFormat pcmFormat; private bool disposed; public WaveFormat OutputFormat => pcmFormat; public AcmMp3FrameDecompressor(WaveFormat sourceFormat) { pcmFormat = AcmStream.SuggestPcmFormat(sourceFormat); try { conversionStream = new AcmStream(sourceFormat, pcmFormat); } catch (Exception) { disposed = true; GC.SuppressFinalize(this); throw; } } public int DecompressFrame(Mp3Frame frame, byte[] dest, int destOffset) { if (frame == null) { throw new ArgumentNullException("frame", "You must provide a non-null Mp3Frame to decompress"); } Array.Copy(frame.RawData, conversionStream.SourceBuffer, frame.FrameLength); int sourceBytesConverted; int num = conversionStream.Convert(frame.FrameLength, out sourceBytesConverted); if (sourceBytesConverted != frame.FrameLength) { throw new InvalidOperationException($"Couldn't convert the whole MP3 frame (converted {sourceBytesConverted}/{frame.FrameLength})"); } Array.Copy(conversionStream.DestBuffer, 0, dest, destOffset, num); return num; } public void Reset() { conversionStream.Reposition(); } public void Dispose() { if (!disposed) { disposed = true; if (conversionStream != null) { conversionStream.Dispose(); } GC.SuppressFinalize(this); } } ~AcmMp3FrameDecompressor() { Dispose(); } } public class WaveFormatConversionProvider : IWaveProvider, IDisposable { private readonly AcmStream conversionStream; private readonly IWaveProvider sourceProvider; private readonly int preferredSourceReadSize; private int leftoverDestBytes; private int leftoverDestOffset; private int leftoverSourceBytes; private bool isDisposed; public WaveFormat WaveFormat { get; } public WaveFormatConversionProvider(WaveFormat targetFormat, IWaveProvider sourceProvider) { this.sourceProvider = sourceProvider; WaveFormat = targetFormat; conversionStream = new AcmStream(sourceProvider.WaveFormat, targetFormat); preferredSourceReadSize = Math.Min(sourceProvider.WaveFormat.AverageBytesPerSecond, conversionStream.SourceBuffer.Length); preferredSourceReadSize -= preferredSourceReadSize % sourceProvider.WaveFormat.BlockAlign; } public void Reposition() { leftoverDestBytes = 0; leftoverDestOffset = 0; leftoverSourceBytes = 0; conversionStream.Reposition(); } public int Read(byte[] buffer, int offset, int count) { int i = 0; if (count % WaveFormat.BlockAlign != 0) { count -= count % WaveFormat.BlockAlign; } int num5; for (; i < count; i += num5) { int num = Math.Min(count - i, leftoverDestBytes); if (num > 0) { Array.Copy(conversionStream.DestBuffer, leftoverDestOffset, buffer, offset + i, num); leftoverDestOffset += num; leftoverDestBytes -= num; i += num; } if (i >= count) { break; } int num2 = Math.Min(preferredSourceReadSize, conversionStream.SourceBuffer.Length - leftoverSourceBytes); int num3 = sourceProvider.Read(conversionStream.SourceBuffer, leftoverSourceBytes, num2) + leftoverSourceBytes; if (num3 == 0) { break; } int sourceBytesConverted; int num4 = conversionStream.Convert(num3, out sourceBytesConverted); if (sourceBytesConverted == 0) { break; } leftoverSourceBytes = num3 - sourceBytesConverted; if (leftoverSourceBytes > 0) { Buffer.BlockCopy(conversionStream.SourceBuffer, sourceBytesConverted, conversionStream.SourceBuffer, 0, leftoverSourceBytes); } if (num4 <= 0) { break; } int val = count - i; num5 = Math.Min(num4, val); if (num5 < num4) { leftoverDestBytes = num4 - num5; leftoverDestOffset = num5; } Array.Copy(conversionStream.DestBuffer, 0, buffer, i + offset, num5); } return i; } protected virtual void Dispose(bool disposing) { if (!isDisposed) { isDisposed = true; conversionStream?.Dispose(); } } public void Dispose() { GC.SuppressFinalize(this); Dispose(disposing: true); } ~WaveFormatConversionProvider() { Dispose(disposing: false); } } public class WaveFormatConversionStream : WaveStream { private readonly WaveFormatConversionProvider conversionProvider; private readonly WaveFormat targetFormat; private readonly long length; private long position; private readonly WaveStream sourceStream; private bool isDisposed; public override long Position { get { return position; } set { value -= value % ((WaveStream)this).BlockAlign; long num = EstimateDestToSource(value); ((Stream)(object)sourceStream).Position = num; position = EstimateSourceToDest(((Stream)(object)sourceStream).Position); conversionProvider.Reposition(); } } public override long Length => length; public override WaveFormat WaveFormat => targetFormat; public WaveFormatConversionStream(WaveFormat targetFormat, WaveStream sourceStream) { this.sourceStream = sourceStream; this.targetFormat = targetFormat; conversionProvider = new WaveFormatConversionProvider(targetFormat, (IWaveProvider)(object)sourceStream); length = EstimateSourceToDest((int)((Stream)(object)sourceStream).Length); position = 0L; } public static WaveStream CreatePcmStream(WaveStream sourceStream) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if ((int)sourceStream.WaveFormat.Encoding == 1) { return sourceStream; } WaveFormat val = AcmStream.SuggestPcmFormat(sourceStream.WaveFormat); if (val.SampleRate < 8000) { if ((int)sourceStream.WaveFormat.Encoding != 163) { throw new InvalidOperationException("Invalid suggested output format, please explicitly provide a target format"); } val = new WaveFormat(8000, 16, 1); } return (WaveStream)(object)new WaveFormatConversionStream(val, sourceStream); } [Obsolete("can be unreliable, use of this method not encouraged")] public int SourceToDest(int source) { return (int)EstimateSourceToDest(source); } private long EstimateSourceToDest(long source) { long num = source * targetFormat.AverageBytesPerSecond / sourceStream.WaveFormat.AverageBytesPerSecond; return num - num % targetFormat.BlockAlign; } private long EstimateDestToSource(long dest) { long num = dest * sourceStream.WaveFormat.AverageBytesPerSecond / targetFormat.AverageBytesPerSecond; return (int)(num - num % sourceStream.WaveFormat.BlockAlign); } [Obsolete("can be unreliable, use of this method not encouraged")] public int DestToSource(int dest) { return (int)EstimateDestToSource(dest); } public override int Read(byte[] buffer, int offset, int count) { int num = conversionProvider.Read(buffer, offset, count); position += num; return num; } protected override void Dispose(bool disposing) { if (!isDisposed) { isDisposed = true; if (disposing) { ((Stream)(object)sourceStream).Dispose(); conversionProvider.Dispose(); } } ((Stream)this).Dispose(disposing); } } public class WaveInBuffer : IDisposable { private readonly WaveHeader header; private readonly int bufferSize; private readonly byte[] buffer; private GCHandle hBuffer; private IntPtr waveInHandle; private GCHandle hHeader; private GCHandle hThis; public byte[] Data => buffer; public bool Done => (header.flags & WaveHeaderFlags.Done) == WaveHeaderFlags.Done; public bool InQueue => (header.flags & WaveHeaderFlags.InQueue) == WaveHeaderFlags.InQueue; public int BytesRecorded => header.bytesRecorded; public int BufferSize => bufferSize; public WaveInBuffer(IntPtr waveInHandle, int bufferSize) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) this.bufferSize = bufferSize; buffer = new byte[bufferSize]; hBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); this.waveInHandle = waveInHandle; header = new WaveHeader(); hHeader = GCHandle.Alloc(header, GCHandleType.Pinned); header.dataBuffer = hBuffer.AddrOfPinnedObject(); header.bufferLength = bufferSize; header.loops = 1; hThis = GCHandle.Alloc(this); header.userData = (IntPtr)hThis; MmException.Try(WaveInterop.waveInPrepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveInPrepareHeader"); } public void Reuse() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) MmException.Try(WaveInterop.waveInUnprepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveUnprepareHeader"); MmException.Try(WaveInterop.waveInPrepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveInPrepareHeader"); MmException.Try(WaveInterop.waveInAddBuffer(waveInHandle, header, Marshal.SizeOf(header)), "waveInAddBuffer"); } ~WaveInBuffer() { Dispose(disposing: false); } public void Dispose() { GC.SuppressFinalize(this); Dispose(disposing: true); } protected void Dispose(bool disposing) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (waveInHandle != IntPtr.Zero) { WaveInterop.waveInUnprepareHeader(waveInHandle, header, Marshal.SizeOf(header)); waveInHandle = IntPtr.Zero; } if (hHeader.IsAllocated) { hHeader.Free(); } if (hBuffer.IsAllocated) { hBuffer.Free(); } if (hThis.IsAllocated) { hThis.Free(); } } } public class WaveInEvent : IWaveIn, IDisposable { private readonly AutoResetEvent callbackEvent; private readonly SynchronizationContext syncContext; private IntPtr waveInHandle; private volatile CaptureState captureState; private WaveInBuffer[] buffers; public static int DeviceCount => WaveInterop.waveInGetNumDevs(); public int BufferMilliseconds { get; set; } public int NumberOfBuffers { get; set; } public int DeviceNumber { get; set; } public WaveFormat WaveFormat { get; set; } public event EventHandler<WaveInEventArgs> DataAvailable; public event EventHandler<StoppedEventArgs> RecordingStopped; public WaveInEvent() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) callbackEvent = new AutoResetEvent(initialState: false); syncContext = SynchronizationContext.Current; DeviceNumber = 0; WaveFormat = new WaveFormat(8000, 16, 1); BufferMilliseconds = 100; NumberOfBuffers = 3; captureState = (CaptureState)0; } public static WaveInCapabilities GetCapabilities(int devNumber) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) WaveInCapabilities waveInCaps = default(WaveInCapabilities); int waveInCapsSize = Marshal.SizeOf(waveInCaps); MmException.Try(WaveInterop.waveInGetDevCaps((IntPtr)devNumber, out waveInCaps, waveInCapsSize), "waveInGetDevCaps"); return waveInCaps; } private void CreateBuffers() { int num = BufferMilliseconds * WaveFormat.AverageBytesPerSecond / 1000; if (num % WaveFormat.BlockAlign != 0) { num -= num % WaveFormat.BlockAlign; } buffers = new WaveInBuffer[NumberOfBuffers]; for (int i = 0; i < buffers.Length; i++) { buffers[i] = new WaveInBuffer(waveInHandle, num); } } private void OpenWaveInDevice() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) CloseWaveInDevice(); MmException.Try(WaveInterop.waveInOpenWindow(out waveInHandle, (IntPtr)DeviceNumber, WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent), "waveInOpen"); CreateBuffers(); } public void StartRecording() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if ((int)captureState != 0) { throw new InvalidOperationException("Already recording"); } OpenWaveInDevice(); MmException.Try(WaveInterop.waveInStart(waveInHandle), "waveInStart"); captureState = (CaptureState)1; ThreadPool.QueueUserWorkItem(delegate { RecordThread(); }, null); } private void RecordThread() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) Exception e = null; try { DoRecording(); } catch (Exception ex) { e = ex; } finally { captureState = (CaptureState)0; RaiseRecordingStoppedEvent(e); } } private void DoRecording() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Invalid comparison between Unknown and I4 //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Invalid comparison between Unknown and I4 //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown captureState = (CaptureState)2; WaveInBuffer[] array = buffers; foreach (WaveInBuffer waveInBuffer in array) { if (!waveInBuffer.InQueue) { waveInBuffer.Reuse(); } } while ((int)captureState == 2) { if (!callbackEvent.WaitOne()) { continue; } array = buffers; foreach (WaveInBuffer waveInBuffer2 in array) { if (waveInBuffer2.Done) { if (waveInBuffer2.BytesRecorded > 0) { this.DataAvailable?.Invoke(this, new WaveInEventArgs(waveInBuffer2.Data, waveInBuffer2.BytesRecorded)); } if ((int)captureState == 2) { waveInBuffer2.Reuse(); } } } } } private void RaiseRecordingStoppedEvent(Exception e) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown EventHandler<StoppedEventArgs> handler = this.RecordingStopped; if (handler == null) { return; } if (syncContext == null) { handler(this, new StoppedEventArgs(e)); return; } syncContext.Post(delegate { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown handler(this, new StoppedEventArgs(e)); }, null); } public void StopRecording() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if ((int)captureState != 0) { captureState = (CaptureState)3; MmException.Try(WaveInterop.waveInStop(waveInHandle), "waveInStop"); MmException.Try(WaveInterop.waveInReset(waveInHandle), "waveInReset"); callbackEvent.Set(); } } public long GetPosition() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) MmTime mmTime = default(MmTime); mmTime.wType = 4u; MmException.Try(WaveInterop.waveInGetPosition(waveInHandle, out mmTime, Marshal.SizeOf(mmTime)), "waveInGetPosition"); if (mmTime.wType != 4) { throw new Exception($"waveInGetPosition: wType -> Expected {4}, Received {mmTime.wType}"); } return mmTime.cb; } protected virtual void Dispose(bool disposing) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (disposing) { if ((int)captureState != 0) { StopRecording(); } CloseWaveInDevice(); } } private void CloseWaveInDevice() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) WaveInterop.waveInReset(waveInHandle); if (buffers != null) { for (int i = 0; i < buffers.Length; i++) { buffers[i].Dispose(); } buffers = null; } WaveInterop.waveInClose(waveInHandle); waveInHandle = IntPtr.Zero; } public MixerLine GetMixerLine() { if (waveInHandle != IntPtr.Zero) { return new MixerLine(waveInHandle, 0, MixerFlags.WaveInHandle); } return new MixerLine((IntPtr)DeviceNumber, 0, MixerFlags.WaveIn); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } } public class WaveOutBuffer : IDisposable { private readonly WaveHeader header; private readonly int bufferSize; private readonly byte[] buffer; private readonly IWaveProvider waveStream; private readonly object waveOutLock; private GCHandle hBuffer; private IntPtr hWaveOut; private GCHandle hHeader; private GCHandle hThis; public bool InQueue => (header.flags & WaveHeaderFlags.InQueue) == WaveHeaderFlags.InQueue; public int BufferSize => bufferSize; public WaveOutBuffer(IntPtr hWaveOut, int bufferSize, IWaveProvider bufferFillStream, object waveOutLock) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) this.bufferSize = bufferSize; buffer = new byte[bufferSize]; hBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); this.hWaveOut = hWaveOut; waveStream = bufferFillStream; this.waveOutLock = waveOutLock; header = new WaveHeader(); hHeader = GCHandle.Alloc(header, GCHandleType.Pinned); header.dataBuffer = hBuffer.AddrOfPinnedObject(); header.bufferLength = bufferSize; header.loops = 1; hThis = GCHandle.Alloc(this); header.userData = (IntPtr)hThis; lock (waveOutLock) { MmException.Try(WaveInterop.waveOutPrepareHeader(hWaveOut, header, Marshal.SizeOf(header)), "waveOutPrepareHeader"); } } ~WaveOutBuffer() { Dispose(disposing: false); } public void Dispose() { GC.SuppressFinalize(this); Dispose(disposing: true); } protected void Dispose(bool disposing) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (hHeader.IsAllocated) { hHeader.Free(); } if (hBuffer.IsAllocated) { hBuffer.Free(); } if (hThis.IsAllocated) { hThis.Free(); } if (hWaveOut != IntPtr.Zero) { lock (waveOutLock) { WaveInterop.waveOutUnprepareHeader(hWaveOut, header, Marshal.SizeOf(header)); } hWaveOut = IntPtr.Zero; } } public bool OnDone() { int num; lock (waveStream) { num = waveStream.Read(buffer, 0, buffer.Length); } if (num == 0) { return false; } for (int i = num; i < buffer.Length; i++) { buffer[i] = 0; } WriteToWaveOut(); return true; } private void WriteToWaveOut() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) MmResult val; lock (waveOutLock) { val = WaveInterop.waveOutWrite(hWaveOut, header, Marshal.SizeOf(header)); } if ((int)val != 0) { throw new MmException(val, "waveOutWrite"); } GC.KeepAlive(this); } } public class WaveOutEvent : IWavePlayer, IDisposable, IWavePosition { private readonly object waveOutLock; private readonly SynchronizationContext syncContext; private IntPtr hWaveOut; private WaveOutBuffer[] buffers; private IWaveProvider waveStream; private volatile PlaybackState playbackState; private AutoResetEvent callbackEvent; public int DesiredLatency { get; set; } public int NumberOfBuffers { get; set; } public int DeviceNumber { get; set; } = -1; public WaveFormat OutputWaveFormat => waveStream.WaveFormat; public PlaybackState PlaybackState => playbackState; public float Volume { get { return WaveOutUtils.GetWaveOutVolume(hWaveOut, waveOutLock); } set { WaveOutUtils.SetWaveOutVolume(value, hWaveOut, waveOutLock); } } public event EventHandler<StoppedEventArgs> PlaybackStopped; public WaveOutEvent() { syncContext = SynchronizationContext.Current; if (syncContext != null && (syncContext.GetType().Name == "LegacyAspNetSynchronizationContext" || syncContext.GetType().Name == "AspNetSynchronizationContext")) { syncContext = null; } DesiredLatency = 300; NumberOfBuffers = 2; waveOutLock = new object(); } public void Init(IWaveProvider waveProvider) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if ((int)playbackState != 0) { throw new InvalidOperationException("Can't re-initialize during playback"); } if (hWaveOut != IntPtr.Zero) { DisposeBuffers(); CloseWaveOut(); } callbackEvent = new AutoResetEvent(initialState: false); waveStream = waveProvider; int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers); MmResult val; lock (waveOutLock) { val = WaveInterop.waveOutOpenWindow(out hWaveOut, (IntPtr)DeviceNumber, waveStream.WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent); } MmException.Try(val, "waveOutOpen"); buffers = new WaveOutBuffer[NumberOfBuffers]; playbackState = (PlaybackState)0; for (int i = 0; i < NumberOfBuffers; i++) { buffers[i] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock); } } public void Play() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (buffers == null || waveStream == null) { throw new InvalidOperationException("Must call Init first"); } if ((int)playbackState == 0) { playbackState = (PlaybackState)1; callbackEvent.Set(); ThreadPool.QueueUserWorkItem(delegate { PlaybackThread(); }, null); } else if ((int)playbackState == 2) { Resume(); callbackEvent.Set(); } } private void PlaybackThread() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) Exception e = null; try { DoPlayback(); } catch (Exception ex) { e = ex; } finally { playbackState = (PlaybackState)0; RaisePlaybackStoppedEvent(e); } } private void DoPlayback() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) while ((int)playbackState != 0) { if (!callbackEvent.WaitOne(DesiredLatency)) { _ = playbackState; _ = 1; } if ((int)playbackState != 1) { continue; } int num = 0; WaveOutBuffer[] array = buffers; foreach (WaveOutBuffer waveOutBuffer in array) { if (waveOutBuffer.InQueue || waveOutBuffer.OnDone()) { num++; } } if (num == 0) { playbackState = (PlaybackState)0; callbackEvent.Set(); } } } public void Pause() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if ((int)playbackState == 1) { playbackState = (PlaybackState)2; MmResult val; lock (waveOutLock) { val = WaveInterop.waveOutPause(hWaveOut); } if ((int)val != 0) { throw new MmException(val, "waveOutPause"); } } } private void Resume() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if ((int)playbackState == 2) { MmResult val; lock (waveOutLock) { val = WaveInterop.waveOutRestart(hWaveOut); } if ((int)val != 0) { throw new MmException(val, "waveOutRestart"); } playbackState = (PlaybackState)1; } } public void Stop() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if ((int)playbackState != 0) { playbackState = (PlaybackState)0; MmResult val; lock (waveOutLock) { val = WaveInterop.waveOutReset(hWaveOut); } if ((int)val != 0) { throw new MmException(val, "waveOutReset"); } callbackEvent.Set(); } } public long GetPosition() { return WaveOutUtils.GetPositionBytes(hWaveOut, waveOutLock); } public void Dispose() { GC.SuppressFinalize(this); Dispose(disposing: true); } protected void Dispose(bool disposing) { Stop(); if (disposing) { DisposeBuffers(); } CloseWaveOut(); } private void CloseWaveOut() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (callbackEvent != null) { callbackEvent.Close(); callbackEvent = null; } lock (waveOutLock) { if (hWaveOut != IntPtr.Zero) { WaveInterop.waveOutClose(hWaveOut); hWaveOut = IntPtr.Zero; } } } private void DisposeBuffers() { if (buffers != null) { WaveOutBuffer[] array = buffers; for (int i = 0; i < array.Length; i++) { array[i].Dispose(); } buffers = null; } } ~WaveOutEvent() { Dispose(disposing: false); } private void RaisePlaybackStoppedEvent(Exception e) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown EventHandler<StoppedEventArgs> handler = this.PlaybackStopped; if (handler == null) { return; } if (syncContext == null) { handler(this, new StoppedEventArgs(e)); return; } syncContext.Post(delegate { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown handler(this, new StoppedEventArgs(e)); }, null); } } public static class WaveOutUtils { public static float GetWaveOutVolume(IntPtr hWaveOut, object lockObject) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) MmResult val; int dwVolume; lock (lockObject) { val = WaveInterop.waveOutGetVolume(hWaveOut, out dwVolume); } MmException.Try(val, "waveOutGetVolume"); return (float)(dwVolume & 0xFFFF) / 65535f; } public static void SetWaveOutVolume(float value, IntPtr hWaveOut, object lockObject) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (value < 0f) { throw new ArgumentOutOfRangeException("value", "Volume must be between 0.0 and 1.0"); } if (value > 1f) { throw new ArgumentOutOfRangeException("value", "Volume must be between 0.0 and 1.0"); } int dwVolume = (int)(value * 65535f) + ((int)(value * 65535f) << 16); MmResult val; lock (lockObject) { val = WaveInterop.waveOutSetVolume(hWaveOut, dwVolume); } MmException.Try(val, "waveOutSetVolume"); } public static long GetPositionBytes(IntPtr hWaveOut, object lockObject) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) lock (lockObject) { MmTime mmTime = default(MmTime); mmTime.wType = 4u; MmException.Try(WaveInterop.waveOutGetPosition(hWaveOut, ref mmTime, Marshal.SizeOf(mmTime)), "waveOutGetPosition"); if (mmTime.wType != 4) { throw new Exception($"waveOutGetPosition: wType -> Expected {4}, Received {mmTime.wType}"); } return mmTime.cb; } } } } namespace NAudio.Wave.Compression { public class AcmDriver : IDisposable { private static List<AcmDriver> drivers; private AcmDriverDetails details; private IntPtr driverId; private IntPtr driverHandle; private List<AcmFormatTag> formatTags; private List<AcmFormat> tempFormatsList; private IntPtr localDllHandle; public int MaxFormatSize { get { //IL_000a: Unknown result type (might be due to invalid IL or missing references) MmException.Try(AcmInterop.acmMetrics(driverHandle, AcmMetrics.MaxSizeFormat, out var output), "acmMetrics"); return output; } } public string ShortName => details.shortName; public string LongName => details.longName; public IntPtr DriverId => driverId; public IEnumerable<AcmFormatTag> FormatTags { get { //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (formatTags == null) { if (driverHandle == IntPtr.Zero) { throw new InvalidOperationException("Driver must be opened first"); } formatTags = new List<AcmFormatTag>(); AcmFormatTagDetails formatTagDetails = default(AcmFormatTagDetails); formatTagDetails.structureSize = Marshal.SizeOf(formatTagDetails); MmException.Try(AcmInterop.acmFormatTagEnum(driverHandle, ref formatTagDetails, AcmFormatTagEnumCallback, IntPtr.Zero, 0), "acmFormatTagEnum"); } return formatTags; } } public static bool IsCodecInstalled(string shortName) { foreach (AcmDriver item in EnumerateAcmDrivers()) { if (item.ShortName == shortName) { return true; } } return false; } public static AcmDriver AddLocalDriver(string driverFile) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) IntPtr intPtr = NativeMethods.LoadLibrary(driverFile); if (intPtr == IntPtr.Zero) { throw new ArgumentException("Failed to load driver file"); } IntPtr procAddress = NativeMethods.GetProcAddress(intPtr, "DriverProc"); if (procAddress == IntPtr.Zero) { NativeMethods.FreeLibrary(intPtr); throw new ArgumentException("Failed to discover DriverProc"); } IntPtr hAcmDriver; MmResult val = AcmInterop.acmDriverAdd(out hAcmDriver, intPtr, procAddress, 0, AcmDriverAddFlags.Function); if ((int)val != 0) { NativeMethods.FreeLibrary(intPtr); throw new MmException(val, "acmDriverAdd"); } AcmDriver acmDriver = new AcmDriver(hAcmDriver); if (string.IsNullOrEmpty(acmDriver.details.longName)) { acmDriver.details.longName = "Local driver: " + Path.GetFileName(driverFile); acmDriver.localDllHandle = intPtr; } return acmDriver; } public static void RemoveLocalDriver(AcmDriver localDriver) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (localDriver.localDllHandle == IntPtr.Zero) { throw new ArgumentException("Please pass in the AcmDriver returned by the AddLocalDriver method"); } MmResult val = AcmInterop.acmDriverRemove(localDriver.driverId, 0); NativeMethods.FreeLibrary(localDriver.localDllHandle); MmException.Try(val, "acmDriverRemove"); } public static bool ShowFormatChooseDialog(IntPtr ownerWindowHandle, string windowTitle, AcmFormatEnumFlags enumFlags, WaveFormat enumFormat, out WaveFormat selectedFormat, out string selectedFormatDescription, out string selectedFormatTagDescription) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Invalid comparison between Unknown and I4 //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Invalid comparison between Unknown and I4 //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) AcmFormatChoose formatChoose = default(AcmFormatChoose); formatChoose.structureSize = Marshal.SizeOf(formatChoose); formatChoose.styleFlags = AcmFormatChooseStyleFlags.None; formatChoose.ownerWindowHandle = ownerWindowHandle; int num = 200; formatChoose.selectedWaveFormatPointer = Marshal.AllocHGlobal(num); formatChoose.selectedWaveFormatByteSize = num; formatChoose.title = windowTitle; formatChoose.name = null; formatChoose.formatEnumFlags = enumFlags; formatChoose.waveFormatEnumPointer = IntPtr.Zero; if (enumFormat != null) { IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf<WaveFormat>(enumFormat)); Marshal.StructureToPtr<WaveFormat>(enumFormat, intPtr, fDeleteOld: false); formatChoose.waveFormatEnumPointer = intPtr; } formatChoose.instanceHandle = IntPtr.Zero; formatChoose.templateName = null; MmResult val = AcmInterop.acmFormatChoose(ref formatChoose); selectedFormat = null; selectedFormatDescription = null; selectedFormatTagDescription = null; if ((int)val == 0) { selectedFormat = WaveFormat.MarshalFromPtr(formatChoose.selectedWaveFormatPointer); selectedFormatDescription = formatChoose.formatDescription; selectedFormatTagDescription = formatChoose.formatTagDescription; } Marshal.FreeHGlobal(formatChoose.waveFormatEnumPointer); Marshal.FreeHGlobal(formatChoose.selectedWaveFormatPointer); if ((int)val != 515 && (int)val != 0) { throw new MmException(val, "acmFormatChoose"); } return (int)val == 0; } public static AcmDriver FindByShortName(string shortName) { foreach (AcmDriver item in EnumerateAcmDrivers()) { if (item.ShortName == shortName) { return item; } } return null; } public static IEnumerable<AcmDriver> EnumerateAcmDrivers() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) drivers = new List<AcmDriver>(); MmException.Try(AcmInterop.acmDriverEnum(DriverEnumCallback, IntPtr.Zero, (AcmDriverEnumFlags)0), "acmDriverEnum"); return drivers; } private static bool DriverEnumCallback(IntPtr hAcmDriver, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags) { drivers.Add(new AcmDriver(hAcmDriver)); return true; } private AcmDriver(IntPtr hAcmDriver) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) driverId = hAcmDriver; details = default(AcmDriverDetails); details.structureSize = Marshal.SizeOf(details); MmException.Try(AcmInterop.acmDriverDetails(hAcmDriver, ref details, 0), "acmDriverDetails"); } public override string ToString() { return LongName; } public IEnumerable<AcmFormat> GetFormats(AcmFormatTag formatTag) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected I4, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) if (driverHandle == IntPtr.Zero) { throw new InvalidOperationException("Driver must be opened first"); } tempFormatsList = new List<AcmFormat>(); AcmFormatDetails formatDetails = default(AcmFormatDetails); formatDetails.structSize = Marshal.SizeOf(formatDetails); formatDetails.waveFormatByteSize = 1024; formatDetails.waveFormatPointer = Marshal.AllocHGlobal(formatDetails.waveFormatByteSize); formatDetails.formatTag = (int)formatTag.FormatTag; MmResult val = AcmInterop.acmFormatEnum(driverHandle, ref formatDetails, AcmFormatEnumCallback, IntPtr.Zero, AcmFormatEnumFlags.None); Marshal.FreeHGlobal(formatDetails.waveFormatPointer); MmException.Try(val, "acmFormatEnum"); return tempFormatsList; } public void Open() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (driverHandle == IntPtr.Zero) { MmException.Try(AcmInterop.acmDriverOpen(out driverHandle, DriverId, 0), "acmDriverOpen"); } } public void Close() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (driverHandle != IntPtr.Zero) { MmException.Try(AcmInterop.acmDriverClose(driverHandle, 0), "acmDriverClose"); driverHandle = IntPtr.Zero; } } private bool AcmFormatTagEnumCallback(IntPtr hAcmDriverId, ref AcmFormatTagDetails formatTagDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags) { formatTags.Add(new AcmFormatTag(formatTagDetails)); return true; } private bool AcmFormatEnumCallback(IntPtr hAcmDriverId, ref AcmFormatDetails formatDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags) { tempFormatsList.Add(new AcmFormat(formatDetails)); return true; } public void Dispose() { if (driverHandle != IntPtr.Zero) { Close(); GC.SuppressFinalize(this); } } } internal enum AcmDriverAddFlags { Local = 0, Global = 8, Function = 3, NotifyWindowHandle = 4 } [StructLayout(LayoutKind.Sequential, Pack = 2)] internal struct AcmDriverDetails { public int structureSize; public uint fccType; public uint fccComp; public ushort manufacturerId; public ushort productId; public uint acmVersion; public uint driverVersion; public AcmDriverDetailsSupportFlags supportFlags; public int formatTagsCount; public int filterTagsCount; public IntPtr hicon; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string shortName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string longName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string copyright; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string licensing; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)] public string features; private const int ShortNameChars = 32; private const int LongNameChars = 128; private const int CopyrightChars = 80; private const int LicensingChars = 128; private const int FeaturesChars = 512; } [Flags] public enum AcmDriverDetailsSupportFlags { Codec = 1, Converter = 2, Filter = 4, Hardware = 8, Async = 0x10, Local = 0x40000000, Disabled = int.MinValue } [Flags] internal enum AcmDriverEnumFlags { NoLocal = 0x40000000, Disabled = int.MinValue } public class AcmFormat { private readonly AcmFormatDetails formatDetails; public int FormatIndex => formatDetails.formatIndex; public WaveFormatEncoding FormatTag => (WaveFormatEncoding)(ushort)formatDetails.formatTag; public AcmDriverDetailsSupportFlags SupportFlags => formatDetails.supportFlags; public WaveFormat WaveFormat { get; private set; } public int WaveFormatByteSize => formatDetails.waveFormatByteSize; public string FormatDescription => formatDetails.formatDescription; internal AcmFormat(AcmFormatDetails formatDetails) { this.formatDetails = formatDetails; WaveFormat = WaveFormat.MarshalFromPtr(formatDetails.waveFormatPointer); } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)] internal struct AcmFormatChoose { public int structureSize; public AcmFormatChooseStyleFlags styleFlags; public IntPtr ownerWindowHandle; public IntPtr selectedWaveFormatPointer; public int selectedWaveFormatByteSize; [MarshalAs(UnmanagedType.LPTStr)] public string title; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)] public string formatTagDescription; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string formatDescription; [MarshalAs(UnmanagedType.LPTStr)] public string name; public int nameByteSize; public AcmFormatEnumFlags formatEnumFlags; public IntPtr waveFormatEnumPointer; public IntPtr instanceHandle; [MarshalAs(UnmanagedType.LPTStr)] public string templateName; public IntPtr customData; public AcmInterop.AcmFormatChooseHookProc windowCallbackFunction; } [Flags] internal enum AcmFormatChooseStyleFlags { None = 0, ShowHelp = 4, EnableHook = 8, EnableTemplate = 0x10, EnableTemplateHandle = 0x20, InitToWfxStruct = 0x40, ContextHelp = 0x80 } [StructLayout(LayoutKind.Sequential, Pack = 4)] internal struct AcmFormatDetails { public int structSize; public int formatIndex; public int formatTag; public AcmDriverDetailsSupportFlags supportFlags; public IntPtr waveFormatPointer; public int waveFormatByteSize; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string formatDescription; public const int FormatDescriptionChars = 128; } [Flags] public enum AcmFormatEnumFlags { None = 0, Convert = 0x100000, Hardware = 0x400000, Input = 0x800000, Channels = 0x20000, SamplesPerSecond = 0x40000, Output = 0x1000000, Suggest = 0x200000, BitsPerSample = 0x80000, FormatTag = 0x10000 } [Flags] internal enum AcmFormatSuggestFlags { FormatTag = 0x10000, Channels = 0x20000, SamplesPerSecond = 0x40000, BitsPerSample = 0x80000, TypeMask = 0xFF0000 } public class AcmFormatTag { private AcmFormatTagDetails formatTagDetails; public int FormatTagIndex => formatTagDetails.formatTagIndex; public WaveFormatEncoding FormatTag => (WaveFormatEncoding)(ushort)formatTagDetails.formatTag; public int FormatSize => formatTagDetails.formatSize; public AcmDriverDetailsSupportFlags SupportFlags => formatTagDetails.supportFlags; public int StandardFormatsCount => formatTagDetails.standardFormatsCount; public string FormatDescription => formatTagDetails.formatDescription; internal AcmFormatTag(AcmFormatTagDetails formatTagDetails) { this.formatTagDetails = formatTagDetails; } } internal struct AcmFormatTagDetails { public int structureSize; public int formatTagIndex; public int formatTag; public int formatSize; public AcmDriverDetailsSupportFlags supportFlags; public int standardFormatsCount; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)] public string formatDescription; public const int FormatTagDescriptionChars = 48; } internal class AcmInterop { public delegate bool AcmDriverEnumCallback(IntPtr hAcmDriverId, IntPtr instance, AcmDriverDetailsSupportFlags flags); public delegate bool AcmFormatEnumCallback(IntPtr hAcmDriverId, ref AcmFormatDetails formatDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags); public delegate bool AcmFormatTagEnumCallback(IntPtr hAcmDriverId, ref AcmFormatTagDetails formatTagDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags); public delegate bool AcmFormatChooseHookProc(IntPtr windowHandle, int message, IntPtr wParam, IntPtr lParam); [DllImport("msacm32.dll")] public static extern MmResult acmDriverAdd(out IntPtr driverHandle, IntPtr driverModule, IntPtr driverFunctionAddress, int priority, AcmDriverAddFlags flags); [DllImport("msacm32.dll")] public static extern MmResult acmDriverRemove(IntPtr driverHandle, int removeFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmDriverClose(IntPtr hAcmDriver, int closeFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmDriverEnum(AcmDriverEnumCallback fnCallback, IntPtr dwInstance, AcmDriverEnumFlags flags); [DllImport("Msacm32.dll")] public static extern MmResult acmDriverDetails(IntPtr hAcmDriver, ref AcmDriverDetails driverDetails, int reserved); [DllImport("Msacm32.dll")] public static extern MmResult acmDriverOpen(out IntPtr pAcmDriver, IntPtr hAcmDriverId, int openFlags); [DllImport("Msacm32.dll", EntryPoint = "acmFormatChooseW")] public static extern MmResult acmFormatChoose(ref AcmFormatChoose formatChoose); [DllImport("Msacm32.dll")] public static extern MmResult acmFormatEnum(IntPtr hAcmDriver, ref AcmFormatDetails formatDetails, AcmFormatEnumCallback callback, IntPtr instance, AcmFormatEnumFlags flags); [DllImport("Msacm32.dll", EntryPoint = "acmFormatSuggest")] public static extern MmResult acmFormatSuggest2(IntPtr hAcmDriver, IntPtr sourceFormatPointer, IntPtr destFormatPointer, int sizeDestFormat, AcmFormatSuggestFlags suggestFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmFormatTagEnum(IntPtr hAcmDriver, ref AcmFormatTagDetails formatTagDetails, AcmFormatTagEnumCallback callback, IntPtr instance, int reserved); [DllImport("Msacm32.dll")] public static extern MmResult acmMetrics(IntPtr hAcmObject, AcmMetrics metric, out int output); [DllImport("Msacm32.dll", EntryPoint = "acmStreamOpen")] public static extern MmResult acmStreamOpen2(out IntPtr hAcmStream, IntPtr hAcmDriver, IntPtr sourceFormatPointer, IntPtr destFormatPointer, [In] WaveFilter waveFilter, IntPtr callback, IntPtr instance, AcmStreamOpenFlags openFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmStreamClose(IntPtr hAcmStream, int closeFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmStreamConvert(IntPtr hAcmStream, [In][Out] AcmStreamHeaderStruct streamHeader, AcmStreamConvertFlags streamConvertFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmStreamPrepareHeader(IntPtr hAcmStream, [In][Out] AcmStreamHeaderStruct streamHeader, int prepareFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmStreamReset(IntPtr hAcmStream, int resetFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmStreamSize(IntPtr hAcmStream, int inputBufferSize, out int outputBufferSize, AcmStreamSizeFlags flags); [DllImport("Msacm32.dll")] public static extern MmResult acmStreamUnprepareHeader(IntPtr hAcmStream, [In][Out] AcmStreamHeaderStruct streamHeader, int flags); } public class AcmStream : IDisposable { private IntPtr streamHandle; private IntPtr driverHandle; private AcmStreamHeader streamHeader; private readonly WaveFormat sourceFormat; public byte[] SourceBuffer => streamHeader.SourceBuffer; public byte[] DestBuffer => streamHeader.DestBuffer; public AcmStream(WaveFormat sourceFormat, WaveFormat destFormat) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) try { streamHandle = IntPtr.Zero; this.sourceFormat = sourceFormat; int num = Math.Max(65536, sourceFormat.AverageBytesPerSecond); num -= num % sourceFormat.BlockAlign; IntPtr intPtr = WaveFormat.MarshalToPtr(sourceFormat); IntPtr intPtr2 = WaveFormat.MarshalToPtr(destFormat); try { MmException.Try(AcmInterop.acmStreamOpen2(out streamHandle, IntPtr.Zero, intPtr, intPtr2, null, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.NonRealTime), "acmStreamOpen"); } finally { Marshal.FreeHGlobal(intPtr); Marshal.FreeHGlobal(intPtr2); } int destBufferLength = SourceToDest(num); streamHeader = new AcmStreamHeader(streamHandle, num, destBufferLength); driverHandle = IntPtr.Zero; } catch { Dispose(); throw; } } public AcmStream(IntPtr driverId, WaveFormat sourceFormat, WaveFilter waveFilter) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) int num = Math.Max(16384, sourceFormat.AverageBytesPerSecond); this.sourceFormat = sourceFormat; num -= num % sourceFormat.BlockAlign; MmException.Try(AcmInterop.acmDriverOpen(out driverHandle, driverId, 0), "acmDriverOpen"); IntPtr intPtr = WaveFormat.MarshalToPtr(sourceFormat); try { MmException.Try(AcmInterop.acmStreamOpen2(out streamHandle, driverHandle, intPtr, intPtr, waveFilter, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.NonRealTime), "acmStreamOpen"); } finally { Marshal.FreeHGlobal(intPtr); } streamHeader = new AcmStreamHeader(streamHandle, num, SourceToDest(num)); } public int SourceToDest(int source) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (source == 0) { return 0; } MmException.Try(AcmInterop.acmStreamSize(streamHandle, source, out var outputBufferSize, AcmStreamSizeFlags.Source), "acmStreamSize"); return outputBufferSize; } public int DestToSource(int dest) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (dest == 0) { return 0; } MmException.Try(AcmInterop.acmStreamSize(streamHandle, dest, out var outputBufferSize, AcmStreamSizeFlags.Destination), "acmStreamSize"); return outputBufferSize; } public static WaveFormat SuggestPcmFormat(WaveFormat compressedFormat) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) WaveFormat val = new WaveFormat(compressedFormat.SampleRate, 16, compressedFormat.Channels); IntPtr intPtr = WaveFormat.MarshalToPtr(val); IntPtr intPtr2 = WaveFormat.MarshalToPtr(compressedFormat); try { MmResult val2 = AcmInterop.acmFormatSuggest2(IntPtr.Zero, intPtr2, intPtr, Marshal.SizeOf<WaveFormat>(val), AcmFormatSuggestFlags.FormatTag); val = WaveFormat.MarshalFromPtr(intPtr); MmException.Try(val2, "acmFormatSuggest"); return val; } finally { Marshal.FreeHGlobal(intPtr); Marshal.FreeHGlobal(intPtr2); } } public void Reposition() { streamHeader.Reposition(); } public int Convert(int bytesToConvert, out int sourceBytesConverted) { if (bytesToConvert % sourceFormat.BlockAlign != 0) { bytesToConvert -= bytesToConvert % sourceFormat.BlockAlign; } return streamHeader.Convert(bytesToConvert, out sourceBytesConverted); } [Obsolete("Call the version returning sourceBytesConverted instead")] public int Convert(int bytesToConvert) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) int sourceBytesConverted; int result = Convert(bytesToConvert, out sourceBytesConverted); if (sourceBytesConverted != bytesToConvert) { throw new MmException((MmResult)8, "AcmStreamHeader.Convert didn't convert everything"); } return result; } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (disposing && streamHeader != null) { streamHeader.Dispose(); streamHeader = null; } if (streamHandle != IntPtr.Zero) { MmResult val = AcmInterop.acmStreamClose(streamHandle, 0); streamHandle = IntPtr.Zero; if ((int)val != 0) { throw new MmException(val, "acmStreamClose"); } } if (driverHandle != IntPtr.Zero) { AcmInterop.acmDriverClose(driverHandle, 0); driverHandle = IntPtr.Zero; } } ~AcmStream() { Dispose(disposing: false); } } internal class AcmStreamHeader : IDisposable { private AcmStreamHeaderStruct streamHeader; private GCHandle hSourceBuffer; private GCHandle hDestBuffer; private IntPtr streamHandle; private bool firstTime; private bool disposed; public byte[] SourceBuffer { get; private set; } public byte[] DestBuffer { get; private set; } public AcmStreamHeader(IntPtr streamHandle, int sourceBufferLength, int destBufferLength) { streamHeader = new AcmStreamHeaderStruct(); SourceBuffer = new byte[sourceBufferLength]; hSourceBuffer = GCHandle.Alloc(SourceBuffer, GCHandleType.Pinned); DestBuffer = new byte[destBufferLength]; hDestBuffer = GCHandle.Alloc(DestBuffer, GCHandleType.Pinned); this.streamHandle = streamHandle; firstTime = true; } private void Prepare() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) streamHeader.cbStruct = Marshal.SizeOf(streamHeader); streamHeader.sourceBufferLength = SourceBuffer.Length; streamHeader.sourceBufferPointer = hSourceBuffer.AddrOfPinnedObject(); streamHeader.destBufferLength = DestBuffer.Length; streamHeader.destBufferPointer = hDestBuffer.AddrOfPinnedObject(); MmException.Try(AcmInterop.acmStreamPrepareHeader(streamHandle, streamHeader, 0), "acmStreamPrepareHeader"); } private void Unprepare() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) streamHeader.sourceBufferLength = SourceBuffer.Length; streamHeader.sourceBufferPointer = hSourceBuffer.AddrOfPinnedObject(); streamHeader.destBufferLength = DestBuffer.Length; streamHeader.destBufferPointer = hDestBuffer.AddrOfPinnedObject(); MmResult val = AcmInterop.acmStreamUnprepareHeader(streamHandle, streamHeader, 0); if ((int)val != 0) { throw new MmException(val, "acmStreamUnprepareHeader"); } } public void Reposition() { firstTime = true; } public int Convert(int bytesToConvert, out int sourceBytesConverted) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) Prepare(); try { streamHeader.sourceBufferLength = bytesToConvert; streamHeader.sourceBufferLengthUsed = bytesToConvert; AcmStreamConvertFlags streamConvertFlags = (firstTime ? (AcmStreamConvertFlags.BlockAlign | AcmStreamConvertFlags.Start) : AcmStreamConvertFlags.BlockAlign); MmException.Try(AcmInterop.acmStreamConvert(streamHandle, streamHeader, streamConvertFlags), "acmStreamConvert"); firstTime = false; sourceBytesConverted = streamHeader.sourceBufferLengthUsed; } finally { Unprepare(); } return streamHeader.destBufferLengthUsed; } public void Dispose() { GC.SuppressFinalize(this); Dispose(disposing: true); } protected virtual void Dispose(bool disposing) { if (!disposed) { SourceBuffer = null; DestBuffer = null; hSourceBuffer.Free(); hDestBuffer.Free(); } disposed = true; } ~AcmStreamHeader() { Dispose(disposing: false); } } [Flags] internal enum AcmStreamHeaderStatusFlags { Done = 0x10000, Prepared = 0x20000, InQueue = 0x100000 } [StructLayout(LayoutKind.Sequential, Size = 128)] internal class AcmStreamHeaderStruct { public int cbStruct; public AcmStreamHeaderStatusFlags fdwStatus; public IntPtr userData; public IntPtr sourceBufferPointer; public int sourceBufferLength; public int sourceBufferLengthUsed; public IntPtr sourceUserData; public IntPtr destBufferPointer; public int destBufferLength; public int destBufferLengthUsed; public IntPtr destUserData; } [Flags] internal enum AcmStreamOpenFlags { Query = 1, Async = 2, NonRealTime = 4, CallbackTypeMask = 0x70000, CallbackNull = 0, CallbackWindow = 0x10000, CallbackTask = 0x20000, CallbackFunction = 0x30000, CallbackThread = 0x20000, CallbackEvent = 0x50000 } internal enum AcmStreamSizeFlags { Source, Destination } [StructLayout(LayoutKind.Sequential)] public class WaveFilter { public int StructureSize = Marshal.SizeOf(typeof(WaveFilter)); public int FilterTag; public int Filter; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public int[] Reserved; } }
plugins/NVorbis.dll
Decompiled a month ago
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.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using NVorbis.Contracts; using NVorbis.Contracts.Ogg; using NVorbis.Ogg; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] [assembly: AssemblyCompany("Andrew Ward")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © Andrew Ward 2021")] [assembly: AssemblyDescription("A fully managed implementation of a Xiph.org Foundation Ogg Vorbis decoder.")] [assembly: AssemblyFileVersion("0.10.5.0")] [assembly: AssemblyInformationalVersion("0.10.5")] [assembly: AssemblyProduct("NVorbis")] [assembly: AssemblyTitle("NVorbis")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/NVorbis/NVorbis")] [assembly: NeutralResourcesLanguage("en")] [assembly: AssemblyVersion("0.10.5.0")] namespace NVorbis { internal class Codebook : ICodebook { private class FastRange : IReadOnlyList<int>, IReadOnlyCollection<int>, IEnumerable<int>, IEnumerable { [ThreadStatic] private static FastRange _cachedRange; private int _start; private int _count; public int this[int index] { get { if (index > _count) { throw new ArgumentOutOfRangeException(); } return _start + index; } } public int Count => _count; internal static FastRange Get(int start, int count) { FastRange obj = _cachedRange ?? (_cachedRange = new FastRange()); obj._start = start; obj._count = count; return obj; } private FastRange() { } public IEnumerator<int> GetEnumerator() { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } private int[] _lengths; private float[] _lookupTable; private IReadOnlyList<HuffmanListNode> _overflowList; private IReadOnlyList<HuffmanListNode> _prefixList; private int _prefixBitLength; private int _maxBits; public float this[int entry, int dim] => _lookupTable[entry * Dimensions + dim]; public int Dimensions { get; private set; } public int Entries { get; private set; } public int MapType { get; private set; } public void Init(IPacket packet, IHuffman huffman) { if (packet.ReadBits(24) != 5653314) { throw new InvalidDataException("Book header had invalid signature!"); } Dimensions = (int)packet.ReadBits(16); Entries = (int)packet.ReadBits(24); _lengths = new int[Entries]; InitTree(packet, huffman); InitLookupTable(packet); } private void InitTree(IPacket packet, IHuffman huffman) { int num = 0; bool flag; int num5; if (packet.ReadBit()) { int num2 = (int)packet.ReadBits(5) + 1; int num3 = 0; while (num3 < Entries) { int num4 = (int)packet.ReadBits(Utils.ilog(Entries - num3)); while (--num4 >= 0) { _lengths[num3++] = num2; } num2++; } num = 0; flag = false; num5 = num2; } else { num5 = -1; flag = packet.ReadBit(); for (int i = 0; i < Entries; i++) { if (!flag || packet.ReadBit()) { _lengths[i] = (int)packet.ReadBits(5) + 1; num++; } else { _lengths[i] = -1; } if (_lengths[i] > num5) { num5 = _lengths[i]; } } } if ((_maxBits = num5) > -1) { int[] array = null; if (flag && num >= Entries >> 2) { array = new int[Entries]; Array.Copy(_lengths, array, Entries); flag = false; } int num6 = (flag ? num : 0); int[] array2 = null; int[] array3 = null; if (!flag) { array3 = new int[Entries]; } else if (num6 != 0) { array = new int[num6]; array3 = new int[num6]; array2 = new int[num6]; } if (!ComputeCodewords(flag, array3, array, _lengths, Entries, array2)) { throw new InvalidDataException(); } IReadOnlyList<int> readOnlyList = array2; IReadOnlyList<int> value = readOnlyList ?? FastRange.Get(0, array3.Length); huffman.GenerateTable(value, array ?? _lengths, array3); _prefixList = huffman.PrefixTree; _prefixBitLength = huffman.TableBits; _overflowList = huffman.OverflowList; } } private bool ComputeCodewords(bool sparse, int[] codewords, int[] codewordLengths, int[] len, int n, int[] values) { int num = 0; uint[] array = new uint[32]; int i; for (i = 0; i < n && len[i] <= 0; i++) { } if (i == n) { return true; } AddEntry(sparse, codewords, codewordLengths, 0u, i, num++, len[i], values); for (int j = 1; j <= len[i]; j++) { array[j] = (uint)(1 << 32 - j); } for (int j = i + 1; j < n; j++) { int num2 = len[j]; if (num2 <= 0) { continue; } while (num2 > 0 && array[num2] == 0) { num2--; } if (num2 == 0) { return false; } uint num3 = array[num2]; array[num2] = 0u; AddEntry(sparse, codewords, codewordLengths, Utils.BitReverse(num3), j, num++, len[j], values); if (num2 != len[j]) { for (int num4 = len[j]; num4 > num2; num4--) { array[num4] = num3 + (uint)(1 << 32 - num4); } } } return true; } private void AddEntry(bool sparse, int[] codewords, int[] codewordLengths, uint huffCode, int symbol, int count, int len, int[] values) { if (sparse) { codewords[count] = (int)huffCode; codewordLengths[count] = len; values[count] = symbol; } else { codewords[symbol] = (int)huffCode; } } private void InitLookupTable(IPacket packet) { MapType = (int)packet.ReadBits(4); if (MapType == 0) { return; } float num = Utils.ConvertFromVorbisFloat32((uint)packet.ReadBits(32)); float num2 = Utils.ConvertFromVorbisFloat32((uint)packet.ReadBits(32)); int count = (int)packet.ReadBits(4) + 1; bool flag = packet.ReadBit(); int num3 = Entries * Dimensions; float[] array = new float[num3]; if (MapType == 1) { num3 = lookup1_values(); } uint[] array2 = new uint[num3]; for (int i = 0; i < num3; i++) { array2[i] = (uint)packet.ReadBits(count); } if (MapType == 1) { for (int j = 0; j < Entries; j++) { double num4 = 0.0; int num5 = 1; for (int k = 0; k < Dimensions; k++) { int num6 = j / num5 % num3; double num7 = (double)((float)array2[num6] * num2 + num) + num4; array[j * Dimensions + k] = (float)num7; if (flag) { num4 = num7; } num5 *= num3; } } } else { for (int l = 0; l < Entries; l++) { double num8 = 0.0; int num9 = l * Dimensions; for (int m = 0; m < Dimensions; m++) { double num10 = (double)((float)array2[num9] * num2 + num) + num8; array[l * Dimensions + m] = (float)num10; if (flag) { num8 = num10; } num9++; } } } _lookupTable = array; } private int lookup1_values() { int num = (int)Math.Floor(Math.Exp(Math.Log(Entries) / (double)Dimensions)); if (Math.Floor(Math.Pow(num + 1, Dimensions)) <= (double)Entries) { num++; } return num; } public int DecodeScalar(IPacket packet) { int index = (int)packet.TryPeekBits(_prefixBitLength, out var bitsRead); if (bitsRead == 0) { return -1; } HuffmanListNode huffmanListNode = _prefixList[index]; if (huffmanListNode != null) { packet.SkipBits(huffmanListNode.Length); return huffmanListNode.Value; } index = (int)packet.TryPeekBits(_maxBits, out var _); for (int i = 0; i < _overflowList.Count; i++) { huffmanListNode = _overflowList[i]; if (huffmanListNode.Bits == (index & huffmanListNode.Mask)) { packet.SkipBits(huffmanListNode.Length); return huffmanListNode.Value; } } return -1; } } public abstract class DataPacket : IPacket { [Flags] protected enum PacketFlags : byte { IsResync = 1, IsEndOfStream = 2, IsShort = 4, User0 = 8, User1 = 0x10, User2 = 0x20, User3 = 0x40, User4 = 0x80 } private ulong _bitBucket; private int _bitCount; private byte _overflowBits; private PacketFlags _packetFlags; private int _readBits; public int ContainerOverheadBits { get; set; } public long? GranulePosition { get; set; } public bool IsResync { get { return GetFlag(PacketFlags.IsResync); } set { SetFlag(PacketFlags.IsResync, value); } } public bool IsShort { get { return GetFlag(PacketFlags.IsShort); } private set { SetFlag(PacketFlags.IsShort, value); } } public bool IsEndOfStream { get { return GetFlag(PacketFlags.IsEndOfStream); } set { SetFlag(PacketFlags.IsEndOfStream, value); } } public int BitsRead => _readBits; public int BitsRemaining => TotalBits - _readBits; protected abstract int TotalBits { get; } private bool GetFlag(PacketFlags flag) { return _packetFlags.HasFlag(flag); } private void SetFlag(PacketFlags flag, bool value) { if (value) { _packetFlags |= flag; } else { _packetFlags &= (PacketFlags)(byte)(~(int)flag); } } protected abstract int ReadNextByte(); public virtual void Done() { } public virtual void Reset() { _bitBucket = 0uL; _bitCount = 0; _overflowBits = 0; _readBits = 0; } ulong IPacket.ReadBits(int count) { if (count == 0) { return 0uL; } int bitsRead; ulong result = TryPeekBits(count, out bitsRead); SkipBits(count); return result; } public ulong TryPeekBits(int count, out int bitsRead) { switch (count) { default: throw new ArgumentOutOfRangeException("count"); case 0: bitsRead = 0; return 0uL; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59: case 60: case 61: case 62: case 63: case 64: break; } while (_bitCount < count) { int num = ReadNextByte(); if (num == -1) { bitsRead = _bitCount; return _bitBucket; } _bitBucket = (ulong)((long)(num & 0xFF) << _bitCount) | _bitBucket; _bitCount += 8; if (_bitCount > 64) { _overflowBits = (byte)(num >> 72 - _bitCount); } } ulong num2 = _bitBucket; if (count < 64) { num2 &= (ulong)((1L << count) - 1); } bitsRead = count; return num2; } public void SkipBits(int count) { if (count <= 0) { return; } if (_bitCount > count) { if (count > 63) { _bitBucket = 0uL; } else { _bitBucket >>= count; } if (_bitCount > 64) { int num = _bitCount - 64; _bitBucket |= (ulong)_overflowBits << _bitCount - count - num; if (num > count) { _overflowBits = (byte)(_overflowBits >> count); } } _bitCount -= count; _readBits += count; return; } if (_bitCount == count) { _bitBucket = 0uL; _bitCount = 0; _readBits += count; return; } count -= _bitCount; _readBits += _bitCount; _bitCount = 0; _bitBucket = 0uL; while (count > 8) { if (ReadNextByte() == -1) { count = 0; IsShort = true; break; } count -= 8; _readBits += 8; } if (count > 0) { int num2 = ReadNextByte(); if (num2 == -1) { IsShort = true; return; } _bitBucket = (ulong)(num2 >> count); _bitCount = 8 - count; _readBits += count; } } } public static class Extensions { public static int Read(this IPacket packet, byte[] buffer, int index, int count) { if (index < 0 || index >= buffer.Length) { throw new ArgumentOutOfRangeException("index"); } if (count < 0 || index + count > buffer.Length) { throw new ArgumentOutOfRangeException("count"); } for (int i = 0; i < count; i++) { int bitsRead; byte b = (byte)packet.TryPeekBits(8, out bitsRead); if (bitsRead == 0) { return i; } buffer[index++] = b; packet.SkipBits(8); } return count; } public static byte[] ReadBytes(this IPacket packet, int count) { byte[] array = new byte[count]; int num = packet.Read(array, 0, count); if (num < count) { byte[] array2 = new byte[num]; Buffer.BlockCopy(array, 0, array2, 0, num); return array2; } return array; } public static bool ReadBit(this IPacket packet) { return packet.ReadBits(1) == 1; } public static byte PeekByte(this IPacket packet) { int bitsRead; return (byte)packet.TryPeekBits(8, out bitsRead); } public static byte ReadByte(this IPacket packet) { return (byte)packet.ReadBits(8); } public static short ReadInt16(this IPacket packet) { return (short)packet.ReadBits(16); } public static int ReadInt32(this IPacket packet) { return (int)packet.ReadBits(32); } public static long ReadInt64(this IPacket packet) { return (long)packet.ReadBits(64); } public static ushort ReadUInt16(this IPacket packet) { return (ushort)packet.ReadBits(16); } public static uint ReadUInt32(this IPacket packet) { return (uint)packet.ReadBits(32); } public static ulong ReadUInt64(this IPacket packet) { return packet.ReadBits(64); } public static void SkipBytes(this IPacket packet, int count) { packet.SkipBits(count * 8); } } internal class Factory : IFactory { public IHuffman CreateHuffman() { return new Huffman(); } public IMdct CreateMdct() { return new Mdct(); } public ICodebook CreateCodebook() { return new Codebook(); } public IFloor CreateFloor(IPacket packet) { return (int)packet.ReadBits(16) switch { 0 => new Floor0(), 1 => new Floor1(), _ => throw new InvalidDataException("Invalid floor type!"), }; } public IMapping CreateMapping(IPacket packet) { if (packet.ReadBits(16) != 0L) { throw new InvalidDataException("Invalid mapping type!"); } return new Mapping(); } public IMode CreateMode() { return new Mode(); } public IResidue CreateResidue(IPacket packet) { return (int)packet.ReadBits(16) switch { 0 => new Residue0(), 1 => new Residue1(), 2 => new Residue2(), _ => throw new InvalidDataException("Invalid residue type!"), }; } } internal class Floor0 : IFloor { private class Data : IFloorData { internal float[] Coeff; internal float Amp; public bool ExecuteChannel { get { if (ForceEnergy || Amp > 0f) { return !ForceNoEnergy; } return false; } } public bool ForceEnergy { get; set; } public bool ForceNoEnergy { get; set; } } private int _order; private int _rate; private int _bark_map_size; private int _ampBits; private int _ampOfs; private int _ampDiv; private ICodebook[] _books; private int _bookBits; private Dictionary<int, float[]> _wMap; private Dictionary<int, int[]> _barkMaps; public void Init(IPacket packet, int channels, int block0Size, int block1Size, ICodebook[] codebooks) { _order = (int)packet.ReadBits(8); _rate = (int)packet.ReadBits(16); _bark_map_size = (int)packet.ReadBits(16); _ampBits = (int)packet.ReadBits(6); _ampOfs = (int)packet.ReadBits(8); _books = new ICodebook[(int)packet.ReadBits(4) + 1]; if (_order < 1 || _rate < 1 || _bark_map_size < 1 || _books.Length == 0) { throw new InvalidDataException(); } _ampDiv = (1 << _ampBits) - 1; for (int i = 0; i < _books.Length; i++) { int num = (int)packet.ReadBits(8); if (num < 0 || num >= codebooks.Length) { throw new InvalidDataException(); } ICodebook codebook = codebooks[num]; if (codebook.MapType == 0 || codebook.Dimensions < 1) { throw new InvalidDataException(); } _books[i] = codebook; } _bookBits = Utils.ilog(_books.Length); _barkMaps = new Dictionary<int, int[]> { [block0Size] = SynthesizeBarkCurve(block0Size / 2), [block1Size] = SynthesizeBarkCurve(block1Size / 2) }; _wMap = new Dictionary<int, float[]> { [block0Size] = SynthesizeWDelMap(block0Size / 2), [block1Size] = SynthesizeWDelMap(block1Size / 2) }; } private int[] SynthesizeBarkCurve(int n) { float num = (float)_bark_map_size / toBARK(_rate / 2); int[] array = new int[n + 1]; for (int i = 0; i < n - 1; i++) { array[i] = Math.Min(_bark_map_size - 1, (int)Math.Floor(toBARK((float)_rate / 2f / (float)n * (float)i) * num)); } array[n] = -1; return array; } private static float toBARK(double lsp) { return (float)(13.1 * Math.Atan(0.00074 * lsp) + 2.24 * Math.Atan(1.85E-08 * lsp * lsp) + 0.0001 * lsp); } private float[] SynthesizeWDelMap(int n) { float num = (float)(Math.PI / (double)_bark_map_size); float[] array = new float[n]; for (int i = 0; i < n; i++) { array[i] = 2f * (float)Math.Cos(num * (float)i); } return array; } public IFloorData Unpack(IPacket packet, int blockSize, int channel) { Data data = new Data { Coeff = new float[_order + 1] }; data.Amp = packet.ReadBits(_ampBits); if (data.Amp > 0f) { Array.Clear(data.Coeff, 0, data.Coeff.Length); data.Amp = data.Amp / (float)_ampDiv * (float)_ampOfs; uint num = (uint)packet.ReadBits(_bookBits); if (num >= _books.Length) { data.Amp = 0f; return data; } ICodebook codebook = _books[num]; int i = 0; while (i < _order) { int num2 = codebook.DecodeScalar(packet); if (num2 == -1) { data.Amp = 0f; return data; } int num3 = 0; for (; i < _order; i++) { if (num3 >= codebook.Dimensions) { break; } data.Coeff[i] = codebook[num2, num3]; num3++; } } float num4 = 0f; int num5 = 0; while (num5 < _order) { int num6 = 0; while (num5 < _order && num6 < codebook.Dimensions) { data.Coeff[num5] += num4; num5++; num6++; } num4 = data.Coeff[num5 - 1]; } } return data; } public void Apply(IFloorData floorData, int blockSize, float[] residue) { if (!(floorData is Data data)) { throw new ArgumentException("Incorrect packet data!"); } int num = blockSize / 2; if (data.Amp > 0f) { int[] array = _barkMaps[blockSize]; float[] array2 = _wMap[blockSize]; int num2 = 0; for (num2 = 0; num2 < _order; num2++) { data.Coeff[num2] = 2f * (float)Math.Cos(data.Coeff[num2]); } num2 = 0; while (num2 < num) { int num3 = array[num2]; float num4 = 0.5f; float num5 = 0.5f; float num6 = array2[num3]; int i; for (i = 1; i < _order; i += 2) { num5 *= num6 - data.Coeff[i - 1]; num4 *= num6 - data.Coeff[i]; } if (i == _order) { num5 *= num6 - data.Coeff[i - 1]; num4 *= num4 * (4f - num6 * num6); num5 *= num5; } else { num4 *= num4 * (2f - num6); num5 *= num5 * (2f + num6); } num5 = data.Amp / (float)Math.Sqrt(num4 + num5) - (float)_ampOfs; num5 = (float)Math.Exp(num5 * 0.11512925f); residue[num2] *= num5; while (array[++num2] == num3) { residue[num2] *= num5; } } } else { Array.Clear(residue, 0, num); } } } internal class Floor1 : IFloor { private class Data : IFloorData { internal int[] Posts = new int[64]; internal int PostCount; public bool ExecuteChannel { get { if (ForceEnergy || PostCount > 0) { return !ForceNoEnergy; } return false; } } public bool ForceEnergy { get; set; } public bool ForceNoEnergy { get; set; } } private int[] _partitionClass; private int[] _classDimensions; private int[] _classSubclasses; private int[] _xList; private int[] _classMasterBookIndex; private int[] _hNeigh; private int[] _lNeigh; private int[] _sortIdx; private int _multiplier; private int _range; private int _yBits; private ICodebook[] _classMasterbooks; private ICodebook[][] _subclassBooks; private int[][] _subclassBookIndex; private static readonly int[] _rangeLookup = new int[4] { 256, 128, 86, 64 }; private static readonly int[] _yBitsLookup = new int[4] { 8, 7, 7, 6 }; private static readonly float[] inverse_dB_table = new float[256] { 1.0649863E-07f, 1.1341951E-07f, 1.2079015E-07f, 1.2863978E-07f, 1.369995E-07f, 1.459025E-07f, 1.5538409E-07f, 1.6548181E-07f, 1.7623574E-07f, 1.8768856E-07f, 1.998856E-07f, 2.128753E-07f, 2.2670913E-07f, 2.4144197E-07f, 2.5713223E-07f, 2.7384212E-07f, 2.9163792E-07f, 3.1059022E-07f, 3.307741E-07f, 3.5226967E-07f, 3.7516213E-07f, 3.995423E-07f, 4.255068E-07f, 4.5315863E-07f, 4.8260745E-07f, 5.1397E-07f, 5.4737063E-07f, 5.829419E-07f, 6.208247E-07f, 6.611694E-07f, 7.041359E-07f, 7.4989464E-07f, 7.98627E-07f, 8.505263E-07f, 9.057983E-07f, 9.646621E-07f, 1.0273513E-06f, 1.0941144E-06f, 1.1652161E-06f, 1.2409384E-06f, 1.3215816E-06f, 1.4074654E-06f, 1.4989305E-06f, 1.5963394E-06f, 1.7000785E-06f, 1.8105592E-06f, 1.9282195E-06f, 2.053526E-06f, 2.1869757E-06f, 2.3290977E-06f, 2.4804558E-06f, 2.6416496E-06f, 2.813319E-06f, 2.9961443E-06f, 3.1908505E-06f, 3.39821E-06f, 3.619045E-06f, 3.8542307E-06f, 4.1047006E-06f, 4.371447E-06f, 4.6555283E-06f, 4.958071E-06f, 5.280274E-06f, 5.623416E-06f, 5.988857E-06f, 6.3780467E-06f, 6.7925284E-06f, 7.2339453E-06f, 7.704048E-06f, 8.2047E-06f, 8.737888E-06f, 9.305725E-06f, 9.910464E-06f, 1.0554501E-05f, 1.1240392E-05f, 1.1970856E-05f, 1.2748789E-05f, 1.3577278E-05f, 1.4459606E-05f, 1.5399271E-05f, 1.6400005E-05f, 1.7465769E-05f, 1.8600793E-05f, 1.9809577E-05f, 2.1096914E-05f, 2.2467912E-05f, 2.3928002E-05f, 2.5482977E-05f, 2.7139005E-05f, 2.890265E-05f, 3.078091E-05f, 3.2781227E-05f, 3.4911533E-05f, 3.718028E-05f, 3.9596467E-05f, 4.2169668E-05f, 4.491009E-05f, 4.7828602E-05f, 5.0936775E-05f, 5.424693E-05f, 5.7772202E-05f, 6.152657E-05f, 6.552491E-05f, 6.9783084E-05f, 7.4317984E-05f, 7.914758E-05f, 8.429104E-05f, 8.976875E-05f, 9.560242E-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f, 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, 0.00015820454f, 0.00016848555f, 0.00017943469f, 0.00019109536f, 0.00020351382f, 0.0002167393f, 0.00023082423f, 0.00024582449f, 0.00026179955f, 0.00027881275f, 0.00029693157f, 0.00031622787f, 0.00033677815f, 0.00035866388f, 0.00038197188f, 0.00040679457f, 0.00043323037f, 0.0004613841f, 0.0004913675f, 0.00052329927f, 0.0005573062f, 0.0005935231f, 0.0006320936f, 0.0006731706f, 0.000716917f, 0.0007635063f, 0.00081312325f, 0.00086596457f, 0.00092223985f, 0.0009821722f, 0.0010459992f, 0.0011139743f, 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f, 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, 0.0019632196f, 0.0020908006f, 0.0022266726f, 0.0023713743f, 0.0025254795f, 0.0026895993f, 0.0028643848f, 0.0030505287f, 0.003248769f, 0.0034598925f, 0.0036847359f, 0.0039241905f, 0.0041792067f, 0.004450795f, 0.004740033f, 0.005048067f, 0.0053761187f, 0.005725489f, 0.0060975635f, 0.0064938175f, 0.0069158226f, 0.0073652514f, 0.007843887f, 0.008353627f, 0.008896492f, 0.009474637f, 0.010090352f, 0.01074608f, 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, 0.014722068f, 0.015678791f, 0.016697686f, 0.017782796f, 0.018938422f, 0.020169148f, 0.021479854f, 0.022875736f, 0.02436233f, 0.025945531f, 0.027631618f, 0.029427277f, 0.031339627f, 0.03337625f, 0.035545226f, 0.037855156f, 0.0403152f, 0.042935107f, 0.045725275f, 0.048696756f, 0.05186135f, 0.05523159f, 0.05882085f, 0.062643364f, 0.06671428f, 0.07104975f, 0.075666964f, 0.08058423f, 0.08582105f, 0.09139818f, 0.097337745f, 0.1036633f, 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f, 0.14201812f, 0.15124726f, 0.16107617f, 0.1715438f, 0.18269168f, 0.19456401f, 0.20720787f, 0.22067343f, 0.23501402f, 0.25028655f, 0.26655158f, 0.28387362f, 0.3023213f, 0.32196787f, 0.34289113f, 0.36517414f, 0.3889052f, 0.41417846f, 0.44109413f, 0.4697589f, 0.50028646f, 0.53279793f, 0.5674221f, 0.6042964f, 0.64356697f, 0.6853896f, 0.72993004f, 0.777365f, 0.8278826f, 0.88168305f, 0.9389798f, 1f }; public void Init(IPacket packet, int channels, int block0Size, int block1Size, ICodebook[] codebooks) { int num = -1; _partitionClass = new int[(uint)packet.ReadBits(5)]; for (int i = 0; i < _partitionClass.Length; i++) { _partitionClass[i] = (int)packet.ReadBits(4); if (_partitionClass[i] > num) { num = _partitionClass[i]; } } _classDimensions = new int[++num]; _classSubclasses = new int[num]; _classMasterbooks = new ICodebook[num]; _classMasterBookIndex = new int[num]; _subclassBooks = new ICodebook[num][]; _subclassBookIndex = new int[num][]; for (int j = 0; j < num; j++) { _classDimensions[j] = (int)packet.ReadBits(3) + 1; _classSubclasses[j] = (int)packet.ReadBits(2); if (_classSubclasses[j] > 0) { _classMasterBookIndex[j] = (int)packet.ReadBits(8); _classMasterbooks[j] = codebooks[_classMasterBookIndex[j]]; } _subclassBooks[j] = new ICodebook[1 << _classSubclasses[j]]; _subclassBookIndex[j] = new int[_subclassBooks[j].Length]; for (int k = 0; k < _subclassBooks[j].Length; k++) { int num2 = (int)packet.ReadBits(8) - 1; if (num2 >= 0) { _subclassBooks[j][k] = codebooks[num2]; } _subclassBookIndex[j][k] = num2; } } _multiplier = (int)packet.ReadBits(2); _range = _rangeLookup[_multiplier]; _yBits = _yBitsLookup[_multiplier]; _multiplier++; int num3 = (int)packet.ReadBits(4); List<int> list = new List<int>(); list.Add(0); list.Add(1 << num3); for (int l = 0; l < _partitionClass.Length; l++) { int num4 = _partitionClass[l]; for (int m = 0; m < _classDimensions[num4]; m++) { list.Add((int)packet.ReadBits(num3)); } } _xList = list.ToArray(); _lNeigh = new int[list.Count]; _hNeigh = new int[list.Count]; _sortIdx = new int[list.Count]; _sortIdx[0] = 0; _sortIdx[1] = 1; for (int n = 2; n < _lNeigh.Length; n++) { _lNeigh[n] = 0; _hNeigh[n] = 1; _sortIdx[n] = n; for (int num5 = 2; num5 < n; num5++) { int num6 = _xList[num5]; if (num6 < _xList[n]) { if (num6 > _xList[_lNeigh[n]]) { _lNeigh[n] = num5; } } else if (num6 < _xList[_hNeigh[n]]) { _hNeigh[n] = num5; } } } for (int num7 = 0; num7 < _sortIdx.Length - 1; num7++) { for (int num8 = num7 + 1; num8 < _sortIdx.Length; num8++) { if (_xList[num7] == _xList[num8]) { throw new InvalidDataException(); } if (_xList[_sortIdx[num7]] > _xList[_sortIdx[num8]]) { int num9 = _sortIdx[num7]; _sortIdx[num7] = _sortIdx[num8]; _sortIdx[num8] = num9; } } } } public IFloorData Unpack(IPacket packet, int blockSize, int channel) { Data data = new Data(); if (packet.ReadBit()) { int num = 2; data.Posts[0] = (int)packet.ReadBits(_yBits); data.Posts[1] = (int)packet.ReadBits(_yBits); for (int i = 0; i < _partitionClass.Length; i++) { int num2 = _partitionClass[i]; int num3 = _classDimensions[num2]; int num4 = _classSubclasses[num2]; int num5 = (1 << num4) - 1; uint num6 = 0u; if (num4 > 0 && (num6 = (uint)_classMasterbooks[num2].DecodeScalar(packet)) == uint.MaxValue) { num = 0; break; } for (int j = 0; j < num3; j++) { ICodebook codebook = _subclassBooks[num2][num6 & num5]; num6 >>= num4; if (codebook != null && (data.Posts[num] = codebook.DecodeScalar(packet)) == -1) { num = 0; i = _partitionClass.Length; break; } num++; } } data.PostCount = num; } return data; } public void Apply(IFloorData floorData, int blockSize, float[] residue) { if (!(floorData is Data data)) { throw new ArgumentException("Incorrect packet data!", "packetData"); } int num = blockSize / 2; if (data.PostCount > 0) { bool[] array = UnwrapPosts(data); int num2 = 0; int num3 = data.Posts[0] * _multiplier; for (int i = 1; i < data.PostCount; i++) { int num4 = _sortIdx[i]; if (array[num4]) { int num5 = _xList[num4]; int num6 = data.Posts[num4] * _multiplier; if (num2 < num) { RenderLineMulti(num2, num3, Math.Min(num5, num), num6, residue); } num2 = num5; num3 = num6; } if (num2 >= num) { break; } } if (num2 < num) { RenderLineMulti(num2, num3, num, num3, residue); } } else { Array.Clear(residue, 0, num); } } private bool[] UnwrapPosts(Data data) { bool[] array = new bool[64]; array[0] = true; array[1] = true; int[] array2 = new int[64]; array2[0] = data.Posts[0]; array2[1] = data.Posts[1]; for (int i = 2; i < data.PostCount; i++) { int num = _lNeigh[i]; int num2 = _hNeigh[i]; int num3 = RenderPoint(_xList[num], array2[num], _xList[num2], array2[num2], _xList[i]); int num4 = data.Posts[i]; int num5 = _range - num3; int num6 = num3; int num7 = ((num5 >= num6) ? (num6 * 2) : (num5 * 2)); if (num4 != 0) { array[num] = true; array[num2] = true; array[i] = true; if (num4 >= num7) { if (num5 > num6) { array2[i] = num4 - num6 + num3; } else { array2[i] = num3 - num4 + num5 - 1; } } else if (num4 % 2 == 1) { array2[i] = num3 - (num4 + 1) / 2; } else { array2[i] = num3 + num4 / 2; } } else { array[i] = false; array2[i] = num3; } } for (int j = 0; j < data.PostCount; j++) { data.Posts[j] = array2[j]; } return array; } private int RenderPoint(int x0, int y0, int x1, int y1, int X) { int num = y1 - y0; int num2 = x1 - x0; int num3 = Math.Abs(num) * (X - x0) / num2; if (num < 0) { return y0 - num3; } return y0 + num3; } private void RenderLineMulti(int x0, int y0, int x1, int y1, float[] v) { int num = y1 - y0; int num2 = x1 - x0; int num3 = Math.Abs(num); int num4 = 1 - ((num >> 31) & 1) * 2; int num5 = num / num2; int num6 = x0; int num7 = y0; int num8 = -num2; v[x0] *= inverse_dB_table[y0]; num3 -= Math.Abs(num5) * num2; while (++num6 < x1) { num7 += num5; num8 += num3; if (num8 >= 0) { num8 -= num2; num7 += num4; } v[num6] *= inverse_dB_table[num7]; } } } internal class Huffman : IHuffman, IComparer<HuffmanListNode> { private const int MAX_TABLE_BITS = 10; public int TableBits { get; private set; } public IReadOnlyList<HuffmanListNode> PrefixTree { get; private set; } public IReadOnlyList<HuffmanListNode> OverflowList { get; private set; } public void GenerateTable(IReadOnlyList<int> values, int[] lengthList, int[] codeList) { HuffmanListNode[] array = new HuffmanListNode[lengthList.Length]; int num = 0; for (int i = 0; i < array.Length; i++) { array[i] = new HuffmanListNode { Value = values[i], Length = ((lengthList[i] <= 0) ? 99999 : lengthList[i]), Bits = codeList[i], Mask = (1 << lengthList[i]) - 1 }; if (lengthList[i] > 0 && num < lengthList[i]) { num = lengthList[i]; } } Array.Sort(array, 0, array.Length, this); int num2 = ((num > 10) ? 10 : num); List<HuffmanListNode> list = new List<HuffmanListNode>(1 << num2); List<HuffmanListNode> list2 = null; for (int j = 0; j < array.Length && array[j].Length < 99999; j++) { int length = array[j].Length; if (length > num2) { list2 = new List<HuffmanListNode>(array.Length - j); for (; j < array.Length && array[j].Length < 99999; j++) { list2.Add(array[j]); } continue; } int num3 = 1 << num2 - length; HuffmanListNode huffmanListNode = array[j]; for (int k = 0; k < num3; k++) { int num4 = (k << length) | huffmanListNode.Bits; while (list.Count <= num4) { list.Add(null); } list[num4] = huffmanListNode; } } while (list.Count < 1 << num2) { list.Add(null); } TableBits = num2; PrefixTree = list; OverflowList = list2; } int IComparer<HuffmanListNode>.Compare(HuffmanListNode x, HuffmanListNode y) { int num = x.Length - y.Length; if (num == 0) { return x.Bits - y.Bits; } return num; } } [Obsolete("Moved to NVorbis.Contracts.IContainerReader", true)] public interface IContainerReader : NVorbis.Contracts.IContainerReader, IDisposable { [Obsolete("Use Streams.Select(s => s.StreamSerial).ToArray() instead.", true)] int[] StreamSerials { get; } [Obsolete("No longer supported.", true)] int PagesRead { get; } [Obsolete("Moved to NewStreamCallback.", true)] event EventHandler<NewStreamEventArgs> NewStream; [Obsolete("Renamed to TryInit().", true)] bool Init(); [Obsolete("No longer supported.", true)] int GetTotalPageCount(); } [Obsolete("Moved to NVorbis.Contracts.IPacketProvider", true)] public interface IPacketProvider : NVorbis.Contracts.IPacketProvider { [Obsolete("Moved to per-stream IStreamStats instance on IStreamDecoder.Stats or VorbisReader.Stats.", true)] long ContainerBits { get; } [Obsolete("No longer supported.", true)] event EventHandler ParameterChange; [Obsolete("No longer supported.", true)] int GetTotalPageCount(); [Obsolete("Getting a packet by index is no longer supported.", true)] DataPacket GetPacket(int packetIndex); [Obsolete("Moved to long SeekTo(long, int, GetPacketGranuleCount)", true)] DataPacket FindPacket(long granulePos, Func<DataPacket, DataPacket, int> packetGranuleCountCallback); [Obsolete("Seeking to a specified packet is no longer supported. See SeekTo(...) instead.", true)] void SeekToPacket(DataPacket packet, int preRoll); } [Obsolete("Moved to NVorbis.Contracts.IStreamStats", true)] public interface IVorbisStreamStatus : IStreamStats { [Obsolete("No longer supported.", true)] TimeSpan PageLatency { get; } [Obsolete("No longer supported.", true)] TimeSpan PacketLatency { get; } [Obsolete("No longer supported.", true)] TimeSpan SecondLatency { get; } [Obsolete("No longer supported.", true)] int PagesRead { get; } [Obsolete("No longer supported.", true)] int TotalPages { get; } [Obsolete("Use IStreamDecoder.HasClipped instead. VorbisReader.HasClipped will return the same value for the stream it is handling.", true)] bool Clipped { get; } } internal class Mapping : IMapping { private IMdct _mdct; private int[] _couplingAngle; private int[] _couplingMangitude; private IFloor[] _submapFloor; private IResidue[] _submapResidue; private IFloor[] _channelFloor; private IResidue[] _channelResidue; public void Init(IPacket packet, int channels, IFloor[] floors, IResidue[] residues, IMdct mdct) { int num = 1; if (packet.ReadBit()) { num += (int)packet.ReadBits(4); } int num2 = 0; if (packet.ReadBit()) { num2 = (int)packet.ReadBits(8) + 1; } int count = Utils.ilog(channels - 1); _couplingAngle = new int[num2]; _couplingMangitude = new int[num2]; for (int i = 0; i < num2; i++) { int num3 = (int)packet.ReadBits(count); int num4 = (int)packet.ReadBits(count); if (num3 == num4 || num3 > channels - 1 || num4 > channels - 1) { throw new InvalidDataException("Invalid magnitude or angle in mapping header!"); } _couplingAngle[i] = num4; _couplingMangitude[i] = num3; } if (packet.ReadBits(2) != 0L) { throw new InvalidDataException("Reserved bits not 0 in mapping header."); } int[] array = new int[channels]; if (num > 1) { for (int j = 0; j < channels; j++) { array[j] = (int)packet.ReadBits(4); if (array[j] > num) { throw new InvalidDataException("Invalid channel mux submap index in mapping header!"); } } } _submapFloor = new IFloor[num]; _submapResidue = new IResidue[num]; for (int k = 0; k < num; k++) { packet.SkipBits(8); int num5 = (int)packet.ReadBits(8); if (num5 >= floors.Length) { throw new InvalidDataException("Invalid floor number in mapping header!"); } int num6 = (int)packet.ReadBits(8); if (num6 >= residues.Length) { throw new InvalidDataException("Invalid residue number in mapping header!"); } _submapFloor[k] = floors[num5]; _submapResidue[k] = residues[num6]; } _channelFloor = new IFloor[channels]; _channelResidue = new IResidue[channels]; for (int l = 0; l < channels; l++) { _channelFloor[l] = _submapFloor[array[l]]; _channelResidue[l] = _submapResidue[array[l]]; } _mdct = mdct; } public void DecodePacket(IPacket packet, int blockSize, int channels, float[][] buffer) { int num = blockSize >> 1; IFloorData[] array = new IFloorData[_channelFloor.Length]; bool[] array2 = new bool[_channelFloor.Length]; for (int i = 0; i < _channelFloor.Length; i++) { array[i] = _channelFloor[i].Unpack(packet, blockSize, i); array2[i] = !array[i].ExecuteChannel; Array.Clear(buffer[i], 0, num); } for (int j = 0; j < _couplingAngle.Length; j++) { if (array[_couplingAngle[j]].ExecuteChannel || array[_couplingMangitude[j]].ExecuteChannel) { array[_couplingAngle[j]].ForceEnergy = true; array[_couplingMangitude[j]].ForceEnergy = true; } } for (int k = 0; k < _submapFloor.Length; k++) { for (int l = 0; l < _channelFloor.Length; l++) { if (_submapFloor[k] != _channelFloor[l] || _submapResidue[k] != _channelResidue[l]) { array[l].ForceNoEnergy = true; } } _submapResidue[k].Decode(packet, array2, blockSize, buffer); } for (int num2 = _couplingAngle.Length - 1; num2 >= 0; num2--) { if (array[_couplingAngle[num2]].ExecuteChannel || array[_couplingMangitude[num2]].ExecuteChannel) { float[] array3 = buffer[_couplingMangitude[num2]]; float[] array4 = buffer[_couplingAngle[num2]]; for (int m = 0; m < num; m++) { float num3 = array3[m]; float num4 = array4[m]; float num5; float num6; if (num3 > 0f) { if (num4 > 0f) { num5 = num3; num6 = num3 - num4; } else { num6 = num3; num5 = num3 + num4; } } else if (num4 > 0f) { num5 = num3; num6 = num3 + num4; } else { num6 = num3; num5 = num3 - num4; } array3[m] = num5; array4[m] = num6; } } } for (int n = 0; n < _channelFloor.Length; n++) { if (array[n].ExecuteChannel) { _channelFloor[n].Apply(array[n], blockSize, buffer[n]); _mdct.Reverse(buffer[n], blockSize); } else { Array.Clear(buffer[n], num, num); } } } } internal class Mdct : IMdct { private class MdctImpl { private readonly int _n; private readonly int _n2; private readonly int _n4; private readonly int _n8; private readonly int _ld; private readonly float[] _a; private readonly float[] _b; private readonly float[] _c; private readonly ushort[] _bitrev; public MdctImpl(int n) { _n = n; _n2 = n >> 1; _n4 = _n2 >> 1; _n8 = _n4 >> 1; _ld = Utils.ilog(n) - 1; _a = new float[_n2]; _b = new float[_n2]; _c = new float[_n4]; int num; int num2 = (num = 0); while (num2 < _n4) { _a[num] = (float)Math.Cos((float)(4 * num2) * (float)Math.PI / (float)n); _a[num + 1] = (float)(0.0 - Math.Sin((float)(4 * num2) * (float)Math.PI / (float)n)); _b[num] = (float)Math.Cos((float)(num + 1) * (float)Math.PI / (float)n / 2f) * 0.5f; _b[num + 1] = (float)Math.Sin((float)(num + 1) * (float)Math.PI / (float)n / 2f) * 0.5f; num2++; num += 2; } num2 = (num = 0); while (num2 < _n8) { _c[num] = (float)Math.Cos((float)(2 * (num + 1)) * (float)Math.PI / (float)n); _c[num + 1] = (float)(0.0 - Math.Sin((float)(2 * (num + 1)) * (float)Math.PI / (float)n)); num2++; num += 2; } _bitrev = new ushort[_n8]; for (int i = 0; i < _n8; i++) { _bitrev[i] = (ushort)(Utils.BitReverse((uint)i, _ld - 3) << 2); } } internal void CalcReverse(float[] buffer) { float[] array = new float[_n2]; int num = _n2 - 2; int num2 = 0; int i = 0; for (int n = _n2; i != n; i += 4) { array[num + 1] = buffer[i] * _a[num2] - buffer[i + 2] * _a[num2 + 1]; array[num] = buffer[i] * _a[num2 + 1] + buffer[i + 2] * _a[num2]; num -= 2; num2 += 2; } i = _n2 - 3; while (num >= 0) { array[num + 1] = (0f - buffer[i + 2]) * _a[num2] - (0f - buffer[i]) * _a[num2 + 1]; array[num] = (0f - buffer[i + 2]) * _a[num2 + 1] + (0f - buffer[i]) * _a[num2]; num -= 2; num2 += 2; i -= 4; } float[] array2 = array; int num3 = _n2 - 8; int num4 = _n4; int num5 = 0; int num6 = _n4; int num7 = 0; while (num3 >= 0) { float num8 = array2[num4 + 1] - array2[num5 + 1]; float num9 = array2[num4] - array2[num5]; buffer[num6 + 1] = array2[num4 + 1] + array2[num5 + 1]; buffer[num6] = array2[num4] + array2[num5]; buffer[num7 + 1] = num8 * _a[num3 + 4] - num9 * _a[num3 + 5]; buffer[num7] = num9 * _a[num3 + 4] + num8 * _a[num3 + 5]; num8 = array2[num4 + 3] - array2[num5 + 3]; num9 = array2[num4 + 2] - array2[num5 + 2]; buffer[num6 + 3] = array2[num4 + 3] + array2[num5 + 3]; buffer[num6 + 2] = array2[num4 + 2] + array2[num5 + 2]; buffer[num7 + 3] = num8 * _a[num3] - num9 * _a[num3 + 1]; buffer[num7 + 2] = num9 * _a[num3] + num8 * _a[num3 + 1]; num3 -= 8; num6 += 4; num7 += 4; num4 += 4; num5 += 4; } int n2 = _n >> 4; int num10 = _n2 - 1; _ = _n4; step3_iter0_loop(n2, buffer, num10 - 0, -_n8); step3_iter0_loop(_n >> 4, buffer, _n2 - 1 - _n4, -_n8); int lim = _n >> 5; int num11 = _n2 - 1; _ = _n8; step3_inner_r_loop(lim, buffer, num11 - 0, -(_n >> 4), 16); step3_inner_r_loop(_n >> 5, buffer, _n2 - 1 - _n8, -(_n >> 4), 16); step3_inner_r_loop(_n >> 5, buffer, _n2 - 1 - _n8 * 2, -(_n >> 4), 16); step3_inner_r_loop(_n >> 5, buffer, _n2 - 1 - _n8 * 3, -(_n >> 4), 16); int j; for (j = 2; j < _ld - 3 >> 1; j++) { int num12 = _n >> j + 2; int num13 = num12 >> 1; int num14 = 1 << j + 1; for (int k = 0; k < num14; k++) { step3_inner_r_loop(_n >> j + 4, buffer, _n2 - 1 - num12 * k, -num13, 1 << j + 3); } } for (; j < _ld - 6; j++) { int num15 = _n >> j + 2; int num16 = 1 << j + 3; int num17 = num15 >> 1; int num18 = _n >> j + 6; int n3 = 1 << j + 1; int num19 = _n2 - 1; int num20 = 0; for (int num21 = num18; num21 > 0; num21--) { step3_inner_s_loop(n3, buffer, num19, -num17, num20, num16, num15); num20 += num16 * 4; num19 -= 8; } } step3_inner_s_loop_ld654(_n >> 5, buffer, _n2 - 1, _n); int num22 = 0; int num23 = _n4 - 4; int num24 = _n2 - 4; while (num23 >= 0) { int num25 = _bitrev[num22]; array2[num24 + 3] = buffer[num25]; array2[num24 + 2] = buffer[num25 + 1]; array2[num23 + 3] = buffer[num25 + 2]; array2[num23 + 2] = buffer[num25 + 3]; num25 = _bitrev[num22 + 1]; array2[num24 + 1] = buffer[num25]; array2[num24] = buffer[num25 + 1]; array2[num23 + 1] = buffer[num25 + 2]; array2[num23] = buffer[num25 + 3]; num23 -= 4; num24 -= 4; num22 += 2; } int num26 = 0; int num27 = 0; int num28 = _n2 - 4; while (num27 < num28) { float num29 = array2[num27] - array2[num28 + 2]; float num30 = array2[num27 + 1] + array2[num28 + 3]; float num31 = _c[num26 + 1] * num29 + _c[num26] * num30; float num32 = _c[num26 + 1] * num30 - _c[num26] * num29; float num33 = array2[num27] + array2[num28 + 2]; float num34 = array2[num27 + 1] - array2[num28 + 3]; array2[num27] = num33 + num31; array2[num27 + 1] = num34 + num32; array2[num28 + 2] = num33 - num31; array2[num28 + 3] = num32 - num34; num29 = array2[num27 + 2] - array2[num28]; num30 = array2[num27 + 3] + array2[num28 + 1]; num31 = _c[num26 + 3] * num29 + _c[num26 + 2] * num30; num32 = _c[num26 + 3] * num30 - _c[num26 + 2] * num29; num33 = array2[num27 + 2] + array2[num28]; num34 = array2[num27 + 3] - array2[num28 + 1]; array2[num27 + 2] = num33 + num31; array2[num27 + 3] = num34 + num32; array2[num28] = num33 - num31; array2[num28 + 1] = num32 - num34; num26 += 4; num27 += 4; num28 -= 4; } int num35 = _n2 - 8; int num36 = _n2 - 8; int num37 = 0; int num38 = _n2 - 4; int num39 = _n2; int num40 = _n - 4; while (num36 >= 0) { float num41 = array[num36 + 6] * _b[num35 + 7] - array[num36 + 7] * _b[num35 + 6]; float num42 = (0f - array[num36 + 6]) * _b[num35 + 6] - array[num36 + 7] * _b[num35 + 7]; buffer[num37] = num41; buffer[num38 + 3] = 0f - num41; buffer[num39] = num42; buffer[num40 + 3] = num42; float num43 = array[num36 + 4] * _b[num35 + 5] - array[num36 + 5] * _b[num35 + 4]; float num44 = (0f - array[num36 + 4]) * _b[num35 + 4] - array[num36 + 5] * _b[num35 + 5]; buffer[num37 + 1] = num43; buffer[num38 + 2] = 0f - num43; buffer[num39 + 1] = num44; buffer[num40 + 2] = num44; num41 = array[num36 + 2] * _b[num35 + 3] - array[num36 + 3] * _b[num35 + 2]; num42 = (0f - array[num36 + 2]) * _b[num35 + 2] - array[num36 + 3] * _b[num35 + 3]; buffer[num37 + 2] = num41; buffer[num38 + 1] = 0f - num41; buffer[num39 + 2] = num42; buffer[num40 + 1] = num42; num43 = array[num36] * _b[num35 + 1] - array[num36 + 1] * _b[num35]; num44 = (0f - array[num36]) * _b[num35] - array[num36 + 1] * _b[num35 + 1]; buffer[num37 + 3] = num43; buffer[num38] = 0f - num43; buffer[num39 + 3] = num44; buffer[num40] = num44; num35 -= 8; num36 -= 8; num37 += 4; num39 += 4; num38 -= 4; num40 -= 4; } } private void step3_iter0_loop(int n, float[] e, int i_off, int k_off) { int num = i_off; int num2 = num + k_off; int num3 = 0; for (int num4 = n >> 2; num4 > 0; num4--) { float num5 = e[num] - e[num2]; float num6 = e[num - 1] - e[num2 - 1]; e[num] += e[num2]; e[num - 1] += e[num2 - 1]; e[num2] = num5 * _a[num3] - num6 * _a[num3 + 1]; e[num2 - 1] = num6 * _a[num3] + num5 * _a[num3 + 1]; num3 += 8; num5 = e[num - 2] - e[num2 - 2]; num6 = e[num - 3] - e[num2 - 3]; e[num - 2] += e[num2 - 2]; e[num - 3] += e[num2 - 3]; e[num2 - 2] = num5 * _a[num3] - num6 * _a[num3 + 1]; e[num2 - 3] = num6 * _a[num3] + num5 * _a[num3 + 1]; num3 += 8; num5 = e[num - 4] - e[num2 - 4]; num6 = e[num - 5] - e[num2 - 5]; e[num - 4] += e[num2 - 4]; e[num - 5] += e[num2 - 5]; e[num2 - 4] = num5 * _a[num3] - num6 * _a[num3 + 1]; e[num2 - 5] = num6 * _a[num3] + num5 * _a[num3 + 1]; num3 += 8; num5 = e[num - 6] - e[num2 - 6]; num6 = e[num - 7] - e[num2 - 7]; e[num - 6] += e[num2 - 6]; e[num - 7] += e[num2 - 7]; e[num2 - 6] = num5 * _a[num3] - num6 * _a[num3 + 1]; e[num2 - 7] = num6 * _a[num3] + num5 * _a[num3 + 1]; num3 += 8; num -= 8; num2 -= 8; } } private void step3_inner_r_loop(int lim, float[] e, int d0, int k_off, int k1) { int num = d0; int num2 = num + k_off; int num3 = 0; for (int num4 = lim >> 2; num4 > 0; num4--) { float num5 = e[num] - e[num2]; float num6 = e[num - 1] - e[num2 - 1]; e[num] += e[num2]; e[num - 1] += e[num2 - 1]; e[num2] = num5 * _a[num3] - num6 * _a[num3 + 1]; e[num2 - 1] = num6 * _a[num3] + num5 * _a[num3 + 1]; num3 += k1; num5 = e[num - 2] - e[num2 - 2]; num6 = e[num - 3] - e[num2 - 3]; e[num - 2] += e[num2 - 2]; e[num - 3] += e[num2 - 3]; e[num2 - 2] = num5 * _a[num3] - num6 * _a[num3 + 1]; e[num2 - 3] = num6 * _a[num3] + num5 * _a[num3 + 1]; num3 += k1; num5 = e[num - 4] - e[num2 - 4]; num6 = e[num - 5] - e[num2 - 5]; e[num - 4] += e[num2 - 4]; e[num - 5] += e[num2 - 5]; e[num2 - 4] = num5 * _a[num3] - num6 * _a[num3 + 1]; e[num2 - 5] = num6 * _a[num3] + num5 * _a[num3 + 1]; num3 += k1; num5 = e[num - 6] - e[num2 - 6]; num6 = e[num - 7] - e[num2 - 7]; e[num - 6] += e[num2 - 6]; e[num - 7] += e[num2 - 7]; e[num2 - 6] = num5 * _a[num3] - num6 * _a[num3 + 1]; e[num2 - 7] = num6 * _a[num3] + num5 * _a[num3 + 1]; num3 += k1; num -= 8; num2 -= 8; } } private void step3_inner_s_loop(int n, float[] e, int i_off, int k_off, int a, int a_off, int k0) { float num = _a[a]; float num2 = _a[a + 1]; float num3 = _a[a + a_off]; float num4 = _a[a + a_off + 1]; float num5 = _a[a + a_off * 2]; float num6 = _a[a + a_off * 2 + 1]; float num7 = _a[a + a_off * 3]; float num8 = _a[a + a_off * 3 + 1]; int num9 = i_off; int num10 = num9 + k_off; for (int num11 = n; num11 > 0; num11--) { float num12 = e[num9] - e[num10]; float num13 = e[num9 - 1] - e[num10 - 1]; e[num9] += e[num10]; e[num9 - 1] += e[num10 - 1]; e[num10] = num12 * num - num13 * num2; e[num10 - 1] = num13 * num + num12 * num2; num12 = e[num9 - 2] - e[num10 - 2]; num13 = e[num9 - 3] - e[num10 - 3]; e[num9 - 2] += e[num10 - 2]; e[num9 - 3] += e[num10 - 3]; e[num10 - 2] = num12 * num3 - num13 * num4; e[num10 - 3] = num13 * num3 + num12 * num4; num12 = e[num9 - 4] - e[num10 - 4]; num13 = e[num9 - 5] - e[num10 - 5]; e[num9 - 4] += e[num10 - 4]; e[num9 - 5] += e[num10 - 5]; e[num10 - 4] = num12 * num5 - num13 * num6; e[num10 - 5] = num13 * num5 + num12 * num6; num12 = e[num9 - 6] - e[num10 - 6]; num13 = e[num9 - 7] - e[num10 - 7]; e[num9 - 6] += e[num10 - 6]; e[num9 - 7] += e[num10 - 7]; e[num10 - 6] = num12 * num7 - num13 * num8; e[num10 - 7] = num13 * num7 + num12 * num8; num9 -= k0; num10 -= k0; } } private void step3_inner_s_loop_ld654(int n, float[] e, int i_off, int base_n) { int num = base_n >> 3; float num2 = _a[num]; int num3 = i_off; int num4 = num3 - 16 * n; while (num3 > num4) { float num5 = e[num3] - e[num3 - 8]; float num6 = e[num3 - 1] - e[num3 - 9]; e[num3] += e[num3 - 8]; e[num3 - 1] += e[num3 - 9]; e[num3 - 8] = num5; e[num3 - 9] = num6; num5 = e[num3 - 2] - e[num3 - 10]; num6 = e[num3 - 3] - e[num3 - 11]; e[num3 - 2] += e[num3 - 10]; e[num3 - 3] += e[num3 - 11]; e[num3 - 10] = (num5 + num6) * num2; e[num3 - 11] = (num6 - num5) * num2; num5 = e[num3 - 12] - e[num3 - 4]; num6 = e[num3 - 5] - e[num3 - 13]; e[num3 - 4] += e[num3 - 12]; e[num3 - 5] += e[num3 - 13]; e[num3 - 12] = num6; e[num3 - 13] = num5; num5 = e[num3 - 14] - e[num3 - 6]; num6 = e[num3 - 7] - e[num3 - 15]; e[num3 - 6] += e[num3 - 14]; e[num3 - 7] += e[num3 - 15]; e[num3 - 14] = (num5 + num6) * num2; e[num3 - 15] = (num5 - num6) * num2; iter_54(e, num3); iter_54(e, num3 - 8); num3 -= 16; } } private void iter_54(float[] e, int z) { float num = e[z] - e[z - 4]; float num2 = e[z] + e[z - 4]; float num3 = e[z - 2] + e[z - 6]; float num4 = e[z - 2] - e[z - 6]; e[z] = num2 + num3; e[z - 2] = num2 - num3; float num5 = e[z - 3] - e[z - 7]; e[z - 4] = num + num5; e[z - 6] = num - num5; float num6 = e[z - 1] - e[z - 5]; float num7 = e[z - 1] + e[z - 5]; float num8 = e[z - 3] + e[z - 7]; e[z - 1] = num7 + num8; e[z - 3] = num7 - num8; e[z - 5] = num6 - num4; e[z - 7] = num6 + num4; } } private const float M_PI = (float)Math.PI; private Dictionary<int, MdctImpl> _setupCache = new Dictionary<int, MdctImpl>(); public void Reverse(float[] samples, int sampleCount) { if (!_setupCache.TryGetValue(sampleCount, out var value)) { value = new MdctImpl(sampleCount); _setupCache[sampleCount] = value; } value.CalcReverse(samples); } } internal class Mode : IMode { private struct OverlapInfo { public int PacketStartIndex; public int PacketTotalLength; public int PacketValidLength; } private const float M_PI2 = (float)Math.PI / 2f; private int _channels; private bool _blockFlag; private int _blockSize; private IMapping _mapping; private float[][] _windows; private OverlapInfo[] _overlapInfo; public void Init(IPacket packet, int channels, int block0Size, int block1Size, IMapping[] mappings) { _channels = channels; _blockFlag = packet.ReadBit(); if (packet.ReadBits(32) != 0L) { throw new InvalidDataException("Mode header had invalid window or transform type!"); } int num = (int)packet.ReadBits(8); if (num >= mappings.Length) { throw new InvalidDataException("Mode header had invalid mapping index!"); } _mapping = mappings[num]; if (_blockFlag) { _blockSize = block1Size; _windows = new float[4][] { CalcWindow(block0Size, block1Size, block0Size), CalcWindow(block1Size, block1Size, block0Size), CalcWindow(block0Size, block1Size, block1Size), CalcWindow(block1Size, block1Size, block1Size) }; _overlapInfo = new OverlapInfo[4] { CalcOverlap(block0Size, block1Size, block0Size), CalcOverlap(block1Size, block1Size, block0Size), CalcOverlap(block0Size, block1Size, block1Size), CalcOverlap(block1Size, block1Size, block1Size) }; } else { _blockSize = block0Size; _windows = new float[1][] { CalcWindow(block0Size, block0Size, block0Size) }; } } private static float[] CalcWindow(int prevBlockSize, int blockSize, int nextBlockSize) { float[] array = new float[blockSize]; int num = prevBlockSize / 2; int num2 = nextBlockSize / 2; int num3 = blockSize / 4 - num / 2; int num4 = blockSize - blockSize / 4 - num2 / 2; for (int i = 0; i < num; i++) { float num5 = (float)Math.Sin(((double)i + 0.5) / (double)num * 1.5707963705062866); num5 *= num5; array[num3 + i] = (float)Math.Sin(num5 * ((float)Math.PI / 2f)); } for (int j = num3 + num; j < num4; j++) { array[j] = 1f; } for (int k = 0; k < num2; k++) { float num6 = (float)Math.Sin(((double)(num2 - k) - 0.5) / (double)num2 * 1.5707963705062866); num6 *= num6; array[num4 + k] = (float)Math.Sin(num6 * ((float)Math.PI / 2f)); } return array; } private static OverlapInfo CalcOverlap(int prevBlockSize, int blockSize, int nextBlockSize) { int num = prevBlockSize / 4; int num2 = nextBlockSize / 4; int packetStartIndex = blockSize / 4 - num; int num3 = blockSize / 4 * 3 + num2; int packetValidLength = num3 - num2 * 2; OverlapInfo result = default(OverlapInfo); result.PacketStartIndex = packetStartIndex; result.PacketValidLength = packetValidLength; result.PacketTotalLength = num3; return result; } private bool GetPacketInfo(IPacket packet, out int windowIndex, out int packetStartIndex, out int packetValidLength, out int packetTotalLength) { if (packet.IsShort) { windowIndex = 0; packetStartIndex = 0; packetValidLength = 0; packetTotalLength = 0; return false; } if (_blockFlag) { bool flag = packet.ReadBit(); bool flag2 = packet.ReadBit(); windowIndex = (flag ? 1 : 0) + (flag2 ? 2 : 0); OverlapInfo overlapInfo = _overlapInfo[windowIndex]; packetStartIndex = overlapInfo.PacketStartIndex; packetValidLength = overlapInfo.PacketValidLength; packetTotalLength = overlapInfo.PacketTotalLength; } else { windowIndex = 0; packetStartIndex = 0; packetValidLength = _blockSize / 2; packetTotalLength = _blockSize; } return true; } public bool Decode(IPacket packet, float[][] buffer, out int packetStartindex, out int packetValidLength, out int packetTotalLength) { if (GetPacketInfo(packet, out var windowIndex, out packetStartindex, out packetValidLength, out packetTotalLength)) { _mapping.DecodePacket(packet, _blockSize, _channels, buffer); float[] array = _windows[windowIndex]; for (int i = 0; i < _blockSize; i++) { for (int j = 0; j < _channels; j++) { buffer[j][i] *= array[i]; } } return true; } return false; } public int GetPacketSampleCount(IPacket packet) { GetPacketInfo(packet, out var _, out var packetStartIndex, out var packetValidLength, out var _); return packetValidLength - packetStartIndex; } } [Serializable] public class NewStreamEventArgs : EventArgs { public IStreamDecoder StreamDecoder { get; } public bool IgnoreStream { get; set; } public NewStreamEventArgs(IStreamDecoder streamDecoder) { StreamDecoder = streamDecoder ?? throw new ArgumentNullException("streamDecoder"); } } internal class Residue0 : IResidue { private int _channels; private int _begin; private int _end; private int _partitionSize; private int _classifications; private int _maxStages; private ICodebook[][] _books; private ICodebook _classBook; private int[] _cascade; private int[][] _decodeMap; private static int icount(int v) { int num = 0; while (v != 0) { num += v & 1; v >>= 1; } return num; } public virtual void Init(IPacket packet, int channels, ICodebook[] codebooks) { _begin = (int)packet.ReadBits(24); _end = (int)packet.ReadBits(24); _partitionSize = (int)packet.ReadBits(24) + 1; _classifications = (int)packet.ReadBits(6) + 1; _classBook = codebooks[(uint)packet.ReadBits(8)]; _cascade = new int[_classifications]; int num = 0; for (int i = 0; i < _classifications; i++) { int num2 = (int)packet.ReadBits(3); if (packet.ReadBit()) { _cascade[i] = ((int)packet.ReadBits(5) << 3) | num2; } else { _cascade[i] = num2; } num += icount(_cascade[i]); } int[] array = new int[num]; for (int j = 0; j < num; j++) { array[j] = (int)packet.ReadBits(8); if (codebooks[array[j]].MapType == 0) { throw new InvalidDataException(); } } int entries = _classBook.Entries; int num3 = _classBook.Dimensions; int num4 = 1; while (num3 > 0) { num4 *= _classifications; if (num4 > entries) { throw new InvalidDataException(); } num3--; } _books = new ICodebook[_classifications][]; num = 0; int num5 = 0; for (int k = 0; k < _classifications; k++) { int num6 = Utils.ilog(_cascade[k]); _books[k] = new ICodebook[num6]; if (num6 <= 0) { continue; } num5 = Math.Max(num5, num6); for (int l = 0; l < num6; l++) { if ((_cascade[k] & (1 << l)) > 0) { _books[k][l] = codebooks[array[num++]]; } } } _maxStages = num5; _decodeMap = new int[num4][]; for (int m = 0; m < num4; m++) { int num7 = m; int num8 = num4 / _classifications; _decodeMap[m] = new int[_classBook.Dimensions]; for (int n = 0; n < _classBook.Dimensions; n++) { int num9 = num7 / num8; num7 -= num9 * num8; num8 /= _classifications; _decodeMap[m][n] = num9; } } _channels = channels; } public virtual void Decode(IPacket packet, bool[] doNotDecodeChannel, int blockSize, float[][] buffer) { int num = ((_end < blockSize / 2) ? _end : (blockSize / 2)) - _begin; if (num <= 0 || Array.IndexOf(doNotDecodeChannel, value: false) == -1) { return; } int num2 = num / _partitionSize; int num3 = (num2 + _classBook.Dimensions - 1) / _classBook.Dimensions; int[,][] array = new int[_channels, num3][]; for (int i = 0; i < _maxStages; i++) { int j = 0; int num4 = 0; while (j < num2) { if (i == 0) { for (int k = 0; k < _channels; k++) { int num5 = _classBook.DecodeScalar(packet); if (num5 >= 0 && num5 < _decodeMap.Length) { array[k, num4] = _decodeMap[num5]; continue; } j = num2; i = _maxStages; break; } } int num6 = 0; for (; j < num2; j++) { if (num6 >= _classBook.Dimensions) { break; } int offset = _begin + j * _partitionSize; for (int l = 0; l < _channels; l++) { int num7 = array[l, num4][num6]; if ((_cascade[num7] & (1 << i)) != 0) { ICodebook codebook = _books[num7][i]; if (codebook != null && WriteVectors(codebook, packet, buffer, l, offset, _partitionSize)) { j = num2; i = _maxStages; break; } } } num6++; } num4++; } } } protected virtual bool WriteVectors(ICodebook codebook, IPacket packet, float[][] residue, int channel, int offset, int partitionSize) { float[] array = residue[channel]; int num = partitionSize / codebook.Dimensions; int[] array2 = new int[num]; for (int i = 0; i < num; i++) { if ((array2[i] = codebook.DecodeScalar(packet)) == -1) { return true; } } for (int j = 0; j < codebook.Dimensions; j++) { int num2 = 0; while (num2 < num) { array[offset] += codebook[array2[num2], j]; num2++; offset++; } } return false; } } internal class Residue1 : Residue0 { protected override bool WriteVectors(ICodebook codebook, IPacket packet, float[][] residue, int channel, int offset, int partitionSize) { float[] array = residue[channel]; int num = 0; while (num < partitionSize) { int num2 = codebook.DecodeScalar(packet); if (num2 == -1) { return true; } for (int i = 0; i < codebook.Dimensions; i++) { array[offset + num] += codebook[num2, i]; num++; } } return false; } } internal class Residue2 : Residue0 { private int _channels; public override void Init(IPacket packet, int channels, ICodebook[] codebooks) { _channels = channels; base.Init(packet, 1, codebooks); } public override void Decode(IPacket packet, bool[] doNotDecodeChannel, int blockSize, float[][] buffer) { base.Decode(packet, doNotDecodeChannel, blockSize * _channels, buffer); } protected override bool WriteVectors(ICodebook codebook, IPacket packet, float[][] residue, int channel, int offset, int partitionSize) { int num = 0; offset /= _channels; int num2 = 0; while (num2 < partitionSize) { int num3 = codebook.DecodeScalar(packet); if (num3 == -1) { return true; } int num4 = 0; while (num4 < codebook.Dimensions) { residue[num][offset] += codebook[num3, num4]; if (++num == _channels) { num = 0; offset++; } num4++; num2++; } } return false; } } public sealed class StreamDecoder : IStreamDecoder, IDisposable { private NVorbis.Contracts.IPacketProvider _packetProvider; private IFactory _factory; private StreamStats _stats; private byte _channels; private int _sampleRate; private int _block0Size; private int _block1Size; private IMode[] _modes; private int _modeFieldBits; private string _vendor; private string[] _comments; private ITagData _tags; private long _currentPosition; private bool _hasClipped; private bool _hasPosition; private bool _eosFound; private float[][] _nextPacketBuf; private float[][] _prevPacketBuf; private int _prevPacketStart; private int _prevPacketEnd; private int _prevPacketStop; private static readonly byte[] PacketSignatureStream = new byte[11] { 1, 118, 111, 114, 98, 105, 115, 0, 0, 0, 0 }; private static readonly byte[] PacketSignatureComments = new byte[7] { 3, 118, 111, 114, 98, 105, 115 }; private static readonly byte[] PacketSignatureBooks = new byte[7] { 5, 118, 111, 114, 98, 105, 115 }; internal static Func<IFactory> CreateFactory { get; set; } = () => new Factory(); public int Channels => _channels; public int SampleRate => _sampleRate; public int UpperBitrate { get; private set; } public int NominalBitrate { get; private set; } public int LowerBitrate { get; private set; } public ITagData Tags => _tags ?? (_tags = new TagData(_vendor, _comments)); public TimeSpan TotalTime => TimeSpan.FromSeconds((double)TotalSamples / (double)_sampleRate); public long TotalSamples => (_packetProvider ?? throw new ObjectDisposedException("StreamDecoder")).GetGranuleCount(); public TimeSpan TimePosition { get { return TimeSpan.FromSeconds((double)_currentPosition / (double)_sampleRate); } set { SeekTo(value); } } public long SamplePosition { get { return _currentPosition; } set { SeekTo(value); } } public bool ClipSamples { get; set; } public bool HasClipped => _hasClipped; public bool IsEndOfStream { get { if (_eosFound) { return _prevPacketBuf == null; } return false; } } public IStreamStats Stats => _stats; public StreamDecoder(NVorbis.Contracts.IPacketProvider packetProvider) : this(packetProvider, new Factory()) { } internal StreamDecoder(NVorbis.Contracts.IPacketProvider packetProvider, IFactory factory) { _packetProvider = packetProvider ?? throw new ArgumentNullException("packetProvider"); _factory = factory ?? throw new ArgumentNullException("factory"); _stats = new StreamStats(); _currentPosition = 0L; ClipSamples = true; IPacket packet = _packetProvider.PeekNextPacket(); if (!ProcessHeaderPackets(packet)) { _packetProvider = null; packet.Reset(); throw GetInvalidStreamException(packet); } } private static Exception GetInvalidStreamException(IPacket packet) { try { ulong num = packet.ReadBits(64); if (num == 7233173838382854223L) { return new ArgumentException("Found OPUS bitstream."); } if ((num & 0xFF) == 127) { return new ArgumentException("Found FLAC bitstream."); } switch (num) { case 2314885909937746003uL: return new ArgumentException("Found Speex bitstream."); case 28254585843050854uL: return new ArgumentException("Found Skeleton metadata bitstream."); default: if ((num & 0xFFFFFFFFFFFF00L) == 27428895509214208L) { return new ArgumentException("Found Theora bitsream."); } return new ArgumentException("Could not find Vorbis data to decode."); } } finally { packet.Reset(); } } private bool ProcessHeaderPackets(IPacket packet) { if (!ProcessHeaderPacket(packet, LoadStreamHeader, delegate { _packetProvider.GetNextPacket().Done(); })) { return false; } if (!ProcessHeaderPacket(_packetProvider.GetNextPacket(), LoadComments, delegate(IPacket pkt) { pkt.Done(); })) { return false; } if (!ProcessHeaderPacket(_packetProvider.GetNextPacket(), LoadBooks, delegate(IPacket pkt) { pkt.Done(); })) { return false; } _currentPosition = 0L; ResetDecoder(); return true; } private static bool ProcessHeaderPacket(IPacket packet, Func<IPacket, bool> processAction, Action<IPacket> doneAction) { if (packet != null) { try { return processAction(packet); } finally { doneAction(packet); } } return false; } private static bool ValidateHeader(IPacket packet, byte[] expected) { for (int i = 0; i < expected.Length; i++) { if (expected[i] != packet.ReadBits(8)) { return false; } } return true; } private static string ReadString(IPacket packet) { int num = (int)packet.ReadBits(32); if (num == 0) { return string.Empty; } byte[] array = new byte[num]; if (packet.Read(array, 0, num) < num) { throw new InvalidDataException("Could not read full string!"); } return Encoding.UTF8.GetString(array); } private bool LoadStreamHeader(IPacket packet) { if (!ValidateHeader(packet, PacketSignatureStream)) { return false; } _channels = (byte)packet.ReadBits(8); _sampleRate = (int)packet.ReadBits(32); UpperBitrate = (int)packet.ReadBits(32); NominalBitrate = (int)packet.ReadBits(32); LowerBitrate = (int)packet.ReadBits(32); _block0Size = 1 << (int)packet.ReadBits(4); _block1Size = 1 << (int)packet.ReadBits(4); if (NominalBitrate == 0 && UpperBitrate > 0 && LowerBitrate > 0) { NominalBitrate = (UpperBitrate + LowerBitrate) / 2; } _stats.SetSampleRate(_sampleRate); _stats.AddPacket(-1, packet.BitsRead, packet.BitsRemaining, packet.ContainerOverheadBits); return true; } private bool LoadComments(IPacket packet) { if (!ValidateHeader(packet, PacketSignatureComments)) { return false; } _vendor = ReadString(packet); _comments = new string[packet.ReadBits(32)]; for (int i = 0; i < _comments.Length; i++) { _comments[i] = ReadString(packet); } _stats.AddPacket(-1, packet.BitsRead, packet.BitsRemaining, packet.ContainerOverheadBits); return true; } private bool LoadBooks(IPacket packet) { if (!ValidateHeader(packet, PacketSignatureBooks)) { return false; } IMdct mdct = _factory.CreateMdct(); IHuffman huffman = _factory.CreateHuffman(); ICodebook[] array = new ICodebook[packet.ReadBits(8) + 1]; for (int i = 0; i < array.Length; i++) { array[i] = _factory.CreateCodebook(); array[i].Init(packet, huffman); } int num = (int)packet.ReadBits(6) + 1; packet.SkipBits(16 * num); IFloor[] array2 = new IFloor[packet.ReadBits(6) + 1]; for (int j = 0; j < array2.Length; j++) { array2[j] = _factory.CreateFloor(packet); array2[j].Init(packet, _channels, _block0Size, _block1Size, array); } IResidue[] array3 = new IResidue[packet.ReadBits(6) + 1]; for (int k = 0; k < array3.Length; k++) { array3[k] = _factory.CreateResidue(packet); array3[k].Init(packet, _channels, array); } IMapping[] array4 = new IMapping[packet.ReadBits(6) + 1]; for (int l = 0; l < array4.Length; l++) { array4[l] = _factory.CreateMapping(packet); array4[l].Init(packet, _channels, array2, array3, mdct); } _modes = new IMode[packet.ReadBits(6) + 1]; for (int m = 0; m < _modes.Length; m++) { _modes[m] = _factory.CreateMode(); _modes[m].Init(packet, _channels, _block0Size, _block1Size, array4); } if (!packet.ReadBit()) { throw new InvalidDataException("Book packet did not end on correct bit!"); } _modeFieldBits = Utils.ilog(_modes.Length - 1); _stats.AddPacket(-1, packet.BitsRead, packet.BitsRemaining, packet.ContainerOverheadBits); return true; } private void ResetDecoder() { _prevPacketBuf = null; _prevPacketStart = 0; _prevPacketEnd = 0; _prevPacketStop = 0; _nextPacketBuf = null; _eosFound = false; _hasClipped = false; _hasPosition = false; } public int Read(Span<float> buffer, int offset, int count) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0 || offset + count > buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (count % _channels != 0) { throw new ArgumentOutOfRangeException("count", "Must be a multiple of Channels!"); } if (_packetProvider == null) { throw new ObjectDisposedException("StreamDecoder"); } if (count == 0) { return 0; } int num = offset; int num2 = offset + count; while (num < num2) { if (_prevPacketStart == _prevPacketEnd) { if (_eosFound) { _nextPacketBuf = null; _prevPacketBuf = null; break; } if (!ReadNextPacket((num - offset) / _channels, out var samplePosition)) { _prevPacketEnd = _prevPacketStop; } if (samplePosition.HasValue && !_hasPosition) { _hasPosition = true; _currentPosition = samplePosition.Value - (_prevPacketEnd - _prevPacketStart) - (num - offset) / _channels; } } int num3 = Math.Min((num2 - num) / _channels, _prevPacketEnd - _prevPacketStart); if (num3 > 0) { num = ((!ClipSamples) ? (num + CopyBuffer(buffer, num, num3)) : (num + ClippingCopyBuffer(buffer, num, num3))); } } count = num - offset; _currentPosition += count / _channels; return count; } private int ClippingCopyBuffer(Span<float> target, int targetIndex, int count) { int num = targetIndex; while (count > 0) { for (int i = 0; i < _channels; i++) { target[num++] = Utils.ClipValue(_prevPacketBuf[i][_prevPacketStart], ref _hasClipped); } _prevPacketStart++; count--; } return num - targetIndex; } private int CopyBuffer(Span<float> target, int targetIndex, int count) { int num = targetIndex; while (count > 0) { for (int i = 0; i < _channels; i++) { target[num++] = _prevPacketBuf[i][_prevPacketStart]; } _prevPacketStart++; count--; } return num - targetIndex; } private bool ReadNextPacket(int bufferedSamples, out long? samplePosition) { int packetStartindex; int packetValidLength; int packetTotalLength; bool isEndOfStream; int bitsRead; int bitsRemaining; int containerOverheadBits; float[][] array = DecodeNextPacket(out packetStartindex, out packetValidLength, out packetTotalLength, out isEndOfStream, out samplePosition, out bitsRead, out bitsRemaining, out containerOverheadBits); _eosFound |= isEndOfStream; if (array == null) { _stats.AddPacket(0, bitsRead, bitsRemaining, containerOverheadBits); return false; } if (samplePosition.HasValue && isEndOfStream) { long num = _currentPosition + bufferedSamples + packetValidLength - packetStartindex; int num2 = (int)(samplePosition.Value - num); if (num2 < 0) { packetValidLength += num2; } } if (_prevPacketEnd > 0) { OverlapBuffers(_prevPacketBuf, array, _prevPacketStart, _prevPacketStop, packetStartindex, _channels); _prevPacketStart = packetStartindex; } else if (_prevPacketBuf == null) { _prevPacketStart = packetValidLength; } _stats.AddPacket(packetValidLength - _prevPacketStart, bitsRead, bitsRemaining, containerOverheadBits); _nextPacketBuf = _prevPacketBuf; _prevPacketEnd = packetValidLength; _prevPacketStop = packetTotalLength; _prevPacketBuf = array; return true; } private float[][] DecodeNextPacket(out int packetStartindex, out int packetValidLength, out int packetTotalLength, out bool isEndOfStream, out long? samplePosition, out int bitsRead, out int bitsRemaining, out int containerOverheadBits) { IPacket packet = null; try { if ((packet = _packetProvider.GetNextPacket()) == null) { isEndOfStream = true; } else { isEndOfStream = packet.IsEndOfStream; if (packet.IsResync) { _hasPosition = false; } containerOverheadBits = packet.ContainerOverheadBits; if (packet.ReadBit()) { bitsRemaining = packet.BitsRemaining + 1; } else { IMode mode = _modes[(uint)packet.ReadBits(_modeFieldBits)]; if (_nextPacketBuf == null) { _nextPacketBuf = new float[_channels][]; for (int i = 0; i < _channels; i++) { _nextPacketBuf[i] = new float[_block1Size]; } } if (mode.Decode(packet, _nextPacketBuf, out packetStartindex, out packetValidLength, out packetTotalLength)) { samplePosition = packet.GranulePosition; bitsRead = packet.BitsRead; bitsRemaining = packet.BitsRemaining; return _nextPacketBuf; } bitsRemaining = packet.BitsRead + packet.BitsRemaining; } } packetStartindex = 0; packetValidLength = 0; packetTotalLength = 0; samplePosition = null; bitsRead = 0; bitsRemaining = 0; containerOverheadBits = 0; return null; } finally { packet?.Done(); } } private static void OverlapBuffers(float[][] previous, float[][] next, int prevStart, int prevLen, int nextStart, int channels) { while (prevStart < prevLen) { for (int i = 0; i < channels; i++) { next[i][nextStart] += previous[i][prevStart]; } prevStart++; nextStart++; } } public void SeekTo(TimeSpan timePosition, SeekOrigin seekOrigin = SeekOrigin.Begin) { SeekTo((long)((double)SampleRate * timePosition.TotalSeconds), seekOrigin); } public void SeekTo(long samplePosition, SeekOrigin seekOrigin = SeekOrigin.Begin) { if (_packetProvider == null) { throw new ObjectDisposedException("StreamDecoder"); } if (!_packetProvider.CanSeek) { throw new InvalidOperationException("Seek is not supported by the Contracts.IPacketProvider instance."); } switch (seekOrigin) { case SeekOrigin.Current: samplePosition = SamplePosition - samplePosition; break; case SeekOrigin.End: samplePosition = TotalSamples - samplePosition; break; default: throw new ArgumentOutOfRangeException("seekOrigin"); case SeekOrigin.Begin: break; } if (samplePosition < 0) { throw new ArgumentOutOfRangeException("samplePosition"); } int num; if (samplePosition == 0L) { _packetProvider.SeekTo(0L, 0, GetPacketGranules); num = 0; } else { long num2 = _packetProvider.SeekTo(samplePosition, 1, GetPacketGranules); num = (int)(samplePosition - num2); } ResetDecoder(); _hasPosition = true; if (!ReadNextPacket(0, out var samplePosition2)) { _eosFound = true; if (_packetProvider.GetGranuleCount() != samplePosition) { throw new InvalidOperationException("Could not read pre-roll packet! Try seeking again prior to reading more samples."); } _prevPacketStart = _prevPacketStop; _currentPosition = samplePosition; return; } if (!ReadNextPacket(0, out samplePosition2)) { ResetDecoder(); _eosFound = true; throw new InvalidOperationException("Could not read pre-roll packet! Try seeking again prior to reading more samples."); } _prevPacketStart += num; _currentPosition = samplePosition; } private int GetPacketGranules(IPacket curPacket) { if (curPacket.IsResync) { return 0; } if (curPacket.ReadBit()) { return 0; } int num = (int)curPacket.ReadBits(_modeFieldBits); if (num < 0 || num >= _modes.Length) { return 0; } return _modes[num].GetPacketSampleCount(curPacket); } public void Dispose() { (_packetProvider as IDisposable)?.Dispose(); _packetProvider = null; } } internal class StreamStats : IStreamStats { private int _sampleRate; private readonly int[] _packetBits = new int[2]; private readonly int[] _packetSamples = new int[2]; private int _packetIndex; private long _totalSamples; private long _audioBits; private long _headerBits; private long _containerBits; private long _wasteBits; private object _lock = new object(); private int _packetCount; public int EffectiveBitRate { get { long totalSamples; long num; lock (_lock) { totalSamples = _totalSamples; num = _audioBits + _headerBits + _containerBits + _wasteBits; } if (totalSamples > 0) { return (int)((double)num / (double)totalSamples * (double)_sampleRate); } return 0; } } public int InstantBitRate { get { int num; int num2; lock (_lock) { num = _packetBits[0] + _packetBits[1]; num2 = _packetSamples[0] + _packetSamples[1]; } if (num2 > 0) { return (int)((double)num / (double)num2 * (double)_sampleRate); } return 0; } } public long ContainerBits => _containerBits; public long OverheadBits => _headerBits; public long AudioBits => _audioBits; public long WasteBits => _wasteBits; public int PacketCount => _packetCount; public void ResetStats() { lock (_lock) { _packetBits[0] = (_packetBits[1] = 0); _packetSamples[0] = (_packetSamples[1] = 0); _packetIndex = 0; _packetCount = 0; _audioBits = 0L; _totalSamples = 0L; _headerBits = 0L; _containerBits = 0L; _wasteBits = 0L; } } internal void SetSampleRate(int sampleRate) { lock (_lock) { _sampleRate = sampleRate; ResetStats(); } } internal void AddPacket(int samples, int bits, int waste, int container) { lock (_lock) { if (samples >= 0) { _audioBits += bits; _wasteBits += waste; _containerBits += container; _totalSamples += samples; _packetBits[_packetIndex] = bits + waste; _packetSamples[_packetIndex] = samples; if (++_packetIndex == 2) { _packetIndex = 0; } } else { _headerBits += bits; _wasteBits += waste; _containerBits += container; } } } } internal class TagData : ITagData { private static IReadOnlyList<string> s_emptyList = new List<string>(); private Dictionary<string, IReadOnlyList<string>> _tags; public IReadOnlyDictionary<string, IReadOnlyList<string>> All => _tags; public string EncoderVendor { get; } public string Title => GetTagSingle("TITLE"); public string Version => GetTagSingle("VERSION"); public string Album => GetTagSingle("ALBUM"); public string TrackNumber => GetTagSingle("TRACKNUMBER"); public string Artist => GetTagSingle("ARTIST"); public IReadOnlyList<string> Performers => GetTagMulti("PERFORMER"); public string Copyright => GetTagSingle("COPYRIGHT"); public string License => GetTagSingle("LICENSE"); public string Organization => GetTagSingle("ORGANIZATION"); public string Description => GetTagSingle("DESCRIPTION"); public IReadOnlyList<string> Genres => GetTagMulti("GENRE"); public IReadOnlyList<string> Dates => GetTagMulti("DATE"); public IReadOnlyList<string> Locations => GetTagMulti("LOCATION"); public string Contact => GetTagSingle("CONTACT"); public string Isrc => GetTagSingle("ISRC"); public TagData(string vendor, string[] comments) { EncoderVendor = vendor; Dictionary<string, IReadOnlyList<string>> dictionary = new Dictionary<string, IReadOnlyList<string>>(); for (int i = 0; i < comments.Length; i++) { string[] array = comments[i].Split(new char[1] { '=' }); if (array.Length == 1) { array = new string[2] { array[0], string.Empty }; } int num = array[0].IndexOf('['); if (num > -1) { array[1] = array[0].Substring(num + 1, array[0].Length - num - 2).ToUpper(CultureInfo.CurrentCulture) + ": " + array[1]; array[0] = array[0].Substring(0, num); } if (dictionary.TryGetValue(array[0].ToUpperInvariant(), out var value)) { ((List<string>)value).Add(array[1]); continue; } dictionary.Add(array[0].ToUpperInvariant(), new List<string> { array[1] }); } _tags = dictionary; } public string GetTagSingle(string key, bool concatenate = false) { IReadOnlyList<string> tagMulti = GetTagMulti(key); if (tagMulti.Count > 0) { if (concatenate) { return string.Join(Environment.NewLine, tagMulti.ToArray()); } return tagMulti[tagMulti.Count - 1]; } return string.Empty; } public IReadOnlyList<string> GetTagMulti(string key) { if (_tags.TryGetValue(key.ToUpperInvariant(), out var value)) { return value; } return s_emptyList; } } internal static class Utils { internal static int ilog(int x) { int num = 0; while (x > 0) { num++; x >>= 1; } return num; } internal static uint BitReverse(uint n) { return BitReverse(n, 32); } internal static uint BitReverse(uint n, int bits) { n = ((n & 0xAAAAAAAAu) >> 1) | ((n & 0x55555555) << 1); n = ((n & 0xCCCCCCCCu) >> 2) | ((n & 0x33333333) << 2); n = ((n & 0xF0F0F0F0u) >> 4) | ((n & 0xF0F0F0F) << 4); n = ((n & 0xFF00FF00u) >> 8) | ((n & 0xFF00FF) << 8); return ((n >> 16) | (n << 16)) >> 32 - bits; } internal static float ClipValue(float value, ref bool clipped) { if (value > (float)Math.PI * 113f / 355f) { clipped = true; return (float)Math.PI * 113f / 355f; } if (value < (float)Math.PI * -113f / 355f) { clipped = true; return (float)Math.PI * -113f / 355f; } return value; } internal static float ConvertFromVorbisFloat32(uint bits) { int num = (int)bits >> 31; double y = (int)(((bits & 0x7FE00000) >> 21) - 788); return (float)(((bits & 0x1FFFFF) ^ num) + (num & 1)) * (float)Math.Pow(2.0, y); } } public sealed class VorbisReader : IVorbisReader, IDisposable { private readonly List<IStreamDecoder> _decoders; private readonly NVorbis.Contracts.IContainerReader _containerReader; private readonly bool _closeOnDispose; private IStreamDecoder _streamDecoder; internal static Func<Stream, bool, NVorbis.Contracts.IContainerReader> CreateContainerReader { get; set; } = (Stream s, bool cod) => new ContainerReader(s, cod); internal static Func<NVorbis.Contracts.IPacketProvider, IStreamDecoder> CreateStreamDecoder { get; set; } = (NVorbis.Contracts.IPacketProvider pp) => new StreamDecoder(pp, new Factory()); public IReadOnlyList<IStreamDecoder> Streams => _decoders; public int Channels => _streamDecoder.Channels; public int SampleRate => _streamDecoder.SampleRate; public int UpperBitrate => _streamDecoder.UpperBitrate; public int NominalBitrate => _streamDecoder.NominalBitrate; public int LowerBitrate => _streamDecoder.LowerBitrate; public ITagData Tags => _streamDecoder.Tags; [Obsolete("Use .Tags.EncoderVendor instead.")] public string Vendor => _streamDecoder.Tags.EncoderVendor; [Obsolete("Use .Tags.All instead.")] public string[] Comments => _streamDecoder.Tags.All.SelectMany((KeyValuePair<string, IReadOnlyList<string>> k) => k.Value, (KeyValuePair<string, IReadOnlyList<string>> kvp, string Item) => kvp.Key + "=" + Item).ToArray(); [Obsolete("No longer supported. Will receive a new stream when parameters change.", true)] public bool IsParameterChange { get { throw new NotSupportedException(); } } public long ContainerOverheadBits => _containerReader?.ContainerBits ?? 0; public long ContainerWasteBits => _containerReader?.WasteBits ?? 0; public int StreamIndex => _decoders.IndexOf(_streamDecoder); [Obsolete("Use .Streams.Count instead.")] public int StreamCount => _decoders.Count; [Obsolete("Use VorbisReader.TimePosition instead.")] public TimeSpan DecodedTime { get { return _streamDecoder.TimePosition; } set { TimePosition = value; } } [Obsolete("Use VorbisReader.SamplePosition instead.")] public long DecodedPosition { get { return _streamDecoder.SamplePosition; } set { SamplePosition = value; } } public TimeSpan TotalTime => _streamDecoder.TotalTime; public long TotalSamples => _streamDecoder.TotalSamples; public TimeSpan TimePosition { get { return _streamDecoder.TimePosition; } set { _streamDecoder.TimePosition = value; } } public long SamplePosition { get { return _streamDecoder.SamplePosition; } set { _streamDecoder.SamplePosition = value; } } public bool IsEndOfStream => _streamDecoder.IsEndOfStream; public bool ClipSamples { get { return _streamDecoder.ClipSamples; } set { _streamDecoder.ClipSamples = value; } } public bool HasClipped => _streamDecoder.HasClipped; public IStreamStats StreamStats => _streamDecoder.Stats; [Obsolete("Use Streams[*].Stats instead.", true)] public IVorbisStreamStatus[] Stats { get { throw new NotSupportedException(); } } public event EventHandler<NewStreamEventArgs> NewStream; public VorbisReader(string fileName) : this(File.OpenRead(fileName)) { } public VorbisReader(Stream stream, bool closeOnDispose = true) { _decoders = new List<IStreamDecoder>(); NVorbis.Contracts.IContainerReader containerReader = CreateContainerReader(stream, closeOnDispose); containerReader.NewStreamCallback = ProcessNewStream; if (!containerReader.TryInit() || _decoders.Count == 0) { containerReader.NewStreamCallback = null; containerReader.Dispose(); if (closeOnDispose) { stream.Dispose(); } throw new ArgumentException("Could not load the specified container!", "containerReader"); } _closeOnDispose = closeOnDispose; _containerReader = containerReader; _streamDecoder = _decoders[0]; } [Obsolete("Use \"new StreamDecoder(Contracts.IPacketProvider)\" and the container's NewStreamCallback or Streams property instead.", true)] public VorbisReader(NVorbis.Contracts.IContainerReader containerReader) { throw new NotSupportedException(); } [Obsolete("Use \"new StreamDecoder(Contracts.IPacketProvider)\" instead.", true)] public VorbisReader(NVorbis.Contracts.IPacketProvider packetProvider) { throw new NotSupportedException(); } private bool ProcessNewStream(NVorbis.Contracts.IPacketProvider packetProvider) { IStreamDecoder streamDecoder = CreateStreamDecoder(packetProvider); streamDecoder.ClipSamples = true; NewStreamEventArgs newStreamEventArgs = new NewStreamEventArgs(streamDecoder); this.NewStream?.Invoke(this, newStreamEventArgs); if (!newStreamEventArgs.IgnoreStream) { _decoders.Add(streamDecoder); return true; } return false; } public void Dispose() { if (_decoders != null) { foreach (IStreamDecoder decoder in _decoders) { decoder.Dispose(); } _decoders.Clear(); } if (_containerReader != null) { _containerReader.NewStreamCallback = null; if (_closeOnDispose) { _containerReader.Dispose(); } } } public bool FindNextStream() { if (_containerReader == null) { return false; } return _containerReader.FindNextStream(); } public bool SwitchStreams(int index) { if (index < 0 || index >= _decoders.Count) { throw new ArgumentOutOfRangeException("index"); } IStreamDecoder streamDecoder = _decoders[index]; IStreamDecoder streamDecoder2 = _streamDecoder; if (streamDecoder == streamDecoder2) { return false; } streamDecoder.ClipSamples = streamDecoder2.ClipSamples; _streamDecoder = streamDecoder; if (streamDecoder.Channels == streamDecoder2.Channels) { return streamDecoder.SampleRate != streamDecoder2.SampleRate; } return true; } public void SeekTo(TimeSpan timePosition, SeekOrigin seekOrigin = SeekOrigin.Begin) { _streamDecoder.SeekTo(timePosition, seekOrigin); } public void SeekTo(long samplePosition, SeekOrigin seekOrigin = SeekOrigin.Begin) { _streamDecoder.SeekTo(samplePosition, seekOrigin); } public int ReadSamples(float[] buffer, int offset, int count) { count -= count % _streamDecoder.Channels; if (count > 0) { return _streamDecoder.Read(buffer, offset, count); } return 0; } public int ReadSamples(Span<float> buffer) { int count = buffer.Length - buffer.Length % _streamDecoder.Channels; if (!buffer.IsEmpty) { return _streamDecoder.Read(buffer, 0, count); } return 0; } [Obsolete("No longer needed.", true)] public void ClearParameterChange() { throw new NotSupportedException(); } } } namespace NVorbis.Ogg { public sealed class ContainerReader : NVorbis.Contracts.IContainerReader, IDisposable { private IPageReader _reader; private List<WeakReference<NVorbis.Contracts.IPacketProvider>> _packetProviders; private bool _foundStream; internal static Func<Stream, bool, Func<NVorbis.Contracts.IPacketProvider, bool>, IPageReader> CreatePageReader { get; set; } = (Stream s, bool cod, Func<NVorbis.Contracts.IPacketProvider, bool> cb) => new PageReader(s, cod, cb); internal static Func<Stream, bool, Func<NVorbis.Contracts.IPacketProvider, bool>, IPageReader> CreateForwardOnlyPageReader { get; set; } = (Stream s, bool cod, Func<NVorbis.Contracts.IPacketProvider, bool> cb) => new ForwardOnlyPageReader(s, cod, cb); public NewStreamHandler NewStreamCallback { get; set; } public bool CanSeek { get; } public long WasteBits => _reader.WasteBits; public long ContainerBits => _reader.ContainerBits; public IReadOnlyList<NVorbis.Contracts.IPacketProvider> GetStreams() { List<NVorbis.Contracts.IPacketProvider> list = new List<NVorbis.Contracts.IPacketProvider>(_packetProviders.Count); for (int i = 0; i < _packetProviders.Count; i++) { if (_packetProviders[i].TryGetTarget(out var target)) { list.Add(target); continue; } list.RemoveAt(i); i--; } return list; } public ContainerReader(Stream stream, bool closeOnDispose) { if (stream == null) { throw new ArgumentNullException("stream"); } _packetProviders = new List<WeakReference<NVorbis.Contracts.IPacketProvider>>(); if (stream.CanSeek) { _reader = CreatePageReader(stream, closeOnDispose, ProcessNewStream); CanSeek = true; } else { _reader = CreateForwardOnlyPageReader(stream, closeOnDispose, ProcessNewStream); } } public bool TryInit() { return FindNextStream(); } public bool FindNextStream() { _reader.Lock(); try { _foundStream = false; while (_reader.ReadNextPage()) { if (_foundStream) { return true; } } return false; } finally { _reader.Release(); } } private bool ProcessNewStream(NVorbis.Contracts.IPacketProvider packetProvider) { bool flag = _reader.Release(); try { NewStreamHandler newStreamCallback = NewStreamCallback; if (newStreamCallback == null || newStreamCallback(packetProvider)) { _packetProviders.Add(new WeakReference<NVorbis.Contracts.IPacketProvider>(packetProvider)); _foundStream = true; return true; } return false; } finally { if (flag) { _reader.Lock(); } } } public void Dispose() { _reader?.Dispose(); _reader = null; } } internal class Crc : ICrc { private const uint CRC32_POLY = 79764919u; private static readonly uint[] s_crcTable; private uint _crc; static Crc() { s_crcTable = new uint[256]; for (uint num = 0u; num < 256; num++) { uint num2 = num << 24; for (int i = 0; i < 8; i++) { num2 = (num2 << 1) ^ ((num2 >= 2147483648u) ? 79764919u : 0u); } s_crcTable[num] = num2; } } public Crc() { Reset(); } public void Reset() { _crc = 0u; } public void Update(int nextVal) { _crc = (_crc << 8) ^ s_crcTable[nextVal ^ (_crc >> 24)]; } public bool Test(uint checkCrc) { return _crc == checkCrc; } } internal class ForwardOnlyPacketProvider : DataPacket, IForwardOnlyPacketProvider, NVorbis.Contracts.IPacketProvider { private int _lastSeqNo; private readonly Queue<(byte[] buf, bool isResync)> _pageQueue = new Queue<(byte[], bool)>(); private readonly IPageReader _reader; private byte[] _pageBuf; private int _packetIndex; private bool _isEndOfStream; private int _dataStart; private bool _lastWasPeek; private Memory<byte> _packetBuf; private int _dataIndex; public bool CanSeek => false; public int StreamSerial { get; } protected override int TotalBits => _packetBuf.Length * 8; public ForwardOnlyPacketProvider(IPageReader reader, int streamSerial) { _reader = reader; StreamSerial = streamSerial; _packetIndex = int.MaxValue; } public bool AddPage(byte[] buf, bool isResync) { if ((buf[5] & 2u) != 0) { if (_isEndOfStream) { return false; } isResync = true; _lastSeqNo = BitConverter.ToInt32(buf, 18); } else { int num = BitConverter.ToInt32(buf, 18); isResync |= num != _lastSeqNo + 1; _lastSeqNo = num; } int num2 = 0; for (int i = 0; i < buf[26]; i++) { num2 += buf[27 + i]; } if (num2 == 0) { return false; } _pageQueue.Enqueue((buf, isResync)); return true; } public void SetEndOfStream() { _isEndOfStream = true; } public IPacket GetNextPacket() { if (_packetBuf.Length > 0) { if (!_lastWasPeek) { throw new InvalidOperationException("Must call Done() on previous packet first."); } _lastWasPeek = false; return this; } _lastWasPeek = false; if (GetPacket()) { return this; } return null; } public IPacket PeekNextPacket() { if (_packetBuf.Length > 0) { if (!_lastWasPeek) { throw new InvalidOperationException("Must call Done() on previous packet first."); } return this; } _lastWasPeek = true; if (GetPacket()) { return this; } return null; } private bool GetPacket() { byte[] pageBuf; bool isResync; int packetIndex; bool isContinuation; bool isContinued; int dataStart; if (_pageBuf != null && _packetIndex < 27 + _pageBuf[26]) { pageBuf = _pageBuf; isResync = false; dataStart = _dataStart; packetIndex = _packetIndex; isContinuation = false; isContinued = pageBuf[26 + pageBuf[26]] == byte.MaxValue; } else if (!ReadNextPage(out pageBuf, out isResync, out dataStart, out packetIndex, out isContinuation, out isContinued)) { return false; } int num = dataStart; bool flag = packetIndex == 27; if (isContinuation && flag) { isResync = true; num += GetPacketLength(pageBuf, ref packetIndex); if (packetIndex == 27 + pageBuf[26]) { return GetPacket(); } } if (!flag) { num = 0; } int packetLength = GetPacketLength(pageBuf, ref packetIndex); Memory<byte> memory = new Memory<byte>(pageBuf, dataStart, packetLength); dataStart += packetLength; bool flag2 = packetIndex == 27 + pageBuf[26]; if (isContinued) { if (flag2) { flag2 = false; } else { int packetIndex2 = packetIndex; GetPacketLength(pageBuf, ref packetIndex2); flag2 = packetIndex2 == 27 + pageBuf[26]; } } bool flag3 = false; long? granulePosition = null; if (flag2) { granulePosition = BitConverter.ToInt64(pageBuf, 6); if ((pageBuf[5] & 4u) != 0 || (_isEndOfStream && _pageQueue.Count == 0)) { flag3 = true; } } else { while (isContinued && packetIndex == 27 + pageBuf[26] && ReadNextPage(out pageBuf, out isResync, out dataStart, out packetIndex, out isContinuation, out isContinued) && !isResync && isContinuation) { num += 27 + pageBuf[26]; Memory<byte> memory2 = memory; int packetLength2 = GetPacketLength(pageBuf, ref packetIndex); memory = new Memory<byte>(new byte[memory2.Length + packetLength2]); memory2.CopyTo(memory); new Memory<byte>(pageBuf, dataStart, packetLength2).CopyTo(memory.Slice(memory2.Length)); dataStart += packetLength2; } } base.IsResync = isResync; base.GranulePosition = granulePosition; base.IsEndOfStream = flag3; base.ContainerOverheadBits = num * 8; _pageBuf = pageBuf; _dataStart = dataStart; _packetIndex = packetIndex; _packetBuf = memory; _isEndOfStream |= flag3; Reset(); return true; } private bool ReadNextPage(out byte[] pageBuf, out bool isResync, out int dataStart, out int packetIndex, out bool isContinuation, out bool isContinued) { while (_pageQueue.Count == 0) { if (_isEndOfStream || !_reader.ReadNextPage()) { pageBuf = null; isResync = false; dataStart = 0; packetIndex = 0; isContinuation = false; isContinued = false; return false; } } (byte[], bool) tuple = _pageQueue.Dequeue(); pageBuf = tuple.Item1; isResync = tuple.Item2; dataStart = pageBuf[26] + 27; packetIndex = 27; isContinuation = (pageBuf[5] & 1) != 0; isContinued = pageBuf[26 + pageBuf[26]] == byte.MaxValue; retu
plugins/System.Buffers.dll
Decompiled a month agousing System; using System.Diagnostics; using System.Diagnostics.Tracing; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using System.Threading; using FxResources.System.Buffers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: NeutralResourcesLanguage("en-US")] [assembly: AssemblyTitle("System.Buffers")] [assembly: AssemblyDescription("System.Buffers")] [assembly: AssemblyDefaultAlias("System.Buffers")] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyProduct("Microsoft® .NET Framework")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyFileVersion("4.6.25519.03")] [assembly: AssemblyInformationalVersion("4.6.25519.03 built by: dlab-DDVSOWINAGE013. Commit Hash: 8321c729934c0f8be754953439b88e6e1c120c24")] [assembly: CLSCompliant(true)] [assembly: AssemblyMetadata(".NETFrameworkAssembly", "")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyMetadata("PreferInbox", "True")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("4.0.2.0")] [module: UnverifiableCode] namespace FxResources.System.Buffers { internal static class SR { } } namespace System { internal static class SR { private static ResourceManager s_resourceManager; private const string s_resourcesName = "FxResources.System.Buffers.SR"; private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType)); internal static string ArgumentException_BufferNotFromPool => GetResourceString("ArgumentException_BufferNotFromPool", null); internal static Type ResourceType => typeof(SR); [MethodImpl(MethodImplOptions.NoInlining)] private static bool UsingResourceKeys() { return false; } internal static string GetResourceString(string resourceKey, string defaultString) { string text = null; try { text = ResourceManager.GetString(resourceKey); } catch (MissingManifestResourceException) { } if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal)) { return defaultString; } return text; } internal static string Format(string resourceFormat, params object[] args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + string.Join(", ", args); } return string.Format(resourceFormat, args); } return resourceFormat; } internal static string Format(string resourceFormat, object p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(resourceFormat, p1); } internal static string Format(string resourceFormat, object p1, object p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(resourceFormat, p1, p2); } internal static string Format(string resourceFormat, object p1, object p2, object p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(resourceFormat, p1, p2, p3); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.All)] internal class __BlockReflectionAttribute : Attribute { } } namespace System.Buffers { public abstract class ArrayPool<T> { private static ArrayPool<T> s_sharedInstance; public static ArrayPool<T> Shared { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return Volatile.Read(ref s_sharedInstance) ?? EnsureSharedCreated(); } } [MethodImpl(MethodImplOptions.NoInlining)] private static ArrayPool<T> EnsureSharedCreated() { Interlocked.CompareExchange(ref s_sharedInstance, Create(), null); return s_sharedInstance; } public static ArrayPool<T> Create() { return new DefaultArrayPool<T>(); } public static ArrayPool<T> Create(int maxArrayLength, int maxArraysPerBucket) { return new DefaultArrayPool<T>(maxArrayLength, maxArraysPerBucket); } public abstract T[] Rent(int minimumLength); public abstract void Return(T[] array, bool clearArray = false); } [EventSource(Name = "System.Buffers.ArrayPoolEventSource")] internal sealed class ArrayPoolEventSource : EventSource { internal enum BufferAllocatedReason { Pooled, OverMaximumSize, PoolExhausted } internal static readonly System.Buffers.ArrayPoolEventSource Log = new System.Buffers.ArrayPoolEventSource(); [Event(1, Level = EventLevel.Verbose)] internal unsafe void BufferRented(int bufferId, int bufferSize, int poolId, int bucketId) { EventData* ptr = stackalloc EventData[4]; ptr->Size = 4; ptr->DataPointer = (IntPtr)(&bufferId); ptr[1].Size = 4; ptr[1].DataPointer = (IntPtr)(&bufferSize); ptr[2].Size = 4; ptr[2].DataPointer = (IntPtr)(&poolId); ptr[3].Size = 4; ptr[3].DataPointer = (IntPtr)(&bucketId); WriteEventCore(1, 4, ptr); } [Event(2, Level = EventLevel.Informational)] internal unsafe void BufferAllocated(int bufferId, int bufferSize, int poolId, int bucketId, BufferAllocatedReason reason) { EventData* ptr = stackalloc EventData[5]; ptr->Size = 4; ptr->DataPointer = (IntPtr)(&bufferId); ptr[1].Size = 4; ptr[1].DataPointer = (IntPtr)(&bufferSize); ptr[2].Size = 4; ptr[2].DataPointer = (IntPtr)(&poolId); ptr[3].Size = 4; ptr[3].DataPointer = (IntPtr)(&bucketId); ptr[4].Size = 4; ptr[4].DataPointer = (IntPtr)(&reason); WriteEventCore(2, 5, ptr); } [Event(3, Level = EventLevel.Verbose)] internal void BufferReturned(int bufferId, int bufferSize, int poolId) { WriteEvent(3, bufferId, bufferSize, poolId); } } internal sealed class DefaultArrayPool<T> : ArrayPool<T> { private sealed class Bucket { internal readonly int _bufferLength; private readonly T[][] _buffers; private readonly int _poolId; private SpinLock _lock; private int _index; internal int Id => GetHashCode(); internal Bucket(int bufferLength, int numberOfBuffers, int poolId) { _lock = new SpinLock(Debugger.IsAttached); _buffers = new T[numberOfBuffers][]; _bufferLength = bufferLength; _poolId = poolId; } internal T[] Rent() { T[][] buffers = _buffers; T[] array = null; bool lockTaken = false; bool flag = false; try { _lock.Enter(ref lockTaken); if (_index < buffers.Length) { array = buffers[_index]; buffers[_index++] = null; flag = array == null; } } finally { if (lockTaken) { _lock.Exit(useMemoryBarrier: false); } } if (flag) { array = new T[_bufferLength]; System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log; if (log.IsEnabled()) { log.BufferAllocated(array.GetHashCode(), _bufferLength, _poolId, Id, System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.Pooled); } } return array; } internal void Return(T[] array) { if (array.Length != _bufferLength) { throw new ArgumentException(System.SR.ArgumentException_BufferNotFromPool, "array"); } bool lockTaken = false; try { _lock.Enter(ref lockTaken); if (_index != 0) { _buffers[--_index] = array; } } finally { if (lockTaken) { _lock.Exit(useMemoryBarrier: false); } } } } private const int DefaultMaxArrayLength = 1048576; private const int DefaultMaxNumberOfArraysPerBucket = 50; private static T[] s_emptyArray; private readonly Bucket[] _buckets; private int Id => GetHashCode(); internal DefaultArrayPool() : this(1048576, 50) { } internal DefaultArrayPool(int maxArrayLength, int maxArraysPerBucket) { if (maxArrayLength <= 0) { throw new ArgumentOutOfRangeException("maxArrayLength"); } if (maxArraysPerBucket <= 0) { throw new ArgumentOutOfRangeException("maxArraysPerBucket"); } if (maxArrayLength > 1073741824) { maxArrayLength = 1073741824; } else if (maxArrayLength < 16) { maxArrayLength = 16; } int id = Id; int num = System.Buffers.Utilities.SelectBucketIndex(maxArrayLength); Bucket[] array = new Bucket[num + 1]; for (int i = 0; i < array.Length; i++) { array[i] = new Bucket(System.Buffers.Utilities.GetMaxSizeForBucket(i), maxArraysPerBucket, id); } _buckets = array; } public override T[] Rent(int minimumLength) { if (minimumLength < 0) { throw new ArgumentOutOfRangeException("minimumLength"); } if (minimumLength == 0) { return s_emptyArray ?? (s_emptyArray = new T[0]); } System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log; T[] array = null; int num = System.Buffers.Utilities.SelectBucketIndex(minimumLength); if (num < _buckets.Length) { int num2 = num; do { array = _buckets[num2].Rent(); if (array != null) { if (log.IsEnabled()) { log.BufferRented(array.GetHashCode(), array.Length, Id, _buckets[num2].Id); } return array; } } while (++num2 < _buckets.Length && num2 != num + 2); array = new T[_buckets[num]._bufferLength]; } else { array = new T[minimumLength]; } if (log.IsEnabled()) { int hashCode = array.GetHashCode(); int bucketId = -1; log.BufferRented(hashCode, array.Length, Id, bucketId); log.BufferAllocated(hashCode, array.Length, Id, bucketId, (num >= _buckets.Length) ? System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.OverMaximumSize : System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.PoolExhausted); } return array; } public override void Return(T[] array, bool clearArray = false) { if (array == null) { throw new ArgumentNullException("array"); } if (array.Length == 0) { return; } int num = System.Buffers.Utilities.SelectBucketIndex(array.Length); if (num < _buckets.Length) { if (clearArray) { Array.Clear(array, 0, array.Length); } _buckets[num].Return(array); } System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log; if (log.IsEnabled()) { log.BufferReturned(array.GetHashCode(), array.Length, Id); } } } internal static class Utilities { [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int SelectBucketIndex(int bufferSize) { uint num = (uint)(bufferSize - 1) >> 4; int num2 = 0; if (num > 65535) { num >>= 16; num2 = 16; } if (num > 255) { num >>= 8; num2 += 8; } if (num > 15) { num >>= 4; num2 += 4; } if (num > 3) { num >>= 2; num2 += 2; } if (num > 1) { num >>= 1; num2++; } return num2 + (int)num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int GetMaxSizeForBucket(int binIndex) { return 16 << binIndex; } } }
plugins/System.Memory.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers; using System.Buffers.Binary; using System.Buffers.Text; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Numerics; using System.Numerics.Hashing; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using FxResources.System.Memory; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: NeutralResourcesLanguage("en-US")] [assembly: AssemblyTitle("System.Memory")] [assembly: AssemblyDescription("System.Memory")] [assembly: AssemblyDefaultAlias("System.Memory")] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyProduct("Microsoft® .NET Framework")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyFileVersion("4.6.27617.02")] [assembly: AssemblyInformationalVersion("4.6.27617.02 @BuiltBy: dlab14-DDVSOWINAGE071 @Branch: release/2.1-MSRC @SrcCode: https://github.com/dotnet/corefx/tree/c6cf790234e063b855fcdb50f3fb1b3cfac73275")] [assembly: CLSCompliant(true)] [assembly: AssemblyMetadata(".NETFrameworkAssembly", "")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyMetadata("PreferInbox", "True")] [assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("4.0.1.1")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsByRefLikeAttribute : Attribute { } } namespace FxResources.System.Memory { internal static class SR { } } namespace System { public readonly struct SequencePosition : IEquatable<SequencePosition> { private readonly object _object; private readonly int _integer; public SequencePosition(object @object, int integer) { _object = @object; _integer = integer; } [EditorBrowsable(EditorBrowsableState.Never)] public object GetObject() { return _object; } [EditorBrowsable(EditorBrowsableState.Never)] public int GetInteger() { return _integer; } public bool Equals(SequencePosition other) { if (_integer == other._integer) { return object.Equals(_object, other._object); } return false; } [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object obj) { if (obj is SequencePosition other) { return Equals(other); } return false; } [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { return HashHelpers.Combine(_object?.GetHashCode() ?? 0, _integer); } } internal static class ThrowHelper { internal static void ThrowArgumentNullException(System.ExceptionArgument argument) { throw CreateArgumentNullException(argument); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArgumentNullException(System.ExceptionArgument argument) { return new ArgumentNullException(argument.ToString()); } internal static void ThrowArrayTypeMismatchException() { throw CreateArrayTypeMismatchException(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArrayTypeMismatchException() { return new ArrayTypeMismatchException(); } internal static void ThrowArgumentException_InvalidTypeWithPointersNotSupported(Type type) { throw CreateArgumentException_InvalidTypeWithPointersNotSupported(type); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArgumentException_InvalidTypeWithPointersNotSupported(Type type) { return new ArgumentException(System.SR.Format(System.SR.Argument_InvalidTypeWithPointersNotSupported, type)); } internal static void ThrowArgumentException_DestinationTooShort() { throw CreateArgumentException_DestinationTooShort(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArgumentException_DestinationTooShort() { return new ArgumentException(System.SR.Argument_DestinationTooShort); } internal static void ThrowIndexOutOfRangeException() { throw CreateIndexOutOfRangeException(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateIndexOutOfRangeException() { return new IndexOutOfRangeException(); } internal static void ThrowArgumentOutOfRangeException() { throw CreateArgumentOutOfRangeException(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArgumentOutOfRangeException() { return new ArgumentOutOfRangeException(); } internal static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument) { throw CreateArgumentOutOfRangeException(argument); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArgumentOutOfRangeException(System.ExceptionArgument argument) { return new ArgumentOutOfRangeException(argument.ToString()); } internal static void ThrowArgumentOutOfRangeException_PrecisionTooLarge() { throw CreateArgumentOutOfRangeException_PrecisionTooLarge(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArgumentOutOfRangeException_PrecisionTooLarge() { return new ArgumentOutOfRangeException("precision", System.SR.Format(System.SR.Argument_PrecisionTooLarge, (byte)99)); } internal static void ThrowArgumentOutOfRangeException_SymbolDoesNotFit() { throw CreateArgumentOutOfRangeException_SymbolDoesNotFit(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArgumentOutOfRangeException_SymbolDoesNotFit() { return new ArgumentOutOfRangeException("symbol", System.SR.Argument_BadFormatSpecifier); } internal static void ThrowInvalidOperationException() { throw CreateInvalidOperationException(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateInvalidOperationException() { return new InvalidOperationException(); } internal static void ThrowInvalidOperationException_OutstandingReferences() { throw CreateInvalidOperationException_OutstandingReferences(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateInvalidOperationException_OutstandingReferences() { return new InvalidOperationException(System.SR.OutstandingReferences); } internal static void ThrowInvalidOperationException_UnexpectedSegmentType() { throw CreateInvalidOperationException_UnexpectedSegmentType(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateInvalidOperationException_UnexpectedSegmentType() { return new InvalidOperationException(System.SR.UnexpectedSegmentType); } internal static void ThrowInvalidOperationException_EndPositionNotReached() { throw CreateInvalidOperationException_EndPositionNotReached(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateInvalidOperationException_EndPositionNotReached() { return new InvalidOperationException(System.SR.EndPositionNotReached); } internal static void ThrowArgumentOutOfRangeException_PositionOutOfRange() { throw CreateArgumentOutOfRangeException_PositionOutOfRange(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArgumentOutOfRangeException_PositionOutOfRange() { return new ArgumentOutOfRangeException("position"); } internal static void ThrowArgumentOutOfRangeException_OffsetOutOfRange() { throw CreateArgumentOutOfRangeException_OffsetOutOfRange(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArgumentOutOfRangeException_OffsetOutOfRange() { return new ArgumentOutOfRangeException("offset"); } internal static void ThrowObjectDisposedException_ArrayMemoryPoolBuffer() { throw CreateObjectDisposedException_ArrayMemoryPoolBuffer(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateObjectDisposedException_ArrayMemoryPoolBuffer() { return new ObjectDisposedException("ArrayMemoryPoolBuffer"); } internal static void ThrowFormatException_BadFormatSpecifier() { throw CreateFormatException_BadFormatSpecifier(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateFormatException_BadFormatSpecifier() { return new FormatException(System.SR.Argument_BadFormatSpecifier); } internal static void ThrowArgumentException_OverlapAlignmentMismatch() { throw CreateArgumentException_OverlapAlignmentMismatch(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArgumentException_OverlapAlignmentMismatch() { return new ArgumentException(System.SR.Argument_OverlapAlignmentMismatch); } internal static void ThrowNotSupportedException() { throw CreateThrowNotSupportedException(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateThrowNotSupportedException() { return new NotSupportedException(); } public static bool TryFormatThrowFormatException(out int bytesWritten) { bytesWritten = 0; ThrowFormatException_BadFormatSpecifier(); return false; } public static bool TryParseThrowFormatException<T>(out T value, out int bytesConsumed) { value = default(T); bytesConsumed = 0; ThrowFormatException_BadFormatSpecifier(); return false; } public static void ThrowArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment) { throw CreateArgumentValidationException(startSegment, startIndex, endSegment); } private static Exception CreateArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment) { if (startSegment == null) { return CreateArgumentNullException(System.ExceptionArgument.startSegment); } if (endSegment == null) { return CreateArgumentNullException(System.ExceptionArgument.endSegment); } if (startSegment != endSegment && startSegment.RunningIndex > endSegment.RunningIndex) { return CreateArgumentOutOfRangeException(System.ExceptionArgument.endSegment); } if ((uint)startSegment.Memory.Length < (uint)startIndex) { return CreateArgumentOutOfRangeException(System.ExceptionArgument.startIndex); } return CreateArgumentOutOfRangeException(System.ExceptionArgument.endIndex); } public static void ThrowArgumentValidationException(Array array, int start) { throw CreateArgumentValidationException(array, start); } private static Exception CreateArgumentValidationException(Array array, int start) { if (array == null) { return CreateArgumentNullException(System.ExceptionArgument.array); } if ((uint)start > (uint)array.Length) { return CreateArgumentOutOfRangeException(System.ExceptionArgument.start); } return CreateArgumentOutOfRangeException(System.ExceptionArgument.length); } public static void ThrowStartOrEndArgumentValidationException(long start) { throw CreateStartOrEndArgumentValidationException(start); } private static Exception CreateStartOrEndArgumentValidationException(long start) { if (start < 0) { return CreateArgumentOutOfRangeException(System.ExceptionArgument.start); } return CreateArgumentOutOfRangeException(System.ExceptionArgument.length); } } internal enum ExceptionArgument { length, start, minimumBufferSize, elementIndex, comparable, comparer, destination, offset, startSegment, endSegment, startIndex, endIndex, array, culture, manager } internal static class DecimalDecCalc { private static uint D32DivMod1E9(uint hi32, ref uint lo32) { ulong num = ((ulong)hi32 << 32) | lo32; lo32 = (uint)(num / 1000000000); return (uint)(num % 1000000000); } internal static uint DecDivMod1E9(ref MutableDecimal value) { return D32DivMod1E9(D32DivMod1E9(D32DivMod1E9(0u, ref value.High), ref value.Mid), ref value.Low); } internal static void DecAddInt32(ref MutableDecimal value, uint i) { if (D32AddCarry(ref value.Low, i) && D32AddCarry(ref value.Mid, 1u)) { D32AddCarry(ref value.High, 1u); } } private static bool D32AddCarry(ref uint value, uint i) { uint num = value; uint num2 = (value = num + i); if (num2 >= num) { return num2 < i; } return true; } internal static void DecMul10(ref MutableDecimal value) { MutableDecimal d = value; DecShiftLeft(ref value); DecShiftLeft(ref value); DecAdd(ref value, d); DecShiftLeft(ref value); } private static void DecShiftLeft(ref MutableDecimal value) { uint num = (((value.Low & 0x80000000u) != 0) ? 1u : 0u); uint num2 = (((value.Mid & 0x80000000u) != 0) ? 1u : 0u); value.Low <<= 1; value.Mid = (value.Mid << 1) | num; value.High = (value.High << 1) | num2; } private static void DecAdd(ref MutableDecimal value, MutableDecimal d) { if (D32AddCarry(ref value.Low, d.Low) && D32AddCarry(ref value.Mid, 1u)) { D32AddCarry(ref value.High, 1u); } if (D32AddCarry(ref value.Mid, d.Mid)) { D32AddCarry(ref value.High, 1u); } D32AddCarry(ref value.High, d.High); } } internal static class Number { private static class DoubleHelper { public unsafe static uint Exponent(double d) { return (*(uint*)((byte*)(&d) + 4) >> 20) & 0x7FFu; } public unsafe static ulong Mantissa(double d) { return *(uint*)(&d) | ((ulong)(uint)(*(int*)((byte*)(&d) + 4) & 0xFFFFF) << 32); } public unsafe static bool Sign(double d) { return *(uint*)((byte*)(&d) + 4) >> 31 != 0; } } internal const int DECIMAL_PRECISION = 29; private static readonly ulong[] s_rgval64Power10 = new ulong[30] { 11529215046068469760uL, 14411518807585587200uL, 18014398509481984000uL, 11258999068426240000uL, 14073748835532800000uL, 17592186044416000000uL, 10995116277760000000uL, 13743895347200000000uL, 17179869184000000000uL, 10737418240000000000uL, 13421772800000000000uL, 16777216000000000000uL, 10485760000000000000uL, 13107200000000000000uL, 16384000000000000000uL, 14757395258967641293uL, 11805916207174113035uL, 9444732965739290428uL, 15111572745182864686uL, 12089258196146291749uL, 9671406556917033399uL, 15474250491067253438uL, 12379400392853802751uL, 9903520314283042201uL, 15845632502852867522uL, 12676506002282294018uL, 10141204801825835215uL, 16225927682921336344uL, 12980742146337069075uL, 10384593717069655260uL }; private static readonly sbyte[] s_rgexp64Power10 = new sbyte[15] { 4, 7, 10, 14, 17, 20, 24, 27, 30, 34, 37, 40, 44, 47, 50 }; private static readonly ulong[] s_rgval64Power10By16 = new ulong[42] { 10240000000000000000uL, 11368683772161602974uL, 12621774483536188886uL, 14012984643248170708uL, 15557538194652854266uL, 17272337110188889248uL, 9588073174409622172uL, 10644899600020376798uL, 11818212630765741798uL, 13120851772591970216uL, 14567071740625403792uL, 16172698447808779622uL, 17955302187076837696uL, 9967194951097567532uL, 11065809325636130658uL, 12285516299433008778uL, 13639663065038175358uL, 15143067982934716296uL, 16812182738118149112uL, 9332636185032188787uL, 10361307573072618722uL, 16615349947311448416uL, 14965776766268445891uL, 13479973333575319909uL, 12141680576410806707uL, 10936253623915059637uL, 9850501549098619819uL, 17745086042373215136uL, 15983352577617880260uL, 14396524142538228461uL, 12967236152753103031uL, 11679847981112819795uL, 10520271803096747049uL, 9475818434452569218uL, 17070116948172427008uL, 15375394465392026135uL, 13848924157002783096uL, 12474001934591998882uL, 11235582092889474480uL, 10120112665365530972uL, 18230774251475056952uL, 16420821625123739930uL }; private static readonly short[] s_rgexp64Power10By16 = new short[21] { 54, 107, 160, 213, 266, 319, 373, 426, 479, 532, 585, 638, 691, 745, 798, 851, 904, 957, 1010, 1064, 1117 }; public static void RoundNumber(ref NumberBuffer number, int pos) { Span<byte> digits = number.Digits; int i; for (i = 0; i < pos && digits[i] != 0; i++) { } if (i == pos && digits[i] >= 53) { while (i > 0 && digits[i - 1] == 57) { i--; } if (i > 0) { digits[i - 1]++; } else { number.Scale++; digits[0] = 49; i = 1; } } else { while (i > 0 && digits[i - 1] == 48) { i--; } } if (i == 0) { number.Scale = 0; number.IsNegative = false; } digits[i] = 0; } internal static bool NumberBufferToDouble(ref NumberBuffer number, out double value) { double num = NumberToDouble(ref number); uint num2 = DoubleHelper.Exponent(num); ulong num3 = DoubleHelper.Mantissa(num); switch (num2) { case 2047u: value = 0.0; return false; case 0u: if (num3 == 0L) { num = 0.0; } break; } value = num; return true; } public unsafe static bool NumberBufferToDecimal(ref NumberBuffer number, ref decimal value) { MutableDecimal source = default(MutableDecimal); byte* ptr = number.UnsafeDigits; int num = number.Scale; if (*ptr == 0) { if (num > 0) { num = 0; } } else { if (num > 29) { return false; } while ((num > 0 || (*ptr != 0 && num > -28)) && (source.High < 429496729 || (source.High == 429496729 && (source.Mid < 2576980377u || (source.Mid == 2576980377u && (source.Low < 2576980377u || (source.Low == 2576980377u && *ptr <= 53))))))) { DecimalDecCalc.DecMul10(ref source); if (*ptr != 0) { DecimalDecCalc.DecAddInt32(ref source, (uint)(*(ptr++) - 48)); } num--; } if (*(ptr++) >= 53) { bool flag = true; if (*(ptr - 1) == 53 && *(ptr - 2) % 2 == 0) { int num2 = 20; while (*ptr == 48 && num2 != 0) { ptr++; num2--; } if (*ptr == 0 || num2 == 0) { flag = false; } } if (flag) { DecimalDecCalc.DecAddInt32(ref source, 1u); if ((source.High | source.Mid | source.Low) == 0) { source.High = 429496729u; source.Mid = 2576980377u; source.Low = 2576980378u; num++; } } } } if (num > 0) { return false; } if (num <= -29) { source.High = 0u; source.Low = 0u; source.Mid = 0u; source.Scale = 28; } else { source.Scale = -num; } source.IsNegative = number.IsNegative; value = Unsafe.As<MutableDecimal, decimal>(ref source); return true; } public static void DecimalToNumber(decimal value, ref NumberBuffer number) { ref MutableDecimal reference = ref Unsafe.As<decimal, MutableDecimal>(ref value); Span<byte> digits = number.Digits; number.IsNegative = reference.IsNegative; int num = 29; while ((reference.Mid != 0) | (reference.High != 0)) { uint num2 = DecimalDecCalc.DecDivMod1E9(ref reference); for (int i = 0; i < 9; i++) { digits[--num] = (byte)(num2 % 10 + 48); num2 /= 10; } } for (uint num3 = reference.Low; num3 != 0; num3 /= 10) { digits[--num] = (byte)(num3 % 10 + 48); } int num4 = 29 - num; number.Scale = num4 - reference.Scale; Span<byte> digits2 = number.Digits; int index = 0; while (--num4 >= 0) { digits2[index++] = digits[num++]; } digits2[index] = 0; } private static uint DigitsToInt(ReadOnlySpan<byte> digits, int count) { uint value; int bytesConsumed; bool flag = Utf8Parser.TryParse(digits.Slice(0, count), out value, out bytesConsumed, 'D'); return value; } private static ulong Mul32x32To64(uint a, uint b) { return (ulong)a * (ulong)b; } private static ulong Mul64Lossy(ulong a, ulong b, ref int pexp) { ulong num = Mul32x32To64((uint)(a >> 32), (uint)(b >> 32)) + (Mul32x32To64((uint)(a >> 32), (uint)b) >> 32) + (Mul32x32To64((uint)a, (uint)(b >> 32)) >> 32); if ((num & 0x8000000000000000uL) == 0L) { num <<= 1; pexp--; } return num; } private static int abs(int value) { if (value < 0) { return -value; } return value; } private unsafe static double NumberToDouble(ref NumberBuffer number) { ReadOnlySpan<byte> digits = number.Digits; int i = 0; int numDigits = number.NumDigits; int num = numDigits; for (; digits[i] == 48; i++) { num--; } if (num == 0) { return 0.0; } int num2 = Math.Min(num, 9); num -= num2; ulong num3 = DigitsToInt(digits, num2); if (num > 0) { num2 = Math.Min(num, 9); num -= num2; uint b = (uint)(s_rgval64Power10[num2 - 1] >> 64 - s_rgexp64Power10[num2 - 1]); num3 = Mul32x32To64((uint)num3, b) + DigitsToInt(digits.Slice(9), num2); } int num4 = number.Scale - (numDigits - num); int num5 = abs(num4); if (num5 >= 352) { ulong num6 = ((num4 > 0) ? 9218868437227405312uL : 0); if (number.IsNegative) { num6 |= 0x8000000000000000uL; } return *(double*)(&num6); } int pexp = 64; if ((num3 & 0xFFFFFFFF00000000uL) == 0L) { num3 <<= 32; pexp -= 32; } if ((num3 & 0xFFFF000000000000uL) == 0L) { num3 <<= 16; pexp -= 16; } if ((num3 & 0xFF00000000000000uL) == 0L) { num3 <<= 8; pexp -= 8; } if ((num3 & 0xF000000000000000uL) == 0L) { num3 <<= 4; pexp -= 4; } if ((num3 & 0xC000000000000000uL) == 0L) { num3 <<= 2; pexp -= 2; } if ((num3 & 0x8000000000000000uL) == 0L) { num3 <<= 1; pexp--; } int num7 = num5 & 0xF; if (num7 != 0) { int num8 = s_rgexp64Power10[num7 - 1]; pexp += ((num4 < 0) ? (-num8 + 1) : num8); ulong b2 = s_rgval64Power10[num7 + ((num4 < 0) ? 15 : 0) - 1]; num3 = Mul64Lossy(num3, b2, ref pexp); } num7 = num5 >> 4; if (num7 != 0) { int num9 = s_rgexp64Power10By16[num7 - 1]; pexp += ((num4 < 0) ? (-num9 + 1) : num9); ulong b3 = s_rgval64Power10By16[num7 + ((num4 < 0) ? 21 : 0) - 1]; num3 = Mul64Lossy(num3, b3, ref pexp); } if (((uint)(int)num3 & 0x400u) != 0) { ulong num10 = num3 + 1023 + (ulong)(((int)num3 >> 11) & 1); if (num10 < num3) { num10 = (num10 >> 1) | 0x8000000000000000uL; pexp++; } num3 = num10; } pexp += 1022; num3 = ((pexp <= 0) ? ((pexp == -52 && num3 >= 9223372036854775896uL) ? 1 : ((pexp > -52) ? (num3 >> -pexp + 11 + 1) : 0)) : ((pexp < 2047) ? ((ulong)((long)pexp << 52) + ((num3 >> 11) & 0xFFFFFFFFFFFFFL)) : 9218868437227405312uL)); if (number.IsNegative) { num3 |= 0x8000000000000000uL; } return *(double*)(&num3); } } internal ref struct NumberBuffer { public int Scale; public bool IsNegative; public const int BufferSize = 51; private byte _b0; private byte _b1; private byte _b2; private byte _b3; private byte _b4; private byte _b5; private byte _b6; private byte _b7; private byte _b8; private byte _b9; private byte _b10; private byte _b11; private byte _b12; private byte _b13; private byte _b14; private byte _b15; private byte _b16; private byte _b17; private byte _b18; private byte _b19; private byte _b20; private byte _b21; private byte _b22; private byte _b23; private byte _b24; private byte _b25; private byte _b26; private byte _b27; private byte _b28; private byte _b29; private byte _b30; private byte _b31; private byte _b32; private byte _b33; private byte _b34; private byte _b35; private byte _b36; private byte _b37; private byte _b38; private byte _b39; private byte _b40; private byte _b41; private byte _b42; private byte _b43; private byte _b44; private byte _b45; private byte _b46; private byte _b47; private byte _b48; private byte _b49; private byte _b50; public unsafe Span<byte> Digits => new Span<byte>(Unsafe.AsPointer(ref _b0), 51); public unsafe byte* UnsafeDigits => (byte*)Unsafe.AsPointer(ref _b0); public int NumDigits => Digits.IndexOf<byte>(0); [Conditional("DEBUG")] public void CheckConsistency() { } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append('['); stringBuilder.Append('"'); Span<byte> digits = Digits; for (int i = 0; i < 51; i++) { byte b = digits[i]; if (b == 0) { break; } stringBuilder.Append((char)b); } stringBuilder.Append('"'); stringBuilder.Append(", Scale = " + Scale); stringBuilder.Append(", IsNegative = " + IsNegative); stringBuilder.Append(']'); return stringBuilder.ToString(); } } [DebuggerTypeProxy(typeof(System.MemoryDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] public readonly struct Memory<T> { private readonly object _object; private readonly int _index; private readonly int _length; private const int RemoveFlagsBitMask = int.MaxValue; public static Memory<T> Empty => default(Memory<T>); public int Length => _length & 0x7FFFFFFF; public bool IsEmpty => (_length & 0x7FFFFFFF) == 0; public Span<T> Span { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { Span<T> result; if (_index < 0) { result = ((MemoryManager<T>)_object).GetSpan(); return result.Slice(_index & 0x7FFFFFFF, _length); } if (typeof(T) == typeof(char) && _object is string text) { result = new Span<T>(Unsafe.As<Pinnable<T>>(text), MemoryExtensions.StringAdjustment, text.Length); return result.Slice(_index, _length); } if (_object != null) { return new Span<T>((T[])_object, _index, _length & 0x7FFFFFFF); } result = default(Span<T>); return result; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Memory(T[] array) { if (array == null) { this = default(Memory<T>); return; } if (default(T) == null && array.GetType() != typeof(T[])) { System.ThrowHelper.ThrowArrayTypeMismatchException(); } _object = array; _index = 0; _length = array.Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Memory(T[] array, int start) { if (array == null) { if (start != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(); } this = default(Memory<T>); return; } if (default(T) == null && array.GetType() != typeof(T[])) { System.ThrowHelper.ThrowArrayTypeMismatchException(); } if ((uint)start > (uint)array.Length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(); } _object = array; _index = start; _length = array.Length - start; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Memory(T[] array, int start, int length) { if (array == null) { if (start != 0 || length != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(); } this = default(Memory<T>); return; } if (default(T) == null && array.GetType() != typeof(T[])) { System.ThrowHelper.ThrowArrayTypeMismatchException(); } if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(); } _object = array; _index = start; _length = length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Memory(MemoryManager<T> manager, int length) { if (length < 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(); } _object = manager; _index = int.MinValue; _length = length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Memory(MemoryManager<T> manager, int start, int length) { if (length < 0 || start < 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(); } _object = manager; _index = start | int.MinValue; _length = length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Memory(object obj, int start, int length) { _object = obj; _index = start; _length = length; } public static implicit operator Memory<T>(T[] array) { return new Memory<T>(array); } public static implicit operator Memory<T>(ArraySegment<T> segment) { return new Memory<T>(segment.Array, segment.Offset, segment.Count); } public static implicit operator ReadOnlyMemory<T>(Memory<T> memory) { return Unsafe.As<Memory<T>, ReadOnlyMemory<T>>(ref memory); } public override string ToString() { if (typeof(T) == typeof(char)) { if (!(_object is string text)) { return Span.ToString(); } return text.Substring(_index, _length & 0x7FFFFFFF); } return $"System.Memory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Memory<T> Slice(int start) { int length = _length; int num = length & 0x7FFFFFFF; if ((uint)start > (uint)num) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new Memory<T>(_object, _index + start, length - start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Memory<T> Slice(int start, int length) { int length2 = _length; int num = length2 & 0x7FFFFFFF; if ((uint)start > (uint)num || (uint)length > (uint)(num - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(); } return new Memory<T>(_object, _index + start, length | (length2 & int.MinValue)); } public void CopyTo(Memory<T> destination) { Span.CopyTo(destination.Span); } public bool TryCopyTo(Memory<T> destination) { return Span.TryCopyTo(destination.Span); } public unsafe MemoryHandle Pin() { if (_index < 0) { return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF); } if (typeof(T) == typeof(char) && _object is string value) { GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned); void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index); return new MemoryHandle(pointer, handle); } if (_object is T[] array) { if (_length < 0) { void* pointer2 = Unsafe.Add<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference<T>(array)), _index); return new MemoryHandle(pointer2); } GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned); void* pointer3 = Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index); return new MemoryHandle(pointer3, handle2); } return default(MemoryHandle); } public T[] ToArray() { return Span.ToArray(); } [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object obj) { if (obj is ReadOnlyMemory<T> readOnlyMemory) { return readOnlyMemory.Equals(this); } if (obj is Memory<T> other) { return Equals(other); } return false; } public bool Equals(Memory<T> other) { if (_object == other._object && _index == other._index) { return _length == other._length; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { if (_object == null) { return 0; } int hashCode = _object.GetHashCode(); int index = _index; int hashCode2 = index.GetHashCode(); index = _length; return CombineHashCodes(hashCode, hashCode2, index.GetHashCode()); } private static int CombineHashCodes(int left, int right) { return ((left << 5) + left) ^ right; } private static int CombineHashCodes(int h1, int h2, int h3) { return CombineHashCodes(CombineHashCodes(h1, h2), h3); } } internal sealed class MemoryDebugView<T> { private readonly ReadOnlyMemory<T> _memory; [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public T[] Items => _memory.ToArray(); public MemoryDebugView(Memory<T> memory) { _memory = memory; } public MemoryDebugView(ReadOnlyMemory<T> memory) { _memory = memory; } } public static class MemoryExtensions { internal static readonly IntPtr StringAdjustment = MeasureStringAdjustment(); public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span) { return span.TrimStart().TrimEnd(); } public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span) { int i; for (i = 0; i < span.Length && char.IsWhiteSpace(span[i]); i++) { } return span.Slice(i); } public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span) { int num = span.Length - 1; while (num >= 0 && char.IsWhiteSpace(span[num])) { num--; } return span.Slice(0, num + 1); } public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, char trimChar) { return span.TrimStart(trimChar).TrimEnd(trimChar); } public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, char trimChar) { int i; for (i = 0; i < span.Length && span[i] == trimChar; i++) { } return span.Slice(i); } public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, char trimChar) { int num = span.Length - 1; while (num >= 0 && span[num] == trimChar) { num--; } return span.Slice(0, num + 1); } public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars) { return span.TrimStart(trimChars).TrimEnd(trimChars); } public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars) { if (trimChars.IsEmpty) { return span.TrimStart(); } int i; for (i = 0; i < span.Length; i++) { int num = 0; while (num < trimChars.Length) { if (span[i] != trimChars[num]) { num++; continue; } goto IL_003c; } break; IL_003c:; } return span.Slice(i); } public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars) { if (trimChars.IsEmpty) { return span.TrimEnd(); } int num; for (num = span.Length - 1; num >= 0; num--) { int num2 = 0; while (num2 < trimChars.Length) { if (span[num] != trimChars[num2]) { num2++; continue; } goto IL_0044; } break; IL_0044:; } return span.Slice(0, num + 1); } public static bool IsWhiteSpace(this ReadOnlySpan<char> span) { for (int i = 0; i < span.Length; i++) { if (!char.IsWhiteSpace(span[i])) { return false; } } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOf<T>(this Span<T> span, T value) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length); } if (typeof(T) == typeof(char)) { return System.SpanHelpers.IndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length); } return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length); } return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOf<T>(this Span<T> span, T value) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length); } if (typeof(T) == typeof(char)) { return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length); } return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length); } return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool SequenceEqual<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IEquatable<T> { int length = span.Length; if (default(T) != null && IsTypeComparableAsBytes<T>(out var size)) { if (length == other.Length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size); } return false; } if (length == other.Length) { return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length); } return false; } public static int SequenceCompareTo<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IComparable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length); } if (typeof(T) == typeof(char)) { return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length); } return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length); } if (typeof(T) == typeof(char)) { return System.SpanHelpers.IndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length); } return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length); } return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length); } if (typeof(T) == typeof(char)) { return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length); } return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length); } return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length); } return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length); } return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length); } return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length); } return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length); } return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length); } return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length); } return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length); } return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length); } return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length); } return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length); } return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length); } return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool SequenceEqual<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IEquatable<T> { int length = span.Length; if (default(T) != null && IsTypeComparableAsBytes<T>(out var size)) { if (length == other.Length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size); } return false; } if (length == other.Length) { return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length); } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SequenceCompareTo<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IComparable<T> { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length); } if (typeof(T) == typeof(char)) { return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length); } return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool StartsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { int length = value.Length; if (default(T) != null && IsTypeComparableAsBytes<T>(out var size)) { if (length <= span.Length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size); } return false; } if (length <= span.Length) { return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length); } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool StartsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { int length = value.Length; if (default(T) != null && IsTypeComparableAsBytes<T>(out var size)) { if (length <= span.Length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size); } return false; } if (length <= span.Length) { return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length); } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool EndsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { int length = span.Length; int length2 = value.Length; if (default(T) != null && IsTypeComparableAsBytes<T>(out var size)) { if (length2 <= length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size); } return false; } if (length2 <= length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2); } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool EndsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { int length = span.Length; int length2 = value.Length; if (default(T) != null && IsTypeComparableAsBytes<T>(out var size)) { if (length2 <= length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size); } return false; } if (length2 <= length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2); } return false; } public static void Reverse<T>(this Span<T> span) { ref T reference = ref MemoryMarshal.GetReference(span); int num = 0; int num2 = span.Length - 1; while (num < num2) { T val = Unsafe.Add(ref reference, num); Unsafe.Add(ref reference, num) = Unsafe.Add(ref reference, num2); Unsafe.Add(ref reference, num2) = val; num++; num2--; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span<T> AsSpan<T>(this T[] array) { return new Span<T>(array); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span<T> AsSpan<T>(this T[] array, int start, int length) { return new Span<T>(array, start, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span<T> AsSpan<T>(this ArraySegment<T> segment) { return new Span<T>(segment.Array, segment.Offset, segment.Count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start) { if ((uint)start > segment.Count) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new Span<T>(segment.Array, segment.Offset + start, segment.Count - start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start, int length) { if ((uint)start > segment.Count) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } if ((uint)length > segment.Count - start) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length); } return new Span<T>(segment.Array, segment.Offset + start, length); } public static Memory<T> AsMemory<T>(this T[] array) { return new Memory<T>(array); } public static Memory<T> AsMemory<T>(this T[] array, int start) { return new Memory<T>(array, start); } public static Memory<T> AsMemory<T>(this T[] array, int start, int length) { return new Memory<T>(array, start, length); } public static Memory<T> AsMemory<T>(this ArraySegment<T> segment) { return new Memory<T>(segment.Array, segment.Offset, segment.Count); } public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start) { if ((uint)start > segment.Count) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new Memory<T>(segment.Array, segment.Offset + start, segment.Count - start); } public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start, int length) { if ((uint)start > segment.Count) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } if ((uint)length > segment.Count - start) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length); } return new Memory<T>(segment.Array, segment.Offset + start, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void CopyTo<T>(this T[] source, Span<T> destination) { new ReadOnlySpan<T>(source).CopyTo(destination); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void CopyTo<T>(this T[] source, Memory<T> destination) { source.CopyTo(destination.Span); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other) { return ((ReadOnlySpan<T>)span).Overlaps(other); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other, out int elementOffset) { return ((ReadOnlySpan<T>)span).Overlaps(other, out elementOffset); } public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) { if (span.IsEmpty || other.IsEmpty) { return false; } IntPtr intPtr = Unsafe.ByteOffset(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other)); if (Unsafe.SizeOf<IntPtr>() == 4) { if ((uint)(int)intPtr >= (uint)(span.Length * Unsafe.SizeOf<T>())) { return (uint)(int)intPtr > (uint)(-(other.Length * Unsafe.SizeOf<T>())); } return true; } if ((ulong)(long)intPtr >= (ulong)((long)span.Length * (long)Unsafe.SizeOf<T>())) { return (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)Unsafe.SizeOf<T>())); } return true; } public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other, out int elementOffset) { if (span.IsEmpty || other.IsEmpty) { elementOffset = 0; return false; } IntPtr intPtr = Unsafe.ByteOffset(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other)); if (Unsafe.SizeOf<IntPtr>() == 4) { if ((uint)(int)intPtr < (uint)(span.Length * Unsafe.SizeOf<T>()) || (uint)(int)intPtr > (uint)(-(other.Length * Unsafe.SizeOf<T>()))) { if ((int)intPtr % Unsafe.SizeOf<T>() != 0) { System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch(); } elementOffset = (int)intPtr / Unsafe.SizeOf<T>(); return true; } elementOffset = 0; return false; } if ((ulong)(long)intPtr < (ulong)((long)span.Length * (long)Unsafe.SizeOf<T>()) || (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)Unsafe.SizeOf<T>()))) { if ((long)intPtr % Unsafe.SizeOf<T>() != 0L) { System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch(); } elementOffset = (int)((long)intPtr / Unsafe.SizeOf<T>()); return true; } elementOffset = 0; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch<T>(this Span<T> span, IComparable<T> comparable) { return span.BinarySearch<T, IComparable<T>>(comparable); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch<T, TComparable>(this Span<T> span, TComparable comparable) where TComparable : IComparable<T> { return BinarySearch((ReadOnlySpan<T>)span, comparable); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch<T, TComparer>(this Span<T> span, T value, TComparer comparer) where TComparer : IComparer<T> { return ((ReadOnlySpan<T>)span).BinarySearch(value, comparer); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch<T>(this ReadOnlySpan<T> span, IComparable<T> comparable) { return MemoryExtensions.BinarySearch<T, IComparable<T>>(span, comparable); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T> { return System.SpanHelpers.BinarySearch(span, comparable); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch<T, TComparer>(this ReadOnlySpan<T> span, T value, TComparer comparer) where TComparer : IComparer<T> { if (comparer == null) { System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparer); } System.SpanHelpers.ComparerComparable<T, TComparer> comparable = new System.SpanHelpers.ComparerComparable<T, TComparer>(value, comparer); return BinarySearch(span, comparable); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool IsTypeComparableAsBytes<T>(out NUInt size) { if (typeof(T) == typeof(byte) || typeof(T) == typeof(sbyte)) { size = (NUInt)1; return true; } if (typeof(T) == typeof(char) || typeof(T) == typeof(short) || typeof(T) == typeof(ushort)) { size = (NUInt)2; return true; } if (typeof(T) == typeof(int) || typeof(T) == typeof(uint)) { size = (NUInt)4; return true; } if (typeof(T) == typeof(long) || typeof(T) == typeof(ulong)) { size = (NUInt)8; return true; } size = default(NUInt); return false; } public static Span<T> AsSpan<T>(this T[] array, int start) { return Span<T>.Create(array, start); } public static bool Contains(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType) { return span.IndexOf(value, comparisonType) >= 0; } public static bool Equals(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType) { switch (comparisonType) { case StringComparison.Ordinal: return span.SequenceEqual(other); case StringComparison.OrdinalIgnoreCase: if (span.Length != other.Length) { return false; } return EqualsOrdinalIgnoreCase(span, other); default: return span.ToString().Equals(other.ToString(), comparisonType); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool EqualsOrdinalIgnoreCase(ReadOnlySpan<char> span, ReadOnlySpan<char> other) { if (other.Length == 0) { return true; } return CompareToOrdinalIgnoreCase(span, other) == 0; } public static int CompareTo(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType) { return comparisonType switch { StringComparison.Ordinal => span.SequenceCompareTo(other), StringComparison.OrdinalIgnoreCase => CompareToOrdinalIgnoreCase(span, other), _ => string.Compare(span.ToString(), other.ToString(), comparisonType), }; } private unsafe static int CompareToOrdinalIgnoreCase(ReadOnlySpan<char> strA, ReadOnlySpan<char> strB) { int num = Math.Min(strA.Length, strB.Length); int num2 = num; fixed (char* ptr = &MemoryMarshal.GetReference(strA)) { fixed (char* ptr3 = &MemoryMarshal.GetReference(strB)) { char* ptr2 = ptr; char* ptr4 = ptr3; while (num != 0 && *ptr2 <= '\u007f' && *ptr4 <= '\u007f') { int num3 = *ptr2; int num4 = *ptr4; if (num3 == num4) { ptr2++; ptr4++; num--; continue; } if ((uint)(num3 - 97) <= 25u) { num3 -= 32; } if ((uint)(num4 - 97) <= 25u) { num4 -= 32; } if (num3 != num4) { return num3 - num4; } ptr2++; ptr4++; num--; } if (num == 0) { return strA.Length - strB.Length; } num2 -= num; return string.Compare(strA.Slice(num2).ToString(), strB.Slice(num2).ToString(), StringComparison.OrdinalIgnoreCase); } } } public static int IndexOf(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType) { if (comparisonType == StringComparison.Ordinal) { return span.IndexOf(value); } return span.ToString().IndexOf(value.ToString(), comparisonType); } public static int ToLower(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture) { if (culture == null) { System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture); } if (destination.Length < source.Length) { return -1; } string text = source.ToString(); string text2 = text.ToLower(culture); AsSpan(text2).CopyTo(destination); return source.Length; } public static int ToLowerInvariant(this ReadOnlySpan<char> source, Span<char> destination) { return source.ToLower(destination, CultureInfo.InvariantCulture); } public static int ToUpper(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture) { if (culture == null) { System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture); } if (destination.Length < source.Length) { return -1; } string text = source.ToString(); string text2 = text.ToUpper(culture); AsSpan(text2).CopyTo(destination); return source.Length; } public static int ToUpperInvariant(this ReadOnlySpan<char> source, Span<char> destination) { return source.ToUpper(destination, CultureInfo.InvariantCulture); } public static bool EndsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType) { switch (comparisonType) { case StringComparison.Ordinal: return span.EndsWith(value); case StringComparison.OrdinalIgnoreCase: if (value.Length <= span.Length) { return EqualsOrdinalIgnoreCase(span.Slice(span.Length - value.Length), value); } return false; default: { string text = span.ToString(); string value2 = value.ToString(); return text.EndsWith(value2, comparisonType); } } } public static bool StartsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType) { switch (comparisonType) { case StringComparison.Ordinal: return span.StartsWith(value); case StringComparison.OrdinalIgnoreCase: if (value.Length <= span.Length) { return EqualsOrdinalIgnoreCase(span.Slice(0, value.Length), value); } return false; default: { string text = span.ToString(); string value2 = value.ToString(); return text.StartsWith(value2, comparisonType); } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlySpan<char> AsSpan(this string text) { if (text == null) { return default(ReadOnlySpan<char>); } return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment, text.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlySpan<char> AsSpan(this string text, int start) { if (text == null) { if (start != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return default(ReadOnlySpan<char>); } if ((uint)start > (uint)text.Length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment + start * 2, text.Length - start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlySpan<char> AsSpan(this string text, int start, int length) { if (text == null) { if (start != 0 || length != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return default(ReadOnlySpan<char>); } if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment + start * 2, length); } public static ReadOnlyMemory<char> AsMemory(this string text) { if (text == null) { return default(ReadOnlyMemory<char>); } return new ReadOnlyMemory<char>(text, 0, text.Length); } public static ReadOnlyMemory<char> AsMemory(this string text, int start) { if (text == null) { if (start != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return default(ReadOnlyMemory<char>); } if ((uint)start > (uint)text.Length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new ReadOnlyMemory<char>(text, start, text.Length - start); } public static ReadOnlyMemory<char> AsMemory(this string text, int start, int length) { if (text == null) { if (start != 0 || length != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return default(ReadOnlyMemory<char>); } if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new ReadOnlyMemory<char>(text, start, length); } private unsafe static IntPtr MeasureStringAdjustment() { string text = "a"; fixed (char* source = text) { return Unsafe.ByteOffset(ref Unsafe.As<Pinnable<char>>(text).Data, ref Unsafe.AsRef<char>(source)); } } } [DebuggerTypeProxy(typeof(System.MemoryDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] public readonly struct ReadOnlyMemory<T> { private readonly object _object; private readonly int _index; private readonly int _length; internal const int RemoveFlagsBitMask = int.MaxValue; public static ReadOnlyMemory<T> Empty => default(ReadOnlyMemory<T>); public int Length => _length & 0x7FFFFFFF; public bool IsEmpty => (_length & 0x7FFFFFFF) == 0; public ReadOnlySpan<T> Span { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if (_index < 0) { return ((MemoryManager<T>)_object).GetSpan().Slice(_index & 0x7FFFFFFF, _length); } ReadOnlySpan<T> result; if (typeof(T) == typeof(char) && _object is string text) { result = new ReadOnlySpan<T>(Unsafe.As<Pinnable<T>>(text), MemoryExtensions.StringAdjustment, text.Length); return result.Slice(_index, _length); } if (_object != null) { return new ReadOnlySpan<T>((T[])_object, _index, _length & 0x7FFFFFFF); } result = default(ReadOnlySpan<T>); return result; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlyMemory(T[] array) { if (array == null) { this = default(ReadOnlyMemory<T>); return; } _object = array; _index = 0; _length = array.Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlyMemory(T[] array, int start, int length) { if (array == null) { if (start != 0 || length != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(); } this = default(ReadOnlyMemory<T>); return; } if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(); } _object = array; _index = start; _length = length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ReadOnlyMemory(object obj, int start, int length) { _object = obj; _index = start; _length = length; } public static implicit operator ReadOnlyMemory<T>(T[] array) { return new ReadOnlyMemory<T>(array); } public static implicit operator ReadOnlyMemory<T>(ArraySegment<T> segment) { return new ReadOnlyMemory<T>(segment.Array, segment.Offset, segment.Count); } public override string ToString() { if (typeof(T) == typeof(char)) { if (!(_object is string text)) { return Span.ToString(); } return text.Substring(_index, _length & 0x7FFFFFFF); } return $"System.ReadOnlyMemory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlyMemory<T> Slice(int start) { int length = _length; int num = length & 0x7FFFFFFF; if ((uint)start > (uint)num) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new ReadOnlyMemory<T>(_object, _index + start, length - start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlyMemory<T> Slice(int start, int length) { int length2 = _length; int num = _length & 0x7FFFFFFF; if ((uint)start > (uint)num || (uint)length > (uint)(num - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new ReadOnlyMemory<T>(_object, _index + start, length | (length2 & int.MinValue)); } public void CopyTo(Memory<T> destination) { Span.CopyTo(destination.Span); } public bool TryCopyTo(Memory<T> destination) { return Span.TryCopyTo(destination.Span); } public unsafe MemoryHandle Pin() { if (_index < 0) { return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF); } if (typeof(T) == typeof(char) && _object is string value) { GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned); void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index); return new MemoryHandle(pointer, handle); } if (_object is T[] array) { if (_length < 0) { void* pointer2 = Unsafe.Add<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference<T>(array)), _index); return new MemoryHandle(pointer2); } GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned); void* pointer3 = Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index); return new MemoryHandle(pointer3, handle2); } return default(MemoryHandle); } public T[] ToArray() { return Span.ToArray(); } [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object obj) { if (obj is ReadOnlyMemory<T> other) { return Equals(other); } if (obj is Memory<T> memory) { return Equals(memory); } return false; } public bool Equals(ReadOnlyMemory<T> other) { if (_object == other._object && _index == other._index) { return _length == other._length; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { if (_object == null) { return 0; } int hashCode = _object.GetHashCode(); int index = _index; int hashCode2 = index.GetHashCode(); index = _length; return CombineHashCodes(hashCode, hashCode2, index.GetHashCode()); } private static int CombineHashCodes(int left, int right) { return ((left << 5) + left) ^ right; } private static int CombineHashCodes(int h1, int h2, int h3) { return CombineHashCodes(CombineHashCodes(h1, h2), h3); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal object GetObjectStartLength(out int start, out int length) { start = _index; length = _length; return _object; } } [DebuggerTypeProxy(typeof(System.SpanDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] [DebuggerTypeProxy(typeof(System.SpanDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] public readonly ref struct ReadOnlySpan<T> { public ref struct Enumerator { private readonly ReadOnlySpan<T> _span; private int _index; public ref readonly T Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _span[_index]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Enumerator(ReadOnlySpan<T> span) { _span = span; _index = -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() { int num = _index + 1; if (num < _span.Length) { _index = num; return true; } return false; } } private readonly Pinnable<T> _pinnable; private readonly IntPtr _byteOffset; private readonly int _length; public int Length => _length; public bool IsEmpty => _length == 0; public static ReadOnlySpan<T> Empty => default(ReadOnlySpan<T>); public unsafe ref readonly T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if ((uint)index >= (uint)_length) { System.ThrowHelper.ThrowIndexOutOfRangeException(); } if (_pinnable == null) { IntPtr byteOffset = _byteOffset; return ref Unsafe.Add(ref Unsafe.AsRef<T>(byteOffset.ToPointer()), index); } return ref Unsafe.Add(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset), index); } } internal Pinnable<T> Pinnable => _pinnable; internal IntPtr ByteOffset => _byteOffset; public static bool operator !=(ReadOnlySpan<T> left, ReadOnlySpan<T> right) { return !(left == right); } [Obsolete("Equals() on ReadOnlySpan will always throw an exception. Use == instead.")] [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object obj) { throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan); } [Obsolete("GetHashCode() on ReadOnlySpan will always throw an exception.")] [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan); } public static implicit operator ReadOnlySpan<T>(T[] array) { return new ReadOnlySpan<T>(array); } public static implicit operator ReadOnlySpan<T>(ArraySegment<T> segment) { return new ReadOnlySpan<T>(segment.Array, segment.Offset, segment.Count); } public Enumerator GetEnumerator() { return new Enumerator(this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan(T[] array) { if (array == null) { this = default(ReadOnlySpan<T>); return; } _length = array.Length; _pinnable = Unsafe.As<Pinnable<T>>(array); _byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan(T[] array, int start, int length) { if (array == null) { if (start != 0 || length != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } this = default(ReadOnlySpan<T>); return; } if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } _length = length; _pinnable = Unsafe.As<Pinnable<T>>(array); _byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public unsafe ReadOnlySpan(void* pointer, int length) { if (System.SpanHelpers.IsReferenceOrContainsReferences<T>()) { System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T)); } if (length < 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } _length = length; _pinnable = null; _byteOffset = new IntPtr(pointer); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ReadOnlySpan(Pinnable<T> pinnable, IntPtr byteOffset, int length) { _length = length; _pinnable = pinnable; _byteOffset = byteOffset; } [EditorBrowsable(EditorBrowsableState.Never)] public unsafe ref readonly T GetPinnableReference() { if (_length != 0) { if (_pinnable == null) { IntPtr byteOffset = _byteOffset; return ref Unsafe.AsRef<T>(byteOffset.ToPointer()); } return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset); } return ref Unsafe.AsRef<T>(null); } public void CopyTo(Span<T> destination) { if (!TryCopyTo(destination)) { System.ThrowHelper.ThrowArgumentException_DestinationTooShort(); } } public bool TryCopyTo(Span<T> destination) { int length = _length; int length2 = destination.Length; if (length == 0) { return true; } if ((uint)length > (uint)length2) { return false; } ref T src = ref DangerousGetPinnableReference(); System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length); return true; } public static bool operator ==(ReadOnlySpan<T> left, ReadOnlySpan<T> right) { if (left._length == right._length) { return Unsafe.AreSame(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference()); } return false; } public unsafe override string ToString() { if (typeof(T) == typeof(char)) { if (_byteOffset == MemoryExtensions.StringAdjustment) { object obj = Unsafe.As<object>(_pinnable); if (obj is string text && _length == text.Length) { return text; } } fixed (char* value = &Unsafe.As<T, char>(ref DangerousGetPinnableReference())) { return new string(value, 0, _length); } } return $"System.ReadOnlySpan<{typeof(T).Name}>[{_length}]"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan<T> Slice(int start) { if ((uint)start > (uint)_length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } IntPtr byteOffset = _byteOffset.Add<T>(start); int length = _length - start; return new ReadOnlySpan<T>(_pinnable, byteOffset, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan<T> Slice(int start, int length) { if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } IntPtr byteOffset = _byteOffset.Add<T>(start); return new ReadOnlySpan<T>(_pinnable, byteOffset, length); } public T[] ToArray() { if (_length == 0) { return System.SpanHelpers.PerTypeValues<T>.EmptyArray; } T[] array = new T[_length]; CopyTo(array); return array; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [EditorBrowsable(EditorBrowsableState.Never)] internal unsafe ref T DangerousGetPinnableReference() { if (_pinnable == null) { IntPtr byteOffset = _byteOffset; return ref Unsafe.AsRef<T>(byteOffset.ToPointer()); } return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset); } } [DebuggerTypeProxy(typeof(System.SpanDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] [DebuggerTypeProxy(typeof(System.SpanDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] public readonly ref struct Span<T> { public ref struct Enumerator { private readonly Span<T> _span; private int _index; public ref T Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _span[_index]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Enumerator(Span<T> span) { _span = span; _index = -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() { int num = _index + 1; if (num < _span.Length) { _index = num; return true; } return false; } } private readonly Pinnable<T> _pinnable; private readonly IntPtr _byteOffset; private readonly int _length; public int Length => _length; public bool IsEmpty => _length == 0; public static Span<T> Empty => default(Span<T>); public unsafe ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if ((uint)index >= (uint)_length) { System.ThrowHelper.ThrowIndexOutOfRangeException(); } if (_pinnable == null) { IntPtr byteOffset = _byteOffset; return ref Unsafe.Add(ref Unsafe.AsRef<T>(byteOffset.ToPointer()), index); } return ref Unsafe.Add(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset), index); } } internal Pinnable<T> Pinnable => _pinnable; internal IntPtr ByteOffset => _byteOffset; public static bool operator !=(Span<T> left, Span<T> right) { return !(left == right); } [Obsolete("Equals() on Span will always throw an exception. Use == instead.")] [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object obj) { throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan); } [Obsolete("GetHashCode() on Span will always throw an exception.")] [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan); } public static implicit operator Span<T>(T[] array) { return new Span<T>(array); } public static implicit operator Span<T>(ArraySegment<T> segment) { return new Span<T>(segment.Array, segment.Offset, segment.Count); } public Enumerator GetEnumerator() { return new Enumerator(this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Span(T[] array) { if (array == null) { this = default(Span<T>); return; } if (default(T) == null && array.GetType() != typeof(T[])) { System.ThrowHelper.ThrowArrayTypeMismatchException(); } _length = array.Length; _pinnable = Unsafe.As<Pinnable<T>>(array); _byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Span<T> Create(T[] array, int start) { if (array == null) { if (start != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return default(Span<T>); } if (default(T) == null && array.GetType() != typeof(T[])) { System.ThrowHelper.ThrowArrayTypeMismatchException(); } if ((uint)start > (uint)array.Length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } IntPtr byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start); int length = array.Length - start; return new Span<T>(Unsafe.As<Pinnable<T>>(array), byteOffset, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Span(T[] array, int start, int length) { if (array == null) { if (start != 0 || length != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } this = default(Span<T>); return; } if (default(T) == null && array.GetType() != typeof(T[])) { System.ThrowHelper.ThrowArrayTypeMismatchException(); } if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } _length = length; _pinnable = Unsafe.As<Pinnable<T>>(array); _byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public unsafe Span(void* pointer, int length) { if (System.SpanHelpers.IsReferenceOrContainsReferences<T>()) { System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T)); } if (length < 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } _length = length; _pinnable = null; _byteOffset = new IntPtr(pointer); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Span(Pinnable<T> pinnable, IntPtr byteOffset, int length) { _length = length; _pinnable = pinnable; _byteOffset = byteOffset; } [EditorBrowsable(EditorBrowsableState.Never)] public unsafe ref T GetPinnableReference() { if (_length != 0) { if (_pinnable == null) { IntPtr byteOffset = _byteOffset; return ref Unsafe.AsRef<T>(byteOffset.ToPointer()); } return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset); } return ref Unsafe.AsRef<T>(null); } public unsafe void Clear() { int length = _length; if (length == 0) { return; } UIntPtr byteLength = (UIntPtr)(ulong)((uint)length * Unsafe.SizeOf<T>()); if ((Unsafe.SizeOf<T>() & (sizeof(IntPtr) - 1)) != 0) { if (_pinnable == null) { IntPtr byteOffset = _byteOffset; byte* ptr = (byte*)byteOffset.ToPointer(); System.SpanHelpers.ClearLessThanPointerSized(ptr, byteLength); } else { System.SpanHelpers.ClearLessThanPointerSized(ref Unsafe.As<T, byte>(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset)), byteLength); } } else if (System.SpanHelpers.IsReferenceOrContainsReferences<T>()) { UIntPtr pointerSizeLength = (UIntPtr)(ulong)(length * Unsafe.SizeOf<T>() / sizeof(IntPtr)); System.SpanHelpers.ClearPointerSizedWithReferences(ref Unsafe.As<T, IntPtr>(ref DangerousGetPinnableReference()), pointerSizeLength); } else { System.SpanHelpers.ClearPointerSizedWithoutReferences(ref Unsafe.As<T, byte>(ref DangerousGetPinnableReference()), byteLength); } } public unsafe void Fill(T value) { int length = _length; if (length == 0) { return; } if (Unsafe.SizeOf<T>() == 1) { byte value2 = Unsafe.As<T, byte>(ref value); if (_pinnable == null) { IntPtr byteOffset = _byteOffset; Unsafe.InitBlockUnaligned(byteOffset.ToPointer(), value2, (uint)length); } else { Unsafe.InitBlockUnaligned(ref Unsafe.As<T, byte>(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset)), value2, (uint)length); } return; } ref T source = ref DangerousGetPinnableReference(); int i; for (i = 0; i < (length & -8); i += 8) { Unsafe.Add(ref source, i) = value; Unsafe.Add(ref source, i + 1) = value; Unsafe.Add(ref source, i + 2) = value; Unsafe.Add(ref source, i + 3) = value; Unsafe.Add(ref source, i + 4) = value; Unsafe.Add(ref source, i + 5) = value; Unsafe.Add(ref source, i + 6) = value; Unsafe.Add(ref source, i + 7) = value; } if (i < (length & -4)) { Unsafe.Add(ref source, i) = value; Unsafe.Add(ref source, i + 1) = value; Unsafe.Add(ref source, i + 2) = value; Unsafe.Add(ref source, i + 3) = value; i += 4; } for (; i < length; i++) { Unsafe.Add(ref source, i) = value; } } public void CopyTo(Span<T> destination) { if (!TryCopyTo(destination)) { System.ThrowHelper.ThrowArgumentException_DestinationTooShort(); } } public bool TryCopyTo(Span<T> destination) { int length = _length; int length2 = destination._length; if (length == 0) { return true; } if ((uint)length > (uint)length2) { return false; } ref T src = ref DangerousGetPinnableReference(); System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length); return true; } public static bool operator ==(Span<T> left, Span<T> right) { if (left._length == right._length) { return Unsafe.AreSame(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference()); } return false; } public static implicit operator ReadOnlySpan<T>(Span<T> span) { return new ReadOnlySpan<T>(span._pinnable, span._byteOffset, span._length); } public unsafe override string ToString() { if (typeof(T) == typeof(char)) { fixed (char* value = &Unsafe.As<T, char>(ref DangerousGetPinnableReference())) { return new string(value, 0, _length); } } return $"System.Span<{typeof(T).Name}>[{_length}]"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Span<T> Slice(int start) { if ((uint)start > (uint)_length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } IntPtr byteOffset = _byteOffset.Add<T>(start); int length = _length - start; return new Span<T>(_pinnable, byteOffset, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Span<T> Slice(int start, int length) { if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } IntPtr byteOffset = _byteOffset.Add<T>(start); return new Span<T>(_pinnable, byteOffset, length); } public T[] ToArray() { if (_length == 0) { return System.SpanHelpers.PerTypeValues<T>.EmptyArray; } T[] array = new T[_length]; CopyTo(array); return array; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [EditorBrowsable(EditorBrowsableState.Never)] internal unsafe ref T DangerousGetPinnableReference() { if (_pinnable == null) { IntPtr byteOffset = _byteOffset; return ref Unsafe.AsRef<T>(byteOffset.ToPointer()); } return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset); } } internal sealed class SpanDebugView<T> { private readonly T[] _array; [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public T[] Items => _array; public SpanDebugView(Span<T> span) { _array = span.ToArray(); } public SpanDebugView(ReadOnlySpan<T> span) { _array = span.ToArray(); } } internal static class SpanHelpers { internal struct ComparerComparable<T, TComparer> : IComparable<T> where TComparer : IComparer<T> { private readonly T _value; private readonly TComparer _comparer; public ComparerComparable(T value, TComparer comparer) { _value = value; _comparer = comparer; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CompareTo(T other) { return _comparer.Compare(_value, other); } } [StructLayout(LayoutKind.Sequential, Size = 64)] private struct Reg64 { } [StructLayout(LayoutKind.Sequential, Size = 32)] private struct Reg32 { } [StructLayout(LayoutKind.Sequential, Size = 16)] private struct Reg16 { } public static class PerTypeValues<T> { public static readonly bool IsReferenceOrContainsReferences = IsReferenceOrContainsReferencesCore(typeof(T)); public static readonly T[] EmptyArray = new T[0]; public static readonly IntPtr ArrayAdjustment = MeasureArrayAdjustment(); private static IntPtr MeasureArrayAdjustment() { T[] array = new T[1]; return Unsafe.ByteOffset(ref Unsafe.As<Pinnable<T>>(array).Data, ref array[0]); } } private const ulong XorPowerOfTwoToHighByte = 283686952306184uL; private const ulong XorPowerOfTwoToHighChar = 4295098372uL; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T> { if (comparable == null) { System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparable); } return BinarySearch(ref MemoryMarshal.GetReference(span), span.Length, comparable); } public static int BinarySearch<T, TComparable>(ref T spanStart, int length, TComparable comparable) where TComparable : IComparable<T> { int num = 0; int num2 = length - 1; while (num <= num2) { int num3 = num2 + num >>> 1; int num4 = comparable.CompareTo(Unsafe.Add(ref spanStart, num3)); if (num4 == 0) { return num3; } if (num4 > 0) { num = num3 + 1; } else { num2 = num3 - 1; } } return ~num; } public static int IndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength) { if (valueLength == 0) { return 0; } byte value2 = value; ref byte second = ref Unsafe.Add(ref value, 1); int num = valueLength - 1; int num2 = 0; while (true) { int num3 = searchSpaceLength - num2 - num; if (num3 <= 0) { break; } int num4 = IndexOf(ref Unsafe.Add(ref searchSpace, num2), value2, num3); if (num4 == -1) { break; } num2 += num4; if (SequenceEqual(ref Unsafe.Add(ref searchSpace, num2 + 1), ref second, num)) { return num2; } num2++; } return -1; } public static int IndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength) { if (valueLength == 0) { return 0; } int num = -1; for (int i = 0; i < valueLength; i++) { int num2 = IndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength); if ((uint)num2 < (uint)num) { num = num2; searchSpaceLength = num2; if (num == 0) { break; } } } return num; } public static int LastIndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength) { if (valueLength == 0) { return 0; } int num = -1; for (int i = 0; i < valueLength; i++) { int num2 = LastIndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength); if (num2 > num) { num = num2; } } return num; } public unsafe static int IndexOf(ref byte searchSpace, byte value, int length) { IntPtr intPtr = (IntPtr)0; IntPtr intPtr2 = (IntPtr)length; if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2) { int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1); intPtr2 = (IntPtr)((Vector<byte>.Count - num) & (Vector<byte>.Count - 1)); } while (true) { if ((nuint)(void*)intPtr2 >= (nuint)8u) { intPtr2 -= 8; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr)) { goto IL_0242; } if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1)) { goto IL_024a; } if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2)) { goto IL_0258; } if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 3)) { if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 4)) { if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 5)) { if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 6)) { if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 7)) { break; } intPtr += 8; continue; } return (int)(void*)(intPtr + 6); } return (int)(void*)(intPtr + 5); } return (int)(void*)(intPtr + 4); } goto IL_0266; } if ((nuint)(void*)intPtr2 >= (nuint)4u) { intPtr2 -= 4; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr)) { goto IL_0242; } if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1)) { goto IL_024a; } if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2)) { goto IL_0258; } if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3)) { goto IL_0266; } intPtr += 4; } while ((void*)intPtr2 != null) { intPtr2 -= 1; if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr)) { intPtr += 1; continue; } goto IL_0242; } if (Vector.IsHardwareAccelerated && (int)(void*)intPtr < length) { intPtr2 = (IntPtr)((length - (int)(void*)intPtr) & ~(Vector<byte>.Count - 1)); Vector<byte> vector = GetVector(value); for (; (void*)intPtr2 > (void*)intPtr; intPtr += Vector<byte>.Count) { Vector<byte> vector2 = Vector.Equals(vector, Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr))); if (!Vector<byte>.Zero.Equals(vector2)) { return (int)(void*)intPtr + LocateFirstFoundByte(vector2); } } if ((int)(void*)intPtr < length) { intPtr2 = (IntPtr)(length - (int)(void*)intPtr); continue; } } return -1; IL_0266: return (int)(void*)(intPtr + 3); IL_0242: return (int)(void*)intPtr; IL_0258: return (int)(void*)(intPtr + 2); IL_024a: return (int)(void*)(intPtr + 1); } return (int)(void*)(intPtr + 7); } public static int LastIndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength) { if (valueLength == 0) { return 0; } byte value2 = value; ref byte second = ref Unsafe.Add(ref value, 1); int num = valueLength - 1; int num2 = 0; while (true) { int num3 = searchSpaceLength - num2 - num; if (num3 <= 0) { break; } int num4 = LastIndexOf(ref searchSpace, value2, num3); if (num4 == -1) { break; } if (SequenceEqual(ref Unsafe.Add(ref searchSpace, num4 + 1), ref second, num)) { return num4; } num2 += num3 - num4; } return -1; } public unsafe static int LastIndexOf(ref byte searchSpace, byte value, int length) { IntPtr intPtr = (IntPtr)length; IntPtr intPtr2 = (IntPtr)length; if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2) { int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1); intPtr2 = (IntPtr)(((length & (Vector<byte>.Count - 1)) + num) & (Vector<byte>.Count - 1)); } while (true) { if ((nuint)(void*)intPtr2 >= (nuint)8u) { intPtr2 -= 8; intPtr -= 8; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 7)) { break; } if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 6)) { if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 5)) { if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 4)) { if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 3)) { if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 2)) { if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 1)) { if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr)) { continue; } goto IL_0254; } goto IL_025c; } goto IL_026a; } goto IL_0278; } return (int)(void*)(intPtr + 4); } return (int)(void*)(intPtr + 5); } return (int)(void*)(intPtr + 6); } if ((nuint)(void*)intPtr2 >= (nuint)4u) { intPtr2 -= 4; intPtr -= 4; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3)) { goto IL_0278; } if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2)) { goto IL_026a; } if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1)) { goto IL_025c; } if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr)) { goto IL_0254; } } while ((void*)intPtr2 != null) { intPtr2 -= 1; intPtr -= 1; if (value !
plugins/System.Numerics.Vectors.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Diagnostics; using System.Globalization; using System.Numerics; using System.Numerics.Hashing; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using FxResources.System.Numerics.Vectors; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: NeutralResourcesLanguage("en-US")] [assembly: AssemblyTitle("System.Numerics.Vectors")] [assembly: AssemblyDescription("System.Numerics.Vectors")] [assembly: AssemblyDefaultAlias("System.Numerics.Vectors")] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyProduct("Microsoft® .NET Framework")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyFileVersion("4.6.25519.03")] [assembly: AssemblyInformationalVersion("4.6.25519.03 built by: dlab-DDVSOWINAGE013. Commit Hash: 8321c729934c0f8be754953439b88e6e1c120c24")] [assembly: CLSCompliant(true)] [assembly: AssemblyMetadata(".NETFrameworkAssembly", "")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyMetadata("PreferInbox", "True")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("4.1.3.0")] [assembly: TypeForwardedTo(typeof(Matrix3x2))] [assembly: TypeForwardedTo(typeof(Matrix4x4))] [assembly: TypeForwardedTo(typeof(Plane))] [assembly: TypeForwardedTo(typeof(Quaternion))] [assembly: TypeForwardedTo(typeof(Vector2))] [assembly: TypeForwardedTo(typeof(Vector3))] [assembly: TypeForwardedTo(typeof(Vector4))] [module: UnverifiableCode] namespace FxResources.System.Numerics.Vectors { internal static class SR { } } namespace System { internal static class MathF { public const float PI = 3.1415927f; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Abs(float x) { return Math.Abs(x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Acos(float x) { return (float)Math.Acos(x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Cos(float x) { return (float)Math.Cos(x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float IEEERemainder(float x, float y) { return (float)Math.IEEERemainder(x, y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Sin(float x) { return (float)Math.Sin(x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Sqrt(float x) { return (float)Math.Sqrt(x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Tan(float x) { return (float)Math.Tan(x); } } internal static class SR { private static ResourceManager s_resourceManager; private const string s_resourcesName = "FxResources.System.Numerics.Vectors.SR"; private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType)); internal static string Arg_ArgumentOutOfRangeException => GetResourceString("Arg_ArgumentOutOfRangeException", null); internal static string Arg_ElementsInSourceIsGreaterThanDestination => GetResourceString("Arg_ElementsInSourceIsGreaterThanDestination", null); internal static string Arg_NullArgumentNullRef => GetResourceString("Arg_NullArgumentNullRef", null); internal static string Arg_TypeNotSupported => GetResourceString("Arg_TypeNotSupported", null); internal static Type ResourceType => typeof(SR); [MethodImpl(MethodImplOptions.NoInlining)] private static bool UsingResourceKeys() { return false; } internal static string GetResourceString(string resourceKey, string defaultString) { string text = null; try { text = ResourceManager.GetString(resourceKey); } catch (MissingManifestResourceException) { } if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal)) { return defaultString; } return text; } internal static string Format(string resourceFormat, params object[] args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + string.Join(", ", args); } return string.Format(resourceFormat, args); } return resourceFormat; } internal static string Format(string resourceFormat, object p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(resourceFormat, p1); } internal static string Format(string resourceFormat, object p1, object p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(resourceFormat, p1, p2); } internal static string Format(string resourceFormat, object p1, object p2, object p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(resourceFormat, p1, p2, p3); } } } namespace System.Numerics { internal class ConstantHelper { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte GetByteWithAllBitsSet() { byte result = 0; result = byte.MaxValue; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte GetSByteWithAllBitsSet() { sbyte result = 0; result = -1; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort GetUInt16WithAllBitsSet() { ushort result = 0; result = ushort.MaxValue; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short GetInt16WithAllBitsSet() { short result = 0; result = -1; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint GetUInt32WithAllBitsSet() { uint result = 0u; result = uint.MaxValue; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetInt32WithAllBitsSet() { int result = 0; result = -1; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong GetUInt64WithAllBitsSet() { ulong result = 0uL; result = ulong.MaxValue; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long GetInt64WithAllBitsSet() { long result = 0L; result = -1L; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static float GetSingleWithAllBitsSet() { float result = 0f; *(int*)(&result) = -1; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static double GetDoubleWithAllBitsSet() { double result = 0.0; *(long*)(&result) = -1L; return result; } } [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property)] internal class JitIntrinsicAttribute : Attribute { } [StructLayout(LayoutKind.Explicit)] internal struct Register { [FieldOffset(0)] internal byte byte_0; [FieldOffset(1)] internal byte byte_1; [FieldOffset(2)] internal byte byte_2; [FieldOffset(3)] internal byte byte_3; [FieldOffset(4)] internal byte byte_4; [FieldOffset(5)] internal byte byte_5; [FieldOffset(6)] internal byte byte_6; [FieldOffset(7)] internal byte byte_7; [FieldOffset(8)] internal byte byte_8; [FieldOffset(9)] internal byte byte_9; [FieldOffset(10)] internal byte byte_10; [FieldOffset(11)] internal byte byte_11; [FieldOffset(12)] internal byte byte_12; [FieldOffset(13)] internal byte byte_13; [FieldOffset(14)] internal byte byte_14; [FieldOffset(15)] internal byte byte_15; [FieldOffset(0)] internal sbyte sbyte_0; [FieldOffset(1)] internal sbyte sbyte_1; [FieldOffset(2)] internal sbyte sbyte_2; [FieldOffset(3)] internal sbyte sbyte_3; [FieldOffset(4)] internal sbyte sbyte_4; [FieldOffset(5)] internal sbyte sbyte_5; [FieldOffset(6)] internal sbyte sbyte_6; [FieldOffset(7)] internal sbyte sbyte_7; [FieldOffset(8)] internal sbyte sbyte_8; [FieldOffset(9)] internal sbyte sbyte_9; [FieldOffset(10)] internal sbyte sbyte_10; [FieldOffset(11)] internal sbyte sbyte_11; [FieldOffset(12)] internal sbyte sbyte_12; [FieldOffset(13)] internal sbyte sbyte_13; [FieldOffset(14)] internal sbyte sbyte_14; [FieldOffset(15)] internal sbyte sbyte_15; [FieldOffset(0)] internal ushort uint16_0; [FieldOffset(2)] internal ushort uint16_1; [FieldOffset(4)] internal ushort uint16_2; [FieldOffset(6)] internal ushort uint16_3; [FieldOffset(8)] internal ushort uint16_4; [FieldOffset(10)] internal ushort uint16_5; [FieldOffset(12)] internal ushort uint16_6; [FieldOffset(14)] internal ushort uint16_7; [FieldOffset(0)] internal short int16_0; [FieldOffset(2)] internal short int16_1; [FieldOffset(4)] internal short int16_2; [FieldOffset(6)] internal short int16_3; [FieldOffset(8)] internal short int16_4; [FieldOffset(10)] internal short int16_5; [FieldOffset(12)] internal short int16_6; [FieldOffset(14)] internal short int16_7; [FieldOffset(0)] internal uint uint32_0; [FieldOffset(4)] internal uint uint32_1; [FieldOffset(8)] internal uint uint32_2; [FieldOffset(12)] internal uint uint32_3; [FieldOffset(0)] internal int int32_0; [FieldOffset(4)] internal int int32_1; [FieldOffset(8)] internal int int32_2; [FieldOffset(12)] internal int int32_3; [FieldOffset(0)] internal ulong uint64_0; [FieldOffset(8)] internal ulong uint64_1; [FieldOffset(0)] internal long int64_0; [FieldOffset(8)] internal long int64_1; [FieldOffset(0)] internal float single_0; [FieldOffset(4)] internal float single_1; [FieldOffset(8)] internal float single_2; [FieldOffset(12)] internal float single_3; [FieldOffset(0)] internal double double_0; [FieldOffset(8)] internal double double_1; } public struct Vector<T> : IEquatable<Vector<T>>, IFormattable where T : struct { private struct VectorSizeHelper { internal Vector<T> _placeholder; internal byte _byte; } private System.Numerics.Register register; private static readonly int s_count = InitializeCount(); private static readonly Vector<T> zero = new Vector<T>(GetZeroValue()); private static readonly Vector<T> one = new Vector<T>(GetOneValue()); private static readonly Vector<T> allOnes = new Vector<T>(GetAllBitsSetValue()); [JitIntrinsic] public static int Count => s_count; [JitIntrinsic] public static Vector<T> Zero => zero; [JitIntrinsic] public static Vector<T> One => one; internal static Vector<T> AllOnes => allOnes; [JitIntrinsic] public unsafe T this[int index] { get { if (index >= Count || index < 0) { throw new IndexOutOfRangeException(System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, index)); } if (typeof(T) == typeof(byte)) { fixed (byte* ptr = ®ister.byte_0) { return (T)(object)ptr[index]; } } if (typeof(T) == typeof(sbyte)) { fixed (sbyte* ptr2 = ®ister.sbyte_0) { return (T)(object)ptr2[index]; } } if (typeof(T) == typeof(ushort)) { fixed (ushort* ptr3 = ®ister.uint16_0) { return (T)(object)ptr3[index]; } } if (typeof(T) == typeof(short)) { fixed (short* ptr4 = ®ister.int16_0) { return (T)(object)ptr4[index]; } } if (typeof(T) == typeof(uint)) { fixed (uint* ptr5 = ®ister.uint32_0) { return (T)(object)ptr5[index]; } } if (typeof(T) == typeof(int)) { fixed (int* ptr6 = ®ister.int32_0) { return (T)(object)ptr6[index]; } } if (typeof(T) == typeof(ulong)) { fixed (ulong* ptr7 = ®ister.uint64_0) { return (T)(object)ptr7[index]; } } if (typeof(T) == typeof(long)) { fixed (long* ptr8 = ®ister.int64_0) { return (T)(object)ptr8[index]; } } if (typeof(T) == typeof(float)) { fixed (float* ptr9 = ®ister.single_0) { return (T)(object)ptr9[index]; } } if (typeof(T) == typeof(double)) { fixed (double* ptr10 = ®ister.double_0) { return (T)(object)ptr10[index]; } } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } } private unsafe static int InitializeCount() { VectorSizeHelper vectorSizeHelper = default(VectorSizeHelper); byte* ptr = &vectorSizeHelper._placeholder.register.byte_0; byte* ptr2 = &vectorSizeHelper._byte; int num = (int)(ptr2 - ptr); int num2 = -1; if (typeof(T) == typeof(byte)) { num2 = 1; } else if (typeof(T) == typeof(sbyte)) { num2 = 1; } else if (typeof(T) == typeof(ushort)) { num2 = 2; } else if (typeof(T) == typeof(short)) { num2 = 2; } else if (typeof(T) == typeof(uint)) { num2 = 4; } else if (typeof(T) == typeof(int)) { num2 = 4; } else if (typeof(T) == typeof(ulong)) { num2 = 8; } else if (typeof(T) == typeof(long)) { num2 = 8; } else if (typeof(T) == typeof(float)) { num2 = 4; } else { if (!(typeof(T) == typeof(double))) { throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } num2 = 8; } return num / num2; } [JitIntrinsic] public unsafe Vector(T value) { this = default(Vector<T>); if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { fixed (byte* ptr = ®ister.byte_0) { for (int i = 0; i < Count; i++) { ptr[i] = (byte)(object)value; } } } else if (typeof(T) == typeof(sbyte)) { fixed (sbyte* ptr2 = ®ister.sbyte_0) { for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(object)value; } } } else if (typeof(T) == typeof(ushort)) { fixed (ushort* ptr3 = ®ister.uint16_0) { for (int k = 0; k < Count; k++) { ptr3[k] = (ushort)(object)value; } } } else if (typeof(T) == typeof(short)) { fixed (short* ptr4 = ®ister.int16_0) { for (int l = 0; l < Count; l++) { ptr4[l] = (short)(object)value; } } } else if (typeof(T) == typeof(uint)) { fixed (uint* ptr5 = ®ister.uint32_0) { for (int m = 0; m < Count; m++) { ptr5[m] = (uint)(object)value; } } } else if (typeof(T) == typeof(int)) { fixed (int* ptr6 = ®ister.int32_0) { for (int n = 0; n < Count; n++) { ptr6[n] = (int)(object)value; } } } else if (typeof(T) == typeof(ulong)) { fixed (ulong* ptr7 = ®ister.uint64_0) { for (int num = 0; num < Count; num++) { ptr7[num] = (ulong)(object)value; } } } else if (typeof(T) == typeof(long)) { fixed (long* ptr8 = ®ister.int64_0) { for (int num2 = 0; num2 < Count; num2++) { ptr8[num2] = (long)(object)value; } } } else if (typeof(T) == typeof(float)) { fixed (float* ptr9 = ®ister.single_0) { for (int num3 = 0; num3 < Count; num3++) { ptr9[num3] = (float)(object)value; } } } else { if (!(typeof(T) == typeof(double))) { return; } fixed (double* ptr10 = ®ister.double_0) { for (int num4 = 0; num4 < Count; num4++) { ptr10[num4] = (double)(object)value; } } } } else if (typeof(T) == typeof(byte)) { register.byte_0 = (byte)(object)value; register.byte_1 = (byte)(object)value; register.byte_2 = (byte)(object)value; register.byte_3 = (byte)(object)value; register.byte_4 = (byte)(object)value; register.byte_5 = (byte)(object)value; register.byte_6 = (byte)(object)value; register.byte_7 = (byte)(object)value; register.byte_8 = (byte)(object)value; register.byte_9 = (byte)(object)value; register.byte_10 = (byte)(object)value; register.byte_11 = (byte)(object)value; register.byte_12 = (byte)(object)value; register.byte_13 = (byte)(object)value; register.byte_14 = (byte)(object)value; register.byte_15 = (byte)(object)value; } else if (typeof(T) == typeof(sbyte)) { register.sbyte_0 = (sbyte)(object)value; register.sbyte_1 = (sbyte)(object)value; register.sbyte_2 = (sbyte)(object)value; register.sbyte_3 = (sbyte)(object)value; register.sbyte_4 = (sbyte)(object)value; register.sbyte_5 = (sbyte)(object)value; register.sbyte_6 = (sbyte)(object)value; register.sbyte_7 = (sbyte)(object)value; register.sbyte_8 = (sbyte)(object)value; register.sbyte_9 = (sbyte)(object)value; register.sbyte_10 = (sbyte)(object)value; register.sbyte_11 = (sbyte)(object)value; register.sbyte_12 = (sbyte)(object)value; register.sbyte_13 = (sbyte)(object)value; register.sbyte_14 = (sbyte)(object)value; register.sbyte_15 = (sbyte)(object)value; } else if (typeof(T) == typeof(ushort)) { register.uint16_0 = (ushort)(object)value; register.uint16_1 = (ushort)(object)value; register.uint16_2 = (ushort)(object)value; register.uint16_3 = (ushort)(object)value; register.uint16_4 = (ushort)(object)value; register.uint16_5 = (ushort)(object)value; register.uint16_6 = (ushort)(object)value; register.uint16_7 = (ushort)(object)value; } else if (typeof(T) == typeof(short)) { register.int16_0 = (short)(object)value; register.int16_1 = (short)(object)value; register.int16_2 = (short)(object)value; register.int16_3 = (short)(object)value; register.int16_4 = (short)(object)value; register.int16_5 = (short)(object)value; register.int16_6 = (short)(object)value; register.int16_7 = (short)(object)value; } else if (typeof(T) == typeof(uint)) { register.uint32_0 = (uint)(object)value; register.uint32_1 = (uint)(object)value; register.uint32_2 = (uint)(object)value; register.uint32_3 = (uint)(object)value; } else if (typeof(T) == typeof(int)) { register.int32_0 = (int)(object)value; register.int32_1 = (int)(object)value; register.int32_2 = (int)(object)value; register.int32_3 = (int)(object)value; } else if (typeof(T) == typeof(ulong)) { register.uint64_0 = (ulong)(object)value; register.uint64_1 = (ulong)(object)value; } else if (typeof(T) == typeof(long)) { register.int64_0 = (long)(object)value; register.int64_1 = (long)(object)value; } else if (typeof(T) == typeof(float)) { register.single_0 = (float)(object)value; register.single_1 = (float)(object)value; register.single_2 = (float)(object)value; register.single_3 = (float)(object)value; } else if (typeof(T) == typeof(double)) { register.double_0 = (double)(object)value; register.double_1 = (double)(object)value; } } [JitIntrinsic] public Vector(T[] values) : this(values, 0) { } public unsafe Vector(T[] values, int index) { this = default(Vector<T>); if (values == null) { throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef); } if (index < 0 || values.Length - index < Count) { throw new IndexOutOfRangeException(); } if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { fixed (byte* ptr = ®ister.byte_0) { for (int i = 0; i < Count; i++) { ptr[i] = (byte)(object)values[i + index]; } } } else if (typeof(T) == typeof(sbyte)) { fixed (sbyte* ptr2 = ®ister.sbyte_0) { for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(object)values[j + index]; } } } else if (typeof(T) == typeof(ushort)) { fixed (ushort* ptr3 = ®ister.uint16_0) { for (int k = 0; k < Count; k++) { ptr3[k] = (ushort)(object)values[k + index]; } } } else if (typeof(T) == typeof(short)) { fixed (short* ptr4 = ®ister.int16_0) { for (int l = 0; l < Count; l++) { ptr4[l] = (short)(object)values[l + index]; } } } else if (typeof(T) == typeof(uint)) { fixed (uint* ptr5 = ®ister.uint32_0) { for (int m = 0; m < Count; m++) { ptr5[m] = (uint)(object)values[m + index]; } } } else if (typeof(T) == typeof(int)) { fixed (int* ptr6 = ®ister.int32_0) { for (int n = 0; n < Count; n++) { ptr6[n] = (int)(object)values[n + index]; } } } else if (typeof(T) == typeof(ulong)) { fixed (ulong* ptr7 = ®ister.uint64_0) { for (int num = 0; num < Count; num++) { ptr7[num] = (ulong)(object)values[num + index]; } } } else if (typeof(T) == typeof(long)) { fixed (long* ptr8 = ®ister.int64_0) { for (int num2 = 0; num2 < Count; num2++) { ptr8[num2] = (long)(object)values[num2 + index]; } } } else if (typeof(T) == typeof(float)) { fixed (float* ptr9 = ®ister.single_0) { for (int num3 = 0; num3 < Count; num3++) { ptr9[num3] = (float)(object)values[num3 + index]; } } } else { if (!(typeof(T) == typeof(double))) { return; } fixed (double* ptr10 = ®ister.double_0) { for (int num4 = 0; num4 < Count; num4++) { ptr10[num4] = (double)(object)values[num4 + index]; } } } } else if (typeof(T) == typeof(byte)) { fixed (byte* ptr11 = ®ister.byte_0) { *ptr11 = (byte)(object)values[index]; ptr11[1] = (byte)(object)values[1 + index]; ptr11[2] = (byte)(object)values[2 + index]; ptr11[3] = (byte)(object)values[3 + index]; ptr11[4] = (byte)(object)values[4 + index]; ptr11[5] = (byte)(object)values[5 + index]; ptr11[6] = (byte)(object)values[6 + index]; ptr11[7] = (byte)(object)values[7 + index]; ptr11[8] = (byte)(object)values[8 + index]; ptr11[9] = (byte)(object)values[9 + index]; ptr11[10] = (byte)(object)values[10 + index]; ptr11[11] = (byte)(object)values[11 + index]; ptr11[12] = (byte)(object)values[12 + index]; ptr11[13] = (byte)(object)values[13 + index]; ptr11[14] = (byte)(object)values[14 + index]; ptr11[15] = (byte)(object)values[15 + index]; } } else if (typeof(T) == typeof(sbyte)) { fixed (sbyte* ptr12 = ®ister.sbyte_0) { *ptr12 = (sbyte)(object)values[index]; ptr12[1] = (sbyte)(object)values[1 + index]; ptr12[2] = (sbyte)(object)values[2 + index]; ptr12[3] = (sbyte)(object)values[3 + index]; ptr12[4] = (sbyte)(object)values[4 + index]; ptr12[5] = (sbyte)(object)values[5 + index]; ptr12[6] = (sbyte)(object)values[6 + index]; ptr12[7] = (sbyte)(object)values[7 + index]; ptr12[8] = (sbyte)(object)values[8 + index]; ptr12[9] = (sbyte)(object)values[9 + index]; ptr12[10] = (sbyte)(object)values[10 + index]; ptr12[11] = (sbyte)(object)values[11 + index]; ptr12[12] = (sbyte)(object)values[12 + index]; ptr12[13] = (sbyte)(object)values[13 + index]; ptr12[14] = (sbyte)(object)values[14 + index]; ptr12[15] = (sbyte)(object)values[15 + index]; } } else if (typeof(T) == typeof(ushort)) { fixed (ushort* ptr13 = ®ister.uint16_0) { *ptr13 = (ushort)(object)values[index]; ptr13[1] = (ushort)(object)values[1 + index]; ptr13[2] = (ushort)(object)values[2 + index]; ptr13[3] = (ushort)(object)values[3 + index]; ptr13[4] = (ushort)(object)values[4 + index]; ptr13[5] = (ushort)(object)values[5 + index]; ptr13[6] = (ushort)(object)values[6 + index]; ptr13[7] = (ushort)(object)values[7 + index]; } } else if (typeof(T) == typeof(short)) { fixed (short* ptr14 = ®ister.int16_0) { *ptr14 = (short)(object)values[index]; ptr14[1] = (short)(object)values[1 + index]; ptr14[2] = (short)(object)values[2 + index]; ptr14[3] = (short)(object)values[3 + index]; ptr14[4] = (short)(object)values[4 + index]; ptr14[5] = (short)(object)values[5 + index]; ptr14[6] = (short)(object)values[6 + index]; ptr14[7] = (short)(object)values[7 + index]; } } else if (typeof(T) == typeof(uint)) { fixed (uint* ptr15 = ®ister.uint32_0) { *ptr15 = (uint)(object)values[index]; ptr15[1] = (uint)(object)values[1 + index]; ptr15[2] = (uint)(object)values[2 + index]; ptr15[3] = (uint)(object)values[3 + index]; } } else if (typeof(T) == typeof(int)) { fixed (int* ptr16 = ®ister.int32_0) { *ptr16 = (int)(object)values[index]; ptr16[1] = (int)(object)values[1 + index]; ptr16[2] = (int)(object)values[2 + index]; ptr16[3] = (int)(object)values[3 + index]; } } else if (typeof(T) == typeof(ulong)) { fixed (ulong* ptr17 = ®ister.uint64_0) { *ptr17 = (ulong)(object)values[index]; ptr17[1] = (ulong)(object)values[1 + index]; } } else if (typeof(T) == typeof(long)) { fixed (long* ptr18 = ®ister.int64_0) { *ptr18 = (long)(object)values[index]; ptr18[1] = (long)(object)values[1 + index]; } } else if (typeof(T) == typeof(float)) { fixed (float* ptr19 = ®ister.single_0) { *ptr19 = (float)(object)values[index]; ptr19[1] = (float)(object)values[1 + index]; ptr19[2] = (float)(object)values[2 + index]; ptr19[3] = (float)(object)values[3 + index]; } } else if (typeof(T) == typeof(double)) { fixed (double* ptr20 = ®ister.double_0) { *ptr20 = (double)(object)values[index]; ptr20[1] = (double)(object)values[1 + index]; } } } internal unsafe Vector(void* dataPointer) : this(dataPointer, 0) { } internal unsafe Vector(void* dataPointer, int offset) { this = default(Vector<T>); if (typeof(T) == typeof(byte)) { byte* ptr = (byte*)dataPointer; ptr += offset; fixed (byte* ptr2 = ®ister.byte_0) { for (int i = 0; i < Count; i++) { ptr2[i] = ptr[i]; } } return; } if (typeof(T) == typeof(sbyte)) { sbyte* ptr3 = (sbyte*)dataPointer; ptr3 += offset; fixed (sbyte* ptr4 = ®ister.sbyte_0) { for (int j = 0; j < Count; j++) { ptr4[j] = ptr3[j]; } } return; } if (typeof(T) == typeof(ushort)) { ushort* ptr5 = (ushort*)dataPointer; ptr5 += offset; fixed (ushort* ptr6 = ®ister.uint16_0) { for (int k = 0; k < Count; k++) { ptr6[k] = ptr5[k]; } } return; } if (typeof(T) == typeof(short)) { short* ptr7 = (short*)dataPointer; ptr7 += offset; fixed (short* ptr8 = ®ister.int16_0) { for (int l = 0; l < Count; l++) { ptr8[l] = ptr7[l]; } } return; } if (typeof(T) == typeof(uint)) { uint* ptr9 = (uint*)dataPointer; ptr9 += offset; fixed (uint* ptr10 = ®ister.uint32_0) { for (int m = 0; m < Count; m++) { ptr10[m] = ptr9[m]; } } return; } if (typeof(T) == typeof(int)) { int* ptr11 = (int*)dataPointer; ptr11 += offset; fixed (int* ptr12 = ®ister.int32_0) { for (int n = 0; n < Count; n++) { ptr12[n] = ptr11[n]; } } return; } if (typeof(T) == typeof(ulong)) { ulong* ptr13 = (ulong*)dataPointer; ptr13 += offset; fixed (ulong* ptr14 = ®ister.uint64_0) { for (int num = 0; num < Count; num++) { ptr14[num] = ptr13[num]; } } return; } if (typeof(T) == typeof(long)) { long* ptr15 = (long*)dataPointer; ptr15 += offset; fixed (long* ptr16 = ®ister.int64_0) { for (int num2 = 0; num2 < Count; num2++) { ptr16[num2] = ptr15[num2]; } } return; } if (typeof(T) == typeof(float)) { float* ptr17 = (float*)dataPointer; ptr17 += offset; fixed (float* ptr18 = ®ister.single_0) { for (int num3 = 0; num3 < Count; num3++) { ptr18[num3] = ptr17[num3]; } } return; } if (typeof(T) == typeof(double)) { double* ptr19 = (double*)dataPointer; ptr19 += offset; fixed (double* ptr20 = ®ister.double_0) { for (int num4 = 0; num4 < Count; num4++) { ptr20[num4] = ptr19[num4]; } } return; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } private Vector(ref System.Numerics.Register existingRegister) { register = existingRegister; } [JitIntrinsic] public void CopyTo(T[] destination) { CopyTo(destination, 0); } [JitIntrinsic] public unsafe void CopyTo(T[] destination, int startIndex) { if (destination == null) { throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef); } if (startIndex < 0 || startIndex >= destination.Length) { throw new ArgumentOutOfRangeException("startIndex", System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, startIndex)); } if (destination.Length - startIndex < Count) { throw new ArgumentException(System.SR.Format(System.SR.Arg_ElementsInSourceIsGreaterThanDestination, startIndex)); } if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { fixed (byte* ptr = (byte[])(object)destination) { for (int i = 0; i < Count; i++) { ptr[startIndex + i] = (byte)(object)this[i]; } } } else if (typeof(T) == typeof(sbyte)) { fixed (sbyte* ptr2 = (sbyte[])(object)destination) { for (int j = 0; j < Count; j++) { ptr2[startIndex + j] = (sbyte)(object)this[j]; } } } else if (typeof(T) == typeof(ushort)) { fixed (ushort* ptr3 = (ushort[])(object)destination) { for (int k = 0; k < Count; k++) { ptr3[startIndex + k] = (ushort)(object)this[k]; } } } else if (typeof(T) == typeof(short)) { fixed (short* ptr4 = (short[])(object)destination) { for (int l = 0; l < Count; l++) { ptr4[startIndex + l] = (short)(object)this[l]; } } } else if (typeof(T) == typeof(uint)) { fixed (uint* ptr5 = (uint[])(object)destination) { for (int m = 0; m < Count; m++) { ptr5[startIndex + m] = (uint)(object)this[m]; } } } else if (typeof(T) == typeof(int)) { fixed (int* ptr6 = (int[])(object)destination) { for (int n = 0; n < Count; n++) { ptr6[startIndex + n] = (int)(object)this[n]; } } } else if (typeof(T) == typeof(ulong)) { fixed (ulong* ptr7 = (ulong[])(object)destination) { for (int num = 0; num < Count; num++) { ptr7[startIndex + num] = (ulong)(object)this[num]; } } } else if (typeof(T) == typeof(long)) { fixed (long* ptr8 = (long[])(object)destination) { for (int num2 = 0; num2 < Count; num2++) { ptr8[startIndex + num2] = (long)(object)this[num2]; } } } else if (typeof(T) == typeof(float)) { fixed (float* ptr9 = (float[])(object)destination) { for (int num3 = 0; num3 < Count; num3++) { ptr9[startIndex + num3] = (float)(object)this[num3]; } } } else { if (!(typeof(T) == typeof(double))) { return; } fixed (double* ptr10 = (double[])(object)destination) { for (int num4 = 0; num4 < Count; num4++) { ptr10[startIndex + num4] = (double)(object)this[num4]; } } } } else if (typeof(T) == typeof(byte)) { fixed (byte* ptr11 = (byte[])(object)destination) { ptr11[startIndex] = register.byte_0; ptr11[startIndex + 1] = register.byte_1; ptr11[startIndex + 2] = register.byte_2; ptr11[startIndex + 3] = register.byte_3; ptr11[startIndex + 4] = register.byte_4; ptr11[startIndex + 5] = register.byte_5; ptr11[startIndex + 6] = register.byte_6; ptr11[startIndex + 7] = register.byte_7; ptr11[startIndex + 8] = register.byte_8; ptr11[startIndex + 9] = register.byte_9; ptr11[startIndex + 10] = register.byte_10; ptr11[startIndex + 11] = register.byte_11; ptr11[startIndex + 12] = register.byte_12; ptr11[startIndex + 13] = register.byte_13; ptr11[startIndex + 14] = register.byte_14; ptr11[startIndex + 15] = register.byte_15; } } else if (typeof(T) == typeof(sbyte)) { fixed (sbyte* ptr12 = (sbyte[])(object)destination) { ptr12[startIndex] = register.sbyte_0; ptr12[startIndex + 1] = register.sbyte_1; ptr12[startIndex + 2] = register.sbyte_2; ptr12[startIndex + 3] = register.sbyte_3; ptr12[startIndex + 4] = register.sbyte_4; ptr12[startIndex + 5] = register.sbyte_5; ptr12[startIndex + 6] = register.sbyte_6; ptr12[startIndex + 7] = register.sbyte_7; ptr12[startIndex + 8] = register.sbyte_8; ptr12[startIndex + 9] = register.sbyte_9; ptr12[startIndex + 10] = register.sbyte_10; ptr12[startIndex + 11] = register.sbyte_11; ptr12[startIndex + 12] = register.sbyte_12; ptr12[startIndex + 13] = register.sbyte_13; ptr12[startIndex + 14] = register.sbyte_14; ptr12[startIndex + 15] = register.sbyte_15; } } else if (typeof(T) == typeof(ushort)) { fixed (ushort* ptr13 = (ushort[])(object)destination) { ptr13[startIndex] = register.uint16_0; ptr13[startIndex + 1] = register.uint16_1; ptr13[startIndex + 2] = register.uint16_2; ptr13[startIndex + 3] = register.uint16_3; ptr13[startIndex + 4] = register.uint16_4; ptr13[startIndex + 5] = register.uint16_5; ptr13[startIndex + 6] = register.uint16_6; ptr13[startIndex + 7] = register.uint16_7; } } else if (typeof(T) == typeof(short)) { fixed (short* ptr14 = (short[])(object)destination) { ptr14[startIndex] = register.int16_0; ptr14[startIndex + 1] = register.int16_1; ptr14[startIndex + 2] = register.int16_2; ptr14[startIndex + 3] = register.int16_3; ptr14[startIndex + 4] = register.int16_4; ptr14[startIndex + 5] = register.int16_5; ptr14[startIndex + 6] = register.int16_6; ptr14[startIndex + 7] = register.int16_7; } } else if (typeof(T) == typeof(uint)) { fixed (uint* ptr15 = (uint[])(object)destination) { ptr15[startIndex] = register.uint32_0; ptr15[startIndex + 1] = register.uint32_1; ptr15[startIndex + 2] = register.uint32_2; ptr15[startIndex + 3] = register.uint32_3; } } else if (typeof(T) == typeof(int)) { fixed (int* ptr16 = (int[])(object)destination) { ptr16[startIndex] = register.int32_0; ptr16[startIndex + 1] = register.int32_1; ptr16[startIndex + 2] = register.int32_2; ptr16[startIndex + 3] = register.int32_3; } } else if (typeof(T) == typeof(ulong)) { fixed (ulong* ptr17 = (ulong[])(object)destination) { ptr17[startIndex] = register.uint64_0; ptr17[startIndex + 1] = register.uint64_1; } } else if (typeof(T) == typeof(long)) { fixed (long* ptr18 = (long[])(object)destination) { ptr18[startIndex] = register.int64_0; ptr18[startIndex + 1] = register.int64_1; } } else if (typeof(T) == typeof(float)) { fixed (float* ptr19 = (float[])(object)destination) { ptr19[startIndex] = register.single_0; ptr19[startIndex + 1] = register.single_1; ptr19[startIndex + 2] = register.single_2; ptr19[startIndex + 3] = register.single_3; } } else if (typeof(T) == typeof(double)) { fixed (double* ptr20 = (double[])(object)destination) { ptr20[startIndex] = register.double_0; ptr20[startIndex + 1] = register.double_1; } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool Equals(object obj) { if (!(obj is Vector<T>)) { return false; } return Equals((Vector<T>)obj); } [JitIntrinsic] public bool Equals(Vector<T> other) { if (Vector.IsHardwareAccelerated) { for (int i = 0; i < Count; i++) { if (!ScalarEquals(this[i], other[i])) { return false; } } return true; } if (typeof(T) == typeof(byte)) { if (register.byte_0 == other.register.byte_0 && register.byte_1 == other.register.byte_1 && register.byte_2 == other.register.byte_2 && register.byte_3 == other.register.byte_3 && register.byte_4 == other.register.byte_4 && register.byte_5 == other.register.byte_5 && register.byte_6 == other.register.byte_6 && register.byte_7 == other.register.byte_7 && register.byte_8 == other.register.byte_8 && register.byte_9 == other.register.byte_9 && register.byte_10 == other.register.byte_10 && register.byte_11 == other.register.byte_11 && register.byte_12 == other.register.byte_12 && register.byte_13 == other.register.byte_13 && register.byte_14 == other.register.byte_14) { return register.byte_15 == other.register.byte_15; } return false; } if (typeof(T) == typeof(sbyte)) { if (register.sbyte_0 == other.register.sbyte_0 && register.sbyte_1 == other.register.sbyte_1 && register.sbyte_2 == other.register.sbyte_2 && register.sbyte_3 == other.register.sbyte_3 && register.sbyte_4 == other.register.sbyte_4 && register.sbyte_5 == other.register.sbyte_5 && register.sbyte_6 == other.register.sbyte_6 && register.sbyte_7 == other.register.sbyte_7 && register.sbyte_8 == other.register.sbyte_8 && register.sbyte_9 == other.register.sbyte_9 && register.sbyte_10 == other.register.sbyte_10 && register.sbyte_11 == other.register.sbyte_11 && register.sbyte_12 == other.register.sbyte_12 && register.sbyte_13 == other.register.sbyte_13 && register.sbyte_14 == other.register.sbyte_14) { return register.sbyte_15 == other.register.sbyte_15; } return false; } if (typeof(T) == typeof(ushort)) { if (register.uint16_0 == other.register.uint16_0 && register.uint16_1 == other.register.uint16_1 && register.uint16_2 == other.register.uint16_2 && register.uint16_3 == other.register.uint16_3 && register.uint16_4 == other.register.uint16_4 && register.uint16_5 == other.register.uint16_5 && register.uint16_6 == other.register.uint16_6) { return register.uint16_7 == other.register.uint16_7; } return false; } if (typeof(T) == typeof(short)) { if (register.int16_0 == other.register.int16_0 && register.int16_1 == other.register.int16_1 && register.int16_2 == other.register.int16_2 && register.int16_3 == other.register.int16_3 && register.int16_4 == other.register.int16_4 && register.int16_5 == other.register.int16_5 && register.int16_6 == other.register.int16_6) { return register.int16_7 == other.register.int16_7; } return false; } if (typeof(T) == typeof(uint)) { if (register.uint32_0 == other.register.uint32_0 && register.uint32_1 == other.register.uint32_1 && register.uint32_2 == other.register.uint32_2) { return register.uint32_3 == other.register.uint32_3; } return false; } if (typeof(T) == typeof(int)) { if (register.int32_0 == other.register.int32_0 && register.int32_1 == other.register.int32_1 && register.int32_2 == other.register.int32_2) { return register.int32_3 == other.register.int32_3; } return false; } if (typeof(T) == typeof(ulong)) { if (register.uint64_0 == other.register.uint64_0) { return register.uint64_1 == other.register.uint64_1; } return false; } if (typeof(T) == typeof(long)) { if (register.int64_0 == other.register.int64_0) { return register.int64_1 == other.register.int64_1; } return false; } if (typeof(T) == typeof(float)) { if (register.single_0 == other.register.single_0 && register.single_1 == other.register.single_1 && register.single_2 == other.register.single_2) { return register.single_3 == other.register.single_3; } return false; } if (typeof(T) == typeof(double)) { if (register.double_0 == other.register.double_0) { return register.double_1 == other.register.double_1; } return false; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } public override int GetHashCode() { int num = 0; if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { for (int i = 0; i < Count; i++) { num = HashHelpers.Combine(num, ((byte)(object)this[i]).GetHashCode()); } return num; } if (typeof(T) == typeof(sbyte)) { for (int j = 0; j < Count; j++) { num = HashHelpers.Combine(num, ((sbyte)(object)this[j]).GetHashCode()); } return num; } if (typeof(T) == typeof(ushort)) { for (int k = 0; k < Count; k++) { num = HashHelpers.Combine(num, ((ushort)(object)this[k]).GetHashCode()); } return num; } if (typeof(T) == typeof(short)) { for (int l = 0; l < Count; l++) { num = HashHelpers.Combine(num, ((short)(object)this[l]).GetHashCode()); } return num; } if (typeof(T) == typeof(uint)) { for (int m = 0; m < Count; m++) { num = HashHelpers.Combine(num, ((uint)(object)this[m]).GetHashCode()); } return num; } if (typeof(T) == typeof(int)) { for (int n = 0; n < Count; n++) { num = HashHelpers.Combine(num, ((int)(object)this[n]).GetHashCode()); } return num; } if (typeof(T) == typeof(ulong)) { for (int num2 = 0; num2 < Count; num2++) { num = HashHelpers.Combine(num, ((ulong)(object)this[num2]).GetHashCode()); } return num; } if (typeof(T) == typeof(long)) { for (int num3 = 0; num3 < Count; num3++) { num = HashHelpers.Combine(num, ((long)(object)this[num3]).GetHashCode()); } return num; } if (typeof(T) == typeof(float)) { for (int num4 = 0; num4 < Count; num4++) { num = HashHelpers.Combine(num, ((float)(object)this[num4]).GetHashCode()); } return num; } if (typeof(T) == typeof(double)) { for (int num5 = 0; num5 < Count; num5++) { num = HashHelpers.Combine(num, ((double)(object)this[num5]).GetHashCode()); } return num; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } if (typeof(T) == typeof(byte)) { num = HashHelpers.Combine(num, register.byte_0.GetHashCode()); num = HashHelpers.Combine(num, register.byte_1.GetHashCode()); num = HashHelpers.Combine(num, register.byte_2.GetHashCode()); num = HashHelpers.Combine(num, register.byte_3.GetHashCode()); num = HashHelpers.Combine(num, register.byte_4.GetHashCode()); num = HashHelpers.Combine(num, register.byte_5.GetHashCode()); num = HashHelpers.Combine(num, register.byte_6.GetHashCode()); num = HashHelpers.Combine(num, register.byte_7.GetHashCode()); num = HashHelpers.Combine(num, register.byte_8.GetHashCode()); num = HashHelpers.Combine(num, register.byte_9.GetHashCode()); num = HashHelpers.Combine(num, register.byte_10.GetHashCode()); num = HashHelpers.Combine(num, register.byte_11.GetHashCode()); num = HashHelpers.Combine(num, register.byte_12.GetHashCode()); num = HashHelpers.Combine(num, register.byte_13.GetHashCode()); num = HashHelpers.Combine(num, register.byte_14.GetHashCode()); return HashHelpers.Combine(num, register.byte_15.GetHashCode()); } if (typeof(T) == typeof(sbyte)) { num = HashHelpers.Combine(num, register.sbyte_0.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_1.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_2.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_3.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_4.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_5.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_6.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_7.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_8.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_9.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_10.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_11.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_12.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_13.GetHashCode()); num = HashHelpers.Combine(num, register.sbyte_14.GetHashCode()); return HashHelpers.Combine(num, register.sbyte_15.GetHashCode()); } if (typeof(T) == typeof(ushort)) { num = HashHelpers.Combine(num, register.uint16_0.GetHashCode()); num = HashHelpers.Combine(num, register.uint16_1.GetHashCode()); num = HashHelpers.Combine(num, register.uint16_2.GetHashCode()); num = HashHelpers.Combine(num, register.uint16_3.GetHashCode()); num = HashHelpers.Combine(num, register.uint16_4.GetHashCode()); num = HashHelpers.Combine(num, register.uint16_5.GetHashCode()); num = HashHelpers.Combine(num, register.uint16_6.GetHashCode()); return HashHelpers.Combine(num, register.uint16_7.GetHashCode()); } if (typeof(T) == typeof(short)) { num = HashHelpers.Combine(num, register.int16_0.GetHashCode()); num = HashHelpers.Combine(num, register.int16_1.GetHashCode()); num = HashHelpers.Combine(num, register.int16_2.GetHashCode()); num = HashHelpers.Combine(num, register.int16_3.GetHashCode()); num = HashHelpers.Combine(num, register.int16_4.GetHashCode()); num = HashHelpers.Combine(num, register.int16_5.GetHashCode()); num = HashHelpers.Combine(num, register.int16_6.GetHashCode()); return HashHelpers.Combine(num, register.int16_7.GetHashCode()); } if (typeof(T) == typeof(uint)) { num = HashHelpers.Combine(num, register.uint32_0.GetHashCode()); num = HashHelpers.Combine(num, register.uint32_1.GetHashCode()); num = HashHelpers.Combine(num, register.uint32_2.GetHashCode()); return HashHelpers.Combine(num, register.uint32_3.GetHashCode()); } if (typeof(T) == typeof(int)) { num = HashHelpers.Combine(num, register.int32_0.GetHashCode()); num = HashHelpers.Combine(num, register.int32_1.GetHashCode()); num = HashHelpers.Combine(num, register.int32_2.GetHashCode()); return HashHelpers.Combine(num, register.int32_3.GetHashCode()); } if (typeof(T) == typeof(ulong)) { num = HashHelpers.Combine(num, register.uint64_0.GetHashCode()); return HashHelpers.Combine(num, register.uint64_1.GetHashCode()); } if (typeof(T) == typeof(long)) { num = HashHelpers.Combine(num, register.int64_0.GetHashCode()); return HashHelpers.Combine(num, register.int64_1.GetHashCode()); } if (typeof(T) == typeof(float)) { num = HashHelpers.Combine(num, register.single_0.GetHashCode()); num = HashHelpers.Combine(num, register.single_1.GetHashCode()); num = HashHelpers.Combine(num, register.single_2.GetHashCode()); return HashHelpers.Combine(num, register.single_3.GetHashCode()); } if (typeof(T) == typeof(double)) { num = HashHelpers.Combine(num, register.double_0.GetHashCode()); return HashHelpers.Combine(num, register.double_1.GetHashCode()); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } public override string ToString() { return ToString("G", CultureInfo.CurrentCulture); } public string ToString(string format) { return ToString(format, CultureInfo.CurrentCulture); } public string ToString(string format, IFormatProvider formatProvider) { StringBuilder stringBuilder = new StringBuilder(); string numberGroupSeparator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator; stringBuilder.Append('<'); for (int i = 0; i < Count - 1; i++) { stringBuilder.Append(((IFormattable)(object)this[i]).ToString(format, formatProvider)); stringBuilder.Append(numberGroupSeparator); stringBuilder.Append(' '); } stringBuilder.Append(((IFormattable)(object)this[Count - 1]).ToString(format, formatProvider)); stringBuilder.Append('>'); return stringBuilder.ToString(); } public unsafe static Vector<T>operator +(Vector<T> left, Vector<T> right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)(object)ScalarAdd(left[i], right[i]); } return new Vector<T>(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(object)ScalarAdd(left[j], right[j]); } return new Vector<T>(ptr2); } if (typeof(T) == typeof(ushort)) { ushort* ptr3 = stackalloc ushort[Count]; for (int k = 0; k < Count; k++) { ptr3[k] = (ushort)(object)ScalarAdd(left[k], right[k]); } return new Vector<T>(ptr3); } if (typeof(T) == typeof(short)) { short* ptr4 = stackalloc short[Count]; for (int l = 0; l < Count; l++) { ptr4[l] = (short)(object)ScalarAdd(left[l], right[l]); } return new Vector<T>(ptr4); } if (typeof(T) == typeof(uint)) { uint* ptr5 = stackalloc uint[Count]; for (int m = 0; m < Count; m++) { ptr5[m] = (uint)(object)ScalarAdd(left[m], right[m]); } return new Vector<T>(ptr5); } if (typeof(T) == typeof(int)) { int* ptr6 = stackalloc int[Count]; for (int n = 0; n < Count; n++) { ptr6[n] = (int)(object)ScalarAdd(left[n], right[n]); } return new Vector<T>(ptr6); } if (typeof(T) == typeof(ulong)) { ulong* ptr7 = stackalloc ulong[Count]; for (int num = 0; num < Count; num++) { ptr7[num] = (ulong)(object)ScalarAdd(left[num], right[num]); } return new Vector<T>(ptr7); } if (typeof(T) == typeof(long)) { long* ptr8 = stackalloc long[Count]; for (int num2 = 0; num2 < Count; num2++) { ptr8[num2] = (long)(object)ScalarAdd(left[num2], right[num2]); } return new Vector<T>(ptr8); } if (typeof(T) == typeof(float)) { float* ptr9 = stackalloc float[Count]; for (int num3 = 0; num3 < Count; num3++) { ptr9[num3] = (float)(object)ScalarAdd(left[num3], right[num3]); } return new Vector<T>(ptr9); } if (typeof(T) == typeof(double)) { double* ptr10 = stackalloc double[Count]; for (int num4 = 0; num4 < Count; num4++) { ptr10[num4] = (double)(object)ScalarAdd(left[num4], right[num4]); } return new Vector<T>(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Vector<T> result = default(Vector<T>); if (typeof(T) == typeof(byte)) { result.register.byte_0 = (byte)(left.register.byte_0 + right.register.byte_0); result.register.byte_1 = (byte)(left.register.byte_1 + right.register.byte_1); result.register.byte_2 = (byte)(left.register.byte_2 + right.register.byte_2); result.register.byte_3 = (byte)(left.register.byte_3 + right.register.byte_3); result.register.byte_4 = (byte)(left.register.byte_4 + right.register.byte_4); result.register.byte_5 = (byte)(left.register.byte_5 + right.register.byte_5); result.register.byte_6 = (byte)(left.register.byte_6 + right.register.byte_6); result.register.byte_7 = (byte)(left.register.byte_7 + right.register.byte_7); result.register.byte_8 = (byte)(left.register.byte_8 + right.register.byte_8); result.register.byte_9 = (byte)(left.register.byte_9 + right.register.byte_9); result.register.byte_10 = (byte)(left.register.byte_10 + right.register.byte_10); result.register.byte_11 = (byte)(left.register.byte_11 + right.register.byte_11); result.register.byte_12 = (byte)(left.register.byte_12 + right.register.byte_12); result.register.byte_13 = (byte)(left.register.byte_13 + right.register.byte_13); result.register.byte_14 = (byte)(left.register.byte_14 + right.register.byte_14); result.register.byte_15 = (byte)(left.register.byte_15 + right.register.byte_15); } else if (typeof(T) == typeof(sbyte)) { result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 + right.register.sbyte_0); result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 + right.register.sbyte_1); result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 + right.register.sbyte_2); result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 + right.register.sbyte_3); result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 + right.register.sbyte_4); result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 + right.register.sbyte_5); result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 + right.register.sbyte_6); result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 + right.register.sbyte_7); result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 + right.register.sbyte_8); result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 + right.register.sbyte_9); result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 + right.register.sbyte_10); result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 + right.register.sbyte_11); result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 + right.register.sbyte_12); result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 + right.register.sbyte_13); result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 + right.register.sbyte_14); result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 + right.register.sbyte_15); } else if (typeof(T) == typeof(ushort)) { result.register.uint16_0 = (ushort)(left.register.uint16_0 + right.register.uint16_0); result.register.uint16_1 = (ushort)(left.register.uint16_1 + right.register.uint16_1); result.register.uint16_2 = (ushort)(left.register.uint16_2 + right.register.uint16_2); result.register.uint16_3 = (ushort)(left.register.uint16_3 + right.register.uint16_3); result.register.uint16_4 = (ushort)(left.register.uint16_4 + right.register.uint16_4); result.register.uint16_5 = (ushort)(left.register.uint16_5 + right.register.uint16_5); result.register.uint16_6 = (ushort)(left.register.uint16_6 + right.register.uint16_6); result.register.uint16_7 = (ushort)(left.register.uint16_7 + right.register.uint16_7); } else if (typeof(T) == typeof(short)) { result.register.int16_0 = (short)(left.register.int16_0 + right.register.int16_0); result.register.int16_1 = (short)(left.register.int16_1 + right.register.int16_1); result.register.int16_2 = (short)(left.register.int16_2 + right.register.int16_2); result.register.int16_3 = (short)(left.register.int16_3 + right.register.int16_3); result.register.int16_4 = (short)(left.register.int16_4 + right.register.int16_4); result.register.int16_5 = (short)(left.register.int16_5 + right.register.int16_5); result.register.int16_6 = (short)(left.register.int16_6 + right.register.int16_6); result.register.int16_7 = (short)(left.register.int16_7 + right.register.int16_7); } else if (typeof(T) == typeof(uint)) { result.register.uint32_0 = left.register.uint32_0 + right.register.uint32_0; result.register.uint32_1 = left.register.uint32_1 + right.register.uint32_1; result.register.uint32_2 = left.register.uint32_2 + right.register.uint32_2; result.register.uint32_3 = left.register.uint32_3 + right.register.uint32_3; } else if (typeof(T) == typeof(int)) { result.register.int32_0 = left.register.int32_0 + right.register.int32_0; result.register.int32_1 = left.register.int32_1 + right.register.int32_1; result.register.int32_2 = left.register.int32_2 + right.register.int32_2; result.register.int32_3 = left.register.int32_3 + right.register.int32_3; } else if (typeof(T) == typeof(ulong)) { result.register.uint64_0 = left.register.uint64_0 + right.register.uint64_0; result.register.uint64_1 = left.register.uint64_1 + right.register.uint64_1; } else if (typeof(T) == typeof(long)) { result.register.int64_0 = left.register.int64_0 + right.register.int64_0; result.register.int64_1 = left.register.int64_1 + right.register.int64_1; } else if (typeof(T) == typeof(float)) { result.register.single_0 = left.register.single_0 + right.register.single_0; result.register.single_1 = left.register.single_1 + right.register.single_1; result.register.single_2 = left.register.single_2 + right.register.single_2; result.register.single_3 = left.register.single_3 + right.register.single_3; } else if (typeof(T) == typeof(double)) { result.register.double_0 = left.register.double_0 + right.register.double_0; result.register.double_1 = left.register.double_1 + right.register.double_1; } return result; } public unsafe static Vector<T>operator -(Vector<T> left, Vector<T> right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)(object)ScalarSubtract(left[i], right[i]); } return new Vector<T>(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(object)ScalarSubtract(left[j], right[j]); } return new Vector<T>(ptr2); } if (typeof(T) == typeof(ushort)) { ushort* ptr3 = stackalloc ushort[Count]; for (int k = 0; k < Count; k++) { ptr3[k] = (ushort)(object)ScalarSubtract(left[k], right[k]); } return new Vector<T>(ptr3); } if (typeof(T) == typeof(short)) { short* ptr4 = stackalloc short[Count]; for (int l = 0; l < Count; l++) { ptr4[l] = (short)(object)ScalarSubtract(left[l], right[l]); } return new Vector<T>(ptr4); } if (typeof(T) == typeof(uint)) { uint* ptr5 = stackalloc uint[Count]; for (int m = 0; m < Count; m++) { ptr5[m] = (uint)(object)ScalarSubtract(left[m], right[m]); } return new Vector<T>(ptr5); } if (typeof(T) == typeof(int)) { int* ptr6 = stackalloc int[Count]; for (int n = 0; n < Count; n++) { ptr6[n] = (int)(object)ScalarSubtract(left[n], right[n]); } return new Vector<T>(ptr6); } if (typeof(T) == typeof(ulong)) { ulong* ptr7 = stackalloc ulong[Count]; for (int num = 0; num < Count; num++) { ptr7[num] = (ulong)(object)ScalarSubtract(left[num], right[num]); } return new Vector<T>(ptr7); } if (typeof(T) == typeof(long)) { long* ptr8 = stackalloc long[Count]; for (int num2 = 0; num2 < Count; num2++) { ptr8[num2] = (long)(object)ScalarSubtract(left[num2], right[num2]); } return new Vector<T>(ptr8); } if (typeof(T) == typeof(float)) { float* ptr9 = stackalloc float[Count]; for (int num3 = 0; num3 < Count; num3++) { ptr9[num3] = (float)(object)ScalarSubtract(left[num3], right[num3]); } return new Vector<T>(ptr9); } if (typeof(T) == typeof(double)) { double* ptr10 = stackalloc double[Count]; for (int num4 = 0; num4 < Count; num4++) { ptr10[num4] = (double)(object)ScalarSubtract(left[num4], right[num4]); } return new Vector<T>(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Vector<T> result = default(Vector<T>); if (typeof(T) == typeof(byte)) { result.register.byte_0 = (byte)(left.register.byte_0 - right.register.byte_0); result.register.byte_1 = (byte)(left.register.byte_1 - right.register.byte_1); result.register.byte_2 = (byte)(left.register.byte_2 - right.register.byte_2); result.register.byte_3 = (byte)(left.register.byte_3 - right.register.byte_3); result.register.byte_4 = (byte)(left.register.byte_4 - right.register.byte_4); result.register.byte_5 = (byte)(left.register.byte_5 - right.register.byte_5); result.register.byte_6 = (byte)(left.register.byte_6 - right.register.byte_6); result.register.byte_7 = (byte)(left.register.byte_7 - right.register.byte_7); result.register.byte_8 = (byte)(left.register.byte_8 - right.register.byte_8); result.register.byte_9 = (byte)(left.register.byte_9 - right.register.byte_9); result.register.byte_10 = (byte)(left.register.byte_10 - right.register.byte_10); result.register.byte_11 = (byte)(left.register.byte_11 - right.register.byte_11); result.register.byte_12 = (byte)(left.register.byte_12 - right.register.byte_12); result.register.byte_13 = (byte)(left.register.byte_13 - right.register.byte_13); result.register.byte_14 = (byte)(left.register.byte_14 - right.register.byte_14); result.register.byte_15 = (byte)(left.register.byte_15 - right.register.byte_15); } else if (typeof(T) == typeof(sbyte)) { result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 - right.register.sbyte_0); result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 - right.register.sbyte_1); result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 - right.register.sbyte_2); result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 - right.register.sbyte_3); result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 - right.register.sbyte_4); result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 - right.register.sbyte_5); result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 - right.register.sbyte_6); result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 - right.register.sbyte_7); result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 - right.register.sbyte_8); result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 - right.register.sbyte_9); result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 - right.register.sbyte_10); result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 - right.register.sbyte_11); result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 - right.register.sbyte_12); result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 - right.register.sbyte_13); result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 - right.register.sbyte_14); result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 - right.register.sbyte_15); } else if (typeof(T) == typeof(ushort)) { result.register.uint16_0 = (ushort)(left.register.uint16_0 - right.register.uint16_0); result.register.uint16_1 = (ushort)(left.register.uint16_1 - right.register.uint16_1); result.register.uint16_2 = (ushort)(left.register.uint16_2 - right.register.uint16_2); result.register.uint16_3 = (ushort)(left.register.uint16_3 - right.register.uint16_3); result.register.uint16_4 = (ushort)(left.register.uint16_4 - right.register.uint16_4); result.register.uint16_5 = (ushort)(left.register.uint16_5 - right.register.uint16_5); result.register.uint16_6 = (ushort)(left.register.uint16_6 - right.register.uint16_6); result.register.uint16_7 = (ushort)(left.register.uint16_7 - right.register.uint16_7); } else if (typeof(T) == typeof(short)) { result.register.int16_0 = (short)(left.register.int16_0 - right.register.int16_0); result.register.int16_1 = (short)(left.register.int16_1 - right.register.int16_1); result.register.int16_2 = (short)(left.register.int16_2 - right.register.int16_2); result.register.int16_3 = (short)(left.register.int16_3 - right.register.int16_3); result.register.int16_4 = (short)(left.register.int16_4 - right.register.int16_4); result.register.int16_5 = (short)(left.register.int16_5 - right.register.int16_5); result.register.int16_6 = (short)(left.register.int16_6 - right.register.int16_6); result.register.int16_7 = (short)(left.register.int16_7 - right.register.int16_7); } else if (typeof(T) == typeof(uint)) { result.register.uint32_0 = left.register.uint32_0 - right.register.uint32_0; result.register.uint32_1 = left.register.uint32_1 - right.register.uint32_1; result.register.uint32_2 = left.register.uint32_2 - right.register.uint32_2; result.register.uint32_3 = left.register.uint32_3 - right.register.uint32_3; } else if (typeof(T) == typeof(int)) { result.register.int32_0 = left.register.int32_0 - right.register.int32_0; result.register.int32_1 = left.register.int32_1 - right.register.int32_1; result.register.int32_2 = left.register.int32_2 - right.register.int32_2; result.register.int32_3 = left.register.int32_3 - right.register.int32_3; } else if (typeof(T) == typeof(ulong)) { result.register.uint64_0 = left.register.uint64_0 - right.register.uint64_0; result.register.uint64_1 = left.register.uint64_1 - right.register.uint64_1; } else if (typeof(T) == typeof(long)) { result.register.int64_0 = left.register.int64_0 - right.register.int64_0; result.register.int64_1 = left.register.int64_1 - right.register.int64_1; } else if (typeof(T) == typeof(float)) { result.register.single_0 = left.register.single_0 - right.register.single_0; result.register.single_1 = left.register.single_1 - right.register.single_1; result.register.single_2 = left.register.single_2 - right.register.single_2; result.register.single_3 = left.register.single_3 - right.register.single_3; } else if (typeof(T) == typeof(double)) { result.register.double_0 = left.register.double_0 - right.register.double_0; result.register.double_1 = left.register.double_1 - right.register.double_1; } return result; } public unsafe static Vector<T>operator *(Vector<T> left, Vector<T> right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)(object)ScalarMultiply(left[i], right[i]); } return new Vector<T>(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(object)ScalarMultiply(left[j], right[j]); } return new Vector<T>(ptr2); } if (typeof(T) == typeof(ushort)) { ushort* ptr3 = stackalloc ushort[Count]; for (int k = 0; k < Count; k++) { ptr3[k] = (ushort)(object)ScalarMultiply(left[k], right[k]); } return new Vector<T>(ptr3); } if (typeof(T) == typeof(short)) { short* ptr4 = stackalloc short[Count]; for (int l = 0; l < Count; l++) { ptr4[l] = (short)(object)ScalarMultiply(left[l], right[l]); } return new Vector<T>(ptr4); } if (typeof(T) == typeof(uint)) { uint* ptr5 = stackalloc uint[Count]; for (int m = 0; m < Count; m++) { ptr5[m] = (uint)(object)ScalarMultiply(left[m], right[m]); } return new Vector<T>(ptr5); } if (typeof(T) == typeof(int)) { int* ptr6 = stackalloc int[Count]; for (int n = 0; n < Count; n++) { ptr6[n] = (int)(object)ScalarMultiply(left[n], right[n]); } return new Vector<T>(ptr6); } if (typeof(T) == typeof(ulong)) { ulong* ptr7 = stackalloc ulong[Count]; for (int num = 0; num < Count; num++) { ptr7[num] = (ulong)(object)ScalarMultiply(left[num], right[num]); } return new Vector<T>(ptr7); } if (typeof(T) == typeof(long)) { long* ptr8 = stackalloc long[Count]; for (int num2 = 0; num2 < Count; num2++) { ptr8[num2] = (long)(object)ScalarMultiply(left[num2], right[num2]); } return new Vector<T>(ptr8); } if (typeof(T) == typeof(float)) { float* ptr9 = stackalloc float[Count]; for (int num3 = 0; num3 < Count; num3++) { ptr9[num3] = (float)(object)ScalarMultiply(left[num3], right[num3]); } return new Vector<T>(ptr9); } if (typeof(T) == typeof(double)) { double* ptr10 = stackalloc double[Count]; for (int num4 = 0; num4 < Count; num4++) { ptr10[num4] = (double)(object)ScalarMultiply(left[num4], right[num4]); } return new Vector<T>(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Vector<T> result = default(Vector<T>); if (typeof(T) == typeof(byte)) { result.register.byte_0 = (byte)(left.register.byte_0 * right.register.byte_0); result.register.byte_1 = (byte)(left.register.byte_1 * right.register.byte_1); result.register.byte_2 = (byte)(left.register.byte_2 * right.register.byte_2); result.register.byte_3 = (byte)(left.register.byte_3 * right.register.byte_3); result.register.byte_4 = (byte)(left.register.byte_4 * right.register.byte_4); result.register.byte_5 = (byte)(left.register.byte_5 * right.register.byte_5); result.register.byte_6 = (byte)(left.register.byte_6 * right.register.byte_6); result.register.byte_7 = (byte)(left.register.byte_7 * right.register.byte_7); result.register.byte_8 = (byte)(left.register.byte_8 * right.register.byte_8); result.register.byte_9 = (byte)(left.register.byte_9 * right.register.byte_9); result.register.byte_10 = (byte)(left.register.byte_10 * right.register.byte_10); result.register.byte_11 = (byte)(left.register.byte_11 * right.register.byte_11); result.register.byte_12 = (byte)(left.register.byte_12 * right.register.byte_12); result.register.byte_13 = (byte)(left.register.byte_13 * right.register.byte_13); result.register.byte_14 = (byte)(left.register.byte_14 * right.register.byte_14); result.register.byte_15 = (byte)(left.register.byte_15 * right.register.byte_15); } else if (typeof(T) == typeof(sbyte)) { result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 * right.register.sbyte_0); result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 * right.register.sbyte_1); result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 * right.register.sbyte_2); result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 * right.register.sbyte_3); result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 * right.register.sbyte_4); result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 * right.register.sbyte_5); result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 * right.register.sbyte_6); result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 * right.register.sbyte_7); result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 * right.register.sbyte_8); result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 * right.register.sbyte_9); result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 * right.register.sbyte_10); result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 * right.register.sbyte_11); result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 * right.register.sbyte_12); result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 * right.register.sbyte_13); result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 * right.register.sbyte_14); result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 * right.register.sbyte_15); } else if (typeof(T) == typeof(ushort)) { result.register.uint16_0 = (ushort)(left.register.uint16_0 * right.register.uint16_0); result.register.uint16_1 = (ushort)(left.register.uint16_1 * right.register.uint16_1); result.register.uint16_2 = (ushort)(left.register.uint16_2 * right.register.uint16_2); result.register.uint16_3 = (ushort)(left.register.uint16_3 * right.register.uint16_3); result.register.uint16_4 = (ushort)(left.register.uint16_4 * right.register.uint16_4); result.register.uint16_5 = (ushort)(left.register.uint16_5 * right.register.uint16_5); result.register.uint16_6 = (ushort)(left.register.uint16_6 * right.register.uint16_6); result.register.uint16_7 = (ushort)(left.register.uint16_7 * right.register.uint16_7); } else if (typeof(T) == typeof(short)) { result.register.int16_0 = (short)(left.register.int16_0 * right.register.int16_0); result.register.int16_1 = (short)(left.register.int16_1 * right.register.int16_1); result.register.int16_2 = (short)(left.register.int16_2 * right.register.int16_2); result.register.int16_3 = (short)(left.register.int16_3 * right.register.int16_3); result.register.int16_4 = (short)(left.register.int16_4 * right.register.int16_4); result.register.int16_5 = (short)(left.register.int16_5 * right.register.int16_5); result.register.int16_6 = (short)(left.register.int16_6 * right.register.int16_6); result.register.int16_7 = (short)(left.register.int16_7 * right.register.int16_7); } else if (typeof(T) == typeof(uint)) { result.register.uint32_0 = left.register.uint32_0 * right.register.uint32_0; result.register.uint32_1 = left.register.uint32_1 * right.register.uint32_1; result.register.uint32_2 = left.register.uint32_2 * right.register.uint32_2; result.register.uint32_3 = left.register.uint32_3 * right.register.uint32_3; } else if (typeof(T) == typeof(int)) { result.register.int32_0 = left.register.int32_0 * right.register.int32_0; result.register.int32_1 = left.register.int32_1 * right.register.int32_1; result.register.int32_2 = left.register.int32_2 * right.register.int32_2; result.register.int32_3 = left.register.int32_3 * right.register.int32_3; } else if (typeof(T) == typeof(ulong)) { result.register.uint64_0 = left.register.uint64_0 * right.register.uint64_0; result.register.uint64_1 = left.register.uint64_1 * right.register.uint64_1; } else if (typeof(T) == typeof(long)) { result.register.int64_0 = left.register.int64_0 * right.register.int64_0; result.register.int64_1 = left.register.int64_1 * right.register.int64_1; } else if (typeof(T) == typeof(float)) { result.register.single_0 = left.register.single_0 * right.register.single_0; result.register.single_1 = left.register.single_1 * right.register.single_1; result.register.single_2 = left.register.single_2 * right.register.single_2; result.register.single_3 = left.register.single_3 * right.register.single_3; } else if (typeof(T) == typeof(double)) { result.register.double_0 = left.register.double_0 * right.register.double_0; result.register.double_1 = left.register.double_1 * right.register.double_1; } return result; } public static Vector<T>operator *(Vector<T> value, T factor) { if (Vector.IsHardwareAccelerated) { return new Vector<T>(factor) * value; } Vector<T> result = default(Vector<T>); if (typeof(T) == typeof(byte)) { result.register.byte_0 = (byte)(value.register.byte_0 * (byte)(object)factor); result.register.byte_1 = (byte)(value.register.byte_1 * (byte)(object)factor); result.register.byte_2 = (byte)(value.register.byte_2 * (byte)(object)factor); result.register.byte_3 = (byte)(value.register.byte_3 * (byte)(object)factor); result.register.byte_4 = (byte)(value.register.byte_4 * (byte)(object)factor); result.register.byte_5 = (byte)(value.register.byte_5 * (byte)(object)factor); result.register.byte_6 = (byte)(value.register.byte_6 * (byte)(object)factor); result.register.byte_7 = (byte)(value.register.byte_7 * (byte)(object)factor); result.register.byte_8 = (byte)(value.register.byte_8 * (byte)(object)factor); result.register.byte_9 = (byte)(value.register.byte_9 * (byte)(object)factor); result.register.byte_10 = (byte)(value.register.byte_10 * (byte)(object)factor); result.register.byte_11 = (byte)(value.register.byte_11 * (byte)(object)factor); result.register.byte_12 = (byte)(value.register.byte_12 * (byte)(object)factor); result.register.byte_13 = (byte)(value.register.byte_13 * (byte)(object)factor); result.register.byte_14 = (byte)(value.register.byte_14 * (byte)(object)factor); result.register.byte_15 = (byte)(value.register.byte_15 * (byte)(object)factor); } else if (typeof(T) == typeof(sbyte)) { result.register.sbyte_0 = (sbyte)(value.register.sbyte_0 * (sbyte)(object)factor); result.register.sbyte_1 = (sbyte)(value.register.sbyte_1 * (sbyte)(object)factor); result.register.sbyte_2 = (sbyte)(value.register.sbyte_2 * (sbyte)(object)factor); result.register.sbyte_3 = (sbyte)(value.register.sbyte_3 * (sbyte)(object)factor); result.register.sbyte_4 = (sbyte)(value.register.sbyte_4 * (sbyte)(object)factor); result.register.sbyte_5 = (sbyte)(value.register.sbyte_5 * (sbyte)(object)factor); result.register.sbyte_6 = (sbyte)(value.register.sbyte_6 * (sbyte)(object)factor); result.register.sbyte_7 = (sbyte)(value.register.sbyte_7 * (sbyte)(object)factor); result.register.sbyte_8 = (sbyte)(value.register.sbyte_8 * (sbyte)(object)factor); result.register.sbyte_9 = (sbyte)(value.register.sbyte_9 * (sbyte)(object)factor); result.register.sbyte_10 = (sbyte)(value.register.sbyte_10 * (sbyte)(object)factor); result.register.sbyte_11 = (sbyte)(value.register.sbyte_11 * (sbyte)(object)factor); result.register.sbyte_12 = (sbyte)(value.register.sbyte_12 * (sbyte)(object)factor); result.register.sbyte_13 = (sbyte)(value.register.sbyte_13 * (sbyte)(object)factor); result.register.sbyte_14 = (sbyte)(value.register.sbyte_14 * (sbyte)(object)factor); result.register.sbyte_15 = (sbyte)(value.register.sbyte_15 * (sbyte)(object)factor); } else if (typeof(T) == typeof(ushort)) { result.register.uint16_0 = (ushort)(value.register.uint16_0 * (ushort)(object)factor); result.register.uint16_1 = (ushort)(value.register.uint16_1 * (ushort)(object)factor); result.register.uint16_2 = (ushort)(value.register.uint16_2 * (ushort)(object)factor); result.register.uint16_3 = (ushort)(value.register.uint16_3 * (ushort)(object)factor); result.register.uint16_4 = (ushort)(value.register.uint16_4 * (ushort)(object)factor); result.register.uint16_5 = (ushort)(value.register.uint16_5 * (ushort)(object)factor); result.register.uint16_6 = (ushort)(value.register.uint16_6 * (ushort)(object)factor); result.register.uint16_7 = (ushort)(value.register.uint16_7 * (ushort)(object)factor); } else if (typeof(T) == typeof(short)) { result.register.int16_0 = (short)(value.register.int16_0 * (short)(object)factor); result.register.int16_1 = (short)(value.register.int16_1 * (short)(object)factor); result.register.int16_2 = (short)(value.register.int16_2 * (short)(object)factor); result.register.int16_3 = (short)(value.register.int16_3 * (short)(object)factor); result.register.int16_4 = (short)(value.register.int16_4 * (short)(object)factor); result.register.int16_5 = (short)(value.register.int16_5 * (short)(object)factor); result.register.int16_6 = (short)(value.register.int16_6 * (short)(object)factor); result.register.int16_7 = (short)(value.register.int16_7 * (short)(object)factor); } else if (typeof(T) == typeof(uint)) { result.register.uint32_0 = value.register.uint32_0 * (uint)(object)factor; result.register.uint32_1 = value.register.uint32_1 * (uint)(object)factor; result.register.uint32_2 = value.register.uint32_2 * (uint)(object)factor; result.register.uint32_3 = value.register.uint32_3 * (uint)(object)factor; } else if (typeof(T) == typeof(int)) { result.register.int32_0 = value.register.int32_0 * (int)(object)factor; result.register.int32_1 = value.register.int32_1 * (int)(object)factor; result.register.int32_2 = value.register.int32_2 * (int)(object)factor; result.register.int32_3 = value.register.int32_3 * (int)(object)factor; } else if (typeof(T) == typeof(ulong)) { result.register.uint64_0 = value.register.uint64_0 * (ulong)(object)factor; result.register.uint64_1 = value.register.uint64_1 * (ulong)(object)factor; } else if (typeof(T) == typeof(long)) { result.register.int64_0 = value.register.int64_0 * (long)(object)factor; result.register.int64_1 = value.register.int64_1 * (long)(object)factor; } else if (typeof(T) == typeof(float)) { result.register.single_0 = value.register.single_0 * (float)(object)factor; result.register.single_1 = value.register.single_1 * (float)(object)factor; result.register.single_2 = value.register.single_2 * (float)(object)factor; result.register.single_3 = value.register.single_3 * (float)(object)factor; } else if (typeof(T) == typeof(double)) { result.register.double_0 = value.register.double_0 * (double)(object)factor; result.register.double_1 = value.register.double_1 * (double)(object)factor; } return result; } public static Vector<T>operator *(T factor, Vector<T> value) { if (Vector.IsHardwareAccelerated) { return new Vector<T>(factor) * value; } Vector<T> result = default(Vector<T>); if (typeof(T) == typeof(byte)) { result.register.byte_0 = (byte)(value.register.byte_0 * (byte)(object)factor); result.register.byte_1 = (byte)(value.register.byte_1 * (byte)(object)factor); result.register.byte_2 = (byte)(value.register.byte_2 * (byte)(object)factor); result.register.byte_3 = (byte)(value.register.byte_3 * (byte)(object)factor); result.register.byte_4 = (byte)(value.register.byte_4 * (byte)(object)factor); result.register.byte_5 = (byte)(value.register.byte_5 * (byte)(object)factor); result.register.byte_6 = (byte)(value.register.byte_6 * (byte)(object)factor); result.register.byte_7 = (byte)(value.register.byte_7 * (byte)(object)factor); result.register.byte_8 = (byte)(value.register.byte_8 * (byte)(object)factor); result.register.byte_9 = (byte)(value.register.byte_9 * (byte)(object)factor); result.register.byte_10 = (byte)(value.register.byte_10 * (byte)(object)factor); result.register.byte_11 = (byte)(value.register.byte_11 * (byte)(object)factor); result.register.byte_12 = (byte)(value.register.byte_12 * (byte)(object)factor); result.register.byte_13 = (byte)(value.register.byte_13 * (byte)(object)factor); result.register.byte_14 = (byte)(value.register.byte_14 * (byte)(object)factor); result.register.byte_15 = (byte)(value.register.byte_15 * (byte)(object)factor); } else if (typeof(T) == typeof(sbyte)) { result.register.sbyte_0 = (sbyte)(value.register.sbyte_0 * (sbyte)(object)factor); result.register.sbyte_1 = (sbyte)(value.register.sbyte_1 * (sbyte)(object)factor); result.register.sbyte_2 = (sbyte)(value.register.sbyte_2 * (sbyte)(object)factor); result.register.sbyte_3 = (sbyte)(value.register.sbyte_3 * (sbyte)(object)factor); result.register.sbyte_4 = (sbyte)(value.register.sbyte_4 * (sbyte)(object)factor); result.register.sbyte_5 = (sbyte)(value.register.sbyte_5 * (sbyte)(object)factor); result.register.sbyte_6 = (sbyte)(value.register.sbyte_6 * (sbyte)(object)factor); result.register.sbyte_7 = (sbyte)(value.register.sbyte_7 * (sbyte)(object)factor); result.register.sbyte_8 = (sbyte)(value.register.sbyte_8 * (sbyte)(object)factor); result.register.sbyte_9 = (sbyte)(value.register.sbyte_9 * (sbyte)(object)factor); result.register.sbyte_10 = (sbyte)(value.register.sbyte_10 * (sbyte)(object)factor); result.register.sbyte_11 = (sbyte)(value.register.sbyte_11 * (sbyte)(object)factor); result.register.sbyte_12 = (sbyte)(value.register.sbyte_12 * (sbyte)(object)factor); result.register.sbyte_13 = (sbyte)(value.register.sbyte_13 * (sbyte)(object)factor); result.register.sbyte_14 = (sbyte)(value.register.sbyte_14 * (sbyte)(object)factor); result.register.sbyte_15 = (sbyte)(value.register.sbyte_15 * (sbyte)(object)factor); } else if (typeof(T) == typeof(ushort)) { result.register.uint16_0 = (ushort)(value.register.uint16_0 * (ushort)(object)factor); result.register.uint16_1 = (ushort)(value.register.uint16_1 * (ushort)(object)factor); result.register.uint16_2 = (ushort)(value.register.uint16_2 * (ushort)(object)factor); result.register.uint16_3 = (ushort)(value.register.uint16_3 * (ushort)(object)factor); result.register.uint16_4 = (ushort)(value.register.uint16_4 * (ushort)(object)factor); result.register.uint16_5 = (ushort)(value.register.uint16_5 * (ushort)(object)factor); result.register.uint16_6 = (ushort)(value.register.uint16_6 * (ushort)(object)factor); result.register.uint16_7 = (ushort)(value.register.uint16_7 * (ushort)(object)factor); } else if (typeof(T) == typeof(short)) { result.register.int16_0 = (short)(value.register.int16_0 * (short)(object)factor); result.register.int16_1 = (short)(value.register.int16_1 * (short)(object)factor); result.register.int16_2 = (short)(value.register.int16_2 * (short)(object)factor); result.register.int16_3 = (short)(value.register.int16_3 * (short)(object)factor); result.register.int16_4 = (short)(value.register.int16_4 * (short)(object)factor); result.register.int16_5 = (short)(value.register.int16_5 * (short)(object)factor); result.register.int16_6 = (short)(value.register.int16_6 * (short)(object)factor); result.register.int16_7 = (short)(value.register.int16_7 * (short)(object)factor); } else if (typeof(T) == typeof(uint)) { result.register.uint32_0 = value.register.uint32_0 * (uint)(object)factor; result.register.uint32_1 = value.register.uint32_1 * (uint)(object)factor; result.register.uint32_2 = value.register.uint32_2 * (uint)(object)factor; result.register.uint32_3 = value.register.uint32_3 * (uint)(object)factor; } else if (typeof(T) == typeof(int)) { result.register.int32_0 = value.register.int32_0 * (int)(object)factor; result.register.int32_1 = value.register.int32_1 * (int)(object)factor; result.register.int32_2 = value.register.int32_2 * (int)(object)factor; result.register.int32_3 = value.register.int32_3 * (int)(object)factor; } else if (typeof(T) == typeof(ulong)) { result.register.uint64_0 = value.register.uint64_0 * (ulong)(object)factor; result.register.uint64_1 = value.register.uint64_1 * (ulong)(object)factor; } else if (typeof(T) == typeof(long)) { result.register.int64_0 = value.register.int64_0 * (long)(object)factor; result.register.int64_1 = value.register.int64_1 * (long)(object)factor; } else if (typeof(T) == typeof(float)) { result.register.single_0 = value.register.single_0 * (float)(object)factor; result.register.single_1 = value.register.single_1 * (float)(object)factor; result.register.single_2 = value.register.single_2 * (float)(object)factor; result.register.single_3 = value.register.single_3 * (float)(object)factor; } else if (typeof(T) == typeof(double)) { result.register.double_0 = value.register.double_0 * (double)(object)factor; result.register.double_1 = value.register.double_1 * (double)(object)factor; } return result; } public unsafe static Vector<T>operator /(Vector<T> left, Vector<T> right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)(object)ScalarDivide(left[i], right[i]); } return new Vector<T>(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(object)ScalarDivide(left[j], right[j]); } return new Vector<T>(ptr2); } if (typeof(T) == typeof(ushort)) { ushort* ptr3 = stackalloc ushort[Count]; for (int k = 0; k < Count; k++) { ptr3[k] = (ushort)(object)ScalarDivide(left[k], right[k]); } return new Vector<T>(ptr3); } if (typeof(T) == typeof(short)) { short* ptr4 = stackalloc short[Count]; for (int l = 0; l < Count; l++) { ptr4[l] = (short)(object)ScalarDivide(left[l], right[l]); } return new Vector<T>(ptr4); } if (typeof(T) == typeof(uint)) { uint* ptr5 = stackalloc uint[Count]; for (int m = 0; m < Count; m++) { ptr5[m] = (uint)(object)ScalarDivide(left[m], right[m]); } return new Vector<T>(ptr5); } if (typeof(T) == typeof(int)) { int* ptr6 = stackalloc int[Count]; for (int n = 0; n < Count; n++) { ptr6[n] = (int)(object)ScalarDivide(left[n], right[n]); } return new Vector<T>(ptr6); } if (typeof(T) == typeof(ulong)) { ulong* ptr7 = stackalloc ulong[Count]; for (int num = 0; num < Count; num++) { ptr7[num] = (ulong)(object)ScalarDivide(left[num], right[num]); } return new Vector<T>(ptr7); } if (typeof(T) == typeof(long)) { long* ptr8 = stackalloc long[Count]; for (int num2 = 0; num2 < Count; num2++) { ptr8[num2] = (long)(object)ScalarDivide(left[num2], right[num2]); } return new Vector<T>(ptr8); } if (typeof(T) == typeof(float)) { float* ptr9 = stackalloc float[Count]; for (int num3 = 0; num3 < Count; num3++) { ptr9[num3] = (float)(object)ScalarDivide(left[num3], right[num3]); } return new Vector<T>(ptr9); } if (typeof(T) == typeof(double)) { double* ptr10 = stackalloc double[Count]; for (int num4 = 0; num4 < Count; num4++) { ptr10[num4] = (double)(object)ScalarDivide(left[num4], right[num4]); } return new Vector<T>(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Vector<T> result = default(Vector<T>); if (typeof(T) == typeof(byte)) { result.register.byte_0 = (byte)(left.register.byte_0 / right.register.byte_0); result.register.byte_1 = (byte)(left.register.byte_1 / right.register.byte_1); result.register.byte_2 = (byte)(left.register.byte_2 / right.register.byte_2); result.register.byte_3 = (byte)(left.register.byte_3 / right.register.byte_3); result.register.byte_4 = (byte)(left.register.byte_4 / right.register.byte_4); result.register.byte_5 = (byte)(left.register.byte_5 / right.register.byte_5); result.register.byte_6 = (byte)(left.register.byte_6 / right.register.byte_6); result.register.byte_7 = (byte)(left.register.byte_7 / right.register.byte_7); result.register.byte_8 = (byte)(left.register.byte_8 / right.register.byte_8); result.register.byte_9 = (byte)(left.register.byte_9 / right.register.byte_9); result.register.byte_10 = (byte)(left.register.byte_10 / right.register.byte_10); result.register.byte_11 = (byte)(left.register.byte_11 / right.register.byte_11); result.register.byte_12 = (byte)(left.register.byte_12 / right.register.byte_12); result.register.byte_13 = (byte)(left.register.byte_13 / right.register.byte_13); result.register.byte_14 = (byte)(left.register.byte_14 / right.register.byte_14); result.register.byte_15 = (byte)(left.register.byte_15 / right.register.byte_15); } else if (typeof(T) == typeof(sbyte)) { result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 / right.register.sbyte_0); result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 / right.register.sbyte_1); result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 / right.register.sbyte_2); result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 / right.register.sbyte_3); result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 / right.register.sbyte_4); result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 / right.register.sbyte_5); result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 / right.register.sbyte_6); result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 / right.register.sbyte_7); result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 / right.register.sbyte_8); result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 / right.register.sbyte_9); result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 / right.register.sbyte_10); result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 / right.register.sbyte_11); result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 / right.register.sbyte_12); result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 / right.register.sbyte_13); result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 / right.register.sbyte_14); result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 / right.register.sbyte_15); } else if (typeof(T) == typeof(ushort)) { result.register.uint16_0 = (ushort)(left.register.uint16_0 / right.register.uint16_0); result.register.uint16_1 = (ushort)(left.register.uint16_1 / right.register.uint16_1); result.register.uint16_2 = (ushort)(left.register.uint16_2 / right.register.uint16_2); result.register.uint16_3 = (ushort)(left.register.uint16_3 / right.register.uint16_3); result.register.uint16_4 = (ushort)(left.register.uint16_4 / right.register.uint16_4); result.register.uint16_5 = (ushort)(left.register.uint16_5 / right.register.uint16_5); result.register.uint16_6 = (ushort)(left.register.uint16_6 / right.register.uint16_6); result.register.uint16_7 = (ushort)(left.register.uint16_7 / right.register.uint16_7); } else if (typeof(T) == typeof(short)) { result.register.int16_0 = (short)(left.register.int16_0 / right.register.int16_0); result.register.int16_1 = (short)(left.register.int16_1 / right.register.int16_1); result.register.int16_2 = (short)(left.register.int16_2 / right.register.int16_2); result.register.int16_3 = (short)(left.register.int16_3 / right.register.int16_3); result.register.int16_4 = (short)(left.register.int16_4 / right.register.int16_4); result.register.int16_5 = (short)(left.register.int16_5 / right.register.int16_5); result.register.int16_6 = (short)(left.register.int16_6 / right.register.int16_6); result.register.int16_7 = (short)(left.register.int16_7 / right.register.int16_7); } else if (typeof(T) == typeof(uint)) { result.register.uint32_0 = left.register.uint32_0 / right.register.uint32_0; result.register.uint32_1 = left.register.uint32_1 / right.register.uint32_1; result.register.uint32_2 = left.register.uint32_2 / right.register.uint32_2; result.register.uint32_3 = left.register.uint32_3 / right.register.uint32_3; } else if (typeof(T) == typeof(int)) { result.register.int32_0 = left.register.int32_0 / right.register.int32_0; result.register.int32_1 = left.register.int32_1 / right.register.int32_1; result.register.int32_2 = left.register.int32_2 / right.register.int32_2; result.register.int32_3 = left.register.int32_3 / right.register.int32_3; } else if (typeof(T) == typeof(ulong)) { result.register.uint64_0 = left.register.uint64_0 / right.register.uint64_0; result.register.uint64_1 = left.register.uint64_1 / right.register.uint64_1; } else if (typeof(T) == typeof(long)) { result.register.int64_0 = left.register.int64_0 / right.register.int64_0; result.register.int64_1 = left.register.int64_1 / right.register.int64_1; } else if (typeof(T) == typeof(float)) { result.register.single_0 = left.register.single_0 / right.register.single_0; result.register.single_1 = left.register.single_1 / right.register.single_1; result.register.single_2 = left.register.single_2 / right.register.single_2; result.register.single_3 = left.register.single_3 / right.register.single_3; } else if (typeof(T) == typeof(double)) { result.register.double_0 = left.register.double_0 / right.register.double_0; result.register.double_1 = left.register.double_1 / right.register.double_1; } return result; } public static Vector<T>operator -(Vector<T> value) { return Zero - value; } [JitIntrinsic] public unsafe static Vector<T>operator &(Vector<T> left, Vector<T> right) { Vector<T> result = default(Vector<T>); if (Vector.IsHardwareAccelerated) { long* ptr = &result.register.int64_0; long* ptr2 = &left.register.int64_0; long* ptr3 = &right.register.int64_0; for (int i = 0; i < Vector<long>.Count; i++) { ptr[i] = ptr2[i] & ptr3[i]; } } else { result.register.int64_0 = left.register.int64_0 & right.register.int64_0; result.register.int64_1 = left.register.int64_1 & right.register.int64_1; } return result; } [JitIntrinsic] public unsafe static Vector<T>operator |(Vector<T> left, Vector<T> right) { Vector<T> result = default(Vector<T>); if (Vector.IsHardwareAccelerated) { long* ptr = &result.register.int64_0; long* ptr2 = &left.register.int64_0; long* ptr3 = &right.register.int64_0; for (int i = 0; i < Vector<long>.Count; i++) { ptr[i] = ptr2[i] | ptr3[i]; } } else { result.register.int64_0 = left.register.int64_0 | right.register.int64_0; result.register.int64_1 = left.register.int64_1 | right.register.int64_1; } return result; } [JitIntrinsic] public unsafe static Vector<T>operator ^(Vector<T> left, Vector<T> right) { Vector<T> result = default(Vector<T>); if (Vector.IsHardwareAccelerated) { long* ptr = &result.register.int64_0; long* ptr2 = &left.register.int64_0; long* ptr3 = &right.register.int64_0; for (int i = 0; i < Vector<long>.Count; i++) { ptr[i] = ptr2[i] ^ ptr3[i]; } } else { result.register.int64_0 = left.register.int64_0 ^ right.register.int64_0; result.register.int64_1 = left.register.int64_1 ^ right.register.int64_1; } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector<T>operator ~(Vector<T> value) { return allOnes ^ value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Vector<T> left, Vector<T> right) { return left.Equals(right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Vector<T> left, Vector<T> right) { return !(left == right); } [JitIntrinsic] public static explicit operator Vector<byte>(Vector<T> value) { return new Vector<byte>(ref value.register); } [CLSCompliant(false)] [JitIntrinsic] public static explicit operator Vector<sbyte>(Vector<T> value) { return new Vector<sbyte>(ref value.register); } [CLSCompliant(false)] [JitIntrinsic] public static explicit operator Vector<ushort>(Vector<T> value) { return new Vector<ushort>(ref value.register); } [JitIntrinsic] public static explicit operator Vector<short>(Vector<T> value) { return new Vector<short>(ref value.register); } [CLSCompliant(false)] [JitIntrinsic] public static explicit operator Vector<uint>(Vector<T> value) { return new Vector<uint>(ref value.register); } [JitIntrinsic] public static explicit operator Vector<int>(Vector<T> value) { return new Vector<int>(ref value.register); } [CLSCompliant(false)] [JitIntrinsic] public static explicit operator Vector<ulong>(Vector<T> value) { return new Vector<ulong>(ref value.register); } [JitIntrinsic] public static explicit operator Vector<long>(Vector<T> value) { return new Vector<long>(ref value.register); } [JitIntrinsic] public static explicit operator Vector<float>(Vector<T> value) { return new Vector<float>(ref value.register); } [JitIntrinsic] public static explicit operator Vector<double>(Vector<T> value) { return new Vector<double>(ref value.register); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [JitIntrinsic] internal unsafe static Vector<T> Equals(Vector<T> left, Vector<T> right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)(ScalarEquals(left[i], right[i]) ? ConstantHelper.GetByteWithAllBitsSet() : 0); } return new Vector<T>(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(ScalarEquals(left[j], right[j]) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); } return new Vector<T>(ptr2); } if (typeof(T) == typeof(ushort)) { ushort* ptr3 = stackalloc ushort[Count]; for (int k = 0; k < Count; k++) { ptr3[k] =
plugins/System.Runtime.CompilerServices.Unsafe.dll
Decompiled a month agousing System; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; [assembly: AssemblyProduct("Microsoft® .NET Framework")] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyFileVersion("4.0.0.0")] [assembly: AssemblyInformationalVersion("4.0.0.0")] [assembly: AssemblyTitle("System.Runtime.CompilerServices.Unsafe")] [assembly: AssemblyDescription("System.Runtime.CompilerServices.Unsafe")] [assembly: AssemblyMetadata(".NETFrameworkAssembly", "")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: CLSCompliant(false)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyVersion("4.0.4.1")] namespace System.Runtime.CompilerServices { public static class Unsafe : Object { [MethodImpl(256)] [NonVersionable] public unsafe static T Read<T>(void* source) { return Unsafe.Read<T>(source); } [MethodImpl(256)] [NonVersionable] public unsafe static T ReadUnaligned<T>(void* source) { return Unsafe.ReadUnaligned<T>(source); } [MethodImpl(256)] [NonVersionable] public static T ReadUnaligned<T>(ref byte source) { return Unsafe.ReadUnaligned<T>(ref source); } [MethodImpl(256)] [NonVersionable] public unsafe static void Write<T>(void* destination, T value) { Unsafe.Write(destination, value); } [MethodImpl(256)] [NonVersionable] public unsafe static void WriteUnaligned<T>(void* destination, T value) { Unsafe.WriteUnaligned(destination, value); } [MethodImpl(256)] [NonVersionable] public static void WriteUnaligned<T>(ref byte destination, T value) { Unsafe.WriteUnaligned(ref destination, value); } [MethodImpl(256)] [NonVersionable] public unsafe static void Copy<T>(void* destination, ref T source) { Unsafe.Write(destination, source); } [MethodImpl(256)] [NonVersionable] public unsafe static void Copy<T>(ref T destination, void* source) { destination = Unsafe.Read<T>(source); } [MethodImpl(256)] [NonVersionable] public unsafe static void* AsPointer<T>(ref T value) { return Unsafe.AsPointer(ref value); } [MethodImpl(256)] [NonVersionable] public static int SizeOf<T>() { return Unsafe.SizeOf<T>(); } [MethodImpl(256)] [NonVersionable] public unsafe static void CopyBlock(void* destination, void* source, uint byteCount) { // IL cpblk instruction Unsafe.CopyBlock(destination, source, byteCount); } [MethodImpl(256)] [NonVersionable] public static void CopyBlock(ref byte destination, ref byte source, uint byteCount) { // IL cpblk instruction Unsafe.CopyBlock(ref destination, ref source, byteCount); } [MethodImpl(256)] [NonVersionable] public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount) { // IL cpblk instruction Unsafe.CopyBlockUnaligned(destination, source, byteCount); } [MethodImpl(256)] [NonVersionable] public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount) { // IL cpblk instruction Unsafe.CopyBlockUnaligned(ref destination, ref source, byteCount); } [MethodImpl(256)] [NonVersionable] public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount) { // IL initblk instruction Unsafe.InitBlock(startAddress, value, byteCount); } [MethodImpl(256)] [NonVersionable] public static void InitBlock(ref byte startAddress, byte value, uint byteCount) { // IL initblk instruction Unsafe.InitBlock(ref startAddress, value, byteCount); } [MethodImpl(256)] [NonVersionable] public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { // IL initblk instruction Unsafe.InitBlockUnaligned(startAddress, value, byteCount); } [MethodImpl(256)] [NonVersionable] public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount) { // IL initblk instruction Unsafe.InitBlockUnaligned(ref startAddress, value, byteCount); } [MethodImpl(256)] [NonVersionable] public static T As<T>(object o) where T : class { return (T)o; } [MethodImpl(256)] [NonVersionable] public unsafe static ref T AsRef<T>(void* source) { return ref *(T*)source; } [MethodImpl(256)] [NonVersionable] public static ref T AsRef<T>(in T source) { return ref source; } [MethodImpl(256)] [NonVersionable] public static ref TTo As<TFrom, TTo>(ref TFrom source) { return ref Unsafe.As<TFrom, TTo>(ref source); } [MethodImpl(256)] [NonVersionable] public static ref T Add<T>(ref T source, int elementOffset) { return ref Unsafe.Add(ref source, elementOffset); } [MethodImpl(256)] [NonVersionable] public unsafe static void* Add<T>(void* source, int elementOffset) { return (byte*)source + (nint)elementOffset * (nint)Unsafe.SizeOf<T>(); } [MethodImpl(256)] [NonVersionable] public static ref T Add<T>(ref T source, System.IntPtr elementOffset) { return ref Unsafe.Add(ref source, elementOffset); } [MethodImpl(256)] [NonVersionable] public static ref T AddByteOffset<T>(ref T source, System.IntPtr byteOffset) { return ref Unsafe.AddByteOffset(ref source, byteOffset); } [MethodImpl(256)] [NonVersionable] public static ref T Subtract<T>(ref T source, int elementOffset) { return ref Unsafe.Subtract(ref source, elementOffset); } [MethodImpl(256)] [NonVersionable] public unsafe static void* Subtract<T>(void* source, int elementOffset) { return (byte*)source - (nint)elementOffset * (nint)Unsafe.SizeOf<T>(); } [MethodImpl(256)] [NonVersionable] public static ref T Subtract<T>(ref T source, System.IntPtr elementOffset) { return ref Unsafe.Subtract(ref source, elementOffset); } [MethodImpl(256)] [NonVersionable] public static ref T SubtractByteOffset<T>(ref T source, System.IntPtr byteOffset) { return ref Unsafe.SubtractByteOffset(ref source, byteOffset); } [MethodImpl(256)] [NonVersionable] public static System.IntPtr ByteOffset<T>(ref T origin, ref T target) { return Unsafe.ByteOffset(target: ref target, origin: ref origin); } [MethodImpl(256)] [NonVersionable] public static bool AreSame<T>(ref T left, ref T right) { return Unsafe.AreSame(ref left, ref right); } [MethodImpl(256)] [NonVersionable] public static bool IsAddressGreaterThan<T>(ref T left, ref T right) { return Unsafe.IsAddressGreaterThan(ref left, ref right); } [MethodImpl(256)] [NonVersionable] public static bool IsAddressLessThan<T>(ref T left, ref T right) { return Unsafe.IsAddressLessThan(ref left, ref right); } } } namespace System.Runtime.Versioning { [AttributeUsage(/*Could not decode attribute arguments.*/)] internal sealed class NonVersionableAttribute : Attribute { } } namespace System.Runtime.CompilerServices { internal sealed class IsReadOnlyAttribute : Attribute { } }
plugins/System.Security.AccessControl.dll
Decompiled a month agousing System; using System.Diagnostics; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Security; using System.Security.AccessControl; using System.Security.Permissions; using FxResources.System.Security.AccessControl; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyDefaultAlias("System.Security.AccessControl")] [assembly: AssemblyMetadata(".NETFrameworkAssembly", "")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyMetadata("PreferInbox", "True")] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyDescription("System.Security.AccessControl")] [assembly: AssemblyFileVersion("4.700.19.56404")] [assembly: AssemblyInformationalVersion("3.1.0+0f7f38c4fd323b26da10cce95f857f77f0f09b48")] [assembly: AssemblyProduct("Microsoft® .NET Core")] [assembly: AssemblyTitle("System.Security.AccessControl")] [assembly: CLSCompliant(true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("4.1.3.0")] [assembly: TypeForwardedTo(typeof(AccessControlActions))] [assembly: TypeForwardedTo(typeof(AccessControlModification))] [assembly: TypeForwardedTo(typeof(AccessControlSections))] [assembly: TypeForwardedTo(typeof(AccessControlType))] [assembly: TypeForwardedTo(typeof(AccessRule))] [assembly: TypeForwardedTo(typeof(AccessRule<>))] [assembly: TypeForwardedTo(typeof(AceEnumerator))] [assembly: TypeForwardedTo(typeof(AceFlags))] [assembly: TypeForwardedTo(typeof(AceQualifier))] [assembly: TypeForwardedTo(typeof(AceType))] [assembly: TypeForwardedTo(typeof(AuditFlags))] [assembly: TypeForwardedTo(typeof(AuditRule))] [assembly: TypeForwardedTo(typeof(AuditRule<>))] [assembly: TypeForwardedTo(typeof(AuthorizationRule))] [assembly: TypeForwardedTo(typeof(AuthorizationRuleCollection))] [assembly: TypeForwardedTo(typeof(CommonAce))] [assembly: TypeForwardedTo(typeof(CommonAcl))] [assembly: TypeForwardedTo(typeof(CommonObjectSecurity))] [assembly: TypeForwardedTo(typeof(CommonSecurityDescriptor))] [assembly: TypeForwardedTo(typeof(CompoundAce))] [assembly: TypeForwardedTo(typeof(CompoundAceType))] [assembly: TypeForwardedTo(typeof(ControlFlags))] [assembly: TypeForwardedTo(typeof(CustomAce))] [assembly: TypeForwardedTo(typeof(DiscretionaryAcl))] [assembly: TypeForwardedTo(typeof(GenericAce))] [assembly: TypeForwardedTo(typeof(GenericAcl))] [assembly: TypeForwardedTo(typeof(GenericSecurityDescriptor))] [assembly: TypeForwardedTo(typeof(InheritanceFlags))] [assembly: TypeForwardedTo(typeof(KnownAce))] [assembly: TypeForwardedTo(typeof(NativeObjectSecurity))] [assembly: TypeForwardedTo(typeof(ObjectAccessRule))] [assembly: TypeForwardedTo(typeof(ObjectAce))] [assembly: TypeForwardedTo(typeof(ObjectAceFlags))] [assembly: TypeForwardedTo(typeof(ObjectAuditRule))] [assembly: TypeForwardedTo(typeof(ObjectSecurity))] [assembly: TypeForwardedTo(typeof(ObjectSecurity<>))] [assembly: TypeForwardedTo(typeof(PrivilegeNotHeldException))] [assembly: TypeForwardedTo(typeof(PropagationFlags))] [assembly: TypeForwardedTo(typeof(QualifiedAce))] [assembly: TypeForwardedTo(typeof(RawAcl))] [assembly: TypeForwardedTo(typeof(RawSecurityDescriptor))] [assembly: TypeForwardedTo(typeof(ResourceType))] [assembly: TypeForwardedTo(typeof(SecurityInfos))] [assembly: TypeForwardedTo(typeof(SystemAcl))] [module: UnverifiableCode] namespace FxResources.System.Security.AccessControl { internal static class SR { } } namespace System { internal static class SR { private static ResourceManager s_resourceManager; internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(FxResources.System.Security.AccessControl.SR))); internal static string AccessControl_AclTooLong => GetResourceString("AccessControl_AclTooLong"); internal static string AccessControl_InvalidAccessRuleType => GetResourceString("AccessControl_InvalidAccessRuleType"); internal static string AccessControl_InvalidAuditRuleType => GetResourceString("AccessControl_InvalidAuditRuleType"); internal static string AccessControl_InvalidOwner => GetResourceString("AccessControl_InvalidOwner"); internal static string AccessControl_InvalidGroup => GetResourceString("AccessControl_InvalidGroup"); internal static string AccessControl_InvalidHandle => GetResourceString("AccessControl_InvalidHandle"); internal static string AccessControl_InvalidSecurityDescriptorRevision => GetResourceString("AccessControl_InvalidSecurityDescriptorRevision"); internal static string AccessControl_InvalidSecurityDescriptorSelfRelativeForm => GetResourceString("AccessControl_InvalidSecurityDescriptorSelfRelativeForm"); internal static string AccessControl_InvalidSidInSDDLString => GetResourceString("AccessControl_InvalidSidInSDDLString"); internal static string AccessControl_MustSpecifyContainerAcl => GetResourceString("AccessControl_MustSpecifyContainerAcl"); internal static string AccessControl_MustSpecifyDirectoryObjectAcl => GetResourceString("AccessControl_MustSpecifyDirectoryObjectAcl"); internal static string AccessControl_MustSpecifyLeafObjectAcl => GetResourceString("AccessControl_MustSpecifyLeafObjectAcl"); internal static string AccessControl_MustSpecifyNonDirectoryObjectAcl => GetResourceString("AccessControl_MustSpecifyNonDirectoryObjectAcl"); internal static string AccessControl_NoAssociatedSecurity => GetResourceString("AccessControl_NoAssociatedSecurity"); internal static string AccessControl_UnexpectedError => GetResourceString("AccessControl_UnexpectedError"); internal static string Arg_EnumAtLeastOneFlag => GetResourceString("Arg_EnumAtLeastOneFlag"); internal static string Arg_EnumIllegalVal => GetResourceString("Arg_EnumIllegalVal"); internal static string Arg_InvalidOperationException => GetResourceString("Arg_InvalidOperationException"); internal static string Arg_MustBeIdentityReferenceType => GetResourceString("Arg_MustBeIdentityReferenceType"); internal static string Argument_ArgumentZero => GetResourceString("Argument_ArgumentZero"); internal static string Argument_InvalidAnyFlag => GetResourceString("Argument_InvalidAnyFlag"); internal static string Argument_InvalidEnumValue => GetResourceString("Argument_InvalidEnumValue"); internal static string Argument_InvalidName => GetResourceString("Argument_InvalidName"); internal static string Argument_InvalidPrivilegeName => GetResourceString("Argument_InvalidPrivilegeName"); internal static string Argument_InvalidSafeHandle => GetResourceString("Argument_InvalidSafeHandle"); internal static string ArgumentException_InvalidAceBinaryForm => GetResourceString("ArgumentException_InvalidAceBinaryForm"); internal static string ArgumentException_InvalidAclBinaryForm => GetResourceString("ArgumentException_InvalidAclBinaryForm"); internal static string ArgumentException_InvalidSDSddlForm => GetResourceString("ArgumentException_InvalidSDSddlForm"); internal static string ArgumentOutOfRange_ArrayLength => GetResourceString("ArgumentOutOfRange_ArrayLength"); internal static string ArgumentOutOfRange_ArrayLengthMultiple => GetResourceString("ArgumentOutOfRange_ArrayLengthMultiple"); internal static string ArgumentOutOfRange_ArrayTooSmall => GetResourceString("ArgumentOutOfRange_ArrayTooSmall"); internal static string ArgumentOutOfRange_Enum => GetResourceString("ArgumentOutOfRange_Enum"); internal static string ArgumentOutOfRange_InvalidUserDefinedAceType => GetResourceString("ArgumentOutOfRange_InvalidUserDefinedAceType"); internal static string ArgumentOutOfRange_NeedNonNegNum => GetResourceString("ArgumentOutOfRange_NeedNonNegNum"); internal static string InvalidOperation_ModificationOfNonCanonicalAcl => GetResourceString("InvalidOperation_ModificationOfNonCanonicalAcl"); internal static string InvalidOperation_MustBeSameThread => GetResourceString("InvalidOperation_MustBeSameThread"); internal static string InvalidOperation_MustLockForReadOrWrite => GetResourceString("InvalidOperation_MustLockForReadOrWrite"); internal static string InvalidOperation_MustLockForWrite => GetResourceString("InvalidOperation_MustLockForWrite"); internal static string InvalidOperation_MustRevertPrivilege => GetResourceString("InvalidOperation_MustRevertPrivilege"); internal static string InvalidOperation_NoSecurityDescriptor => GetResourceString("InvalidOperation_NoSecurityDescriptor"); internal static string InvalidOperation_OnlyValidForDS => GetResourceString("InvalidOperation_OnlyValidForDS"); internal static string InvalidOperation_DisconnectedPipe => GetResourceString("InvalidOperation_DisconnectedPipe"); internal static string NotSupported_SetMethod => GetResourceString("NotSupported_SetMethod"); internal static string PrivilegeNotHeld_Default => GetResourceString("PrivilegeNotHeld_Default"); internal static string PrivilegeNotHeld_Named => GetResourceString("PrivilegeNotHeld_Named"); internal static string Rank_MultiDimNotSupported => GetResourceString("Rank_MultiDimNotSupported"); internal static string PlatformNotSupported_AccessControl => GetResourceString("PlatformNotSupported_AccessControl"); [MethodImpl(MethodImplOptions.NoInlining)] private static bool UsingResourceKeys() { return false; } internal static string GetResourceString(string resourceKey, string defaultString = null) { if (UsingResourceKeys()) { return defaultString ?? resourceKey; } string text = null; try { text = ResourceManager.GetString(resourceKey); } catch (MissingManifestResourceException) { } if (defaultString != null && resourceKey.Equals(text)) { return defaultString; } return text; } internal static string Format(string resourceFormat, object p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(resourceFormat, p1); } internal static string Format(string resourceFormat, object p1, object p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(resourceFormat, p1, p2); } internal static string Format(string resourceFormat, object p1, object p2, object p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(resourceFormat, p1, p2, p3); } internal static string Format(string resourceFormat, params object[] args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + ", " + string.Join(", ", args); } return string.Format(resourceFormat, args); } return resourceFormat; } internal static string Format(IFormatProvider provider, string resourceFormat, object p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(provider, resourceFormat, p1); } internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(provider, resourceFormat, p1, p2); } internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2, object p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(provider, resourceFormat, p1, p2, p3); } internal static string Format(IFormatProvider provider, string resourceFormat, params object[] args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + ", " + string.Join(", ", args); } return string.Format(provider, resourceFormat, args); } return resourceFormat; } } }
plugins/System.Security.Principal.Windows.dll
Decompiled a month agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using System.Security.Principal; using Microsoft.Win32.SafeHandles; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyDefaultAlias("System.Security.Principal.Windows")] [assembly: AssemblyMetadata(".NETFrameworkAssembly", "")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyMetadata("PreferInbox", "True")] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyDescription("System.Security.Principal.Windows")] [assembly: AssemblyFileVersion("4.700.19.56404")] [assembly: AssemblyInformationalVersion("3.1.0+0f7f38c4fd323b26da10cce95f857f77f0f09b48")] [assembly: AssemblyProduct("Microsoft® .NET Core")] [assembly: AssemblyTitle("System.Security.Principal.Windows")] [assembly: CLSCompliant(true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("4.1.3.0")] [assembly: TypeForwardedTo(typeof(SafeAccessTokenHandle))] [assembly: TypeForwardedTo(typeof(IdentityNotMappedException))] [assembly: TypeForwardedTo(typeof(IdentityReference))] [assembly: TypeForwardedTo(typeof(IdentityReferenceCollection))] [assembly: TypeForwardedTo(typeof(NTAccount))] [assembly: TypeForwardedTo(typeof(SecurityIdentifier))] [assembly: TypeForwardedTo(typeof(TokenAccessLevels))] [assembly: TypeForwardedTo(typeof(WellKnownSidType))] [assembly: TypeForwardedTo(typeof(WindowsAccountType))] [assembly: TypeForwardedTo(typeof(WindowsBuiltInRole))] [assembly: TypeForwardedTo(typeof(WindowsIdentity))] [assembly: TypeForwardedTo(typeof(WindowsPrincipal))] [module: UnverifiableCode]
plugins/System.ValueTuple.dll
Decompiled a month agousing System; using System.Diagnostics; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using FxResources.System.ValueTuple; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: NeutralResourcesLanguage("en-US")] [assembly: AssemblyTitle("System.ValueTuple")] [assembly: AssemblyDescription("System.ValueTuple")] [assembly: AssemblyDefaultAlias("System.ValueTuple")] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyProduct("Microsoft® .NET Framework")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyFileVersion("4.6.26515.06")] [assembly: AssemblyInformationalVersion("4.6.26515.06 @BuiltBy: dlab-DDVSOWINAGE059 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/corefx/tree/30ab651fcb4354552bd4891619a0bdd81e0ebdbf")] [assembly: CLSCompliant(true)] [assembly: AssemblyMetadata(".NETFrameworkAssembly", "")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyMetadata("PreferInbox", "True")] [assembly: AssemblyVersion("4.0.3.0")] [assembly: TypeForwardedTo(typeof(TupleElementNamesAttribute))] [assembly: TypeForwardedTo(typeof(TupleExtensions))] [assembly: TypeForwardedTo(typeof(ValueTuple))] [assembly: TypeForwardedTo(typeof(ValueTuple<>))] [assembly: TypeForwardedTo(typeof(ValueTuple<, >))] [assembly: TypeForwardedTo(typeof(ValueTuple<, , >))] [assembly: TypeForwardedTo(typeof(ValueTuple<, , , >))] [assembly: TypeForwardedTo(typeof(ValueTuple<, , , , >))] [assembly: TypeForwardedTo(typeof(ValueTuple<, , , , , >))] [assembly: TypeForwardedTo(typeof(ValueTuple<, , , , , , >))] [assembly: TypeForwardedTo(typeof(ValueTuple<, , , , , , , >))] namespace FxResources.System.ValueTuple { internal static class SR { } } namespace System { internal static class SR { private static ResourceManager s_resourceManager; private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType)); internal static Type ResourceType { get; } = typeof(SR); internal static string ArgumentException_ValueTupleIncorrectType => GetResourceString("ArgumentException_ValueTupleIncorrectType", null); internal static string ArgumentException_ValueTupleLastArgumentNotAValueTuple => GetResourceString("ArgumentException_ValueTupleLastArgumentNotAValueTuple", null); [MethodImpl(MethodImplOptions.NoInlining)] private static bool UsingResourceKeys() { return false; } internal static string GetResourceString(string resourceKey, string defaultString) { string text = null; try { text = ResourceManager.GetString(resourceKey); } catch (MissingManifestResourceException) { } if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal)) { return defaultString; } return text; } internal static string Format(string resourceFormat, params object[] args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + string.Join(", ", args); } return string.Format(resourceFormat, args); } return resourceFormat; } internal static string Format(string resourceFormat, object p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(resourceFormat, p1); } internal static string Format(string resourceFormat, object p1, object p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(resourceFormat, p1, p2); } internal static string Format(string resourceFormat, object p1, object p2, object p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(resourceFormat, p1, p2, p3); } } }